/** * @license * * shelly-porssisahko * shelly-porssisahko-en * * (c) Jussi isotalo - http://jisotalo.fi * https://github.com/jisotalo/shelly-porssisahko * https://github.com/jisotalo/shelly-porssisahko-en * * License: GNU Affero General Public License v3.0 */ const CNST={INST_COUNT:"undefined"==typeof INSTANCE_COUNT?3:INSTANCE_COUNT,HIST_LEN:"undefined"==typeof HIST_LEN?24:HIST_LEN,ERR_LIMIT:3,ERR_DELAY:120,DEF_INST_ST:{chkTs:0,st:0,str:"",cmd:-1,configOK:0,fCmdTs:0,fCmd:0},DEF_CFG:{COM:{g:"fi",vat:25.5,day:0,night:0,names:[]},INST:{en:0,mode:0,m0:{c:0},m1:{l:0},m2:{p:24,c:0,l:-999,s:0,m:999,ps:0,pe:23,ps2:0,pe2:23,c2:0},b:0,e:0,o:[0],f:0,fc:0,i:0,m:60,oc:0}}};let _={s:{v:"3.4.0",dn:"",configOK:0,timeOK:0,errCnt:0,errTs:0,upTs:0,tz:"+02:00",tzh:0,enCnt:0,p:[{ts:0,now:0,low:0,high:0,avg:0},{ts:0,now:0,low:0,high:0,avg:0}]},si:[CNST.DEF_INST_ST],p:[[],[]],h:[],c:{c:CNST.DEF_CFG.COM,i:[CNST.DEF_CFG.INST]}},_i=0,_j=0,_k=0,_inc=0,_cnt=0,_start=0,_end=0,cmd=[],prevEpoch=0,loopRunning=!1;function getKvsKey(e){let t="porssi";return t=0<=e?t+"-"+(e+1):t}function isCurrentHour(e,t){t-=e;return 0<=t&&t<3600}function limit(e,t,s){return Math.min(s,Math.max(e,t))}function epoch(e){return Math.floor((e?e.getTime():Date.now())/1e3)}function getDate(e){return e.getDate()}function updateTz(e){let t=e.toString(),s=0;"+0000"==(t=t.substring(3+t.indexOf("GMT")))?(t="Z",s=0):(s=+t.substring(0,3),t=t.substring(0,3)+":"+t.substring(3)),t!=_.s.tz&&(_.s.p[0].ts=0),_.s.tz=t,_.s.tzh=s}function log(e){console.log("shelly-porssisahko: "+e)}function reqLogic(){for(let e=0;e refresh"),_.s.p[0].ts=0,_.s.p[0].now=0,_.s.p[1].ts=0,_.p[0]=[],_.p[1]=[]),prevEpoch=t,_.s.enCnt=0,_i=0;_i=CNST.INST_COUNT-1&&(CNST.DEF_CFG.COM=null,CNST.DEF_CFG.INST=null),0=s.m&&t.cmd+s.i==1}(e))return void Timer.set(500,!1,logic,e);"function"==typeof USER_LOOP?USER_LOOP():loopRunning=!1}else getConfig(-1)}catch(e){log("error at main loop:"+e),loopRunning=!1}}function pricesNeeded(e){var t=new Date;let s=!1;return s=1==e?_.s.timeOK&&0===_.s.p[1].ts&&15<=t.getHours():((e=getDate(new Date(1e3*_.s.p[0].ts))!==getDate(t))&&(_.s.p[1].ts=0,_.p[1]=[]),_.s.timeOK&&(0==_.s.p[0].ts||e)),_.s.errCnt>=CNST.ERR_LIMIT&&epoch(t)-_.s.errTs=CNST.ERR_LIMIT&&(_.s.errCnt=0),s}function getPrices(l){try{log("fetching prices for day "+l);let g=new Date;updateTz(g);var s=1==l?new Date(864e5+new Date(g.getFullYear(),g.getMonth(),g.getDate()).getTime()):g;let e=s.getFullYear()+"-"+(s.getMonth()<9?"0"+(1+s.getMonth()):1+s.getMonth())+"-"+(getDate(s)<10?"0"+getDate(s):getDate(s))+"T00:00:00"+_.s.tz.replace("+","%2b");var n=e.replace("T00:00:00","T23:59:59");let t={url:"https://dashboard.elering.ee/api/nps/price/csv?fields="+_.c.c.g+"&start="+e+"&end="+n,timeout:5,ssl_ca:"*"};g=null,e=null,Shelly.call("HTTP.GET",t,function(o,e,i){t=null;try{if(0!==e||null==o||200!==o.code||!o.body_b64)throw Error(e+"("+i+") - "+JSON.stringify(o));{o.headers=null,i=o.message=null,_.p[l]=[],_.s.p[l].avg=0,_.s.p[l].high=-999,_.s.p[l].low=999,o.body_b64=atob(o.body_b64),o.body_b64=o.body_b64.substring(1+o.body_b64.indexOf("\n"));let e=0,t=0,s=-1,n=[-1,0];function c(){n[1]=n[1]/t,_.p[l].push(n),_.s.p[l].avg+=n[1],n[1]>_.s.p[l].high&&(_.s.p[l].high=n[1]),n[1]<_.s.p[l].low&&(_.s.p[l].low=n[1])}for(;0<=e;){o.body_b64=o.body_b64.substring(e);var r=[e=0,0];if(0===(e=1+o.body_b64.indexOf('"',e))){0 output: "+cmd[r]),1==c.oc&&i.cmd==cmd[r])log("outputs already set for #"+(r+1)),i.cmd=cmd[r]?1:0,i.chkTs=epoch(),loopRunning=!1;else{let n=0,o=0;for(let e=0;e=s;)_.h[t].splice(0,1);_.h[t].push([epoch(),cmd[t]?1:0,_.si[t].st])}i.cmd=cmd[r]?1:0,i.chkTs=epoch(),Timer.set(500,!1,loop)}loopRunning=!1}})}}0===c.mode?(cmd[r]=1===c.m0.c,i.st=1):_.s.timeOK&&0<_.s.p[0].ts&&getDate(new Date(1e3*_.s.p[0].ts))===getDate(s)?1===c.mode?(cmd[r]=_.s.p[0].now<=("avg"==c.m1.l?_.s.p[0].avg:c.m1.l),i.st=cmd[r]?2:3):2===c.mode&&(cmd[r]=function(e){var t=_.c.i[e],s=(t.m2.ps=limit(0,t.m2.ps,23),t.m2.pe=limit(t.m2.ps,t.m2.pe,24),t.m2.ps2=limit(0,t.m2.ps2,23),t.m2.pe2=limit(t.m2.ps2,t.m2.pe2,24),t.m2.c=limit(0,t.m2.c,0_.p[0].length-1);_j++)n.push(_j);if(t.m2.s){for(_avg=999,_startIndex=0,_j=0;_j<=n.length-_cnt;_j++){for(_sum=0,_k=_j;_k<_j+_cnt;_k++)_sum+=_.p[0][n[_k]][1];_sum/_cnt<_avg&&(_avg=_sum/_cnt,_startIndex=_j)}for(_j=_startIndex;_j<_startIndex+_cnt;_j++)s.push(n[_j])}else{for(_j=0,_k=1;_k("avg"==c.m2.m?_.s.p[0].avg:c.m2.m)&&(cmd[r]=!1,i.st=11):_.s.timeOK?(i.st=7,e=1<=c.m&&(i.st=13,cmd[r]=!1),_.s.timeOK&&0