1- # sensors.py – Sensorinitialisierung und Auslesung / Sensor initialization and data reading
1+ # sensors.py – Sensorlogik für BME280 und VEML7700 / Sensor logic for BME280 and VEML7700
22
3- from machine import Pin , I2C
43from veml7700_driver import VEML7700
54from bme280_driver import BME280
5+ from machine import Pin , I2C
66import time
7- from collections import OrderedDict
8- import state
97import config
8+ import state
9+ import random
10+ from collections import OrderedDict
1011
1112veml = None
1213bme = None
13-
14- # --- Sensor-Versorgung aktivieren / Activate sensor power ---
15- veml_power = Pin (config .VEML_PWR , Pin .OUT )
16- veml_power .value (1 )
17-
18- bme_power = Pin (config .BME_PWR , Pin .OUT )
19- bme_power .value (1 )
20-
21- # --- I2C-Initialisierung / I2C initialization ---
22- i2c_veml = I2C (0 , scl = Pin (config .VEML_SCL ), sda = Pin (config .VEML_SDA ))
23- i2c_bme = I2C (1 , scl = Pin (config .BME_SCL ), sda = Pin (config .BME_SDA ))
24-
25- # --- Initialisierung VEML7700 / VEML7700 initialization ---
26- def init_veml ():
27- global veml
28- try :
29- veml = VEML7700 (i2c = i2c_veml )
30- print ("📷 VEML7700 initialisiert / VEML7700 initialized." )
31- return state .SUCCESS
32- except Exception as e :
33- print ("❌ VEML7700 Fehler bei Init / Init error:" , e )
34- return state .FATAL_ERROR
35-
36- def reset_veml ():
37- print ("🔄 VEML7700 wird neu gestartet / VEML7700 reset..." )
38- veml_power .value (0 )
39- time .sleep (0.2 )
40- veml_power .value (1 )
14+ veml_initialized = False
15+ bme_initialized = False
16+
17+ # --- Sensorstrom aktivieren / Activate sensor power ---
18+ def power_on ():
19+ if hasattr (config , "VEML_PWR" ):
20+ Pin (config .VEML_PWR , Pin .OUT ).on ()
21+ if hasattr (config , "BME_PWR" ):
22+ Pin (config .BME_PWR , Pin .OUT ).on ()
4123 time .sleep (0.2 )
42- return init_veml ()
43-
44- def read_veml ():
45- # Unterstützt active, dummy und inactive / Supports active, dummy, inactive
46- mode = getattr (config , "VEML_MODE" , "active" )
47- if mode == "inactive" :
48- return state .SUCCESS , None
49- if mode == "dummy" :
50- import random
51- return state .SUCCESS , random .randint (0 , 2000 )
52- global veml
53- try :
54- if veml is None :
55- if init_veml () != state .SUCCESS :
56- return state .FATAL_ERROR , {}
57- lux = veml .read_lux ()
58- if not isinstance (lux , (int , float )) or lux < 0 :
59- return state .FATAL_ERROR , {}
60- return state .SUCCESS , lux
61- except Exception as e :
62- print ("❌ VEML7700 Fehler beim Lesen / Read error:" , e )
63- return state .FATAL_ERROR , {}
64-
65- # --- Initialisierung BME280 / BME280 initialization ---
66- def init_bme ():
67- global bme
68- try :
69- bme = BME280 (i2c = i2c_bme , address = config .BME280_ADDRESS )
70- print ("🌡️ BME280 initialisiert / BME280 initialized." )
71- return state .SUCCESS
72- except Exception as e :
73- print ("❌ BME280 Fehler bei Init / Init error:" , e )
74- return state .FATAL_ERROR
75-
76- def read_bme ():
77- mode = getattr (config , "BME_MODE" , "active" )
78- if mode == "inactive" :
79- return state .SUCCESS , {"temp" : None , "pressure" : None , "humidity" : None }
80- if mode == "dummy" :
81- import random
82- return state .SUCCESS , {
83- "temp" : round (random .uniform (20.0 , 35.0 ), 1 ),
84- "pressure" : round (random .uniform (980.0 , 1050.0 ), 1 ),
85- "humidity" : round (random .uniform (20.0 , 80.0 ), 1 )
86- }
87- global bme
88- try :
89- if bme is None :
90- if init_bme () != state .SUCCESS :
91- return state .FATAL_ERROR , {}
92- temp , pressure , humidity = bme .read_compensated_data ()
93- return state .SUCCESS , {
94- "temp" : round (temp , 1 ),
95- "pressure" : round (pressure , 1 ),
96- "humidity" : round (humidity , 1 )
97- }
98- except Exception as e :
99- print ("❌ BME280 Fehler beim Lesen / Read error:" , e )
100- return state .FATAL_ERROR , {}
24+
25+ # --- Sensorstrom deaktivieren / Deactivate sensor power ---
26+ def power_off ():
27+ if hasattr (config , "VEML_PWR" ):
28+ Pin (config .VEML_PWR , Pin .OUT ).off ()
29+ if hasattr (config , "BME_PWR" ):
30+ Pin (config .BME_PWR , Pin .OUT ).off ()
31+
32+ # --- Sensorinitialisierung / Sensor initialization ---
33+ def init_sensors ():
34+ global veml , bme , veml_initialized , bme_initialized
35+
36+ if config .VEML_MODE == "off" and config .BME_MODE == "off" :
37+ return state .SUCCESS # nichts zu tun / nothing to do
38+
39+ power_on ()
40+
41+ if config .VEML_MODE == "active" :
42+ try :
43+ veml_i2c = I2C (0 , sda = Pin (config .VEML_SDA ), scl = Pin (config .VEML_SCL ))
44+ veml = VEML7700 (veml_i2c )
45+ veml_initialized = True
46+ print ("📷 VEML7700 initialisiert / VEML7700 initialized." )
47+ except Exception as e :
48+ print ("❌ VEML7700 Fehler / Error:" , e )
49+ veml = None
50+ veml_initialized = False
51+
52+ if config .BME_MODE == "active" :
53+ try :
54+ bme_i2c = I2C (1 , sda = Pin (config .BME_SDA ), scl = Pin (config .BME_SCL ))
55+ bme = BME280 (i2c = bme_i2c )
56+ bme_initialized = True
57+ print ("🌡️ BME280 initialisiert / BME280 initialized." )
58+ except Exception as e :
59+ print ("❌ BME280 Fehler / Error:" , e )
60+ bme = None
61+ bme_initialized = False
62+
63+ return state .SUCCESS
10164
10265# --- RTC-Zeit holen / Get RTC time ---
10366def get_formatted_rtc ():
@@ -106,46 +69,73 @@ def get_formatted_rtc():
10669 uhrzeit = "{:02d}:{:02d}:{:02d}" .format (now [3 ], now [4 ], now [5 ])
10770 return datum , uhrzeit
10871
109- # --- Hilfsfunktion: Payload bauen nach config / Build payload by config fields ---
72+ # --- Hilfsfunktion: Payload bauen nach config / Helper: Build payload from config ---
11073def build_payload (data ):
11174 fields = getattr (config , "MQTT_PAYLOAD_FIELDS" , None )
11275 if fields :
11376 payload = OrderedDict ()
11477 for field in fields :
11578 payload [field ] = data .get (field , None )
116- # Warnung, falls Felder fehlen
11779 missing = [f for f in fields if f not in data ]
11880 if missing :
119- print ("⚠️ Warnung: Feld(er) in MQTT_PAYLOAD_FIELDS nicht im sensors.py erzeugt: / Warning: Field(s) in MQTT_PAYLOAD_FIELDS not produced in sensors.py :" , missing )
81+ print ("⚠️ MQTT_PAYLOAD_FIELDS enthält unbekannte Felder / contains unknown fields :" , missing )
12082 return payload
121- # Fallback: alle Felder übernehmen / fallback: all fields
122- return OrderedDict (data )
83+ return OrderedDict (data ) # fallback
12384
124- # --- Gesamtsensor-Auslesung / Read all sensors ---
85+ # --- Gesamtsensor-Auslesung / Full sensor reading ---
12586def read_all ():
12687 datum , uhrzeit = get_formatted_rtc ()
127-
128- # VEML
129- status_lux , lux = read_veml ()
130- if status_lux != state .SUCCESS :
131- lux = None
132-
133- # BME280
134- status_bme , bme_data = read_bme ()
135- if status_bme != state .SUCCESS or bme_data is None :
136- bme_data = {"temp" : None , "pressure" : None , "humidity" : None }
137-
138- # Alle Sensorwerte als Dict sammeln / Collect all sensor values as dict
139- data = {
140- "date" : datum ,
141- "time" : uhrzeit ,
142- "temp" : bme_data ["temp" ],
143- "pressure" : bme_data ["pressure" ],
144- "humidity" : bme_data ["humidity" ],
145- "lux" : lux
146- # → Hier beliebig um neue Felder erweitern! / Add more fields here as needed!
147- }
148-
149- # Flexibler Payload je nach Config-Feldliste / Flexible payload according to config field list
150- payload = build_payload (data )
151- return state .SUCCESS , payload
88+ data = {"date" : datum , "time" : uhrzeit }
89+
90+ # Lux-Wert lesen / Read lux
91+ if config .VEML_MODE == "active" and veml_initialized :
92+ try :
93+ data ["lux" ] = veml .read_lux ()
94+ except :
95+ data ["lux" ] = None
96+ elif config .VEML_MODE == "dummy" :
97+ data ["lux" ] = random .randint (100 , 2000 )
98+ else :
99+ data ["lux" ] = None
100+
101+ # BME-Werte lesen / Read BME values
102+ if config .BME_MODE == "active" and bme_initialized :
103+ try :
104+ temp , pressure , humidity = bme .read_compensated_data ()
105+ data ["temp" ] = round (temp , 1 )
106+ data ["pressure" ] = round (pressure / 100 , 1 )
107+ data ["humidity" ] = round (humidity , 1 )
108+ except :
109+ data ["temp" ] = None
110+ data ["pressure" ] = None
111+ data ["humidity" ] = None
112+ elif config .BME_MODE == "dummy" :
113+ data ["temp" ] = round (random .uniform (18.0 , 32.0 ), 1 )
114+ data ["pressure" ] = round (random .uniform (980.0 , 1020.0 ), 1 )
115+ data ["humidity" ] = round (random .uniform (30.0 , 60.0 ), 1 )
116+ else :
117+ data ["temp" ] = None
118+ data ["pressure" ] = None
119+ data ["humidity" ] = None
120+
121+ return state .SUCCESS , build_payload (data )
122+
123+ # --- VEML Reset über GPIO / VEML reset via GPIO ---
124+ def veml_reset ():
125+ if hasattr (config , "VEML_PWR" ):
126+ Pin (config .VEML_PWR , Pin .OUT ).off ()
127+ time .sleep (0.2 )
128+ Pin (config .VEML_PWR , Pin .OUT ).on ()
129+ time .sleep (0.5 )
130+ return True
131+ return False
132+
133+ # --- BME Reset über GPIO / BME reset via GPIO ---
134+ def bme_reset ():
135+ if hasattr (config , "BME_PWR" ):
136+ Pin (config .BME_PWR , Pin .OUT ).off ()
137+ time .sleep (0.2 )
138+ Pin (config .BME_PWR , Pin .OUT ).on ()
139+ time .sleep (0.5 )
140+ return True
141+ return False
0 commit comments