But the "hotfix" worked! You're a wizard!
But the "hotfix" worked! You're a wizard!
But, isnt your PM a switch aswell? mine is a pure PM. So maybe they removed events from pure PMs.
anyway: Thank you so much for your help! Needed to install a motorized damper on the kitchen extractor to avoid -15C air seeping in. But adding a button to open the damper isn't appreciated by the lady of the house.
This is from the diagnostics page
So tracks the changes, but doesnt look like its an Event like yours.
This is my first time handling shelly components, but as far as I can see, thats the "full log" visible. and when watching the power meter on the app I can clearly see the wattage going up and down.
Fan on/off several times during that period. But no events.
that was from the diagnostics tab from the PM
The last script created did nothing: Shelly.addEventHandler(function(e){print('Event --->',JSON.stringify(e));});
The plus 1 mini got the "off" event from starting the power management script:
But no other events
Was monitoring the PM manually during 5 minutes of testing, went from 0 to 20 watts several times. No changes in the script. Looks like it only runs once when its started.
Thank you.
now it turns on/off when i enable the script, but does not update if I change the state of the fan unless i stop and start the script.
the PM (PlusPMMini) is a pure power monitor connected to the fan, the switch to be controlled is a Plus1Mini with the ip 192.168.68.64 , so switch would be correct
please note first screenshot was from the PM, added switch also.
Here is event on/off
For the PM:
For the switch:
//Config __There is a Maximum of 5 Channels/Devices__
var debug= true; //Create Debug output
var configON= { //Device Name and Channel als Key --> 'switch:0', Value als Shelly.Call Array.
called: [], //Called Variabel to reduce useless Calls
powerLimit: 2, //Limit in Watt, power needs to be > Limit for sending a Call
powerTime: 1, //Time in seconds, how long the power needs to be over the powerLimit, before sending a call
'switch:0': ['HTTP.GET',{url:'http://192.168.68.64/relay/0/?turn=on'},null,null,debug],
}
var configOFF= { //Device Name and Channel als Key --> 'switch:0', Value als Shelly.Call Array.
called: [], //Called Variabel to reduce useless Calls
powerLimit: 1, //Limit in Watt, power needs to be <= Limit for sending a Call
powerTime: 1, //Time in seconds, how long the power needs to be over the powerLimit, before sending a call
'switch:0': ['HTTP.GET',{url:'http://192.168.68.64/relay/0/?turn=off'},null,null,debug],
}
var tHandel= []; //global Variabl
function Clear_Timer(id){
Timer.clear(tHandel[id]); //Reset Timer
tHandel[id]= 0;
return id;
}
function DoCall(device,id,map){ //Do call
try{
map.called[id]= true;
tHandel[id]= 0; //Reset Timer Handel
Call(map[device][0],map[device][1],map[device][2],map[device][3],map[device][4]);
}catch(e){ErrorMsg(e,'DoCall()');}
}
function CheckPower(d){
try{
let r= Efilter(d,{device:Object.keys(configON), filterKey:['apower','id','component','state']},0); //Filter event data
if(r && r.state === false){ //Switch off if switch is off
configON.called[r.id]= false;
r.id= Clear_Timer(r.id);
tHandel[r.id]= Timer.set(1000*configOFF.powerTime,false,function(){DoCall(r.component, r.id, configOFF)}); //Delayed Call
}
if(!r || !Str(r.apower)) return; //Exit if usless data
if(r.apower > configON.powerLimit && !configON.called[r.id]){ //Check if over Powerlimit
configOFF.called[r.id]= false;
r.id= Clear_Timer(r.id);
tHandel[r.id]= Timer.set(1000*configON.powerTime,false,function(){DoCall(r.component, r.id, configON)}); //Delayed Call
}
if(r.apower <= configOFF.powerLimit && !configOFF.called[r.id]){ //Check if under Powerlimit
configON.called[r.id]= false;
r.id= Clear_Timer(r.id);
tHandel[r.id]= Timer.set(1000*configOFF.powerTime,false,function(){DoCall(r.component, r.id, configOFF)}); //Delayed Call
}
if(debug) print('Debug: found Event\n',r,'\nDebug:',r.component,'Timer activ:',tHandel[r.id]>0,'\nDebug: called ON:',configON.called[r.id],', OFF:',configOFF.called[r.id]); //Debug output
}catch(e){ErrorMsg(e,'CheckPower()');}
}
function Main(){ //Main Code
try{
let fakeEvents= {};
for(e in configON){ //Create Fake Power Event for Restart
if(Cut(e,':')){
let deviceType= Cut(e,':',0,true); //Getting Device Type
let channelID= Number(Cut(e,':',':')) //Getting Channel ID
fakeEvents[e]= {info: {}}; //Create fake power Event
fakeEvents[e].info.component= e;
fakeEvents[e].info.id= channelID;
fakeEvents[e].info.apower= Status(deviceType,channelID).apower;
}
}
for(e of fakeEvents){
CheckPower(e); //Send fake Power Event
}
}catch(e){ErrorMsg(e,'Creating Fake Power Event');}
fakeEvents= 0; //Delete useless Data
Shelly.addEventHandler(CheckPower); //Add EventHandler with Asyn CallBack
}
// Dekats Toolbox, a universal Toolbox for Shelly scripts
function Efilter(d,p,deBug) { //Event Filter, d=eventdata, p={device:[], filterKey:[], filterValue:[], noInfo:true, inData:true}->optional_parameter
try{
let fR= {};
if(p.noInfo){fR= d; d= {}; d.info= fR; fR= {};} if(p.inData && d.info.data){d.info= d.info.data; delete d.info.data;}
if(!d.info) fR.useless= true; if(p.device && p.device.length > 0 && p.device.indexOf(d.info.component) === -1) fR.useless= true;
if(p.device && p.device.length > 0 && !fR.useless && !p.filterKey && !p.filterValue) fR= d.info;
if(p.filterKey && !fR.useless) for(f of p.filterKey) for(k in d.info) if(f === k) fR[k]= d.info[k];
if(p.filterValue && !fR.useless) for(f of p.filterValue) for(v of d.info) if(Str(v) && f === v) fR[Str(v)]= v;
if(deBug) print('\nDebug: EventData-> ', d, '\n\nDebug: Result-> ', fR, '\n');
if(Str(fR) === '{}' || fR.useless){return;} return fR;}catch(e){ErrorMsg(e,'Efilter()');}}
function ErrorChk(r,e,m,d){ //Shelly.call error check
try{
aC--; if(aC<0) aC= 0;
if(d.CB && d.uD) d.CB(r,d.uD); if(d.CB && !d.uD) d.CB(r);
if(!d.CB && d.uD) print('Debug: ',d.uD); if(e) throw new Error(Str(m));
if(Str(r) && Str(r.code) && r.code !== 200) throw new Error(Str(r));
}catch(e){ErrorMsg(e,'ErrorChk(), call Answer');}}
function Cqueue(){ //Shelly.call queue
try{
if(!cCache[0] && !nCall[0]) return; if(!nCall[0]){nCall= cCache[0]; cCache.splice(0,1);}
if(nCall[0] && aC < callLimit){Call(nCall[0],nCall[1],nCall[2],nCall[3],nCall[4]); nCall= [];}
if((nCall[0] || cCache[0]) && !tH7) tH7= Timer.set(1000*cSp,0,function(){tH7= 0; Cqueue();});}catch(e){ErrorMsg(e,'Cqueue()');}}
function Call(m,p,CB,uD,deBug){ //Upgrade Shelly.call
try{
let d= {};
if(deBug) print('Debug: calling:',m,p); if(CB) d.CB= CB; if(Str(uD)) d.uD= uD; if(!m && CB){CB(uD); return;}
if(aC < callLimit){aC++; Shelly.call(m,p,ErrorChk,d);}else if(cCache.length < cacheLimit){
cCache.push([m,p,CB,uD,deBug]); if(deBug) print('Debug: save call:',m,p,', call queue now:',cCache.length); Cqueue();
}else{throw new Error('to many Calls in use, droping call: '+Str(m)+', '+Str(p));}}catch(e){ErrorMsg(e,'Call()');}}
function Str(d){ //Upgrade JSON.stringify
try{
if(d === null || d === undefined) return null; if(typeof d === 'string')return d;
return JSON.stringify(d);}catch(e){ErrorMsg(e,'Str()');}}
function Cut(f,k,o,i){ //Upgrade slice f=fullData, k=key-> where to cut, o=offset->offset behind key, i=invertCut
try{
let s= f.indexOf(k); if(s === -1) return; if(o) s= s+o.length || s+o; if(i) return f.slice(0,s);
return f.slice(s);}catch(e){ErrorMsg(e,'Cut()');}}
function Setup(l){ //Wating 2sek, to avoid a Shelly FW Bug
try{
if(Main && !tH9){tH9= Timer.set(2000,l,function(){print('\nStatus: started Script _[', scriptN,']_');
if(callLimit > 5){callLimit= 5;} try{Main();}catch(e){ErrorMsg(e,'Main()'); Setup();}});}}catch(e){ErrorMsg(e,'Setup()');}}
function ErrorMsg(e,s){ //Toolbox formatted Error Msg
try{
let i= 0; if(Cut(e.message, '-104: Timed out')) i= 'wrong URL or device may be offline';
if(s === 'Main()') i= e.stack; if(Cut(e.message, '"Main" is not')) i= 'define a Main() function before using Setup()';
print('Error:',s || "",'---> ',e.type,e.message); if(i) print('Info: maybe -->',i);}catch(e){print('Error: ErrorMsg() --->',e);}}
var tH7= 0, tH8= 0, tH9= 0, aC= 0, cCache= [], nCall= [], callLimit= 4, cacheLimit= 40, cSp= 0.2; //Toolbox global variable
var Status= Shelly.getComponentStatus, Config= Shelly.getComponentConfig; //Renamed native function
var info= Shelly.getDeviceInfo(), scriptID= Shelly.getCurrentScriptId(), scriptN= Config('script',scriptID).name; //Pseudo const, variabel
//Toolbox v2.5-Alpha(cut), Shelly FW >1.0.8
Setup();
Alles anzeigen
Status: started Script _[ Open ]_
17:16:56
Error: Creating Fake Power Event ---> Error Cannot read property 'apower' of null
17:16:56
Starting the fan does nothing in the log, but the device shows a powerdraw
PM ip, 192.168.68.63, relay ip: 192.168.68.64 , so the request would be correct since it also works in a browser.
But the PM doesn't seem to trigger the event to call for "'switch:0': ['HTTP.GET',{url:'http://192.168.68.64/relay/0/?turn=on'},null,null,debug],"
Thank you,
If i understand this correctly all I would need to do is change variables for powerlimit and IP adress of the switch (Shelly 1 mini) ? and then run this as a script in the PM mini?
entering http://192.168.68.64/relay/0/?turn=off / on i a browser works, and PM shows a powerdraw of 20W, but no action triggered from the script.
Diagnostics from the PMmini:
shelly_notification:163 Status change of pm1:0: {"id":0,"apower":15.4} 11:46:49
shelly_notification:163 Status change of pm1:0: {"id":0,"current":0.155} 11:46:49
shelly_notification:163 Status change of pm1:0: {"id":0,"apower":6.1} 11:46:50
shelly_notification:163 Status change of pm1:0: {"id":0,"current":0.108} 11:46:50
shelly_notification:163 Status change of pm1:0: {"id":0,"apower":0.0} 11:46:51
shelly_notification:163 Status change of pm1:0: {"id":0,"current":0.000} 11:46:51
shelly_notification:163 Status change of pm1:0: {"id":0,"apower":2.9} 11:46:56
shelly_notification:163 Status change of pm1:0: {"id":0,"current":0.030} 11:46:56
Hi
I have a Shelly mini PM "PMFan" connected to the kitchen fan, and I need it to turn on a relay "spjeld" if the powerdraw is >2W, and turn it of again if its below 2W.
I have tried doing it via actions, but firstly the conditions available are "active power change", which wouldnt do it since the fan can draw 1-200W depending on setting, so a 1W increase or decrease wouldn't turn it of at the right time.
So basicly it would be a simple If statement for functionality if I did this on a arduino etc. (If PmFan power > 2 , spjeld = on, else Spjeld = off.)
But I am struggling to understand how to code this in shelly.
Is there a simple way to do this? Are there any tutorials thats adequate to get this done?
Thanks for any help
Flytrapp.