/** * @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(g){try{log("fetching prices for day "+g);let p=new Date;updateTz(p);var s=1==g?new Date(864e5+new Date(p.getFullYear(),p.getMonth(),p.getDate()).getTime()):p;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:"*"};p=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[g]=[],_.s.p[g].avg=0,_.s.p[g].high=-999,_.s.p[g].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 r(){n[1]=n[1]/t,_.p[g].push(n),_.s.p[g].avg+=n[1],n[1]>_.s.p[g].high&&(_.s.p[g].high=n[1]),n[1]<_.s.p[g].low&&(_.s.p[g].low=n[1])}for(;0<=e;){o.body_b64=o.body_b64.substring(e);var c=[e=0,0];if(0===(e=1+o.body_b64.indexOf('"',e))){0 output: "+cmd[c]),1==r.oc&&i.cmd==cmd[c])log("outputs already set for #"+(c+1)),i.cmd=cmd[c]?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[c]?1:0,i.chkTs=epoch(),Timer.set(500,!1,loop)}loopRunning=!1}})}}0===r.mode?(cmd[c]=1===r.m0.c,i.st=1):_.s.timeOK&&0<_.s.p[0].ts&&getDate(new Date(1e3*_.s.p[0].ts))===getDate(s)?1===r.mode?(cmd[c]=_.s.p[0].now<=("avg"==r.m1.l?_.s.p[0].avg:r.m1.l),i.st=cmd[c]?2:3):2===r.mode&&(cmd[c]=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"==r.m2.m?_.s.p[0].avg:r.m2.m)&&(cmd[c]=!1,i.st=11):_.s.timeOK?(i.st=7,e=1<=r.m&&(i.st=13,cmd[c]=!1),_.s.timeOK&&0