From dfab3b64526f2fbb0b3a63d2141e3f79ffe04588 Mon Sep 17 00:00:00 2001 From: Jussi Isotalo Date: Sun, 21 Jan 2024 20:54:50 +0200 Subject: [PATCH] ## [2.10.2] - 21.01.2024(2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Lisätty koodin tarkistus että halvimpien tuntien lukumäärä <= jakson pituus - Havaittu ongelma kun H&T skriptissä oli isompi tuntimäärä (koska käyttäjän skriptin muutoksia ei tarkisteta) --- CHANGELOG.md | 7 + README.md | 6 +- dist/shelly-porssisahko-addon-temp.js | 60 +++++++ dist/shelly-porssisahko-ht-sensor-temp.js | 153 ++++++++++++++++++ ...helly-porssisahko-ht-sensor-temperature.js | 153 ------------------ ...helly-porssisahko-override-avg-price.js.js | 45 ++++++ ...ly-porssisahko-shelly-addon-temperature.js | 60 ------- dist/shelly-porssisahko-user-config.js | 2 +- ...lly-porssisahko-user-override-avg-price.js | 45 ------ dist/shelly-porssisahko.js | 2 +- shelly-library.json | 6 +- ...re.js => shelly-porssisahko-addon-temp.js} | 0 ...s => shelly-porssisahko-ht-sensor-temp.js} | 0 ...elly-porssisahko-override-avg-price.js.js} | 0 src/shelly-porssisahko.js | 5 +- 15 files changed, 277 insertions(+), 267 deletions(-) create mode 100644 dist/shelly-porssisahko-addon-temp.js create mode 100644 dist/shelly-porssisahko-ht-sensor-temp.js delete mode 100644 dist/shelly-porssisahko-ht-sensor-temperature.js create mode 100644 dist/shelly-porssisahko-override-avg-price.js.js delete mode 100644 dist/shelly-porssisahko-shelly-addon-temperature.js delete mode 100644 dist/shelly-porssisahko-user-override-avg-price.js rename src/after-build-examples/{shelly-porssisahko-shelly-addon-temperature.js => shelly-porssisahko-addon-temp.js} (100%) rename src/after-build-examples/{shelly-porssisahko-ht-sensor-temperature.js => shelly-porssisahko-ht-sensor-temp.js} (100%) rename src/after-build-examples/{shelly-porssisahko-user-override-avg-price.js => shelly-porssisahko-override-avg-price.js.js} (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a0c1e5..0f7b713 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). # Suomeksi +## [2.10.2] - 21.01.2024(2) +- Lisätty koodin tarkistus että halvimpien tuntien lukumäärä <= jakson pituus + - Havaittu ongelma kun H&T skriptissä oli isompi tuntimäärä (koska käyttäjän skriptin muutoksia ei tarkisteta) + ## [2.10.1] - 21.01.2024 - Pakko-ohjauspainikkeella voi valita, haluaako pakko-ohjata ohjauksen päälle vai pois - Tuntikohtaisissa pakko-ohjauksissa voi valita, haluaako pakko-ohjata ohjauksen päälle vai pois @@ -123,6 +127,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Versio 2 julkaistu (tehty täysin uusiksi) # In English +## [2.10.2] - 21.01.2024(2) +- Added a safety check that period hours <= period length + ## [2.10.1] - 21.01.2024 - Possible to manualyl force both on and off - Forced hours commands can be selected both on and off diff --git a/README.md b/README.md index c05dc1e..0a96a98 100644 --- a/README.md +++ b/README.md @@ -270,7 +270,7 @@ Tämä esimerkki näyttää kuinka voi hyödyntää hintatietoja ohjauksen hieno Skripti asettaa ohjauksen pois, mikäli tuntihinta on yli 80% päivän keskiarvosta. Muuten mennään pörssisähköohjauksen mukaan. -**Esimerkin koodi:** +**Esimerkin koodi:** ### Esimerkki: Ohjauksen hienosäätö lämpötilan avulla (Shelly Plus Add-On ja DS18B20) @@ -281,7 +281,7 @@ Käyttää lämpötila-anturia, jonka id on 100. * Jos lämpötila on alle 5 astetta, asetetaan se aina päälle * Muuten annetaan ohjata pörssisähköohjauksen mukaan -**Esimerkin koodi:** +**Esimerkin koodi:** ### Esimerkki: Ohjauksen hienosäätö Shelly H&T:n lämpötilamittauksen avulla @@ -295,7 +295,7 @@ Esimerkin toiminta * Jos lämpötila on alle -5°C, laitetaan halvimpien tuntien määräksi 6h ja ohjausminuuteksi 45min * Muuten annetaan ohjata pörssisähköohjauksen asetusten mukaan -**Esimerkin koodi:** +**Esimerkin koodi:** ### Esimerkki: Ulkolämpötilan hakeminen sääpalvelusta ja sen hyödyntäminen diff --git a/dist/shelly-porssisahko-addon-temp.js b/dist/shelly-porssisahko-addon-temp.js new file mode 100644 index 0000000..ad8bb84 --- /dev/null +++ b/dist/shelly-porssisahko-addon-temp.js @@ -0,0 +1,60 @@ +/** + * @license + * + * shelly-porssisahko + * + * (c) Jussi isotalo - http://jisotalo.fi + * https://github.com/jisotalo/shelly-porssisahko + * + * License: GNU Affero General Public License v3.0 + */ +let C_HIST=24,C_ERRC=3,C_ERRD=120,C_DEF={mode:0,m0:{cmd:0},m1:{lim:0},m2:{per:24,cnt:0,lim:-999,sq:0,m:999},vat:24,day:0,night:0,bk:0,err:0,outs:[0],fh:0,fhCmd:0,inv:0,min:60},_={s:{v:"2.10.2",dn:"",st:0,str:"",cmd:0,chkTs:0,errCnt:0,errTs:0,upTs:0,timeOK:0,configOK:0,fCmdTs:0,fCmd:0,tz:"+02:00",p:{ts:0,now:0,low:0,high:0,avg:0}},p:[],h:[],c:C_DEF},l=!1,i=!1;function r(t,e){e-=t;return 0<=e&&e<3600}function c(t){return Math.floor((t?t.getTime():Date.now())/1e3)}function n(t,e,s){let n=t.toString();for(;n.length=C_ERRC&&c(t)-_.s.errTs=C_ERRC&&(_.s.errCnt=0);return e}()){let e=new Date;o(e);try{let t=e.getFullYear()+"-"+n(1+e.getMonth(),2,"0")+"-"+n(a(e),2,"0")+"T00:00:00"+_.s.tz.replace("+","%2b");var s=t.replace("T00:00:00","T23:59:59");let l={url:"https://dashboard.elering.ee/api/nps/price/csv?fields=fi&start="+t+"&end="+s,timeout:5,ssl_ca:"*"};e=null,t=null,Shelly.call("HTTP.GET",l,function(e,t,s){l=null;try{if(0!==t||null==e||200!==e.code||!e.body_b64)throw Error("conn.err ("+s+") "+JSON.stringify(e));{e.headers=null,s=e.message=null,_.p=[],_.s.p.high=-999,_.s.p.low=999,e.body_b64=atob(e.body_b64),e.body_b64=e.body_b64.substring(1+e.body_b64.indexOf("\n"));let t=0;for(;0<=t;){e.body_b64=e.body_b64.substring(t);var n=[t=0,0];if(0===(t=1+e.body_b64.indexOf('"',t)))break;n[0]=+e.body_b64.substring(t,e.body_b64.indexOf('"',t)),t=2+e.body_b64.indexOf('"',t),t=2+e.body_b64.indexOf(';"',t),n[1]=+(""+e.body_b64.substring(t,e.body_b64.indexOf('"',t)).replace(",",".")),n[1]=n[1]/10*(100+(0_.s.p.high&&(_.s.p.high=n[1]),n[1]<_.s.p.low&&(_.s.p.low=n[1]),t=e.body_b64.indexOf("\n",t)}e=null,_.s.p.avg=0<_.p.length?_.s.p.avg/_.p.length:0;var i=new Date,r=new Date(1e3*_.p[0][0]);if(a(r)!==a(i))throw Error("date err "+i.toString()+" - "+r.toString());_.s.p.ts=c(i),_.s.p.now=p()}}catch(t){_.s.errCnt+=1,_.s.errTs=c(),_.s.p.ts=0,_.p=[],u(t)}v()})}catch(t){u(t),v()}}else!function(){if(0==_.s.chkTs)return 1;var t=new Date,e=new Date(1e3*_.s.chkTs);return e.getHours()!=t.getHours()||e.getFullYear()!=t.getFullYear()||0<_.s.fCmdTs&&_.s.fCmdTs-c(t)<0||0==_.s.fCmdTs&&_.c.min<60&&t.getMinutes()>=_.c.min&&_.s.cmd+_.c.inv==1}()?l=!1:v();else m(!0)}function d(e){_.c.inv&&(i=!i);let s=0,n=0;for(let t=0;t<_.c.outs.length;t++)!function(o,t){var e="{id:"+o+",on:"+(i?"true":"false")+"}";Shelly.call("Switch.Set",e,function(t,e,s,n){0!=e&&u("error setting output "+o+" "+(i?"ON":"OFF")+": "+e+" - "+s),n(0==e)},t)}(_.c.outs[t],function(t){if(s++,t&&n++,s==_.c.outs.length)if(n==s){for(;_.h.length>=C_HIST;)_.h.splice(0,1);_.h.push([c(),i?1:0]),_.s.cmd=i?1:0,e(!0)}else e(!1)})}function v(){"function"==typeof USER_CONFIG&&(_.c=USER_CONFIG(_.c,_,!1));var t,e,s=new Date;o(s),i=!1;try{function n(t){i!=t&&(_.s.st=12,u("HUOMIO: ohjaus muuttunut käyttäjän skriptin toimesta")),i=t,d(function(t){t&&(_.s.chkTs=c()),l=!1})}0===_.c.mode?(i=1===_.c.m0.cmd,_.s.st=1):_.s.timeOK&&0<_.s.p.ts&&a(new Date(1e3*_.s.p.ts))===a(s)?(_.s.p.now=p(),1===_.c.mode?(i=_.s.p.now<=("avg"==_.c.m1.lim?_.s.p.avg:_.c.m1.lim),_.s.st=i?2:3):2===_.c.mode&&(i=function(){if(0!=_.c.m2.cn){_.c.m2.cnt=Math.min(_.c.m2.cnt,_.c.m2.per);var n=[];for(g=0;g<_.p.length;g+=_.c.m2.per){var o=[];for(ind=g;ind_.p.length-1);ind++)o.push(ind);if(_.c.m2.sq){let e=999,s=0;for(A=0;A<=o.length-_.c.m2.cnt;A++){let t=0;for(h=A;h("avg"==_.c.m2.m?_.s.p.avg:_.c.m2.m)&&(i=!1,_.s.st=11)):_.s.timeOK?(_.s.st=7,t=1<=_.c.min&&(_.s.st=13,i=!1),_.s.timeOK&&0<_.s.fCmdTs&&(0<_.s.fCmdTs-c(s)?(i=1==_.s.fCmd,_.s.st=9):_.s.fCmdTs=0),"function"==typeof USER_OVERRIDE?USER_OVERRIDE(i,_,n):n(i)}catch(t){u(t),l=!1}}let g=0,A=0,h=0;function p(){var e=c();for(let t=0;t<_.p.length;t++)if(r(_.p[t][0],e))return _.p[t][1];throw _.p.length<24&&(_.s.p.ts=0),Error("no price for this hour")}u("shelly-porssisahko v."+_.s.v),u("URL: http://"+(Shelly.getComponentStatus("wifi").sta_ip??"192.168.33.1")+"/script/"+Shelly.getCurrentScriptId()),HTTPServer.registerEndpoint("",function(s,n){try{if(l)return s=null,n.code=503,void n.send();var o=function(t){var e={},s=t.split("&");for(let t=0;t 15) { + state.s.str = "Lämpötila " + temp.tC + "°C on yli 15°C -> ohjaus pois"; + console.log("Lämpötila on yli 15 astetta, asetetaan ohjaus pois. Lämpötila nyt:", temp.tC); + cmd = false; + + } else if (!cmd && temp.tC < 5) { + state.s.str = "Lämpötila " + temp.tC + "°C on alle 5°C -> ohjaus päälle"; + console.log("Lämpötila on alle 5 astetta, asetetaan ohjaus päälle. Lämpötila nyt:", temp.tC); + cmd = true; + + } else { + state.s.str = "Lämpötila " + temp.tC + "°C -> mennään ohjauksen mukaan"; + } + + //console.log("USER_OVERRIDE suoritettu. Ohjauksen tila nyt: ", cmd); + callback(cmd); + + } catch (err) { + console.log("Virhe tapahtui USER_OVERRIDE-funktiossa. Virhe:", err); + state.s.str = "Lämpötilaohjauksen virhe:" + err; + callback(cmd); + } +} \ No newline at end of file diff --git a/dist/shelly-porssisahko-ht-sensor-temp.js b/dist/shelly-porssisahko-ht-sensor-temp.js new file mode 100644 index 0000000..760a5d8 --- /dev/null +++ b/dist/shelly-porssisahko-ht-sensor-temp.js @@ -0,0 +1,153 @@ +/** + * @license + * + * shelly-porssisahko + * + * (c) Jussi isotalo - http://jisotalo.fi + * https://github.com/jisotalo/shelly-porssisahko + * + * License: GNU Affero General Public License v3.0 + */ +let C_HIST=24,C_ERRC=3,C_ERRD=120,C_DEF={mode:0,m0:{cmd:0},m1:{lim:0},m2:{per:24,cnt:0,lim:-999,sq:0,m:999},vat:24,day:0,night:0,bk:0,err:0,outs:[0],fh:0,fhCmd:0,inv:0,min:60},_={s:{v:"2.10.2",dn:"",st:0,str:"",cmd:0,chkTs:0,errCnt:0,errTs:0,upTs:0,timeOK:0,configOK:0,fCmdTs:0,fCmd:0,tz:"+02:00",p:{ts:0,now:0,low:0,high:0,avg:0}},p:[],h:[],c:C_DEF},l=!1,i=!1;function r(t,e){e-=t;return 0<=e&&e<3600}function c(t){return Math.floor((t?t.getTime():Date.now())/1e3)}function n(t,e,s){let n=t.toString();for(;n.length=C_ERRC&&c(t)-_.s.errTs=C_ERRC&&(_.s.errCnt=0);return e}()){let e=new Date;o(e);try{let t=e.getFullYear()+"-"+n(1+e.getMonth(),2,"0")+"-"+n(a(e),2,"0")+"T00:00:00"+_.s.tz.replace("+","%2b");var s=t.replace("T00:00:00","T23:59:59");let l={url:"https://dashboard.elering.ee/api/nps/price/csv?fields=fi&start="+t+"&end="+s,timeout:5,ssl_ca:"*"};e=null,t=null,Shelly.call("HTTP.GET",l,function(e,t,s){l=null;try{if(0!==t||null==e||200!==e.code||!e.body_b64)throw Error("conn.err ("+s+") "+JSON.stringify(e));{e.headers=null,s=e.message=null,_.p=[],_.s.p.high=-999,_.s.p.low=999,e.body_b64=atob(e.body_b64),e.body_b64=e.body_b64.substring(1+e.body_b64.indexOf("\n"));let t=0;for(;0<=t;){e.body_b64=e.body_b64.substring(t);var n=[t=0,0];if(0===(t=1+e.body_b64.indexOf('"',t)))break;n[0]=+e.body_b64.substring(t,e.body_b64.indexOf('"',t)),t=2+e.body_b64.indexOf('"',t),t=2+e.body_b64.indexOf(';"',t),n[1]=+(""+e.body_b64.substring(t,e.body_b64.indexOf('"',t)).replace(",",".")),n[1]=n[1]/10*(100+(0_.s.p.high&&(_.s.p.high=n[1]),n[1]<_.s.p.low&&(_.s.p.low=n[1]),t=e.body_b64.indexOf("\n",t)}e=null,_.s.p.avg=0<_.p.length?_.s.p.avg/_.p.length:0;var i=new Date,r=new Date(1e3*_.p[0][0]);if(a(r)!==a(i))throw Error("date err "+i.toString()+" - "+r.toString());_.s.p.ts=c(i),_.s.p.now=p()}}catch(t){_.s.errCnt+=1,_.s.errTs=c(),_.s.p.ts=0,_.p=[],u(t)}v()})}catch(t){u(t),v()}}else!function(){if(0==_.s.chkTs)return 1;var t=new Date,e=new Date(1e3*_.s.chkTs);return e.getHours()!=t.getHours()||e.getFullYear()!=t.getFullYear()||0<_.s.fCmdTs&&_.s.fCmdTs-c(t)<0||0==_.s.fCmdTs&&_.c.min<60&&t.getMinutes()>=_.c.min&&_.s.cmd+_.c.inv==1}()?l=!1:v();else m(!0)}function d(e){_.c.inv&&(i=!i);let s=0,n=0;for(let t=0;t<_.c.outs.length;t++)!function(o,t){var e="{id:"+o+",on:"+(i?"true":"false")+"}";Shelly.call("Switch.Set",e,function(t,e,s,n){0!=e&&u("error setting output "+o+" "+(i?"ON":"OFF")+": "+e+" - "+s),n(0==e)},t)}(_.c.outs[t],function(t){if(s++,t&&n++,s==_.c.outs.length)if(n==s){for(;_.h.length>=C_HIST;)_.h.splice(0,1);_.h.push([c(),i?1:0]),_.s.cmd=i?1:0,e(!0)}else e(!1)})}function v(){"function"==typeof USER_CONFIG&&(_.c=USER_CONFIG(_.c,_,!1));var t,e,s=new Date;o(s),i=!1;try{function n(t){i!=t&&(_.s.st=12,u("HUOMIO: ohjaus muuttunut käyttäjän skriptin toimesta")),i=t,d(function(t){t&&(_.s.chkTs=c()),l=!1})}0===_.c.mode?(i=1===_.c.m0.cmd,_.s.st=1):_.s.timeOK&&0<_.s.p.ts&&a(new Date(1e3*_.s.p.ts))===a(s)?(_.s.p.now=p(),1===_.c.mode?(i=_.s.p.now<=("avg"==_.c.m1.lim?_.s.p.avg:_.c.m1.lim),_.s.st=i?2:3):2===_.c.mode&&(i=function(){if(0!=_.c.m2.cn){_.c.m2.cnt=Math.min(_.c.m2.cnt,_.c.m2.per);var n=[];for(g=0;g<_.p.length;g+=_.c.m2.per){var o=[];for(ind=g;ind_.p.length-1);ind++)o.push(ind);if(_.c.m2.sq){let e=999,s=0;for(A=0;A<=o.length-_.c.m2.cnt;A++){let t=0;for(h=A;h("avg"==_.c.m2.m?_.s.p.avg:_.c.m2.m)&&(i=!1,_.s.st=11)):_.s.timeOK?(_.s.st=7,t=1<=_.c.min&&(_.s.st=13,i=!1),_.s.timeOK&&0<_.s.fCmdTs&&(0<_.s.fCmdTs-c(s)?(i=1==_.s.fCmd,_.s.st=9):_.s.fCmdTs=0),"function"==typeof USER_OVERRIDE?USER_OVERRIDE(i,_,n):n(i)}catch(t){u(t),l=!1}}let g=0,A=0,h=0;function p(){var e=c();for(let t=0;t<_.p.length;t++)if(r(_.p[t][0],e))return _.p[t][1];throw _.p.length<24&&(_.s.p.ts=0),Error("no price for this hour")}u("shelly-porssisahko v."+_.s.v),u("URL: http://"+(Shelly.getComponentStatus("wifi").sta_ip??"192.168.33.1")+"/script/"+Shelly.getCurrentScriptId()),HTTPServer.registerEndpoint("",function(s,n){try{if(l)return s=null,n.code=503,void n.send();var o=function(t){var e={},s=t.split("&");for(let t=0;t sensor reports" -osoitteisiin osoite + * http://ip-osoite/script/1/update-temp + * missä ip-osoite on tämän shellyn osoite. + * Muista myös ottaa "sensor reports" -ominaisuus käyttöön + */ + +//Kuinka vanha lämpötilatieto sallitaan ohjauksessa (tunteina) +let TEMPERATURE_MAX_AGE_HOURS = 12; + +//Viimeisin tiedossa oleva lämpötiladata +let data = null; +//Alkuperäiset muokkaamattomat asetukset +let originalConfig = { + hours: 0, + minutes: 60 +}; + +function USER_CONFIG(config, state, initialized) { + //Tallenentaan alkuperäiset asetukset muistiin + if (initialized) { + originalConfig.hours = config.m2.cnt; + originalConfig.minutes = config.min; + + console.log("Alkuperäiset asetukset:", originalConfig); + } + + //Käytetää lähtökohtaisesti alkuperäisiin asetuksiin tallennettua tuntimäärää ja ohjausminuutteja + //Näin ollen jos tallentaa asetukset käyttöliittymältä, tulee ne myös tähän käyttöön + let hours = originalConfig.hours; + let minutes = originalConfig.minutes; + + try { + + if (data == null) { + console.log("Lämpötilatietoa ei ole saatavilla"); + state.s.str = "Lämpötila ei tiedossa -> halvat tunnit: " + hours + " h, ohjaus: " + minutes + " min"; + + } else { + let age = (Date.now() - data.ts) / 1000.0 / 60.0 / 60.0; + console.log("Lämpötila on tiedossa (päivittynyt " + age.toFixed(2) + " h sitten):", data); + + if (age <= TEMPERATURE_MAX_AGE_HOURS * 60) { + //------------------------------ + // Toimintalogiikka + // muokkaa haluamaksesi + //------------------------------ + + //Muutetaan lämpötilan perusteella lämmitystuntien määrää ja minuutteja + if (data.temp <= -15) { + hours = 8; + minutes = 60; + + } else if (data.temp <= -10) { + hours = 7; + minutes = 45; + + } else if (data.temp <= -5) { + hours = 6; + minutes = 45; + } else { + hours = 6; + minutes = 45; + } + + //------------------------------ + // Toimintalogiikka päättyy + //------------------------------ + state.s.str = "Lämpötila " + data.temp.toFixed(1) + "°C (" + age.toFixed(1) + "h sitten) -> halvat tunnit: " + hours + " h, ohjaus: " + minutes + " min"; + console.log("Lämpötila:", data.temp.toFixed(1), "°C -> asetettu halvimpien tuntien määräksi ", hours, "h ja ohjausminuuteiksi", minutes, "min"); + + } else { + console.log("Lämpötilatieto on liian vanha -> ei käytetä"); + state.s.str = "Lämpötilatieto liian vanha (" + age.toFixed(1) + " h) -> halvat tunnit: " + hours + " h, ohjaus: " + minutes + " min"; + } + } + } catch (err) { + state.s.str = "Virhe lämpötilaohjauksessa:" + err; + console.log("Virhe tapahtui USER_CONFIG-funktiossa. Virhe:", err); + } + + //Asetetaan arvot asetuksiin + config.m2.cnt = hours; + config.min = minutes; + + return config; +} + +/** + * Apufunktio, joka kerää parametrit osoitteesta + */ +function parseParams(params) { + let res = {}; + let splitted = params.split("&"); + + for (let i = 0; i < splitted.length; i++) { + let pair = splitted[i].split("="); + + res[pair[0]] = pair[1]; + } + + return res; +} + +/** + * Takaisinkutsu, joka suoritetaan kun saadaan HTTP-pyyntö + */ +function onHttpRequest(request, response) { + try { + let params = parseParams(request.query); + request = null; + + if (params.temp != undefined) { + data = { + temp: Number(params.temp), + ts: Math.floor(Date.now()) + }; + + console.log("Lämpötilatiedot päivitetty, pyydetään pörssisähkölogiikan ajoa. Data:", data); + _.s.chkTs = 0; + response.code = 200; + + } else { + console.log("Lämpötilatiedojen päivitys epäonnistui, 'temp' puuttuu parametreista:", params); + response.code = 400; + } + + response.send(); + + } catch (err) { + console.log("Virhe:", err); + } +} + +//Rekisteröidään /script/x/update-temp -osoite +HTTPServer.registerEndpoint('update-temp', onHttpRequest); \ No newline at end of file diff --git a/dist/shelly-porssisahko-ht-sensor-temperature.js b/dist/shelly-porssisahko-ht-sensor-temperature.js deleted file mode 100644 index 5553880..0000000 --- a/dist/shelly-porssisahko-ht-sensor-temperature.js +++ /dev/null @@ -1,153 +0,0 @@ -/** - * @license - * - * shelly-porssisahko - * - * (c) Jussi isotalo - http://jisotalo.fi - * https://github.com/jisotalo/shelly-porssisahko - * - * License: GNU Affero General Public License v3.0 - */ -let C_HIST=24,C_ERRC=3,C_ERRD=120,C_DEF={mode:0,m0:{cmd:0},m1:{lim:0},m2:{per:24,cnt:0,lim:-999,sq:0,m:999},vat:24,day:0,night:0,bk:0,err:0,outs:[0],fh:0,fhCmd:0,inv:0,min:60},_={s:{v:"2.10.1",dn:"",st:0,str:"",cmd:0,chkTs:0,errCnt:0,errTs:0,upTs:0,timeOK:0,configOK:0,fCmdTs:0,fCmd:0,tz:"+02:00",p:{ts:0,now:0,low:0,high:0,avg:0}},p:[],h:[],c:C_DEF},l=!1,i=!1;function r(t,e){e-=t;return 0<=e&&e<3600}function c(t){return Math.floor((t?t.getTime():Date.now())/1e3)}function n(t,e,s){let n=t.toString();for(;n.length=C_ERRC&&c(t)-_.s.errTs=C_ERRC&&(_.s.errCnt=0);return e}()){let e=new Date;o(e);try{let t=e.getFullYear()+"-"+n(1+e.getMonth(),2,"0")+"-"+n(a(e),2,"0")+"T00:00:00"+_.s.tz.replace("+","%2b");var s=t.replace("T00:00:00","T23:59:59");let l={url:"https://dashboard.elering.ee/api/nps/price/csv?fields=fi&start="+t+"&end="+s,timeout:5,ssl_ca:"*"};e=null,t=null,Shelly.call("HTTP.GET",l,function(e,t,s){l=null;try{if(0!==t||null==e||200!==e.code||!e.body_b64)throw Error("conn.err ("+s+") "+JSON.stringify(e));{e.headers=null,s=e.message=null,_.p=[],_.s.p.high=-999,_.s.p.low=999,e.body_b64=atob(e.body_b64),e.body_b64=e.body_b64.substring(1+e.body_b64.indexOf("\n"));let t=0;for(;0<=t;){e.body_b64=e.body_b64.substring(t);var n=[t=0,0];if(0===(t=1+e.body_b64.indexOf('"',t)))break;n[0]=+e.body_b64.substring(t,e.body_b64.indexOf('"',t)),t=2+e.body_b64.indexOf('"',t),t=2+e.body_b64.indexOf(';"',t),n[1]=+(""+e.body_b64.substring(t,e.body_b64.indexOf('"',t)).replace(",",".")),n[1]=n[1]/10*(100+(0_.s.p.high&&(_.s.p.high=n[1]),n[1]<_.s.p.low&&(_.s.p.low=n[1]),t=e.body_b64.indexOf("\n",t)}e=null,_.s.p.avg=0<_.p.length?_.s.p.avg/_.p.length:0;var i=new Date,r=new Date(1e3*_.p[0][0]);if(a(r)!==a(i))throw Error("date err "+i.toString()+" - "+r.toString());_.s.p.ts=c(i),_.s.p.now=y()}}catch(t){_.s.errCnt+=1,_.s.errTs=c(),_.s.p.ts=0,_.p=[],u(t)}v()})}catch(t){u(t),v()}}else!function(){if(0==_.s.chkTs)return 1;var t=new Date,e=new Date(1e3*_.s.chkTs);return e.getHours()!=t.getHours()||e.getFullYear()!=t.getFullYear()||0<_.s.fCmdTs&&_.s.fCmdTs-c(t)<0||0==_.s.fCmdTs&&_.c.min<60&&t.getMinutes()>=_.c.min&&_.s.cmd+_.c.inv==1}()?l=!1:v();else b(!0)}function d(e){_.c.inv&&(i=!i);let s=0,n=0;for(let t=0;t<_.c.outs.length;t++)!function(o,t){var e="{id:"+o+",on:"+(i?"true":"false")+"}";Shelly.call("Switch.Set",e,function(t,e,s,n){0!=e&&u("error setting output "+o+" "+(i?"ON":"OFF")+": "+e+" - "+s),n(0==e)},t)}(_.c.outs[t],function(t){if(s++,t&&n++,s==_.c.outs.length)if(n==s){for(;_.h.length>=C_HIST;)_.h.splice(0,1);_.h.push([c(),i?1:0]),_.s.cmd=i?1:0,e(!0)}else e(!1)})}function v(){"function"==typeof USER_CONFIG&&(_.c=USER_CONFIG(_.c,_,!1));var t,e,s=new Date;o(s),i=!1;try{function n(t){i!=t&&(_.s.st=12,u("HUOMIO: ohjaus muuttunut käyttäjän skriptin toimesta")),i=t,d(function(t){t&&(_.s.chkTs=c()),l=!1})}0===_.c.mode?(i=1===_.c.m0.cmd,_.s.st=1):_.s.timeOK&&0<_.s.p.ts&&a(new Date(1e3*_.s.p.ts))===a(s)?(_.s.p.now=y(),1===_.c.mode?(i=_.s.p.now<=("avg"==_.c.m1.lim?_.s.p.avg:_.c.m1.lim),_.s.st=i?2:3):2===_.c.mode&&(i=function(){if(0!=_.c.m2.cn){var n=[];for(g=0;g<_.p.length;g+=_.c.m2.per){var o=[];for(ind=g;ind_.p.length-1);ind++)o.push(ind);if(_.c.m2.sq){let e=999,s=0;for(A=0;A<=o.length-_.c.m2.cnt;A++){let t=0;for(h=A;h("avg"==_.c.m2.m?_.s.p.avg:_.c.m2.m)&&(i=!1,_.s.st=11)):_.s.timeOK?(_.s.st=7,t=1<=_.c.min&&(_.s.st=13,i=!1),_.s.timeOK&&0<_.s.fCmdTs&&(0<_.s.fCmdTs-c(s)?(i=1==_.s.fCmd,_.s.st=9):_.s.fCmdTs=0),"function"==typeof USER_OVERRIDE?USER_OVERRIDE(i,_,n):n(i)}catch(t){u(t),l=!1}}let g=0,A=0,h=0;function y(){var e=c();for(let t=0;t<_.p.length;t++)if(r(_.p[t][0],e))return _.p[t][1];throw _.p.length<24&&(_.s.p.ts=0),Error("no price for this hour")}u("shelly-porssisahko v."+_.s.v),u("URL: http://"+(Shelly.getComponentStatus("wifi").sta_ip??"192.168.33.1")+"/script/"+Shelly.getCurrentScriptId()),HTTPServer.registerEndpoint("",function(s,n){try{if(l)return s=null,n.code=503,void n.send();var o=function(t){var e={},s=t.split("&");for(let t=0;t sensor reports" -osoitteisiin osoite - * http://ip-osoite/script/1/update-temp - * missä ip-osoite on tämän shellyn osoite. - * Muista myös ottaa "sensor reports" -ominaisuus käyttöön - */ - -//Kuinka vanha lämpötilatieto sallitaan ohjauksessa (tunteina) -let TEMPERATURE_MAX_AGE_HOURS = 12; - -//Viimeisin tiedossa oleva lämpötiladata -let data = null; -//Alkuperäiset muokkaamattomat asetukset -let originalConfig = { - hours: 0, - minutes: 60 -}; - -function USER_CONFIG(config, state, initialized) { - //Tallenentaan alkuperäiset asetukset muistiin - if (initialized) { - originalConfig.hours = config.m2.cnt; - originalConfig.minutes = config.min; - - console.log("Alkuperäiset asetukset:", originalConfig); - } - - //Käytetää lähtökohtaisesti alkuperäisiin asetuksiin tallennettua tuntimäärää ja ohjausminuutteja - //Näin ollen jos tallentaa asetukset käyttöliittymältä, tulee ne myös tähän käyttöön - let hours = originalConfig.hours; - let minutes = originalConfig.minutes; - - try { - - if (data == null) { - console.log("Lämpötilatietoa ei ole saatavilla"); - state.s.str = "Lämpötila ei tiedossa -> halvat tunnit: " + hours + " h, ohjaus: " + minutes + " min"; - - } else { - let age = (Date.now() - data.ts) / 1000.0 / 60.0 / 60.0; - console.log("Lämpötila on tiedossa (päivittynyt " + age.toFixed(2) + " h sitten):", data); - - if (age <= TEMPERATURE_MAX_AGE_HOURS * 60) { - //------------------------------ - // Toimintalogiikka - // muokkaa haluamaksesi - //------------------------------ - - //Muutetaan lämpötilan perusteella lämmitystuntien määrää ja minuutteja - if (data.temp <= -15) { - hours = 8; - minutes = 60; - - } else if (data.temp <= -10) { - hours = 7; - minutes = 45; - - } else if (data.temp <= -5) { - hours = 6; - minutes = 45; - } else { - hours = 6; - minutes = 45; - } - - //------------------------------ - // Toimintalogiikka päättyy - //------------------------------ - state.s.str = "Lämpötila " + data.temp.toFixed(1) + "°C (" + age.toFixed(1) + "h sitten) -> halvat tunnit: " + hours + " h, ohjaus: " + minutes + " min"; - console.log("Lämpötila:", data.temp.toFixed(1), "°C -> asetettu halvimpien tuntien määräksi ", hours, "h ja ohjausminuuteiksi", minutes, "min"); - - } else { - console.log("Lämpötilatieto on liian vanha -> ei käytetä"); - state.s.str = "Lämpötilatieto liian vanha (" + age.toFixed(1) + " h) -> halvat tunnit: " + hours + " h, ohjaus: " + minutes + " min"; - } - } - } catch (err) { - state.s.str = "Virhe lämpötilaohjauksessa:" + err; - console.log("Virhe tapahtui USER_CONFIG-funktiossa. Virhe:", err); - } - - //Asetetaan arvot asetuksiin - config.m2.cnt = hours; - config.min = minutes; - - return config; -} - -/** - * Apufunktio, joka kerää parametrit osoitteesta - */ -function parseParams(params) { - let res = {}; - let splitted = params.split("&"); - - for (let i = 0; i < splitted.length; i++) { - let pair = splitted[i].split("="); - - res[pair[0]] = pair[1]; - } - - return res; -} - -/** - * Takaisinkutsu, joka suoritetaan kun saadaan HTTP-pyyntö - */ -function onHttpRequest(request, response) { - try { - let params = parseParams(request.query); - request = null; - - if (params.temp != undefined) { - data = { - temp: Number(params.temp), - ts: Math.floor(Date.now()) - }; - - console.log("Lämpötilatiedot päivitetty, pyydetään pörssisähkölogiikan ajoa. Data:", data); - _.s.chkTs = 0; - response.code = 200; - - } else { - console.log("Lämpötilatiedojen päivitys epäonnistui, 'temp' puuttuu parametreista:", params); - response.code = 400; - } - - response.send(); - - } catch (err) { - console.log("Virhe:", err); - } -} - -//Rekisteröidään /script/x/update-temp -osoite -HTTPServer.registerEndpoint('update-temp', onHttpRequest); \ No newline at end of file diff --git a/dist/shelly-porssisahko-override-avg-price.js.js b/dist/shelly-porssisahko-override-avg-price.js.js new file mode 100644 index 0000000..879fba3 --- /dev/null +++ b/dist/shelly-porssisahko-override-avg-price.js.js @@ -0,0 +1,45 @@ +/** + * @license + * + * shelly-porssisahko + * + * (c) Jussi isotalo - http://jisotalo.fi + * https://github.com/jisotalo/shelly-porssisahko + * + * License: GNU Affero General Public License v3.0 + */ +let C_HIST=24,C_ERRC=3,C_ERRD=120,C_DEF={mode:0,m0:{cmd:0},m1:{lim:0},m2:{per:24,cnt:0,lim:-999,sq:0,m:999},vat:24,day:0,night:0,bk:0,err:0,outs:[0],fh:0,fhCmd:0,inv:0,min:60},_={s:{v:"2.10.2",dn:"",st:0,str:"",cmd:0,chkTs:0,errCnt:0,errTs:0,upTs:0,timeOK:0,configOK:0,fCmdTs:0,fCmd:0,tz:"+02:00",p:{ts:0,now:0,low:0,high:0,avg:0}},p:[],h:[],c:C_DEF},l=!1,i=!1;function r(t,e){e-=t;return 0<=e&&e<3600}function c(t){return Math.floor((t?t.getTime():Date.now())/1e3)}function n(t,e,s){let n=t.toString();for(;n.length=C_ERRC&&c(t)-_.s.errTs=C_ERRC&&(_.s.errCnt=0);return e}()){let e=new Date;o(e);try{let t=e.getFullYear()+"-"+n(1+e.getMonth(),2,"0")+"-"+n(a(e),2,"0")+"T00:00:00"+_.s.tz.replace("+","%2b");var s=t.replace("T00:00:00","T23:59:59");let l={url:"https://dashboard.elering.ee/api/nps/price/csv?fields=fi&start="+t+"&end="+s,timeout:5,ssl_ca:"*"};e=null,t=null,Shelly.call("HTTP.GET",l,function(e,t,s){l=null;try{if(0!==t||null==e||200!==e.code||!e.body_b64)throw Error("conn.err ("+s+") "+JSON.stringify(e));{e.headers=null,s=e.message=null,_.p=[],_.s.p.high=-999,_.s.p.low=999,e.body_b64=atob(e.body_b64),e.body_b64=e.body_b64.substring(1+e.body_b64.indexOf("\n"));let t=0;for(;0<=t;){e.body_b64=e.body_b64.substring(t);var n=[t=0,0];if(0===(t=1+e.body_b64.indexOf('"',t)))break;n[0]=+e.body_b64.substring(t,e.body_b64.indexOf('"',t)),t=2+e.body_b64.indexOf('"',t),t=2+e.body_b64.indexOf(';"',t),n[1]=+(""+e.body_b64.substring(t,e.body_b64.indexOf('"',t)).replace(",",".")),n[1]=n[1]/10*(100+(0_.s.p.high&&(_.s.p.high=n[1]),n[1]<_.s.p.low&&(_.s.p.low=n[1]),t=e.body_b64.indexOf("\n",t)}e=null,_.s.p.avg=0<_.p.length?_.s.p.avg/_.p.length:0;var i=new Date,r=new Date(1e3*_.p[0][0]);if(a(r)!==a(i))throw Error("date err "+i.toString()+" - "+r.toString());_.s.p.ts=c(i),_.s.p.now=p()}}catch(t){_.s.errCnt+=1,_.s.errTs=c(),_.s.p.ts=0,_.p=[],u(t)}v()})}catch(t){u(t),v()}}else!function(){if(0==_.s.chkTs)return 1;var t=new Date,e=new Date(1e3*_.s.chkTs);return e.getHours()!=t.getHours()||e.getFullYear()!=t.getFullYear()||0<_.s.fCmdTs&&_.s.fCmdTs-c(t)<0||0==_.s.fCmdTs&&_.c.min<60&&t.getMinutes()>=_.c.min&&_.s.cmd+_.c.inv==1}()?l=!1:v();else m(!0)}function d(e){_.c.inv&&(i=!i);let s=0,n=0;for(let t=0;t<_.c.outs.length;t++)!function(o,t){var e="{id:"+o+",on:"+(i?"true":"false")+"}";Shelly.call("Switch.Set",e,function(t,e,s,n){0!=e&&u("error setting output "+o+" "+(i?"ON":"OFF")+": "+e+" - "+s),n(0==e)},t)}(_.c.outs[t],function(t){if(s++,t&&n++,s==_.c.outs.length)if(n==s){for(;_.h.length>=C_HIST;)_.h.splice(0,1);_.h.push([c(),i?1:0]),_.s.cmd=i?1:0,e(!0)}else e(!1)})}function v(){"function"==typeof USER_CONFIG&&(_.c=USER_CONFIG(_.c,_,!1));var t,e,s=new Date;o(s),i=!1;try{function n(t){i!=t&&(_.s.st=12,u("HUOMIO: ohjaus muuttunut käyttäjän skriptin toimesta")),i=t,d(function(t){t&&(_.s.chkTs=c()),l=!1})}0===_.c.mode?(i=1===_.c.m0.cmd,_.s.st=1):_.s.timeOK&&0<_.s.p.ts&&a(new Date(1e3*_.s.p.ts))===a(s)?(_.s.p.now=p(),1===_.c.mode?(i=_.s.p.now<=("avg"==_.c.m1.lim?_.s.p.avg:_.c.m1.lim),_.s.st=i?2:3):2===_.c.mode&&(i=function(){if(0!=_.c.m2.cn){_.c.m2.cnt=Math.min(_.c.m2.cnt,_.c.m2.per);var n=[];for(g=0;g<_.p.length;g+=_.c.m2.per){var o=[];for(ind=g;ind_.p.length-1);ind++)o.push(ind);if(_.c.m2.sq){let e=999,s=0;for(A=0;A<=o.length-_.c.m2.cnt;A++){let t=0;for(h=A;h("avg"==_.c.m2.m?_.s.p.avg:_.c.m2.m)&&(i=!1,_.s.st=11)):_.s.timeOK?(_.s.st=7,t=1<=_.c.min&&(_.s.st=13,i=!1),_.s.timeOK&&0<_.s.fCmdTs&&(0<_.s.fCmdTs-c(s)?(i=1==_.s.fCmd,_.s.st=9):_.s.fCmdTs=0),"function"==typeof USER_OVERRIDE?USER_OVERRIDE(i,_,n):n(i)}catch(t){u(t),l=!1}}let g=0,A=0,h=0;function p(){var e=c();for(let t=0;t<_.p.length;t++)if(r(_.p[t][0],e))return _.p[t][1];throw _.p.length<24&&(_.s.p.ts=0),Error("no price for this hour")}u("shelly-porssisahko v."+_.s.v),u("URL: http://"+(Shelly.getComponentStatus("wifi").sta_ip??"192.168.33.1")+"/script/"+Shelly.getCurrentScriptId()),HTTPServer.registerEndpoint("",function(s,n){try{if(l)return s=null,n.code=503,void n.send();var o=function(t){var e={},s=t.split("&");for(let t=0;t 0.8 * state.s.p.avg) { + state.s.str = "Hinta (" + state.s.p.now.toFixed(2) + "c/kWh) on yli 80% keskiarvosta -> ohjaus pois"; + console.log("Hinta (" + state.s.p.now.toFixed(2) + "c/kWh) on yli 80% keskiarvosta -> ohjaus pois"); + cmd = false; + + } else { + state.s.str = "Keskiarvo-ohjaus: hinta OK -> ei muutosta"; + } + + //console.log("USER_OVERRIDE suoritettu. Ohjauksen tila nyt: ", cmd); + callback(cmd); + + } catch (err) { + console.log("Virhe tapahtui USER_OVERRIDE-funktiossa. Virhe:", err); + state.s.str = "Keskiarvo-ohjauksen virhe:" + err; + callback(cmd); + } +} \ No newline at end of file diff --git a/dist/shelly-porssisahko-shelly-addon-temperature.js b/dist/shelly-porssisahko-shelly-addon-temperature.js deleted file mode 100644 index bcc9e2f..0000000 --- a/dist/shelly-porssisahko-shelly-addon-temperature.js +++ /dev/null @@ -1,60 +0,0 @@ -/** - * @license - * - * shelly-porssisahko - * - * (c) Jussi isotalo - http://jisotalo.fi - * https://github.com/jisotalo/shelly-porssisahko - * - * License: GNU Affero General Public License v3.0 - */ -let C_HIST=24,C_ERRC=3,C_ERRD=120,C_DEF={mode:0,m0:{cmd:0},m1:{lim:0},m2:{per:24,cnt:0,lim:-999,sq:0,m:999},vat:24,day:0,night:0,bk:0,err:0,outs:[0],fh:0,fhCmd:0,inv:0,min:60},_={s:{v:"2.10.1",dn:"",st:0,str:"",cmd:0,chkTs:0,errCnt:0,errTs:0,upTs:0,timeOK:0,configOK:0,fCmdTs:0,fCmd:0,tz:"+02:00",p:{ts:0,now:0,low:0,high:0,avg:0}},p:[],h:[],c:C_DEF},l=!1,i=!1;function r(t,e){e-=t;return 0<=e&&e<3600}function c(t){return Math.floor((t?t.getTime():Date.now())/1e3)}function n(t,e,s){let n=t.toString();for(;n.length=C_ERRC&&c(t)-_.s.errTs=C_ERRC&&(_.s.errCnt=0);return e}()){let e=new Date;o(e);try{let t=e.getFullYear()+"-"+n(1+e.getMonth(),2,"0")+"-"+n(a(e),2,"0")+"T00:00:00"+_.s.tz.replace("+","%2b");var s=t.replace("T00:00:00","T23:59:59");let l={url:"https://dashboard.elering.ee/api/nps/price/csv?fields=fi&start="+t+"&end="+s,timeout:5,ssl_ca:"*"};e=null,t=null,Shelly.call("HTTP.GET",l,function(e,t,s){l=null;try{if(0!==t||null==e||200!==e.code||!e.body_b64)throw Error("conn.err ("+s+") "+JSON.stringify(e));{e.headers=null,s=e.message=null,_.p=[],_.s.p.high=-999,_.s.p.low=999,e.body_b64=atob(e.body_b64),e.body_b64=e.body_b64.substring(1+e.body_b64.indexOf("\n"));let t=0;for(;0<=t;){e.body_b64=e.body_b64.substring(t);var n=[t=0,0];if(0===(t=1+e.body_b64.indexOf('"',t)))break;n[0]=+e.body_b64.substring(t,e.body_b64.indexOf('"',t)),t=2+e.body_b64.indexOf('"',t),t=2+e.body_b64.indexOf(';"',t),n[1]=+(""+e.body_b64.substring(t,e.body_b64.indexOf('"',t)).replace(",",".")),n[1]=n[1]/10*(100+(0_.s.p.high&&(_.s.p.high=n[1]),n[1]<_.s.p.low&&(_.s.p.low=n[1]),t=e.body_b64.indexOf("\n",t)}e=null,_.s.p.avg=0<_.p.length?_.s.p.avg/_.p.length:0;var i=new Date,r=new Date(1e3*_.p[0][0]);if(a(r)!==a(i))throw Error("date err "+i.toString()+" - "+r.toString());_.s.p.ts=c(i),_.s.p.now=y()}}catch(t){_.s.errCnt+=1,_.s.errTs=c(),_.s.p.ts=0,_.p=[],u(t)}v()})}catch(t){u(t),v()}}else!function(){if(0==_.s.chkTs)return 1;var t=new Date,e=new Date(1e3*_.s.chkTs);return e.getHours()!=t.getHours()||e.getFullYear()!=t.getFullYear()||0<_.s.fCmdTs&&_.s.fCmdTs-c(t)<0||0==_.s.fCmdTs&&_.c.min<60&&t.getMinutes()>=_.c.min&&_.s.cmd+_.c.inv==1}()?l=!1:v();else b(!0)}function d(e){_.c.inv&&(i=!i);let s=0,n=0;for(let t=0;t<_.c.outs.length;t++)!function(o,t){var e="{id:"+o+",on:"+(i?"true":"false")+"}";Shelly.call("Switch.Set",e,function(t,e,s,n){0!=e&&u("error setting output "+o+" "+(i?"ON":"OFF")+": "+e+" - "+s),n(0==e)},t)}(_.c.outs[t],function(t){if(s++,t&&n++,s==_.c.outs.length)if(n==s){for(;_.h.length>=C_HIST;)_.h.splice(0,1);_.h.push([c(),i?1:0]),_.s.cmd=i?1:0,e(!0)}else e(!1)})}function v(){"function"==typeof USER_CONFIG&&(_.c=USER_CONFIG(_.c,_,!1));var t,e,s=new Date;o(s),i=!1;try{function n(t){i!=t&&(_.s.st=12,u("HUOMIO: ohjaus muuttunut käyttäjän skriptin toimesta")),i=t,d(function(t){t&&(_.s.chkTs=c()),l=!1})}0===_.c.mode?(i=1===_.c.m0.cmd,_.s.st=1):_.s.timeOK&&0<_.s.p.ts&&a(new Date(1e3*_.s.p.ts))===a(s)?(_.s.p.now=y(),1===_.c.mode?(i=_.s.p.now<=("avg"==_.c.m1.lim?_.s.p.avg:_.c.m1.lim),_.s.st=i?2:3):2===_.c.mode&&(i=function(){if(0!=_.c.m2.cn){var n=[];for(g=0;g<_.p.length;g+=_.c.m2.per){var o=[];for(ind=g;ind_.p.length-1);ind++)o.push(ind);if(_.c.m2.sq){let e=999,s=0;for(A=0;A<=o.length-_.c.m2.cnt;A++){let t=0;for(h=A;h("avg"==_.c.m2.m?_.s.p.avg:_.c.m2.m)&&(i=!1,_.s.st=11)):_.s.timeOK?(_.s.st=7,t=1<=_.c.min&&(_.s.st=13,i=!1),_.s.timeOK&&0<_.s.fCmdTs&&(0<_.s.fCmdTs-c(s)?(i=1==_.s.fCmd,_.s.st=9):_.s.fCmdTs=0),"function"==typeof USER_OVERRIDE?USER_OVERRIDE(i,_,n):n(i)}catch(t){u(t),l=!1}}let g=0,A=0,h=0;function y(){var e=c();for(let t=0;t<_.p.length;t++)if(r(_.p[t][0],e))return _.p[t][1];throw _.p.length<24&&(_.s.p.ts=0),Error("no price for this hour")}u("shelly-porssisahko v."+_.s.v),u("URL: http://"+(Shelly.getComponentStatus("wifi").sta_ip??"192.168.33.1")+"/script/"+Shelly.getCurrentScriptId()),HTTPServer.registerEndpoint("",function(s,n){try{if(l)return s=null,n.code=503,void n.send();var o=function(t){var e={},s=t.split("&");for(let t=0;t 15) { - state.s.str = "Lämpötila " + temp.tC + "°C on yli 15°C -> ohjaus pois"; - console.log("Lämpötila on yli 15 astetta, asetetaan ohjaus pois. Lämpötila nyt:", temp.tC); - cmd = false; - - } else if (!cmd && temp.tC < 5) { - state.s.str = "Lämpötila " + temp.tC + "°C on alle 5°C -> ohjaus päälle"; - console.log("Lämpötila on alle 5 astetta, asetetaan ohjaus päälle. Lämpötila nyt:", temp.tC); - cmd = true; - - } else { - state.s.str = "Lämpötila " + temp.tC + "°C -> mennään ohjauksen mukaan"; - } - - //console.log("USER_OVERRIDE suoritettu. Ohjauksen tila nyt: ", cmd); - callback(cmd); - - } catch (err) { - console.log("Virhe tapahtui USER_OVERRIDE-funktiossa. Virhe:", err); - state.s.str = "Lämpötilaohjauksen virhe:" + err; - callback(cmd); - } -} \ No newline at end of file diff --git a/dist/shelly-porssisahko-user-config.js b/dist/shelly-porssisahko-user-config.js index 197081d..402ee02 100644 --- a/dist/shelly-porssisahko-user-config.js +++ b/dist/shelly-porssisahko-user-config.js @@ -8,7 +8,7 @@ * * License: GNU Affero General Public License v3.0 */ -let C_HIST=24,C_ERRC=3,C_ERRD=120,C_DEF={mode:0,m0:{cmd:0},m1:{lim:0},m2:{per:24,cnt:0,lim:-999,sq:0,m:999},vat:24,day:0,night:0,bk:0,err:0,outs:[0],fh:0,fhCmd:0,inv:0,min:60},_={s:{v:"2.10.1",dn:"",st:0,str:"",cmd:0,chkTs:0,errCnt:0,errTs:0,upTs:0,timeOK:0,configOK:0,fCmdTs:0,fCmd:0,tz:"+02:00",p:{ts:0,now:0,low:0,high:0,avg:0}},p:[],h:[],c:C_DEF},l=!1,i=!1;function r(t,e){e-=t;return 0<=e&&e<3600}function c(t){return Math.floor((t?t.getTime():Date.now())/1e3)}function n(t,e,s){let n=t.toString();for(;n.length=C_ERRC&&c(t)-_.s.errTs=C_ERRC&&(_.s.errCnt=0);return e}()){let e=new Date;o(e);try{let t=e.getFullYear()+"-"+n(1+e.getMonth(),2,"0")+"-"+n(a(e),2,"0")+"T00:00:00"+_.s.tz.replace("+","%2b");var s=t.replace("T00:00:00","T23:59:59");let l={url:"https://dashboard.elering.ee/api/nps/price/csv?fields=fi&start="+t+"&end="+s,timeout:5,ssl_ca:"*"};e=null,t=null,Shelly.call("HTTP.GET",l,function(e,t,s){l=null;try{if(0!==t||null==e||200!==e.code||!e.body_b64)throw Error("conn.err ("+s+") "+JSON.stringify(e));{e.headers=null,s=e.message=null,_.p=[],_.s.p.high=-999,_.s.p.low=999,e.body_b64=atob(e.body_b64),e.body_b64=e.body_b64.substring(1+e.body_b64.indexOf("\n"));let t=0;for(;0<=t;){e.body_b64=e.body_b64.substring(t);var n=[t=0,0];if(0===(t=1+e.body_b64.indexOf('"',t)))break;n[0]=+e.body_b64.substring(t,e.body_b64.indexOf('"',t)),t=2+e.body_b64.indexOf('"',t),t=2+e.body_b64.indexOf(';"',t),n[1]=+(""+e.body_b64.substring(t,e.body_b64.indexOf('"',t)).replace(",",".")),n[1]=n[1]/10*(100+(0_.s.p.high&&(_.s.p.high=n[1]),n[1]<_.s.p.low&&(_.s.p.low=n[1]),t=e.body_b64.indexOf("\n",t)}e=null,_.s.p.avg=0<_.p.length?_.s.p.avg/_.p.length:0;var i=new Date,r=new Date(1e3*_.p[0][0]);if(a(r)!==a(i))throw Error("date err "+i.toString()+" - "+r.toString());_.s.p.ts=c(i),_.s.p.now=y()}}catch(t){_.s.errCnt+=1,_.s.errTs=c(),_.s.p.ts=0,_.p=[],u(t)}v()})}catch(t){u(t),v()}}else!function(){if(0==_.s.chkTs)return 1;var t=new Date,e=new Date(1e3*_.s.chkTs);return e.getHours()!=t.getHours()||e.getFullYear()!=t.getFullYear()||0<_.s.fCmdTs&&_.s.fCmdTs-c(t)<0||0==_.s.fCmdTs&&_.c.min<60&&t.getMinutes()>=_.c.min&&_.s.cmd+_.c.inv==1}()?l=!1:v();else b(!0)}function d(e){_.c.inv&&(i=!i);let s=0,n=0;for(let t=0;t<_.c.outs.length;t++)!function(o,t){var e="{id:"+o+",on:"+(i?"true":"false")+"}";Shelly.call("Switch.Set",e,function(t,e,s,n){0!=e&&u("error setting output "+o+" "+(i?"ON":"OFF")+": "+e+" - "+s),n(0==e)},t)}(_.c.outs[t],function(t){if(s++,t&&n++,s==_.c.outs.length)if(n==s){for(;_.h.length>=C_HIST;)_.h.splice(0,1);_.h.push([c(),i?1:0]),_.s.cmd=i?1:0,e(!0)}else e(!1)})}function v(){"function"==typeof USER_CONFIG&&(_.c=USER_CONFIG(_.c,_,!1));var t,e,s=new Date;o(s),i=!1;try{function n(t){i!=t&&(_.s.st=12,u("HUOMIO: ohjaus muuttunut käyttäjän skriptin toimesta")),i=t,d(function(t){t&&(_.s.chkTs=c()),l=!1})}0===_.c.mode?(i=1===_.c.m0.cmd,_.s.st=1):_.s.timeOK&&0<_.s.p.ts&&a(new Date(1e3*_.s.p.ts))===a(s)?(_.s.p.now=y(),1===_.c.mode?(i=_.s.p.now<=("avg"==_.c.m1.lim?_.s.p.avg:_.c.m1.lim),_.s.st=i?2:3):2===_.c.mode&&(i=function(){if(0!=_.c.m2.cn){var n=[];for(g=0;g<_.p.length;g+=_.c.m2.per){var o=[];for(ind=g;ind_.p.length-1);ind++)o.push(ind);if(_.c.m2.sq){let e=999,s=0;for(A=0;A<=o.length-_.c.m2.cnt;A++){let t=0;for(h=A;h("avg"==_.c.m2.m?_.s.p.avg:_.c.m2.m)&&(i=!1,_.s.st=11)):_.s.timeOK?(_.s.st=7,t=1<=_.c.min&&(_.s.st=13,i=!1),_.s.timeOK&&0<_.s.fCmdTs&&(0<_.s.fCmdTs-c(s)?(i=1==_.s.fCmd,_.s.st=9):_.s.fCmdTs=0),"function"==typeof USER_OVERRIDE?USER_OVERRIDE(i,_,n):n(i)}catch(t){u(t),l=!1}}let g=0,A=0,h=0;function y(){var e=c();for(let t=0;t<_.p.length;t++)if(r(_.p[t][0],e))return _.p[t][1];throw _.p.length<24&&(_.s.p.ts=0),Error("no price for this hour")}u("shelly-porssisahko v."+_.s.v),u("URL: http://"+(Shelly.getComponentStatus("wifi").sta_ip??"192.168.33.1")+"/script/"+Shelly.getCurrentScriptId()),HTTPServer.registerEndpoint("",function(s,n){try{if(l)return s=null,n.code=503,void n.send();var o=function(t){var e={},s=t.split("&");for(let t=0;t=C_ERRC&&c(t)-_.s.errTs=C_ERRC&&(_.s.errCnt=0);return e}()){let e=new Date;o(e);try{let t=e.getFullYear()+"-"+n(1+e.getMonth(),2,"0")+"-"+n(a(e),2,"0")+"T00:00:00"+_.s.tz.replace("+","%2b");var s=t.replace("T00:00:00","T23:59:59");let l={url:"https://dashboard.elering.ee/api/nps/price/csv?fields=fi&start="+t+"&end="+s,timeout:5,ssl_ca:"*"};e=null,t=null,Shelly.call("HTTP.GET",l,function(e,t,s){l=null;try{if(0!==t||null==e||200!==e.code||!e.body_b64)throw Error("conn.err ("+s+") "+JSON.stringify(e));{e.headers=null,s=e.message=null,_.p=[],_.s.p.high=-999,_.s.p.low=999,e.body_b64=atob(e.body_b64),e.body_b64=e.body_b64.substring(1+e.body_b64.indexOf("\n"));let t=0;for(;0<=t;){e.body_b64=e.body_b64.substring(t);var n=[t=0,0];if(0===(t=1+e.body_b64.indexOf('"',t)))break;n[0]=+e.body_b64.substring(t,e.body_b64.indexOf('"',t)),t=2+e.body_b64.indexOf('"',t),t=2+e.body_b64.indexOf(';"',t),n[1]=+(""+e.body_b64.substring(t,e.body_b64.indexOf('"',t)).replace(",",".")),n[1]=n[1]/10*(100+(0_.s.p.high&&(_.s.p.high=n[1]),n[1]<_.s.p.low&&(_.s.p.low=n[1]),t=e.body_b64.indexOf("\n",t)}e=null,_.s.p.avg=0<_.p.length?_.s.p.avg/_.p.length:0;var i=new Date,r=new Date(1e3*_.p[0][0]);if(a(r)!==a(i))throw Error("date err "+i.toString()+" - "+r.toString());_.s.p.ts=c(i),_.s.p.now=p()}}catch(t){_.s.errCnt+=1,_.s.errTs=c(),_.s.p.ts=0,_.p=[],u(t)}v()})}catch(t){u(t),v()}}else!function(){if(0==_.s.chkTs)return 1;var t=new Date,e=new Date(1e3*_.s.chkTs);return e.getHours()!=t.getHours()||e.getFullYear()!=t.getFullYear()||0<_.s.fCmdTs&&_.s.fCmdTs-c(t)<0||0==_.s.fCmdTs&&_.c.min<60&&t.getMinutes()>=_.c.min&&_.s.cmd+_.c.inv==1}()?l=!1:v();else m(!0)}function d(e){_.c.inv&&(i=!i);let s=0,n=0;for(let t=0;t<_.c.outs.length;t++)!function(o,t){var e="{id:"+o+",on:"+(i?"true":"false")+"}";Shelly.call("Switch.Set",e,function(t,e,s,n){0!=e&&u("error setting output "+o+" "+(i?"ON":"OFF")+": "+e+" - "+s),n(0==e)},t)}(_.c.outs[t],function(t){if(s++,t&&n++,s==_.c.outs.length)if(n==s){for(;_.h.length>=C_HIST;)_.h.splice(0,1);_.h.push([c(),i?1:0]),_.s.cmd=i?1:0,e(!0)}else e(!1)})}function v(){"function"==typeof USER_CONFIG&&(_.c=USER_CONFIG(_.c,_,!1));var t,e,s=new Date;o(s),i=!1;try{function n(t){i!=t&&(_.s.st=12,u("HUOMIO: ohjaus muuttunut käyttäjän skriptin toimesta")),i=t,d(function(t){t&&(_.s.chkTs=c()),l=!1})}0===_.c.mode?(i=1===_.c.m0.cmd,_.s.st=1):_.s.timeOK&&0<_.s.p.ts&&a(new Date(1e3*_.s.p.ts))===a(s)?(_.s.p.now=p(),1===_.c.mode?(i=_.s.p.now<=("avg"==_.c.m1.lim?_.s.p.avg:_.c.m1.lim),_.s.st=i?2:3):2===_.c.mode&&(i=function(){if(0!=_.c.m2.cn){_.c.m2.cnt=Math.min(_.c.m2.cnt,_.c.m2.per);var n=[];for(g=0;g<_.p.length;g+=_.c.m2.per){var o=[];for(ind=g;ind_.p.length-1);ind++)o.push(ind);if(_.c.m2.sq){let e=999,s=0;for(A=0;A<=o.length-_.c.m2.cnt;A++){let t=0;for(h=A;h("avg"==_.c.m2.m?_.s.p.avg:_.c.m2.m)&&(i=!1,_.s.st=11)):_.s.timeOK?(_.s.st=7,t=1<=_.c.min&&(_.s.st=13,i=!1),_.s.timeOK&&0<_.s.fCmdTs&&(0<_.s.fCmdTs-c(s)?(i=1==_.s.fCmd,_.s.st=9):_.s.fCmdTs=0),"function"==typeof USER_OVERRIDE?USER_OVERRIDE(i,_,n):n(i)}catch(t){u(t),l=!1}}let g=0,A=0,h=0;function p(){var e=c();for(let t=0;t<_.p.length;t++)if(r(_.p[t][0],e))return _.p[t][1];throw _.p.length<24&&(_.s.p.ts=0),Error("no price for this hour")}u("shelly-porssisahko v."+_.s.v),u("URL: http://"+(Shelly.getComponentStatus("wifi").sta_ip??"192.168.33.1")+"/script/"+Shelly.getCurrentScriptId()),HTTPServer.registerEndpoint("",function(s,n){try{if(l)return s=null,n.code=503,void n.send();var o=function(t){var e={},s=t.split("&");for(let t=0;t=C_ERRC&&c(t)-_.s.errTs=C_ERRC&&(_.s.errCnt=0);return e}()){let e=new Date;o(e);try{let t=e.getFullYear()+"-"+n(1+e.getMonth(),2,"0")+"-"+n(a(e),2,"0")+"T00:00:00"+_.s.tz.replace("+","%2b");var s=t.replace("T00:00:00","T23:59:59");let l={url:"https://dashboard.elering.ee/api/nps/price/csv?fields=fi&start="+t+"&end="+s,timeout:5,ssl_ca:"*"};e=null,t=null,Shelly.call("HTTP.GET",l,function(e,t,s){l=null;try{if(0!==t||null==e||200!==e.code||!e.body_b64)throw Error("conn.err ("+s+") "+JSON.stringify(e));{e.headers=null,s=e.message=null,_.p=[],_.s.p.high=-999,_.s.p.low=999,e.body_b64=atob(e.body_b64),e.body_b64=e.body_b64.substring(1+e.body_b64.indexOf("\n"));let t=0;for(;0<=t;){e.body_b64=e.body_b64.substring(t);var n=[t=0,0];if(0===(t=1+e.body_b64.indexOf('"',t)))break;n[0]=+e.body_b64.substring(t,e.body_b64.indexOf('"',t)),t=2+e.body_b64.indexOf('"',t),t=2+e.body_b64.indexOf(';"',t),n[1]=+(""+e.body_b64.substring(t,e.body_b64.indexOf('"',t)).replace(",",".")),n[1]=n[1]/10*(100+(0_.s.p.high&&(_.s.p.high=n[1]),n[1]<_.s.p.low&&(_.s.p.low=n[1]),t=e.body_b64.indexOf("\n",t)}e=null,_.s.p.avg=0<_.p.length?_.s.p.avg/_.p.length:0;var i=new Date,r=new Date(1e3*_.p[0][0]);if(a(r)!==a(i))throw Error("date err "+i.toString()+" - "+r.toString());_.s.p.ts=c(i),_.s.p.now=y()}}catch(t){_.s.errCnt+=1,_.s.errTs=c(),_.s.p.ts=0,_.p=[],u(t)}v()})}catch(t){u(t),v()}}else!function(){if(0==_.s.chkTs)return 1;var t=new Date,e=new Date(1e3*_.s.chkTs);return e.getHours()!=t.getHours()||e.getFullYear()!=t.getFullYear()||0<_.s.fCmdTs&&_.s.fCmdTs-c(t)<0||0==_.s.fCmdTs&&_.c.min<60&&t.getMinutes()>=_.c.min&&_.s.cmd+_.c.inv==1}()?l=!1:v();else b(!0)}function d(e){_.c.inv&&(i=!i);let s=0,n=0;for(let t=0;t<_.c.outs.length;t++)!function(o,t){var e="{id:"+o+",on:"+(i?"true":"false")+"}";Shelly.call("Switch.Set",e,function(t,e,s,n){0!=e&&u("error setting output "+o+" "+(i?"ON":"OFF")+": "+e+" - "+s),n(0==e)},t)}(_.c.outs[t],function(t){if(s++,t&&n++,s==_.c.outs.length)if(n==s){for(;_.h.length>=C_HIST;)_.h.splice(0,1);_.h.push([c(),i?1:0]),_.s.cmd=i?1:0,e(!0)}else e(!1)})}function v(){"function"==typeof USER_CONFIG&&(_.c=USER_CONFIG(_.c,_,!1));var t,e,s=new Date;o(s),i=!1;try{function n(t){i!=t&&(_.s.st=12,u("HUOMIO: ohjaus muuttunut käyttäjän skriptin toimesta")),i=t,d(function(t){t&&(_.s.chkTs=c()),l=!1})}0===_.c.mode?(i=1===_.c.m0.cmd,_.s.st=1):_.s.timeOK&&0<_.s.p.ts&&a(new Date(1e3*_.s.p.ts))===a(s)?(_.s.p.now=y(),1===_.c.mode?(i=_.s.p.now<=("avg"==_.c.m1.lim?_.s.p.avg:_.c.m1.lim),_.s.st=i?2:3):2===_.c.mode&&(i=function(){if(0!=_.c.m2.cn){var n=[];for(g=0;g<_.p.length;g+=_.c.m2.per){var o=[];for(ind=g;ind_.p.length-1);ind++)o.push(ind);if(_.c.m2.sq){let e=999,s=0;for(A=0;A<=o.length-_.c.m2.cnt;A++){let t=0;for(h=A;h("avg"==_.c.m2.m?_.s.p.avg:_.c.m2.m)&&(i=!1,_.s.st=11)):_.s.timeOK?(_.s.st=7,t=1<=_.c.min&&(_.s.st=13,i=!1),_.s.timeOK&&0<_.s.fCmdTs&&(0<_.s.fCmdTs-c(s)?(i=1==_.s.fCmd,_.s.st=9):_.s.fCmdTs=0),"function"==typeof USER_OVERRIDE?USER_OVERRIDE(i,_,n):n(i)}catch(t){u(t),l=!1}}let g=0,A=0,h=0;function y(){var e=c();for(let t=0;t<_.p.length;t++)if(r(_.p[t][0],e))return _.p[t][1];throw _.p.length<24&&(_.s.p.ts=0),Error("no price for this hour")}u("shelly-porssisahko v."+_.s.v),u("URL: http://"+(Shelly.getComponentStatus("wifi").sta_ip??"192.168.33.1")+"/script/"+Shelly.getCurrentScriptId()),HTTPServer.registerEndpoint("",function(s,n){try{if(l)return s=null,n.code=503,void n.send();var o=function(t){var e={},s=t.split("&");for(let t=0;t 0.8 * state.s.p.avg) { - state.s.str = "Hinta (" + state.s.p.now.toFixed(2) + "c/kWh) on yli 80% keskiarvosta -> ohjaus pois"; - console.log("Hinta (" + state.s.p.now.toFixed(2) + "c/kWh) on yli 80% keskiarvosta -> ohjaus pois"); - cmd = false; - - } else { - state.s.str = "Keskiarvo-ohjaus: hinta OK -> ei muutosta"; - } - - //console.log("USER_OVERRIDE suoritettu. Ohjauksen tila nyt: ", cmd); - callback(cmd); - - } catch (err) { - console.log("Virhe tapahtui USER_OVERRIDE-funktiossa. Virhe:", err); - state.s.str = "Keskiarvo-ohjauksen virhe:" + err; - callback(cmd); - } -} \ No newline at end of file diff --git a/dist/shelly-porssisahko.js b/dist/shelly-porssisahko.js index 4feba05..c6eeeeb 100644 --- a/dist/shelly-porssisahko.js +++ b/dist/shelly-porssisahko.js @@ -8,4 +8,4 @@ * * License: GNU Affero General Public License v3.0 */ -let C_HIST=24,C_ERRC=3,C_ERRD=120,C_DEF={mode:0,m0:{cmd:0},m1:{lim:0},m2:{per:24,cnt:0,lim:-999,sq:0,m:999},vat:24,day:0,night:0,bk:0,err:0,outs:[0],fh:0,fhCmd:0,inv:0,min:60},_={s:{v:"2.10.1",dn:"",st:0,str:"",cmd:0,chkTs:0,errCnt:0,errTs:0,upTs:0,timeOK:0,configOK:0,fCmdTs:0,fCmd:0,tz:"+02:00",p:{ts:0,now:0,low:0,high:0,avg:0}},p:[],h:[],c:C_DEF},l=!1,i=!1;function r(t,e){e-=t;return 0<=e&&e<3600}function c(t){return Math.floor((t?t.getTime():Date.now())/1e3)}function n(t,e,s){let n=t.toString();for(;n.length=C_ERRC&&c(t)-_.s.errTs=C_ERRC&&(_.s.errCnt=0);return e}()){let e=new Date;o(e);try{let t=e.getFullYear()+"-"+n(1+e.getMonth(),2,"0")+"-"+n(a(e),2,"0")+"T00:00:00"+_.s.tz.replace("+","%2b");var s=t.replace("T00:00:00","T23:59:59");let l={url:"https://dashboard.elering.ee/api/nps/price/csv?fields=fi&start="+t+"&end="+s,timeout:5,ssl_ca:"*"};e=null,t=null,Shelly.call("HTTP.GET",l,function(e,t,s){l=null;try{if(0!==t||null==e||200!==e.code||!e.body_b64)throw Error("conn.err ("+s+") "+JSON.stringify(e));{e.headers=null,s=e.message=null,_.p=[],_.s.p.high=-999,_.s.p.low=999,e.body_b64=atob(e.body_b64),e.body_b64=e.body_b64.substring(1+e.body_b64.indexOf("\n"));let t=0;for(;0<=t;){e.body_b64=e.body_b64.substring(t);var n=[t=0,0];if(0===(t=1+e.body_b64.indexOf('"',t)))break;n[0]=+e.body_b64.substring(t,e.body_b64.indexOf('"',t)),t=2+e.body_b64.indexOf('"',t),t=2+e.body_b64.indexOf(';"',t),n[1]=+(""+e.body_b64.substring(t,e.body_b64.indexOf('"',t)).replace(",",".")),n[1]=n[1]/10*(100+(0_.s.p.high&&(_.s.p.high=n[1]),n[1]<_.s.p.low&&(_.s.p.low=n[1]),t=e.body_b64.indexOf("\n",t)}e=null,_.s.p.avg=0<_.p.length?_.s.p.avg/_.p.length:0;var i=new Date,r=new Date(1e3*_.p[0][0]);if(a(r)!==a(i))throw Error("date err "+i.toString()+" - "+r.toString());_.s.p.ts=c(i),_.s.p.now=y()}}catch(t){_.s.errCnt+=1,_.s.errTs=c(),_.s.p.ts=0,_.p=[],u(t)}v()})}catch(t){u(t),v()}}else!function(){if(0==_.s.chkTs)return 1;var t=new Date,e=new Date(1e3*_.s.chkTs);return e.getHours()!=t.getHours()||e.getFullYear()!=t.getFullYear()||0<_.s.fCmdTs&&_.s.fCmdTs-c(t)<0||0==_.s.fCmdTs&&_.c.min<60&&t.getMinutes()>=_.c.min&&_.s.cmd+_.c.inv==1}()?l=!1:v();else b(!0)}function d(e){_.c.inv&&(i=!i);let s=0,n=0;for(let t=0;t<_.c.outs.length;t++)!function(o,t){var e="{id:"+o+",on:"+(i?"true":"false")+"}";Shelly.call("Switch.Set",e,function(t,e,s,n){0!=e&&u("error setting output "+o+" "+(i?"ON":"OFF")+": "+e+" - "+s),n(0==e)},t)}(_.c.outs[t],function(t){if(s++,t&&n++,s==_.c.outs.length)if(n==s){for(;_.h.length>=C_HIST;)_.h.splice(0,1);_.h.push([c(),i?1:0]),_.s.cmd=i?1:0,e(!0)}else e(!1)})}function v(){"function"==typeof USER_CONFIG&&(_.c=USER_CONFIG(_.c,_,!1));var t,e,s=new Date;o(s),i=!1;try{function n(t){i!=t&&(_.s.st=12,u("HUOMIO: ohjaus muuttunut käyttäjän skriptin toimesta")),i=t,d(function(t){t&&(_.s.chkTs=c()),l=!1})}0===_.c.mode?(i=1===_.c.m0.cmd,_.s.st=1):_.s.timeOK&&0<_.s.p.ts&&a(new Date(1e3*_.s.p.ts))===a(s)?(_.s.p.now=y(),1===_.c.mode?(i=_.s.p.now<=("avg"==_.c.m1.lim?_.s.p.avg:_.c.m1.lim),_.s.st=i?2:3):2===_.c.mode&&(i=function(){if(0!=_.c.m2.cn){var n=[];for(g=0;g<_.p.length;g+=_.c.m2.per){var o=[];for(ind=g;ind_.p.length-1);ind++)o.push(ind);if(_.c.m2.sq){let e=999,s=0;for(A=0;A<=o.length-_.c.m2.cnt;A++){let t=0;for(h=A;h("avg"==_.c.m2.m?_.s.p.avg:_.c.m2.m)&&(i=!1,_.s.st=11)):_.s.timeOK?(_.s.st=7,t=1<=_.c.min&&(_.s.st=13,i=!1),_.s.timeOK&&0<_.s.fCmdTs&&(0<_.s.fCmdTs-c(s)?(i=1==_.s.fCmd,_.s.st=9):_.s.fCmdTs=0),"function"==typeof USER_OVERRIDE?USER_OVERRIDE(i,_,n):n(i)}catch(t){u(t),l=!1}}let g=0,A=0,h=0;function y(){var e=c();for(let t=0;t<_.p.length;t++)if(r(_.p[t][0],e))return _.p[t][1];throw _.p.length<24&&(_.s.p.ts=0),Error("no price for this hour")}u("shelly-porssisahko v."+_.s.v),u("URL: http://"+(Shelly.getComponentStatus("wifi").sta_ip??"192.168.33.1")+"/script/"+Shelly.getCurrentScriptId()),HTTPServer.registerEndpoint("",function(s,n){try{if(l)return s=null,n.code=503,void n.send();var o=function(t){var e={},s=t.split("&");for(let t=0;t=C_ERRC&&c(t)-_.s.errTs=C_ERRC&&(_.s.errCnt=0);return e}()){let e=new Date;o(e);try{let t=e.getFullYear()+"-"+n(1+e.getMonth(),2,"0")+"-"+n(a(e),2,"0")+"T00:00:00"+_.s.tz.replace("+","%2b");var s=t.replace("T00:00:00","T23:59:59");let l={url:"https://dashboard.elering.ee/api/nps/price/csv?fields=fi&start="+t+"&end="+s,timeout:5,ssl_ca:"*"};e=null,t=null,Shelly.call("HTTP.GET",l,function(e,t,s){l=null;try{if(0!==t||null==e||200!==e.code||!e.body_b64)throw Error("conn.err ("+s+") "+JSON.stringify(e));{e.headers=null,s=e.message=null,_.p=[],_.s.p.high=-999,_.s.p.low=999,e.body_b64=atob(e.body_b64),e.body_b64=e.body_b64.substring(1+e.body_b64.indexOf("\n"));let t=0;for(;0<=t;){e.body_b64=e.body_b64.substring(t);var n=[t=0,0];if(0===(t=1+e.body_b64.indexOf('"',t)))break;n[0]=+e.body_b64.substring(t,e.body_b64.indexOf('"',t)),t=2+e.body_b64.indexOf('"',t),t=2+e.body_b64.indexOf(';"',t),n[1]=+(""+e.body_b64.substring(t,e.body_b64.indexOf('"',t)).replace(",",".")),n[1]=n[1]/10*(100+(0_.s.p.high&&(_.s.p.high=n[1]),n[1]<_.s.p.low&&(_.s.p.low=n[1]),t=e.body_b64.indexOf("\n",t)}e=null,_.s.p.avg=0<_.p.length?_.s.p.avg/_.p.length:0;var i=new Date,r=new Date(1e3*_.p[0][0]);if(a(r)!==a(i))throw Error("date err "+i.toString()+" - "+r.toString());_.s.p.ts=c(i),_.s.p.now=p()}}catch(t){_.s.errCnt+=1,_.s.errTs=c(),_.s.p.ts=0,_.p=[],u(t)}v()})}catch(t){u(t),v()}}else!function(){if(0==_.s.chkTs)return 1;var t=new Date,e=new Date(1e3*_.s.chkTs);return e.getHours()!=t.getHours()||e.getFullYear()!=t.getFullYear()||0<_.s.fCmdTs&&_.s.fCmdTs-c(t)<0||0==_.s.fCmdTs&&_.c.min<60&&t.getMinutes()>=_.c.min&&_.s.cmd+_.c.inv==1}()?l=!1:v();else m(!0)}function d(e){_.c.inv&&(i=!i);let s=0,n=0;for(let t=0;t<_.c.outs.length;t++)!function(o,t){var e="{id:"+o+",on:"+(i?"true":"false")+"}";Shelly.call("Switch.Set",e,function(t,e,s,n){0!=e&&u("error setting output "+o+" "+(i?"ON":"OFF")+": "+e+" - "+s),n(0==e)},t)}(_.c.outs[t],function(t){if(s++,t&&n++,s==_.c.outs.length)if(n==s){for(;_.h.length>=C_HIST;)_.h.splice(0,1);_.h.push([c(),i?1:0]),_.s.cmd=i?1:0,e(!0)}else e(!1)})}function v(){"function"==typeof USER_CONFIG&&(_.c=USER_CONFIG(_.c,_,!1));var t,e,s=new Date;o(s),i=!1;try{function n(t){i!=t&&(_.s.st=12,u("HUOMIO: ohjaus muuttunut käyttäjän skriptin toimesta")),i=t,d(function(t){t&&(_.s.chkTs=c()),l=!1})}0===_.c.mode?(i=1===_.c.m0.cmd,_.s.st=1):_.s.timeOK&&0<_.s.p.ts&&a(new Date(1e3*_.s.p.ts))===a(s)?(_.s.p.now=p(),1===_.c.mode?(i=_.s.p.now<=("avg"==_.c.m1.lim?_.s.p.avg:_.c.m1.lim),_.s.st=i?2:3):2===_.c.mode&&(i=function(){if(0!=_.c.m2.cn){_.c.m2.cnt=Math.min(_.c.m2.cnt,_.c.m2.per);var n=[];for(g=0;g<_.p.length;g+=_.c.m2.per){var o=[];for(ind=g;ind_.p.length-1);ind++)o.push(ind);if(_.c.m2.sq){let e=999,s=0;for(A=0;A<=o.length-_.c.m2.cnt;A++){let t=0;for(h=A;h("avg"==_.c.m2.m?_.s.p.avg:_.c.m2.m)&&(i=!1,_.s.st=11)):_.s.timeOK?(_.s.st=7,t=1<=_.c.min&&(_.s.st=13,i=!1),_.s.timeOK&&0<_.s.fCmdTs&&(0<_.s.fCmdTs-c(s)?(i=1==_.s.fCmd,_.s.st=9):_.s.fCmdTs=0),"function"==typeof USER_OVERRIDE?USER_OVERRIDE(i,_,n):n(i)}catch(t){u(t),l=!1}}let g=0,A=0,h=0;function p(){var e=c();for(let t=0;t<_.p.length;t++)if(r(_.p[t][0],e))return _.p[t][1];throw _.p.length<24&&(_.s.p.ts=0),Error("no price for this hour")}u("shelly-porssisahko v."+_.s.v),u("URL: http://"+(Shelly.getComponentStatus("wifi").sta_ip??"192.168.33.1")+"/script/"+Shelly.getCurrentScriptId()),HTTPServer.registerEndpoint("",function(s,n){try{if(l)return s=null,n.code=503,void n.send();var o=function(t){var e={},s=t.split("&");for(let t=0;t