NEWS
Flexibler Schedule für Rolladensteuerung über Jarvis steuern
-
Hi zusammen,
ich habe versucht ein Script zu schreiben, dass mir ermöglicht die Rolladen in jedem Raum meines Hauses über mein Jarvis Dashboard zu konfigurieren. Ich wollte keine statischen Zeiten, besser gesagt nicht NUR statische Zeiten um meine Rolladen zu schalten.
Zielvorstellung ist, für jeden Raum eine default Zeit zu haben wann die Rolladen hoch und runter fahren sollen, die aber durch die Eingabe in einem extra Feld überschrieben werden kann. (in meinem Codesnippet ist das Überschreiben noch nicht drin, es soll erstmal so zuverlässig funktionieren)
var ObjectID, j, k, ReadValues, Crondays, formerstate, formerformerstate, openh, openm, closeh, closem, time, openschedule, closeschedule; // Read the description and the value from the object --> Ob die Knöpfe für die Tage gedrückt sind oder nicht async function Read_Info(ObjectID) { let desc = getObject(ObjectID).common.desc; let value = getState(ObjectID).val; return [desc,value]; } // Trigger on({id: [].concat(['shelly.0.FakeDatapoints.BlindScheduler.Office.Blinds_Schedule_Day_Mo']).concat(['shelly.0.FakeDatapoints.BlindScheduler.Office.Blinds_Schedule_Day_Tu']).concat(['shelly.0.FakeDatapoints.BlindScheduler.Office.Blinds_Schedule_Day_We']).concat(['shelly.0.FakeDatapoints.BlindScheduler.Office.Blinds_Schedule_Day_Th']).concat(['shelly.0.FakeDatapoints.BlindScheduler.Office.Blinds_Schedule_Day_Fr']).concat(['shelly.0.FakeDatapoints.BlindScheduler.Office.Blinds_Schedule_Day_Sa']).concat(['shelly.0.FakeDatapoints.BlindScheduler.Office.Blinds_Schedule_Day_Su']).concat(['shelly.0.FakeDatapoints.BlindScheduler.Office.Blinds_Default_Schedule_Close']).concat(['shelly.0.FakeDatapoints.BlindScheduler.Office.Blinds_Default_Schedule_Open']), change: "ne"}, async function (obj) { // Put the list together for the for loop to build the cron value for the dates var j_list = ['shelly.0.FakeDatapoints.BlindScheduler.Office.Blinds_Schedule_Day_Su', 'shelly.0.FakeDatapoints.BlindScheduler.Office.Blinds_Schedule_Day_Mo', 'shelly.0.FakeDatapoints.BlindScheduler.Office.Blinds_Schedule_Day_Tu', 'shelly.0.FakeDatapoints.BlindScheduler.Office.Blinds_Schedule_Day_We', 'shelly.0.FakeDatapoints.BlindScheduler.Office.Blinds_Schedule_Day_Th', 'shelly.0.FakeDatapoints.BlindScheduler.Office.Blinds_Schedule_Day_Fr', 'shelly.0.FakeDatapoints.BlindScheduler.Office.Blinds_Schedule_Day_Sa']; // Put the list together for the for loop to build the cron value for the hours var ObjOpen = 'shelly.0.FakeDatapoints.BlindScheduler.Office.Blinds_Default_Schedule_Open'; var ObjClose = 'shelly.0.FakeDatapoints.BlindScheduler.Office.Blinds_Default_Schedule_Close'; // Resetting some variables Crondays = ""; formerstate = ""; formerformerstate = ""; //Loop to build the cron value for the dates based on j_list for (var j_index in j_list) { j = j_list[j_index]; ReadValues = await Read_Info(j); if (j_index == '0' && ReadValues[1]){ Crondays = "0"; formerstate = ReadValues[1]; continue; } if (j_index >= "1"){ if(ReadValues[1] && formerstate && !(formerformerstate)){ Crondays += ("," + j_index) } if(ReadValues[1] && formerformerstate && formerstate){ Crondays = Crondays.replace(/..$/, "-" + j_index); } if(ReadValues[1] && !(formerstate)){ if(Crondays == ""){ Crondays += j_index }else{ Crondays += ("," + j_index) } } } if(Crondays == "0-6"){Crondays = "*"} formerformerstate = formerstate; formerstate = ReadValues[1]; } ReadValues = await Read_Info(ObjOpen); time = ReadValues[1].split(":"); if(time[0].charAt(0) == 0){ openh = time[0].charAt(1) }else{ openh = time[0] } if(time[1].charAt(0) == 0){ openm = time[1].charAt(1) }else{ openm = time[1] } ReadValues = await Read_Info(ObjClose); time = ReadValues[1].split(":"); if(time[0].charAt(0) == 0){ closeh = time[0].charAt(1) }else{ closeh = time[0] } if(time[1].charAt(0) == 0){ closem = time[1].charAt(1) }else{ closem = time[1] } (function () {if (openschedule) {clearSchedule(openschedule); openschedule = null;}})(); openschedule = schedule(openm + " " + openh + " * * " + Crondays, async function () { setState("shelly.0.SHSW-25#3494547C0118#1.Shutter.Position"/*Position*/, 100); setState("shelly.0.SHSW-25#3494547BF020#1.Shutter.Position"/*Position*/, 100); }); (function () {if (closeschedule) {clearSchedule(closeschedule); closeschedule = null;}})(); closeschedule = schedule(closem + " " + closeh + " * * " + Crondays, async function () { setState("shelly.0.SHSW-25#3494547C0118#1.Shutter.Position"/*Position*/, 0); setState("shelly.0.SHSW-25#3494547BF020#1.Shutter.Position"/*Position*/, 0); }); });
Nun habe ich das Problem, dass die Schedules funktionieren wenn ich die Zeiten z.B. auf in 5 Minuten stelle. Das auch zuverlässig. Wenn aber der nächste Schedule am folgenden Morgen laufen müsste, tut er es meistens nicht. Manchmal, aber nicht immer. Ich habe dieses Script für 2 Räume laufen, bei einem hat es dann mal funktioniert, beim anderen nicht. Ich frage mich woran das liegen könnte. Habt ihr eine Idee?
Darüber hinaus wäre ich an Verbesserungsvorschlägen interessiert wie man das Ganze noch besser lösen könnte, oder, falls der Weg schon gar nicht so schlecht sein sollte, wie ich das Script optimiert bekomme.
Vielen Dank für Eure Hilfe! Peter
-
@messenjah
Weshalb zeigst du nicht das Blockly?
Es werden bei Skriptstart keine Zeitpläne erstellt. -
@paul53
Weil ich das in JavaScript direkt geschrieben habe und kein Blockly dazu habe. Die Auslesefunktion der Objektinfos muss ich ja auch in JavaScript schreiben. Hab zumindest das nicht mit Blockly hinbekommen. Da fand ich es einfacher gleich alles in JS zu schreiben.Ja, ich weiß, dass bei Scriptstart kein Schedule erstellt wird. Das Script soll ja im Prinzip auch durchlaufen und den Schedule basierend auf der Eingabe dann anpassen. Das heißt, dass ich natürlich, nach Start des Scripts, noch einmal eine Änderung in der Gui mache, damit der Schedule dann auch erstellt wird.
-
@messenjah sagte: gleich alles in JS zu schreiben.
Einige Teile sehen aber sehr nach Blockly aus (Zeile 1, Trigger, Zeitplan stoppen, ...).
Du hast eigene Datenpunkte unter "shelly.0" erstellt? Das sollte man nicht machen, da die Datenpunkte vom Shelly-Adapter verwaltet werden.
@messenjah sagte in Flexibler Schedule für Rolladensteuerung über Jarvis steuern:
Die Auslesefunktion der Objektinfos muss ich ja auch in JavaScript schreiben.
Es wird zwar
[desc, value]
zurück gegeben,desc
aber nirgends verwendet. -
@messenjah sagte: alles in JS
Vorschlag für ein lesbares Javascript mit eigenen Datenpunkten unter "0_userdata.0":
const path = '0_userdata.0.Office.Blinds_Schedule.'; const idsWd = [ path + 'Day_Su', path + 'Day_Mo', path + 'Day_Tu', path + 'Day_We', path + 'Day_Th', path + 'Day_Fr', path + 'Day_Sa' ]; const idOpen = path + 'Time_Open'; const idClose = path + 'Time_Close'; const idBlind1 = 'shelly.0.SHSW-25#3494547C0118#1.Shutter.Position'; const idBlind2 = 'shelly.0.SHSW-25#3494547BF020#1.Shutter.Position'; var timeOpen = getState(idOpen).val; var timeClose = getState(idClose).val; var schedOpen = null; var schedClose = null; function getCron(time) { time = time.split(':'); let wds = []; for(let i = 0; i < idsWd.length; i++) { if(getState(idsWd[i]).val) wds.push(i); } if(wds.length) return time[1] + ' ' + time[0] + ' * * ' + wds.join(','); return ''; // kein Wochentag ausgewählt } function setOpen(time) { if(schedOpen) {clearSchedule(schedOpen); schedOpen = null;} let cron = getCron(time); if(cron) { schedOpen = schedule(cron, function() { setState(idBlind1, 100); setState(idBlind2, 100); }); } } function setClose(time) { if(schedClose) {clearSchedule(schedClose); schedClose = null;} let cron = getCron(time); if(cron) { schedClose = schedule(cron, function() { setState(idBlind1, 0); setState(idBlind2, 0); }); } } // Skriptstart setOpen(timeOpen); setClose(timeClose); // Trigger Open on(idOpen, function(dp) { timeOpen = dp.state.val; setOpen(timeOpen); }); // TriggerClose on(idClose, function(dp) { timeClose = dp.state.val; setClose(timeClose); }); // Trigger Wochentage on(idsWd, function () { setOpen(timeOpen); setClose(timeClose); });
EDIT: Zeile 25 korrigiert.
-
@paul53
Erstmal: Respekt! Vielen Dank, dass du dir die Zeit genommen hast dir das so tief anzuschauen.@paul53 sagte: Einige Teile sehen aber sehr nach Blockly aus (Zeile 1, Trigger, Zeitplan stoppen, ...).
Zugegeben, ich bin hier autodidaktisch unterwegs und habe mir die Syntax zu großen Teilen aus den Blockly Bausteinen zusammenkopiert.@paul53 sagte: Du hast eigene Datenpunkte unter "shelly.0" erstellt? Das sollte man nicht machen, da die Datenpunkte vom Shelly-Adapter verwaltet werden.
Ok, das habe ich dann in der Zwischenzeit auch an anderer Stelle hier im Forum schon gelesen. Falls ich also eigene Datenpunkte bräuchte, sollte ich dir ausschließlich unter userdata anlegen, richtig?@paul53 sagte: Es wird zwar [desc, value] zurück gegeben, desc aber nirgends verwendet.
Ach stimmt ja eigentlich, ein Relikt weil ich zwischendurch eine andere Idee hatte das Ziel zu erreichen....@paul53 sagte: Vorschlag für ein lesbares Javascript mit eigenen Datenpunkten unter "0_userdata.0":
Ich schau es mir mal an. Sieht auf jedenfall sehr vielversprechend aus.Warum meine Variante aber über Nacht manchmal einfach nichts mehr gemacht hat (ich weiß natürlich nicht ob dann nach zwei Tagen er wieder was gemacht hätte, weil ich das Script spätestens ja am nächsten Tag wieder angepasst hatte) ist nicht so eindeutig erkennbar, oder? Heute morgen z.B. hat es tatsächlich in beiden Räumen geklappt. Hatte aber nach 0:00 Uhr noch daran rumgedoktort. Wird übernacht irgend ein Dienst neugestartet der die Schedules beeinträchtigen könnte? Dein Script basiert ja auch auf der schedule() Funktion, aber wie gesagt muss ich mir das gleich noch genau anschauen.
-
@messenjah sagte: Falls ich also eigene Datenpunkte bräuchte, sollte ich dir ausschließlich unter userdata anlegen, richtig?
Ja, unter "0_userdata.0".
@messenjah sagte in Flexibler Schedule für Rolladensteuerung über Jarvis steuern:
Warum meine Variante aber über Nacht manchmal einfach nichts mehr gemacht hat (ich weiß natürlich nicht ob dann nach zwei Tagen er wieder was gemacht hätte, weil ich das Script spätestens ja am nächsten Tag wieder angepasst hatte) ist nicht so eindeutig erkennbar, oder?
Nein, man verliert aber leicht die Übersicht.
-
@paul53
Hm, also ich habe versucht das Script zum Laufen zu bekommen, aber mir scheint, als würde die getCron function nicht richtig zu funktionieren. Obwohl die Wochentage true sind, zählt er wds in der for Schleife nicht hoch.Hat das bei dir funktioniert?
Edit: Ach, habs gefunden. wds.push[] muss wds.push() sein, dann funktioniert es. Cool!Dann noch die Frage, du baust ja den Wert für die Tage (die du dann schedule() übergibst) auf indem du sie einfach mit Komma separierst. Akzeptiert die scheduler Funktion diese Syntax? Ich habe im Prinzip versucht den Wert für die Tage so hinzubekommen wie er in Blockly auch über den Wizard erzeugt wird. Und da wäre z.b., wenn ich So,Mo, Di, Do und Fr angehakt hätte, 0-2,4,5 bei rausgekommen. Wenn ich aber 0,1,2,4,5 auch hätte schreiben können, dann wäre mein Script von vornherein auch übersichtlicher gewesen.
-
@messenjah sagte: wds.push[] muss wds.push() sein
Sorry, habe mich vertippt (nicht getestet).
@messenjah sagte in Flexibler Schedule für Rolladensteuerung über Jarvis steuern:
Akzeptiert die scheduler Funktion diese Syntax?
Ja.
-
@paul53 Danke dir für deine Unterstütztung! Ich werde jetzt deinen Vorschlag so weiterverwenden.