1+ // ================================ ============
2+ // Automatische Bettbeleuchtung mit Nacht-Logik
3+ // ================================ ============
4+ // Logik: Licht nur bei Nacht, wenn Kontaktmatte=false UND Bewegung=true
5+ // Timer: 2 Minuten, retriggert bei erneuter Bewegung
6+ // ================================ ============
7+ ( function ( ) {
8+ "use strict" ;
9+ // Konfiguration
10+ const TIMER_MS = 2 * 60 * 1000 ; // 2 Minuten
11+
12+ // Datenpunkte
13+ const DP = {
14+ links : {
15+ led : 'zigbee2mqtt.0.0xa4c13852a863096b.state' ,
16+ motion : 'zigbee2mqtt.0.0xa4c1387d7ee56494.presence' ,
17+ matte : 'hm-rpc.0.001E1D899E94B0.1.STATE'
18+ } ,
19+ rechts : {
20+ led : 'zigbee2mqtt.0.0xa4c138da7c22e582.state' ,
21+ motion : 'zigbee2mqtt.0.0xa4c138f5aeea45b6.presence' ,
22+ matte : 'hm-rpc.0.001E1D899E922D.1.STATE'
23+ } ,
24+ nacht : '0_userdata.0.System.Astro.TagNacht'
25+ } ;
26+
27+ // Timer-Referenzen
28+ let timerLinks = null ;
29+ let timerRechts = null ;
30+
31+ // ================================ ============
32+ // Hilfsfunktion: Licht steuern
33+ // ================================ ============
34+ function setLight ( side , state ) {
35+ const ledId = DP [ side ] . led ;
36+ setState ( ledId , state ) ;
37+ log ( `Licht ${ side } : ${ state ? 'AN' : 'AUS' } ` , 'info' ) ;
38+ }
39+
40+ // ================================ ============
41+ // Hauptlogik: Seite verarbeiten
42+ // ================================ ============
43+ function processSide ( side ) {
44+ const motionVal = getState ( DP [ side ] . motion ) . val ;
45+ const matteVal = getState ( DP [ side ] . matte ) . val ;
46+ const nachtVal = getState ( DP . nacht ) . val ;
47+
48+ // Nur bei Nacht verarbeiten
49+ if ( nachtVal !== 'Nacht' ) {
50+ setLight ( side , false ) ;
51+ if ( timerLinks ) { clearTimeout ( timerLinks ) ; timerLinks = null ; }
52+ if ( timerRechts ) { clearTimeout ( timerRechts ) ; timerRechts = null ; }
53+ return ;
54+ }
55+
56+ // Logik: Matte=false (niemand im Bett) UND Motion=true (Bewegung)
57+ if ( matteVal === 0 && motionVal === true ) {
58+ // Licht einschalten
59+ setLight ( side , true ) ;
60+
61+ // Vorherigen Timer löschen
62+ if ( side === 'links' && timerLinks ) { clearTimeout ( timerLinks ) ; }
63+ if ( side === 'rechts' && timerRechts ) { clearTimeout ( timerRechts ) ; }
64+
65+ // Neuen Timer setzen
66+ if ( side === 'links' ) {
67+ timerLinks = setTimeout ( ( ) => {
68+ setLight ( 'links' , false ) ;
69+ timerLinks = null ;
70+ } , TIMER_MS ) ;
71+ } else {
72+ timerRechts = setTimeout ( ( ) => {
73+ setLight ( 'rechts' , false ) ;
74+ timerRechts = null ;
75+ } , TIMER_MS ) ;
76+ }
77+
78+ log ( `Timer ${ side } gestartet (2 Min)` , 'debug' ) ;
79+ } else if ( matteVal === 1 ) {
80+ // Person im Bett → Licht aus, Timer löschen
81+ setLight ( side , false ) ;
82+ if ( side === 'links' && timerLinks ) { clearTimeout ( timerLinks ) ; timerLinks =
83+ null ; }
84+ if ( side === 'rechts' && timerRechts ) { clearTimeout ( timerRechts ) ;
85+ timerRechts = null ; }
86+ log ( `Seite ${ side } : Person im Bett, Licht bleibt AUS` , 'debug' ) ;
87+ }
88+ }
89+
90+ // ================================ ============
91+ // Trigger: Bewegung links
92+ // ================================ ============
93+ on ( DP . links . motion , function ( ) {
94+ processSide ( 'links' ) ;
95+ } ) ;
96+
97+ // ================================ ============
98+ // Trigger: Bewegung rechts
99+ // ================================ ============
100+ on ( DP . rechts . motion , function ( ) {
101+ processSide ( 'rechts' ) ;
102+ } ) ;
103+
104+ // ================================ ============
105+ // Trigger: Kontaktmatte links
106+ // ================================ ============
107+ on ( DP . links . matte , function ( ) {
108+ processSide ( 'links' ) ;
109+ } ) ;
110+
111+ // ================================ ============
112+ // Trigger: Kontaktmatte rechts
113+ // ================================ ============
114+ on ( DP . rechts . matte , function ( ) {
115+ processSide ( 'rechts' ) ;
116+ } ) ;
117+
118+ // ================================ ============
119+ // Trigger: Tag/Nacht Wechsel
120+ // ================================ ============
121+ on ( DP . nacht , function ( ) {
122+ const nachtVal = getState ( DP . nacht ) . val ;
123+
124+ if ( nachtVal === 'Tag' ) {
125+ // Tag → beide Lichter aus, Timer löschen
126+ setLight ( 'links' , false ) ;
127+ setLight ( 'rechts' , false ) ;
128+ if ( timerLinks ) { clearTimeout ( timerLinks ) ; timerLinks = null ; }
129+ if ( timerRechts ) { clearTimeout ( timerRechts ) ; timerRechts = null ; }
130+ log ( 'Tag erkannt → Beleuchtung deaktiviert' , 'info' ) ;
131+ } else {
132+ log ( 'Nacht erkannt → Beleuchtung aktiv' , 'info' ) ;
133+ // Bei Nacht-Wechsel beide Seiten prüfen
134+ processSide ( 'links' ) ;
135+ processSide ( 'rechts' ) ;
136+ }
137+ } ) ;
138+
139+ // ================================ ============
140+ // Initialisierung beim Start
141+ // ================================ ============
142+ log ( 'Bettbeleuchtung-Skript gestartet' , 'info' ) ;
143+ processSide ( 'links' ) ;
144+ processSide ( 'rechts' ) ;
145+
146+ } ) ( ) ;
0 commit comments