Version 0.54 läuft seit 1 Wche. Kleine Änderungen an der Rampe gegen überschwingen der Regelung mit der neuen openDTU oB Version.
// 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=-160.0; // max. act_power decrease into array
const ip_sz=3; // 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 lim
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
// console.log(ip,"=",sp)
if(ev.freq<49.9){sp=pl}; // freq < min: inverter max immediately
if(ev.freq>50.1){sp=-pl}}; // 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);
Dazu einen script 3 geschrieben: Die aktuelle spotelly version stellt einen event handler bereit. Dieser übergibt u.a.den aktuellen Strompreis, aber nur als Bezugspreis. Übersteigt dieser einen Grenzwert, schalte ich meinen Ausgang 100 ein. Damit wird der WR auf maximale Leistung eingestellt.
function stubCB(res, error_code, error_msg, ud) {}
Shelly.addEventHandler(function (event) {
if (event.name === "script" && event.info && event.info.event === "spotelly_tick") {
const data = event.info.data;
// console.log("data:",data);
const lim=45;
var val=(data.current_price>lim);
console.log("price",data.current_price,"ct/kWh -->>",val);
Shelly.call("switch.set",{id:100, on:val},stubCB,null);
}
});
Das scheint erstmal so zu funktionieren