shelly-EM / openDTU power smoocher: act_power+epex -> js script -> websocket

So. Nach gefühlten 48 Sunden am Rechner an einem einzigen Tag :rofl: bin ich bei Version 0.2 angekommen. js is ja neu für mich. Aktueller Stand: smoother optimiert auf meine Systeme. Paar Schnitzer rausoperiert. Ein epex Signal ausm spotelly auswerten (hab nur ein Relais). Funktionen:

  • spotelly schaltet output → (bei mir Boiler + Lader ein) + WR aus
  • f<49,9 → volle Leistung
  • f>50,1 → WR aus
  • U<210 → volle Leistung
  • U>250 → WR aus
  • ansonsten über die letzten 3 Werte der Leistungsmessung gemittelte Werte
// shelly script power smooch for openDTU oB. extension for spotelly as script1
var a,b,sp;                                           // 2 pointers, send power
var ip[];                                                // array for smoothing
var s0[];                                     // array for switch 0 = min price
var s1[];                                     // array for switch 1 = max price
var ev[];                                                 // array for response
const ip_sz=3;                                                 // size of array
const lp=33.0;                                           // lowest pwr inverter
if ((a===undefined))                                               // init once
{a=0;
 b=0;
 sp=0.0;
 ip=[];
 ev=[];
 for (b=0;b<ip_sz;b++){ip.push(lp)}};             // preset array of size ip_sz
function ps(req,res){                             // THIS IS WEBSOCKET ENDPOINT
 Shelly.call("EM1.GetStatus",{id:0},function(result){  // get shelly power ch 0
  ev=result;                                     // store result in local array
  b++;                                     // b is pointer into smoothing array
  if(b>=ip_sz||b<0){b=0};                  // b is pointer into smoothing array
  ip[b]=ev.act_power;                               // store act_power in array
//s1=(Shelly.getComponentStatus("switch",1)); // get max price switch(spotelly)
//if(s1){if (s1.output===true){ip[b]=1000}}; // if max price true: inverter max
  s0=(Shelly.getComponentStatus("switch",0)); // get min price switch(spotelly)
  if(s0){if (s0.output===true){ip[b]=-1000}};// if min price true: inverter off
  if(ev.freq<49.9){ip[b]=1000};                     // freq < min: inverter max
  if(ev.freq>50.1){ip[b]=-1000};                    // freq > max: inverter off
  if(ev.voltage<210){ip[b]=1000};          // local voltage < min: inverter max
  if(ev.voltage>250){ip[b]=-1000};         // local voltage > max: inverter off
  for (a=0;a<(ip_sz-1);a++){sp+=ip[a]};         // add all power array elements
 sp=(sp/(ip_sz));                            // resize send power to openDTU oB
 });
 ev.act_power=sp;                                      // prepare outgoing data
 ev.id=2;
 res.code=200;
 res.body=JSON.stringify(ev);
 res.headers=[["Content-Type","application/json"],["X-Device-Id",Shelly.getDeviceInfo().id]];
 res.send()};

HTTPServer.registerEndpoint("dtu",ps)

läuft stabil, Überfrequenz hatte ich schon kurz und Relais schaltet WR aus. Läuft so erstmal mit. drawback: DTU kriegt stabil nur alle 3s neuen Wert. Mein code ist noch zu langsam. drawback 2: shelly liefert freq nur mit 1 Nachkommastelle.