Version 0.51 seit 1 Tag aktiv.
// shelly meter script power smooch for openDTU oB.
// smoothes power signal, modifies via signals from epex script, line status
// openDTU oB setup: http+json, interval 1s, http://< addr >/script/2/dtu
var a=0,b=0; // pointers
var sp=28.0; // send power. preset for startup
const pl=500.0 // inverter power limit
var s0=Shelly.getComponentStatus("switch",0);//array for switch 0 = min price
//var s1=Shelly.getComponentStatus("switch",1);//array for switch 1 = max pri
var s1=Shelly.getComponentStatus("switch",100);//array for switch 100 = max p
//var s1=Shelly.getComponentStatus("boolean",200);//array for switch 200 = ma
var ev=Shelly.getComponentStatus("EM1",0); // array for response
var ip=[]; // array for act_power
var up=160.0; // max. act_power increase into array
var dp=-80.0; // max. act_power decrease into array
const ip_sz=5; // size of array
const tick_sz=495; // timer tick (ms)
var TickHandle;
var tock=false;
for (b=0;b<ip_sz;b++){ip.push(sp)}; // preset array of size ip_sz
function Tick(){
ev=Shelly.getComponentStatus("EM1",0); // get shelly power ch 0
b++; // b is pointer into smoothing array
if(b>=ip_sz||b<0){b=0}; // ip_sz ticks passed
ip[b]=((0.98*ev.act_power)-(0.11*ev.aprt_power));//store real power in array
// s1=Shelly.getComponentStatus("switch",1); // max price switch
s1=Shelly.getComponentStatus("switch",100); // max price switch
// s1=Shelly.getComponentStatus("boolean",200); // max price switch
if(s1){if (s1.output===true){ip[b]=up}}; // if max price true: inverter max
// if(s1){if (s1.value===true){ip[b]=100}};// if max price true: inverter max
s0=Shelly.getComponentStatus("switch",0); // get min price switch(spotelly)
if(s0){if (s0.output===true){ip[b]=dp}}; // if min price true: inverter off
if(ev.freq<49.9){ip[b]=up}; // freq < min: inverter max to smoothing array
if(ev.freq>50.1){ip[b]=dp}; // freq > max: inverter off to smoothing array
if(ev.voltage<212){ip[b]+=50}; // local voltage low: inverter ramp up
if(ev.voltage>248){ip[b]-=50}; // local voltage high: inverter ramp down
if(ip[b]>pl){ip[b]=pl}else if(ip[b]>up){ip[b]=up}; // rise/fall limits
if(ip[b]<(-pl/2)){ip[b]=(-pl/2)}else if(ip[b]<dp){ip[b]=dp};// rise/fall limits
sp=0; // clear send power
for (a=0;a<(ip_sz);a++){sp+=ip[a]}; // add all power array elements
sp=((sp/(ip_sz))); // resize send power
if(ev.freq<49.9){sp=2000}; // freq < min: inverter max immediately
if(ev.freq>50.1){sp=-2000}}; // freq > max: inverter off immediately
function startTimer(){TickHandle=Timer.set(tick_sz,true,Tick)};
startTimer();
function ps(req,res){ // THIS IS WEBSOCKET ENDPOINT
sp=(Math.round(sp*10)/10); // prepare outgoing data
tock=!tock;
if(tock){Shelly.call("Number.Set",{"id":200,"value":sp})};
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);
Wesentliche Änderung ist Sprungantwort: Taktende Verbraucher wie Kochplatte werden jetzt schneller nachgeregelt. Das findet sich in diesen Zeilen, in pl wird die Leistung des Inverters eingetragen
const pl=500.0 // inverter power limit
(...)
if(ip[b]>pl){ip[b]=pl}else if(ip[b]>up){ip[b]=up}; // rise/fall limits
if(ip[b]<(-pl/2)){ip[b]=(-pl/2)}else if(ip[b]<dp){ip[b]=dp};// rise/fall limits
Die gestern von mir aufgespielte aktuelle Version der openDTU oB hat bei mir ein etwas anderes Regelverhalten. Leichte Oszillation der Leistung, daher smoothing array auf 5 Elemente geändert und timer tick auf 495ms.