NEWS
[gelöst] setState wiederholen, falls "nicht erfolgreich" (Zigbee Lampe schalten, ack)
-
Hallo zusammen,
ich habe eine Tradfri Fernbedienung und eine Tradfri RGB LED Lampe, die ich über den Zigbee Adapter in den ioBroker eingebunden habe. Die Schaltlogik realisiere ich über ein JavaScript.
Nun habe ich das Problem, dass die Kommandos von der Fernbedienung zwar immer bei ioBroker ankommen und die entsprechenden Funktionen im Script ausgeführt werden, aber leider die Tradfri Lampe nicht immer alles zuverlässig umsetzt wie kommandiert, vermutlich wegen einer nicht ganz einwandfreien Verbindung zum cc2531 Stick. Wenn das Schalten nicht funktioniert, kann ich das feststellen, da der Acknowlege ausbleibt. Ich würde es dann gerne ein paar mal erneut versuchen, bis es erfolgreich war. Ich weiß leider nur nicht so recht, wie man das geschickt macht. Manchmal klappt es, wenn ich einfach erneut setState aufrufe, manchmal aber auch nicht sofort.on({id: "zigbee.0.xxx.toggle", change: "gt"}, function (obj) { if (getState('zigbee.0.yyy.state').val === true) { setState('zigbee.0.yyy.state', false); if(getState('zigbee.0.yyy.state').ack === false) { console.log("no ack"); //??? //setState('zigbee.0.yyy.state', false); //getState('zigbee.0.yyy.state').ack; } } });
Gibt es da eine elegante Methode? Oder gibt es da sogar einen noch ganz anderen Weg?
Danke! -
@haiperf sagte:
da der Acknowlege ausbleibt. Ich würde es dann gerne ein paar mal erneut versuchen, bis es erfolgreich war.
Dann sollte die Wiederholung mit zeitlichem Abstand erfolgen (Intervall). Ein Trigger auf den Datenpunkt mit ack: true muss das Intervall beenden. Allerdings sollte es es auch durch einen Zähler beendet werden, damit nicht ewig gesendet wird, wenn das Acknowlege ausbleibt.
-
Super, das war ein guter Hinweis. Danke.
Habe mir nun folgende Funktion gebastelt, es scheint bislang zu funktionieren:
function setStateAck(objId, value) { var repeatCount = 1; var repeatInterval = setInterval(function() { // alle 200 Millisekunden ausführen //console.log("try " + repeatCount); setState(objId, value); repeatCount++; if(getState(objId).ack === true || repeatCount > 10) { clearInterval(repeatInterval); } }, 200); }
Vielleicht kann das ja jemand so oder so ähnlich auch mal gebrauchen.
Habe es jetzt zwar ohne Trigger umgesetzt, aber ich denke, das sollte so genau so gut gehen, oder?
-
Und dazu noch:
function setStateDelayedAck(objId, value, delay) { setTimeout(function() { setStateAck(objId,value); }, delay); }
In der Log Ausgabe kann ich sehen, dass teilweise bis zu 6 Versuche benötigt werden, aber bislang funktioniert es so immer.
-
-
@haiperf Danke dafür, denke das kann ich auch gebrauchen