Skip to content

Commit 4c0474e

Browse files
committed
Update / Modification from the production live system: 2026-03-09 22:30
1 parent d1408e7 commit 4c0474e

1 file changed

Lines changed: 150 additions & 0 deletions

File tree

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
/********************************************************************************
2+
* Script: Astro Szenen Steuerung
3+
* Description: Steuert Smart Home Szenen (Tag, Nacht, Aus) basierend auf
4+
* dem Astro-Status und der aktuellen Uhrzeit.
5+
* Version: 1.0.0
6+
* Author: Sanweb
7+
* Datum: 2026-03-09
8+
* * Changelog:
9+
* 1.1.1 - Eindeutiger Log-Prefix hinzugefügt für bessere Übersicht im ioBroker-Log.
10+
* 1.1.0 - Konfiguration in ein zentrales CONFIG-Objekt ausgelagert (Refactoring).
11+
* 1.0.0 - Initiale Version (Portierung aus Node-RED)
12+
* inkl. RBE (Report By Exception) und robuster Fehlerprüfung.
13+
********************************************************************************/
14+
15+
(function() {
16+
"use strict";
17+
18+
// ==========================================
19+
// Konfiguration
20+
// ==========================================
21+
const CONFIG = {
22+
LOG_PREFIX: "[Astro-Szenen] ", // Eindeutige Bezeichnung für das Logbuch
23+
ASTRO_ID: "0_userdata.0.System.Astro.TagNacht",
24+
SCENES: {
25+
TAG: "scene.0.Automatisches Licht.Astro_Tag",
26+
NACHT: "scene.0.Automatisches Licht.Astro_Nacht",
27+
AUS: "scene.0.Automatisches Licht.Astro_Aus"
28+
},
29+
TIMES: {
30+
NIGHT_OFF: "22:30", // Ende Abendlicht
31+
EARLIEST_START: 12 // Früheste Stunde für Abendlicht
32+
}
33+
};
34+
35+
// ==========================================
36+
// Initialisierung & RBE (Report By Exception)
37+
// ==========================================
38+
let lastScene = "none";
39+
40+
// Verbesserte Initialisierung mit Priorität
41+
function initializeLastScene() {
42+
if (existsState(CONFIG.SCENES.TAG) && getState(CONFIG.SCENES.TAG).val) {
43+
lastScene = "Tag";
44+
} else if (existsState(CONFIG.SCENES.NACHT) && getState(CONFIG.SCENES.NACHT).val) {
45+
lastScene = "Nacht";
46+
} else if (existsState(CONFIG.SCENES.AUS) && getState(CONFIG.SCENES.AUS).val) {
47+
lastScene = "Alles Aus";
48+
} else {
49+
lastScene = "none";
50+
}
51+
log(`${CONFIG.LOG_PREFIX}Initialisiert: lastScene = ${lastScene}`, "debug");
52+
}
53+
54+
// Dann aufrufen:
55+
initializeLastScene();
56+
57+
// ==========================================
58+
// Hauptlogik
59+
// ==========================================
60+
function checkAstroScene() {
61+
// Input lesen und auf Existenz prüfen
62+
if (!existsState(CONFIG.ASTRO_ID)) {
63+
log(`${CONFIG.LOG_PREFIX}Astro-Datenpunkt existiert nicht: ${CONFIG.ASTRO_ID}`, "warn");
64+
return;
65+
}
66+
67+
const astroState = getState(CONFIG.ASTRO_ID);
68+
if (!astroState || astroState.val === null) {
69+
log(`${CONFIG.LOG_PREFIX}Konnte Astro-Status nicht lesen oder Status ist null`, "warn");
70+
return;
71+
}
72+
73+
// Typensicherheit: Explizit als String behandeln
74+
const astroStatus = String(astroState.val);
75+
76+
// Aktuelle Zeit ermitteln
77+
const now = new Date();
78+
const currentHours = now.getHours();
79+
const currentMinutes = now.getMinutes();
80+
const currentTimeVal = currentHours * 60 + currentMinutes;
81+
82+
// Endzeit in Minuten umrechnen
83+
const [endH, endM] = CONFIG.TIMES.NIGHT_OFF.split(':').map(Number);
84+
const endTimeVal = endH * 60 + endM;
85+
const startTimeVal = CONFIG.TIMES.EARLIEST_START * 60;
86+
87+
// Variablen für die 3 Ausgänge (Standard: false)
88+
let valTag = false;
89+
let valNacht = false;
90+
let valAus = false;
91+
let currentSceneName = "";
92+
93+
// --- LOGIK ---
94+
if (astroStatus === "Tag") {
95+
// Es ist Tag -> Szene Tag aktivieren
96+
valTag = true;
97+
currentSceneName = "Tag";
98+
99+
} else if (astroStatus === "Nacht") {
100+
// Es ist Nacht -> Prüfen ob vor oder nach 22:30
101+
if (currentTimeVal >= startTimeVal && currentTimeVal < endTimeVal) {
102+
// Abend (Dunkel & vor 22:30) -> Szene Nacht aktivieren
103+
valNacht = true;
104+
currentSceneName = "Nacht";
105+
} else {
106+
// Spät (Dunkel & nach 22:30 oder morgens vor 12) -> Szene Aus aktivieren
107+
valAus = true;
108+
currentSceneName = "Alles Aus";
109+
}
110+
} else {
111+
log(`${CONFIG.LOG_PREFIX}Unbekannter Astro Status: ${astroStatus}`, "warn");
112+
return; // Abbruch, wenn der Status ungültig ist
113+
}
114+
115+
// 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");
117+
118+
// --- RBE (Report By Exception) ---
119+
// Wir senden nur Befehle, wenn sich die aktive Szene ändert
120+
if (currentSceneName !== lastScene) {
121+
lastScene = currentSceneName;
122+
log(`${CONFIG.LOG_PREFIX}Status-Änderung erkannt: Aktiviere Szene -> ${currentSceneName}`);
123+
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);
128+
}
129+
}
130+
131+
// ==========================================
132+
// Trigger
133+
// ==========================================
134+
135+
// 1. Trigger: Bei jeder Änderung des Astro-Datenpunkts (entspricht "ioBroker in" Node)
136+
on({ id: CONFIG.ASTRO_ID, change: "ne" }, function (obj) {
137+
checkAstroScene();
138+
});
139+
140+
// 2. Trigger: Zeitplan alle 5 Minuten (entspricht "inject" Node mit repeat: 300)
141+
// Dieser Intervall-Check stellt sicher, dass zeitbasierte Wechsel (z.B. um 22:30 Uhr)
142+
// zuverlässig ausgelöst werden, auch wenn der Astro-Status ("Nacht") sich nicht ändert.
143+
schedule("*/5 * * * *", function () {
144+
checkAstroScene();
145+
});
146+
147+
// 3. Beim Starten des Skripts einmalig prüfen (entspricht fireOnStart)
148+
checkAstroScene();
149+
150+
})();

0 commit comments

Comments
 (0)