NEWS
Variablen innerhalb des Scriptes definieren *gelöst*
-
Hallo, ich habe ein Script, das meine Hue Lampe höher dimmt, wenn die Tür geöffnet wird. Das Script läuft aber nicht mehr. Wenn ich das richtig rausgelesen habe, stört es, das ich den Hellimgkeitswert nicht als Zahl in die Variable schreibe. Aber ich kann das doch gar nicht angeben was für ein Wert es ist, wenn ich eine Script Interne Variable erstelle. Ich hoffe man versteht meine Frage.
-
@gluecksmann sagte in Variablen innerhalb des Scriptes definieren:
. Ich hoffe man versteht meine Frage.
Nein.
Zeig mal:
- das Skript
- die Fehlermeldung aus der du das heraus gelesen hast.
A.
-
var Aussenlampe_Zustand; '0.6725,0.3230'; on({ id: 'alias.0.Sensor Haustür.opened' /* opened */, change: 'ne' }, async (obj) => { let value = obj.state.val; let oldValue = obj.oldState.val; if (getState('alias.0.Sensor Haustür.opened').val == true && compareTime(getAstroDate('sunrise', undefined, 0), getAstroDate('sunset', undefined, 0), 'not between', null)) { Aussenlampe_Zustand = getState('hue.0.Haustür.level').val; setState('hue.0.Haustür.level' /* Haustür.level */, '100'); setState('hue.0.Nachrichtenlampe.on' /* Nachrichtenlampe.on */, true); } else { setStateDelayed('hue.0.Haustür.level' /* Haustür.level */, Aussenlampe_Zustand, 120000, false); setStateDelayed('hue.0.Nachrichtenlampe.on' /* Nachrichtenlampe.on */, false, 45000, false); } });
2025-08-02 22:59:50.185 warn You are assigning a string to the state "hue.0.Flur.ct" which expects a number. Please fix your code to use a number or change the state type to string. This warning might become an error in future versions.
-
@gluecksmann die Meldung hat Nix mit dem Skript zu tun. Du schreibst in dem Skript nicht in den entsprechenden Datenpunkt hinein.
Du hast aber ggf. Ein Problem wenn die Tür zu ungünstigen Zeiten geschlossen wird - dann ist ggf. Die Variable noch nicht mit einem Wert belegt. Du solltest der also in Zeile 1 einen sinnvollen Wert geben.
A.
-
Hallo, das verstehe ich nicht. Die Variable wird doch im Script festgelegt.
-
@gluecksmann es ist eine Timing Frage.
Angenommmen das Skript wird gestartet, wenn die Tür offen ist oder wenn es Tag ist (zwischen sunrise und Sunset, und dann wird die Tür geöffnet bevor es dunkel wird)
Dann wird der “if’ Zweig nicht ausgeführt, sprich die variable Aussenlampe_Zustand bekommt keinen Wert bevor sie beim schließen der Tür verwendet wird,
A.
-
@gluecksmann
Ich habe hier mal das Skript etwas umgeschrieben. Du kannst es als ein neues anlegen und mal ausprobieren. Die Erklärung und was das Skript macht, habe ich geschrieben./** * Haustür-Lampensteuerung mit: * - Dunkelheitsprüfung (nur bei dunkel Türöffnung wird Licht hochgezogen) * - Speichern des vorherigen Lampen-Levels (persistenter State) * - Rücksetzen beim Schließen (mit Verzögerung) * - Entprellung * - Schutz gegen Überschneidungen * - Logging * - Nur der persistente State wird bei Bedarf erstellt; andere States werden vorausgesetzt, es wird aber gewarnt, wenn sie fehlen. * - Verwendung von "number" mit -1 als Marker für "kein gespeicherter Wert" */ // === Konfiguration / Konstanten === const doorSensor = 'alias.0.Sensor Haustür.opened'; // Trigger: Tür geöffnet/geschlossen const hueDoorLevel = 'hue.0.Haustür.level'; // Lichtlevel Haustürlampe const messageLampOn = 'hue.0.Nachrichtenlampe.on'; // Nachrichtenlampe const savedLevelState = 'javascript.0.Aussenlampe_Zustand'; // Persistenter interner Speicher, -1 = leer // === Einstellungen für Robustheit === const DEBOUNCE_MS = 2000; // Entprellzeit in ms let busy = false; let lastEventTime = 0; // Logging ein/aus const enableLogging = true; function logInfo(msg) { if (enableLogging) log(`[Haustür-Script] ${msg}`, 'info'); } function logWarn(msg) { if (enableLogging) log(`[Haustür-Script] ${msg}`, 'warn'); } // === Helfer === // Prüft, ob das Level eine valide Zahl zwischen 0 und 100 ist function isValidLevel(lvl) { return typeof lvl === 'number' && lvl >= 0 && lvl <= 100; } // Prüft, ob es gerade dunkel ist (also NICHT zwischen sunrise und sunset) function isDark() { return !compareTime(getAstroDate('sunrise', undefined, 0), getAstroDate('sunset', undefined, 0), 'between', null); } // === State sicherstellen (nur der persistente State) === if (!existsState(savedLevelState)) { createState(savedLevelState, -1, { read: true, write: true, name: 'Gespeichertes Haustür-Level vor Änderung', role: 'level', type: 'number', def: -1, min: -1, max: 100 }); logInfo(`State "${savedLevelState}" (number mit -1 als Leerwert) wurde angelegt.`); } // === Hauptlistener auf Tür-Statusänderung === on({ id: doorSensor, change: 'ne' }, async (obj) => { const now = Date.now(); // Entprellung: zu schnelle Wiederholungen ignorieren if (now - lastEventTime < DEBOUNCE_MS) { logInfo('Event verworfen wegen Entprellung.'); return; } lastEventTime = now; // Schutz gegen gleichzeitige Ausführung if (busy) { logWarn('Übersprungen: Script ist noch in Bearbeitung.'); return; } busy = true; try { const isOpen = obj.state.val === true; const stored = getState(savedLevelState)?.val; // -1 heißt leer const currentLevelObj = getState(hueDoorLevel); const currentLevel = currentLevelObj?.val; if (isOpen) { logInfo('Tür geöffnet erkannt.'); if (isDark()) { logInfo('Es ist dunkel – Lampenstatus wird angepasst.'); // Vorheriges Level nur speichern, wenn noch nichts gespeichert ist und aktuelles Level valide ist if (stored === -1 && isValidLevel(currentLevel)) { setState(savedLevelState, currentLevel, true); logInfo(`Vorheriges Level gespeichert: ${currentLevel}`); } else if (stored !== -1) { logInfo(`Vorheriger Level war bereits gespeichert: ${stored}`); } else if (!isValidLevel(currentLevel)) { logWarn('Kein gültiger aktueller Level zum Speichern vorhanden.'); } // Haustür-Lampe auf 100 setzen if (existsState(hueDoorLevel)) { setState(hueDoorLevel, 100); logInfo('Haustür-Lampe auf 100 gesetzt.'); } else { logWarn(`State "${hueDoorLevel}" existiert nicht. Kann Lampen-Level nicht setzen.`); } // Nachrichtenlampe einschalten if (existsState(messageLampOn)) { setState(messageLampOn, true); logInfo('Nachrichtenlampe eingeschaltet.'); } else { logWarn(`State "${messageLampOn}" existiert nicht. Kann Nachrichtenlampe nicht setzen.`); } } else { logInfo('Es ist Tag – Nachrichtenlampe aus und gespeicherten Level verwerfen.'); if (existsState(messageLampOn)) { setState(messageLampOn, false); logInfo('Nachrichtenlampe ausgeschaltet.'); } else { logWarn(`State "${messageLampOn}" existiert nicht. Kann Nachrichtenlampe nicht setzen.`); } // Gespeicherten Level löschen (auf -1 setzen) setState(savedLevelState, -1, true); logInfo('Gespeicherter Level zurückgesetzt (Tag-Modus).'); } } else { logInfo('Tür geschlossen erkannt.'); if (stored !== -1) { if (existsState(hueDoorLevel)) { logInfo(`Haustür-Lampe wird in 2 Minuten auf gespeicherten Wert (${stored}) zurückgesetzt.`); setStateDelayed(hueDoorLevel, stored, 120000, false); } else { logWarn(`State "${hueDoorLevel}" existiert nicht. Kann Lampen-Level nicht zurücksetzen.`); } // Gespeicherten Level wieder auf "leer" setzen setState(savedLevelState, -1, true); logInfo('Gespeicherter Level danach gelöscht.'); } else { logInfo('Kein gespeicherter Level vorhanden – nichts zum Zurücksetzen.'); } // Nachrichtenlampe nach Verzögerung aus if (existsState(messageLampOn)) { setStateDelayed(messageLampOn, false, 45000, false); logInfo('Nachrichtenlampe wird nach 45 Sekunden ausgeschaltet.'); } else { logWarn(`State "${messageLampOn}" existiert nicht. Kann Nachrichtenlampe nicht setzen.`); } } } catch (e) { logWarn(`Fehler im Script: ${e.message}`); } finally { busy = false; } });
Erklärung:
Was macht das Script insgesamt?
Wenn die Haustür geöffnet wird, prüft das Script:-
Ist es dunkel draußen?
-
Ja: Dann merkt es sich, wie hell die Haustür-Lampe vorher war, schaltet sie auf 100% und aktiviert die Nachrichtenlampe.
-
Nein (also Tag): Es tut nur: schaltet die Nachrichtenlampe aus und verwirft einen alten gespeicherten Zustand (falls einer da war).
Wenn die Tür wieder geschlossen wird, stellt es nach einer kurzen Verzögerung (2 Minuten) die Haustür-Lampe auf den vorherigen Wert zurück, falls dieser gespeichert war, und schaltet die Nachrichtenlampe nach 45 Sekunden aus.
-
Wichtige Zusatzfunktionen (für Stabilität & Verständlichkeit)
-
Entprellung: Der Türsensor kann manchmal sehr schnell mehrfach hintereinander melden „offen/zu“. Das Script ignoriert solche Schnellfolgen, wenn sie in weniger als 2 Sekunden passieren, damit nichts durcheinandergerät.
-
Verarbeitungsschutz: Wenn das Script gerade dabei ist, eine Aktion durchzuführen, dann wartet es ab und führt nicht gleichzeitig nochmal etwas aus. Das verhindert unsauberes Überschreiben.
-
Speichern des vorherigen Levels: Der vorherige Lampenwert wird nicht nur im flüchtigen Speicher (also nur während dieses Laufes) behalten, sondern in einem echten ioBroker-State (
javascript.0.Aussenlampe_Zustand
), der auch nach einem Neustart des Scripts erhalten bleibt. -
Logging: Das Script schreibt (wenn aktiviert) in das ioBroker-Protokoll, was passiert: z. B. „Tür geöffnet“, „Es ist dunkel, Lampe hochsetzen“, „Level gespeichert“, „Zurücksetzen beim Schließen“ usw. Damit kann man im Log nachvollziehen, warum etwas passiert ist oder nicht.
Was kann der Nutzer tun?
-
Ansehen: In ioBroker unter „Protokoll“ kann man nach [
Haustür-Script
] suchen und sehen, was gerade geschieht. Das hilft beim Debuggen oder Verständnis. -
Anpassen:
-
Will man die Verzögerungen (z. B. die 2 Minuten beim Zurücksetzen) ändern, passt man die Zahl
120000
(Millisekunden) an. -
Wer die Entprellzeit länger oder kürzer will, ändert
DEBOUNCE_MS
. -
Logging ausmachen:
enableLogging = false
setzen, dann schreibt es keine Infos mehr ins Log.
-
-
-
Wow, da hast Dir ja viel mühe gegeben. Leider hab ich Dich auf die falsche Fährte gelockt. Alles mit Nachrichtenlampe muss raus. DAs habe ich nur drin gehabt, um zu prüfen ob der Sensor geht. Die Hue Aussenlampe soll nur bei Dunkelheit auf 100% schalten, wenn die Tür geöffnet wird. Danach wieder die die vorher eingestellte Helligkeit.
-
@gluecksmann
kein problem ich habe halt nur das benutzt was du angegeben hast wuste ja nicht das es nur zu test zweken da war
Hier das aktualisierte Skript. Kannst ihn gerne probieren./** * Haustür-Lampensteuerung: * - Nur bei Dunkelheit: Beim Öffnen der Tür wird die Hue Außenlampe auf 100% gesetzt. * Dabei wird der vorherige Helligkeitswert gespeichert. * - Beim Schließen: Nach 2 Minuten wird der vorherige Wert wiederhergestellt. * - Entprellung, Schutz gegen Überschneidungen und Logging. * - Nur der persistente State wird bei Bedarf erstellt; andere States müssen existieren. * - Gespeichert wird als number mit -1 = "kein Wert gespeichert" */ // === Konfiguration / Konstanten === const doorSensor = 'alias.0.Sensor Haustür.opened'; // Tür geöffnet/geschlossen const hueDoorLevel = 'hue.0.Haustür.level'; // Hue Außenlampe Level const savedLevelState = 'javascript.0.Aussenlampe_Zustand'; // Persistenter interner Speicher (-1 = leer) // === Robustheits-Einstellungen === const DEBOUNCE_MS = 2000; // Entprellzeit in ms let busy = false; let lastEventTime = 0; // Logging ein/aus const enableLogging = true; function logInfo(msg) { if (enableLogging) log(`[Haustür-Script] ${msg}`, 'info'); } function logWarn(msg) { if (enableLogging) log(`[Haustür-Script] ${msg}`, 'warn'); } // === Helfer === // Prüft, ob das Level eine valide Zahl zwischen 0 und 100 ist function isValidLevel(lvl) { return typeof lvl === 'number' && lvl >= 0 && lvl <= 100; } // Prüft, ob es gerade dunkel ist (also NICHT zwischen sunrise und sunset) function isDark() { return !compareTime(getAstroDate('sunrise', undefined, 0), getAstroDate('sunset', undefined, 0), 'between', null); } // === Persistenten State sicherstellen === if (!existsState(savedLevelState)) { createState(savedLevelState, -1, { read: true, write: true, name: 'Gespeichertes Haustür-Level vor Änderung', role: 'level', type: 'number', def: -1, min: -1, max: 100 }); logInfo(`State "${savedLevelState}" (number mit -1 als Leerwert) wurde angelegt.`); } // === Hauptlistener auf Tür-Statusänderung === on({ id: doorSensor, change: 'ne' }, async (obj) => { const now = Date.now(); // Entprellung: zu schnelle Folgetrigger ignorieren if (now - lastEventTime < DEBOUNCE_MS) { logInfo('Event verworfen wegen Entprellung.'); return; } lastEventTime = now; // Schutz gegen parallele Ausführung if (busy) { logWarn('Übersprungen: Script ist noch in Bearbeitung.'); return; } busy = true; try { const isOpen = obj.state.val === true; const stored = getState(savedLevelState)?.val; // -1 = leer const currentLevelObj = getState(hueDoorLevel); const currentLevel = currentLevelObj?.val; if (isOpen) { logInfo('Tür geöffnet erkannt.'); if (isDark()) { logInfo('Es ist dunkel – Lampenstatus wird angepasst.'); // Vorheriges Level nur speichern, wenn noch nichts gespeichert ist und aktueller Level gültig if (stored === -1 && isValidLevel(currentLevel)) { setState(savedLevelState, currentLevel, true); logInfo(`Vorheriges Level gespeichert: ${currentLevel}`); } else if (stored !== -1) { logInfo(`Vorheriger Level war bereits gespeichert: ${stored}`); } else if (!isValidLevel(currentLevel)) { logWarn('Kein gültiger aktueller Level zum Speichern vorhanden.'); } // Hue-Lampe auf 100 setzen if (existsState(hueDoorLevel)) { setState(hueDoorLevel, 100); logInfo('Haustür-Lampe auf 100 gesetzt.'); } else { logWarn(`State "${hueDoorLevel}" existiert nicht. Kann Lampen-Level nicht setzen.`); } } else { logInfo('Es ist Tag – keine Änderung an der Lampe.'); // nichts tun bei Tageslicht } } else { logInfo('Tür geschlossen erkannt.'); if (stored !== -1) { if (existsState(hueDoorLevel)) { logInfo(`Haustür-Lampe wird in 2 Minuten auf gespeicherten Wert (${stored}) zurückgesetzt.`); setStateDelayed(hueDoorLevel, stored, 120000, false); } else { logWarn(`State "${hueDoorLevel}" existiert nicht. Kann Lampen-Level nicht zurücksetzen.`); } // Gespeicherten Level zurücksetzen setState(savedLevelState, -1, true); logInfo('Gespeicherter Level danach gelöscht.'); } else { logInfo('Kein gespeicherter Level vorhanden – nichts zurückzusetzen.'); } } } catch (e) { logWarn(`Fehler im Script: ${e.message}`); } finally { busy = false; } });
-
@issi sagte in Variablen innerhalb des Scriptes definieren:
/** * Haustür-Lampensteuerung: * - Nur bei Dunkelheit: Beim Öffnen der Tür wird die Hue Außenlampe auf 100% gesetzt. * Dabei wird der vorherige Helligkeitswert gespeichert. * - Beim Schließen: Nach 2 Minuten wird der vorherige Wert wiederhergestellt. * - Entprellung, Schutz gegen Überschneidungen und Logging. * - Nur der persistente State wird bei Bedarf erstellt; andere States müssen existieren. * - Gespeichert wird als number mit -1 = "kein Wert gespeichert" */ // === Konfiguration / Konstanten === const doorSensor = 'alias.0.Sensor Haustür.opened'; // Tür geöffnet/geschlossen const hueDoorLevel = 'hue.0.Haustür.level'; // Hue Außenlampe Level const savedLevelState = 'javascript.0.Aussenlampe_Zustand'; // Persistenter interner Speicher (-1 = leer) // === Robustheits-Einstellungen === const DEBOUNCE_MS = 2000; // Entprellzeit in ms let busy = false; let lastEventTime = 0; // Logging ein/aus const enableLogging = true; function logInfo(msg) { if (enableLogging) log(`[Haustür-Script] ${msg}`, 'info'); } function logWarn(msg) { if (enableLogging) log(`[Haustür-Script] ${msg}`, 'warn'); } // === Helfer === // Prüft, ob das Level eine valide Zahl zwischen 0 und 100 ist function isValidLevel(lvl) { return typeof lvl === 'number' && lvl >= 0 && lvl <= 100; } // Prüft, ob es gerade dunkel ist (also NICHT zwischen sunrise und sunset) function isDark() { return !compareTime(getAstroDate('sunrise', undefined, 0), getAstroDate('sunset', undefined, 0), 'between', null); } // === Persistenten State sicherstellen === if (!existsState(savedLevelState)) { createState(savedLevelState, -1, { read: true, write: true, name: 'Gespeichertes Haustür-Level vor Änderung', role: 'level', type: 'number', def: -1, min: -1, max: 100 }); logInfo(`State "${savedLevelState}" (number mit -1 als Leerwert) wurde angelegt.`); } // === Hauptlistener auf Tür-Statusänderung === on({ id: doorSensor, change: 'ne' }, async (obj) => { const now = Date.now(); // Entprellung: zu schnelle Folgetrigger ignorieren if (now - lastEventTime < DEBOUNCE_MS) { logInfo('Event verworfen wegen Entprellung.'); return; } lastEventTime = now; // Schutz gegen parallele Ausführung if (busy) { logWarn('Übersprungen: Script ist noch in Bearbeitung.'); return; } busy = true; try { const isOpen = obj.state.val === true; const stored = getState(savedLevelState)?.val; // -1 = leer const currentLevelObj = getState(hueDoorLevel); const currentLevel = currentLevelObj?.val; if (isOpen) { logInfo('Tür geöffnet erkannt.'); if (isDark()) { logInfo('Es ist dunkel – Lampenstatus wird angepasst.'); // Vorheriges Level nur speichern, wenn noch nichts gespeichert ist und aktueller Level gültig if (stored === -1 && isValidLevel(currentLevel)) { setState(savedLevelState, currentLevel, true); logInfo(`Vorheriges Level gespeichert: ${currentLevel}`); } else if (stored !== -1) { logInfo(`Vorheriger Level war bereits gespeichert: ${stored}`); } else if (!isValidLevel(currentLevel)) { logWarn('Kein gültiger aktueller Level zum Speichern vorhanden.'); } // Hue-Lampe auf 100 setzen if (existsState(hueDoorLevel)) { setState(hueDoorLevel, 100); logInfo('Haustür-Lampe auf 100 gesetzt.'); } else { logWarn(`State "${hueDoorLevel}" existiert nicht. Kann Lampen-Level nicht setzen.`); } } else { logInfo('Es ist Tag – keine Änderung an der Lampe.'); // nichts tun bei Tageslicht } } else { logInfo('Tür geschlossen erkannt.'); if (stored !== -1) { if (existsState(hueDoorLevel)) { logInfo(`Haustür-Lampe wird in 2 Minuten auf gespeicherten Wert (${stored}) zurückgesetzt.`); setStateDelayed(hueDoorLevel, stored, 120000, false); } else { logWarn(`State "${hueDoorLevel}" existiert nicht. Kann Lampen-Level nicht zurücksetzen.`); } // Gespeicherten Level zurücksetzen setState(savedLevelState, -1, true); logInfo('Gespeicherter Level danach gelöscht.'); } else { logInfo('Kein gespeicherter Level vorhanden – nichts zurückzusetzen.'); } } } catch (e) { logWarn(`Fehler im Script: ${e.message}`); } finally { busy = false; } });
1000 Dank. Scheint zu laufen.