NEWS
Scipt Problem "Trockner fertig"
-
Hallo miteinander,
ich war jetzt lange nicht mehr mit iobroker beschäftigt.
Nun habe ich wieder Zeit um damit zu Arbeiten und eine neue VIS aufzubauen.
Jetzt hänge ich hier an einem Script und es will einfach nicht funktionieren.
Vielleicht kann mir einer von euch helfen?
Das Script sieht so aus:code_text var timeout2, timeout; // 'javascript.0.scriptEnabled.Trockner'/*scriptEnabled Trockner*/ // 'hm-rpc.0.OEQ0571917.2.POWER'/*Funksteckdose Trockner:2 POWER*/ // Trockner on({id: 'hm-rpc.0.OEQ0571917.2.POWER', change: "ne"}, function (obj) { var value = obj.state.val; var oldValue = obj.oldState.val; // Aus if (getState("javascript.0.scriptEnabled.Trockner").val != 0 && getState("hm-rpc.0.OEQ0571917.2.POWER").val < 1) { setState("javascript.0.scriptEnabled.Trockner"/*scriptEnabled.Trockner*/, 0); } // An if (getState("javascript.0.scriptEnabled.Trockner").val != 1 && getState("hm-rpc.0.OEQ0571917.2.POWER").val > 25) { timeout2 = setTimeout(function () { if (getState("hm-rpc.0.OEQ0571917.2.POWER").val > 25) { setState("javascript.0.scriptEnabled.Trockner"/*scriptEnabled Trockner*/, 1); } }, 60000); } // Fertig if (getState("javascript.0.scriptEnabled.Trockner").val == 2 && getState("hm-rpc.0.OEQ0571917.2.POWER").val > 2 && getState("hm-rpc.0.OEQ0571917.2.POWER").val < 25) { timeout = setTimeout(function () { if (getState("hm-rpc.0.OEQ0571917.2.POWER").val > 2 && getState("hm-rpc.0.OEQ0571917.2.POWER").val < 25) { setState("javascript.0.scriptEnabled.Trockner"/*scriptEnabled Trockner*/, 2); } }, 300000); } });
Werte sind folgende:
0 = AUS (Ist = 0.05W)
1 = Läuft
2 = FertigHoffe es kann mir dabei jemand helfen?
Und hat jemand vielleicht auch eine Idee wie ich das Nachlaufen vom Trockner abfangen kann?
Ich Danke euch schonmal!
Gruß Tom
-
Hallo,
was ich jetzt auf dem ersten Blick sehe, kann dein Zustand == 2 nicht gesetzt werden, da du initial in der If-Bedingung auf == 2 prüfst, der kommt da nie rein.
Außerdem würde ich ein weiteren Zustand hinzufügen
0 == Aus
1 == wurde eingeschaltet oder ist einfach nur an
2 == läuft
3 == Nachlauf
Das ganze würde sich vermutlich gut mit nen State-Pattern implementieren lassen
State 0 kann nur in State 1 wechseln
State 1 kann nur in State 2 oder State 0 wechseln
State 2 kann in State 3 wechseln oder State 0 was aber vermutlich nen Fehler ist
State 3 kann in State 2 oder 1 oder 0 wechselnViele Grüße
-
Hi ,
da ich selber für mich schon lange dass "TrocknerSkript" basteln wollte
und ich erfolgreich immer kein Bock habe, nehme ich diesen Thread mal als MotivationWeil mir der Gedanke mit dem State-Pattern ganz gut gefällt, habe ich erst mal einen "Trockner" Objekt erstellt welche das Management der States übernimmt.
Das ist erst mal die Initial-Version mit der man ganz gut sieht wie es funktionieren soll.
Diese Version habe ich auch noch nicht im IoBroker getestet, erstmal nur in der Console,
ob die Zustandsänderungen eintreten.
Da ich das Verhalten von deinem und von meinem Trockner zurzeit noch nicht kenne,fällt es mir logischerweise erst mal schwer die genau Logik zu implementieren. Wenn ich diese dann habe würde ich das aktualisierte Skript dann hier einstellen.Im Prinzip muss das Regelwerk der Zustandsänderung in die „newTrocknerValues“ Funktion
In alle weitern Funktionen (enterState,exitState,execute) könnten verwendet werden um die Verhaltensweisen beim eintreten oder verlassen einen Zustandes zu implementiert.let Trockner = { state:undefined, states:{ an:{ initialize: function (father){ this.MyFather = father; console.log("an init"); }, enterState : function(){console.log("enter: an");}, exitState : function(){console.log("exit: an");}, execute : function(){console.log("execute an");}, newTrocknerValues :function (pOldValue,pNewValue){ if(pNewValue > 25) this.MyFather.changeState(this.MyFather.states.trocknet); else if(pNewValue == 0) this.MyFather.changeState(this.MyFather.states.aus); } }, aus:{ initialize: function (father){ this.MyFather = father; console.log("aus init"); }, enterState : function(){console.log("enter: aus");}, exitState : function(){console.log("exit: aus");}, execute : function(){console.log("execute aus");}, newTrocknerValues :function (pOldValue,pNewValue){ if(pNewValue > 0) this.MyFather.changeState(this.MyFather.states.an); } }, trocknet:{ initialize: function (father){ this.MyFather = father; console.log("trocknet init"); }, enterState : function(){console.log("enter: trocknet");}, exitState : function(){console.log("exit: trocknet");}, execute : function(){console.log("execute trocknet");}, newTrocknerValues :function (pOldValue,pNewValue) { if(pNewValue > 5 && pNewValue < 25 ) this.MyFather.changeState(this.MyFather.states.nachlaufen); } }, nachlaufen: { initialize: function (father){ this.MyFather = father; this.MyTimeOut = undefined; console.log("nachlaufen init"); }, enterState : function(){console.log("enter: nachlauf");}, exitState : function(){ console.log("exit: nachlauf"); if(!this.MyTimeOut) this.MyTimeOut = undefined; }, execute : function(){console.log("execute nachlaufen");}, newTrocknerValues :function(pOldValue,pNewValue) { console.log(["newTrocknerValues",pOldValue,pNewValue]); if(pNewValue < 5 && pNewValue > 0 && !this.MyTimeOut) { this.MyTimeOut = setTimeout(()=>{ let currentValue = 0;//getState momentaner Wert abholen if(currentValue < 5 && currentValue > 0) { this.MyFather.changeState(this.MyFather.states.an); } else if (currentValue == 0){ this.MyFather.changeState(this.MyFather.states.aus); } },1500); } else if(pNewValue == 0 && !this.MyTimeOut) this.MyFather.changeState(this.MyFather.states.aus); } } }, initialize : function() { this.states.an.initialize(this); this.states.aus.initialize(this); this.states.trocknet.initialize(this); this.states.nachlaufen.initialize(this); this.state = this.states.aus; }, changeState: function(state) { if (this.state !== state) { this.state.exitState(); this.state = state; this.state.enterState(); this.state.execute(); } }, newTrocknerValues: function (pOldValue,pNewValue){ this.state.newTrocknerValues(pOldValue,pNewValue); } }; Trockner.initialize(); //Trockner.newTrocknerValues(0,1.5); //Trockner.newTrocknerValues(0,30); //Trockner.newTrocknerValues(0,23); //Trockner.newTrocknerValues(0,4); //Trockner.newTrocknerValues(0,150); //Trockner.newTrocknerValues(0,0); //on({id: 'hm-rpc.0.OEQ0571917.2.POWER', change: "ne"}, function (obj) { // let value = obj.state.val; // let oldValue = obj.oldState.val; //Trockner.newTrocknerValues(oldValue,value); //});
Viele Grüße
-
Hallo Nahasapee,
erstmal Danke für die Antwort, ich werde mal versuchen mich am Wochenende da rein zu lesen was du geschrieben und Programmiert hast.
Sieht auf jedenfall schon sehr komplex aus, da muss ich mich erstmal wieder rein Arbeiten...Danke und Gruß
Tom
-
Hi,
ich hab das Skript jetzt mal bissel überarbeit, und in ein Klasse gepackt, ob das jetzt besser ist , ist Geschmackssache
Ich habe es bei mir erst mal gestartet, weiß aber noch nicht ob es 100% läuft, muss erst der Test zeigen.Bei meinem Trockner ist es nicht ganz so kompliziert , da er kein Nachlauf hat und die Energie nicht stark schwankt.
-er geht quasi an 0> && < 10watt
-startet den trocken Modus > 100w
-geht wieder im PauseModus <10w und ist fertigViele Grüße
class State { constructor(states){ this.stateProvider = states; } enterState(){} exitState(){} executeState(){} sendStateMsg(msg) { if(msg){ sendTo('telegram.0',msg); } } checkValues(){} } class isOnState extends State{ enterState(){ const enterMsg = 'Trockner wurde angeschaltet'; this.sendStateMsg(enterMsg); } checkValues(values){ const {oldState:{val:oldValue}} = values; const {newState:{val:newValue}} = values; if(newValue > 10) this.stateProvider.changeState(isDryingState); else if(newValue == 0) this.stateProvider.changeState(isOffState); } } class isOffState extends State{ enterState(){ const enterMsg = 'Trockner wurde ausgeschaltet'; this.sendStateMsg(enterMsg); } checkValues(values){ const {oldState:{val:oldValue}} = values; const {newState:{val:newValue}} = values; if( newValue > 0) this.stateProvider.changeState(isOnState); } } class isDryingState extends State{ enterState(){ const enterMsg = 'Trockner gestartet'; this.sendStateMsg(enterMsg); } exitState(){ const enterMsg = 'trocknen fertig'; this.sendStateMsg(enterMsg); } checkValues(values){ const {oldState:{val:oldValue}} = values; const {newState:{val:newValue}} = values; if(newValue < 10 && newValue > 0) this.stateProvider.changeState(isPostRunState); else if(newValue == 0) this.stateProvider.changeState(isOffState); } } class isPostRunState extends State{ constructor(states){ super(states); this.MyTimer = undefined; } exitState(){ if(this.MyTimer) { clearInterval(this.MyTimer); this.MyTimer = undefined; } } enterState(){ const enterMsg = 'Trockner bitte leeren!'; this.sendStateMsg(enterMsg); if(!this.MyTimer) this.MyTimer = setInterval(this.sendStateMsg.bind(this,"Trockner ist noch an bitte auschalten"),300000); } checkValues(values){ const {oldState:{val:oldValue}} = values; const {newState:{val:newValue}} = values; if(newValue > 10) this.stateProvider.changeState(isDryingState); else (newValue == 0) this.stateProvider.changeState(isOffState); } } class StateContainer { constructor(initState){ this.currentState = new initState(this); } changeState(state){ if(!state) return; const newState = new state(this); if(this.currentState.constructor.name == newState.constructor.name) return; this.currentState.exitState(); delete this.currentState; this.currentState = newState; this.currentState.enterState(); this.currentState.executeState(); } executeState() { if(!this.currentState) return; this.currentState.executeState(); } checkValues(val) { if(!this.currentState) return; this.currentState.checkValues(val); } } class MyTrockner { constructor() { this.statesContainer = new StateContainer(isOffState); const ID_WaescheTrockerPower = 'shelly.0.SHSW-PM#XXXXX#1.Relay0.Power'/*Power*/; on({id: ID_WaescheTrockerPower,change: 'ne'},this.statesContainer.checkValues.bind(this.statesContainer)); } } const trockner = new MyTrockner();
-
Hi
hab heute mal den Trockner laufen lassen,
dabei ist mir noch kleiner Fehler im Script aufgefallen in der Klasse isPostRunState
musste nen else if rein. aber die checkValues Funktion solltest du ja eh nach deinen Trockner verhalten anpassen.
Außerdem hab ich bei mir mal die Watt angaben bisschen korrigiert und beim Senden der Telegramnachricht hab ich
nen kleinen delay eingebaut, da bei mir bei zu schnellen wechsel die Nachrichten durcheinander kamen.
Aber sonst scheint es schon ganz gut zu laufen.
Das kleine Script habe ich auf GitHub hochgeladen, damit ich hier nicht immer alle Änderungen posten muss.
Link TextViele Grüße
und viel Spass beim trocknen