/** * @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,q: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-a.1",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 calculateAverage(t){let n=0;if(0!==t.length){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=n.m&&t.cmd+n.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 n=!1;return n=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),n}function getPrices(f){try{log("fetching prices for day "+f);let d=new Date;updateTz(d);var t=1==f?new Date(864e5+new Date(d.getFullYear(),d.getMonth(),d.getDate()).getTime()):d;let e=t.getFullYear()+"-"+(t.getMonth()<9?"0"+(1+t.getMonth()):1+t.getMonth())+"-"+(getDate(t)<10?"0"+getDate(t):getDate(t))+"T00:00:00"+_.s.tz.replace("+","%2b");let g={T00:"T12",T11:"T23"};var n=e.replace("T00:00:00","T11:59:59");let m={url:"https://dashboard.elering.ee/api/nps/price/csv?fields="+_.c.c.g+"&start="+e+"&end="+n,timeout:5,ssl_ca:"*"};d=null,e=null,_.p[f]=[],_.s.p[f].avg=0,_.s.p[f].high=-999,_.s.p[f].low=999,Shelly.call("HTTP.GET",m,function s(i,e,o,c){try{if(0!==e||null==i||200!==i.code||!i.body_b64)throw Error(e+"("+o+") - "+JSON.stringify(i));{i.headers=null,o=i.message=null,i.body_b64=atob(i.body_b64),i.body_b64=i.body_b64.substring(1+i.body_b64.indexOf("\n"));let e=0,t=0,n=-1,r=[-1,[]];function l(){var e=calculateAverage(r[1]);_.c.c.q&&1!=f||(r[1]=[e]),_.p[f].push(r),_.s.p[f].avg+=e,e>_.s.p[f].high&&(_.s.p[f].high=e),e<_.s.p[f].low&&(_.s.p[f].low=e)}for(;0<=e;){i.body_b64=i.body_b64.substring(e);var p=[e=0,0];if(0==(e=1+i.body_b64.indexOf('"',e))){0 output: "+cmd[i]),1==s.oc&&r.cmd==cmd[i])log("outputs already set for #"+(i+1)),r.cmd=cmd[i]?1:0,r.chkTs=epoch(),loopRunning=!1;else{let t=0,n=0;for(let e=0;e_.p[0].length-1);_j++)_order[_j]=_.p[0][_j][1],_cheapest[_j]={};if(t.m2.s){for(_hours=Object.keys(_order),_sum=0,_quarterCounter=0,_avg=999,_startIndex=null,_skipCounter=-1,_j=0;_j<=_hours.length;_j++)for(_k=0;_k<_order[_hours[_j]].length;_k++)_sum+=_order[_hours[_j]][_k],++_quarterCounter>=_cnt*_cntMultiplier&&(_sum/(_cnt*_cntMultiplier)<_avg&&(_avg=_sum/(_cnt*_cntMultiplier),_startIndex=_skipCounter+1),_skipCounter++,sum-=_order[_hours[Math.floor(_skipCounter/_cntMultiplier)]][_skipCounter%_cntMultiplier]);if(null!=_startIndex)for(_temp=null,_quarter=0,_quarterCounter=0,_j=0;_j<_cnt*_cntMultiplier;_j++)_temp!=_hours[Math.floor((_j+_startIndex)/_cntMultiplier)]&&(_quarterCounter=0),_temp=_hours[Math.floor((_j+_startIndex)/_cntMultiplier)],_quarter=(_j+_startIndex)%_cntMultiplier,_quarterCounter++,t.m<60&&4==_cntMultiplier&&15*_quarterCounter>t.m||(_cheapest[_temp][_quarter]=!0);_order={}}else{for(_j in _entries=[],_order)if(_order.hasOwnProperty(_j))for(_quarter=0;_quarter<_order[_j].length;_quarter++)_entries.push([_order[_j][_quarter],_j,_quarter]);for(_order={},_j=0,_k=1;_k<_entries.length;_k++){for(_temp=_entries[_k],_j=_k-1;0<=_j&&_temp[0]<_entries[_j][0];_j--)_entries[_j+1]=_entries[_j];_entries[_j+1]=_temp}for(_cheapestCounter=0,_j=0;_j<_entries.length&&(_entry=_entries[_j],t.m<60&&4==_cntMultiplier&&15*Object.keys(_cheapest[_entry[1]]).length>=t.m||(_cheapest[_entry[1]][_entry[2]]=!0,!(++_cheapestCounter>=_cnt*_cntMultiplier)));_j++);}if(_entries=[],-1==t.m2.p||-2==t.m2.p&&1<=_i)break}e=new Date,e=(_cheapest[e.getHours()]||{})[Math.floor(e.getMinutes()/15)]||!1;return _cheapest={},e}(i),r.st=cmd[i]?5:4,!cmd[i]&&_.s.p[0].now<=("avg"==s.m2.l?_.s.p[0].avg:s.m2.l)&&(cmd[i]=!0,r.st=6),cmd[i])&&_.s.p[0].now>("avg"==s.m2.m?_.s.p[0].avg:s.m2.m)&&(cmd[i]=!1,r.st=11):_.s.timeOK?(r.st=7,e=1<=s.m&&(!_.c.c.q||2!==s.mode)&&(r.st=13,cmd[i]=!1),_.s.timeOK&&0