|
2 | 2 | * Script: Astro Szenen Steuerung |
3 | 3 | * Description: Steuert Smart Home Szenen (Tag, Nacht, Aus) basierend auf |
4 | 4 | * dem Astro-Status und der aktuellen Uhrzeit. |
5 | | - * Version: 1.0.0 |
| 5 | + * Version: 1.2.1 |
6 | 6 | * Author: Sanweb |
7 | 7 | * Datum: 2026-03-09 |
8 | 8 | * * Changelog: |
| 9 | + * 1.2.1 - Typen-Normalisierung in setIfChanged hinzugefügt für sichereren Vergleich. |
| 10 | + * 1.2.0 - Prüfung des Ist-Zustandes vor dem Schalten hinzugefügt (schont den ioBroker Bus/Funkverkehr). |
9 | 11 | * 1.1.1 - Eindeutiger Log-Prefix hinzugefügt für bessere Übersicht im ioBroker-Log. |
10 | 12 | * 1.1.0 - Konfiguration in ein zentrales CONFIG-Objekt ausgelagert (Refactoring). |
11 | | - * 1.0.0 - Initiale Version (Portierung aus Node-RED) |
| 13 | + * 1.0.0 - Initiale Version |
12 | 14 | * inkl. RBE (Report By Exception) und robuster Fehlerprüfung. |
13 | 15 | ********************************************************************************/ |
14 | 16 |
|
@@ -54,6 +56,37 @@ function initializeLastScene() { |
54 | 56 | // Dann aufrufen: |
55 | 57 | initializeLastScene(); |
56 | 58 |
|
| 59 | +// ========================================== |
| 60 | +// Hilfsfunktionen |
| 61 | +// ========================================== |
| 62 | + |
| 63 | +// Schaltet einen Datenpunkt nur, wenn der neue Wert vom aktuellen Ist-Wert abweicht. |
| 64 | +// Das reduziert unnötigen Schaltverkehr im Smart Home Netzwerk. |
| 65 | +function setIfChanged(id, targetValue) { |
| 66 | + if (!existsState(id)) { |
| 67 | + log(`${CONFIG.LOG_PREFIX}Datenpunkt existiert nicht, kann nicht schalten: ${id}`, "warn"); |
| 68 | + return; |
| 69 | + } |
| 70 | + |
| 71 | + const currentState = getState(id).val; |
| 72 | + |
| 73 | + // Typen normalisieren für sicheren Vergleich |
| 74 | + const normalizedCurrent = typeof currentState === 'boolean' ? currentState : |
| 75 | + currentState === 'true' || currentState === 1 ? true : |
| 76 | + currentState === 'false' || currentState === 0 ? false : |
| 77 | + currentState; |
| 78 | + |
| 79 | + const normalizedTarget = typeof targetValue === 'boolean' ? targetValue : |
| 80 | + targetValue === 'true' || targetValue === 1 ? true : |
| 81 | + targetValue === 'false' || targetValue === 0 ? false : |
| 82 | + targetValue; |
| 83 | + |
| 84 | + if (normalizedCurrent !== normalizedTarget) { |
| 85 | + log(`${CONFIG.LOG_PREFIX}Schalte ${id} von ${currentState} auf ${targetValue}`, "debug"); |
| 86 | + setState(id, targetValue, false); // ack: false explizit gesetzt für Steuerbefehle |
| 87 | + } |
| 88 | +} |
| 89 | + |
57 | 90 | // ========================================== |
58 | 91 | // Hauptlogik |
59 | 92 | // ========================================== |
@@ -113,31 +146,31 @@ function checkAstroScene() { |
113 | 146 | } |
114 | 147 |
|
115 | 148 | // Debug-Logging für bessere Fehlersuche |
116 | | - log(`${CONFIG.LOG_PREFIX}Prüfung: Astro=${astroStatus}, Zeit=${currentHours}:${currentMinutes}, Aktuelle Szene=${currentSceneName}, Letzte Szene=${lastScene}`, "debug"); |
| 149 | + log(`${CONFIG.LOG_PREFIX}Prüfung: Astro=${astroStatus}, Zeit=${currentHours}:${currentMinutes}, Aktuelle Szene=${currentSceneName}, Letzte Szene=${lastScene}`, "info"); |
117 | 150 |
|
118 | 151 | // --- RBE (Report By Exception) --- |
119 | 152 | // Wir senden nur Befehle, wenn sich die aktive Szene ändert |
120 | 153 | if (currentSceneName !== lastScene) { |
121 | 154 | lastScene = currentSceneName; |
122 | 155 | log(`${CONFIG.LOG_PREFIX}Status-Änderung erkannt: Aktiviere Szene -> ${currentSceneName}`); |
123 | 156 |
|
124 | | - // Ausgänge schalten (ack: false explizit gesetzt für Steuerbefehle) |
125 | | - setState(CONFIG.SCENES.TAG, valTag, false); |
126 | | - setState(CONFIG.SCENES.NACHT, valNacht, false); |
127 | | - setState(CONFIG.SCENES.AUS, valAus, false); |
| 157 | + // Ausgänge nur schalten, wenn sich der Wert wirklich ändert (schont den Funkverkehr) |
| 158 | + setIfChanged(CONFIG.SCENES.TAG, valTag); |
| 159 | + setIfChanged(CONFIG.SCENES.NACHT, valNacht); |
| 160 | + setIfChanged(CONFIG.SCENES.AUS, valAus); |
128 | 161 | } |
129 | 162 | } |
130 | 163 |
|
131 | 164 | // ========================================== |
132 | 165 | // Trigger |
133 | 166 | // ========================================== |
134 | 167 |
|
135 | | -// 1. Trigger: Bei jeder Änderung des Astro-Datenpunkts (entspricht "ioBroker in" Node) |
| 168 | +// 1. Trigger: Bei jeder Änderung des Astro-Datenpunkts |
136 | 169 | on({ id: CONFIG.ASTRO_ID, change: "ne" }, function (obj) { |
137 | 170 | checkAstroScene(); |
138 | 171 | }); |
139 | 172 |
|
140 | | -// 2. Trigger: Zeitplan alle 5 Minuten (entspricht "inject" Node mit repeat: 300) |
| 173 | +// 2. Trigger: Zeitplan alle 5 Minuten |
141 | 174 | // Dieser Intervall-Check stellt sicher, dass zeitbasierte Wechsel (z.B. um 22:30 Uhr) |
142 | 175 | // zuverlässig ausgelöst werden, auch wenn der Astro-Status ("Nacht") sich nicht ändert. |
143 | 176 | schedule("*/5 * * * *", function () { |
|
0 commit comments