Skip to content

Commit 80b48b1

Browse files
authored
Add files via upload
1 parent 2ae5261 commit 80b48b1

File tree

3 files changed

+197
-199
lines changed

3 files changed

+197
-199
lines changed

src/lib/config.py

Lines changed: 47 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,72 @@
1+
12
# config.py – zentrale Konfiguration / central configuration
23

34
# ========== WLAN-Konfiguration (primär) / WiFi configuration (primary) ==========
4-
SSID = "Your_Primary_SSID" # Name des primären WLANs / Primary WiFi SSID
5-
PASSWORD = "your_fallback_pass" # Passwort / Primary WiFi password
6-
STATIC_IP = "" # Statische IP-Adresse (optional) / Static IP (optional)
7-
NETMASK = "255.255.255.0" # Subnetzmaske / Subnet mask
8-
GATEWAY = "192.168.1.1" # Gateway-Adresse / Default gateway
9-
DNS = "8.8.8.8" # DNS-Server / DNS server
5+
SSID = "Your_Primary_SSID"
6+
PASSWORD = "your_primary_password"
7+
STATIC_IP = ""
8+
NETMASK = "255.255.255.0"
9+
GATEWAY = "192.168.1.1"
10+
DNS = "8.8.8.8"
1011

1112
# ========== WLAN-Konfiguration (Fallback) / WiFi configuration (fallback) ==========
12-
SSID_FB = "Your_Secondary_SSID" # Fallback WLAN / Secondary WiFi SSID
13-
PASSWORD_FB = "your_fallback_pass" # Fallback Passwort / Password for fallback network
14-
STATIC_IP_FB = "" # Leer für DHCP / Leave empty for DHCP
13+
SSID_FB = "Your_Secondary_SSID"
14+
PASSWORD_FB = "your_fallback_password"
15+
STATIC_IP_FB = ""
1516
NETMASK_FB = "255.255.255.0"
16-
GATEWAY_FB = "192.168.1.1"
17+
GATEWAY_FB = "192.168.2.1"
1718
DNS_FB = "1.1.1.1"
1819

1920
# ========== Zeitsynchronisation / Time sync settings ==========
20-
NTP_SERVER = "192.168.1.1" # NTP-Server / NTP server
21-
UTC_OFFSET = "3600" # Zeitzonenoffset in Sekunden / Timezone offset (seconds, e.g. UTC+1)
22-
SUMMER_OFFSET = "3600" # Sommerzeit-Offset (Sekunden) / DST offset (seconds)
21+
NTP_SERVER = "pool.ntp.org"
22+
UTC_OFFSET = "3600"
23+
SUMMER_OFFSET = "3600"
2324

2425
# ========== WLAN-Verbindungsversuche / WiFi retry logic ==========
25-
MAX_WIFI_RETRIES = 10 # Maximale Versuche / Max connection retries
26-
WIFI_RETRY_DELAY = 0.5 # Pause zwischen Versuchen (s) / Delay between retries (s)
27-
WIFI_PRIMARY_CHECK = 10 # Prüfintervall Primärnetz / Loops before checking primary WiFi
28-
WIFI_CONNECT_TIMEOUT = 3 # Sekunden für WLAN-Timeout / Timeout for WiFi connect (seconds)
26+
MAX_WIFI_RETRIES = 10
27+
WIFI_RETRY_DELAY = 0.5
28+
WIFI_PRIMARY_CHECK = 10
29+
WIFI_CONNECT_TIMEOUT = 3
2930

3031
# ========== MQTT-Konfiguration / MQTT configuration ==========
31-
MQTT_MODE = "active" # "active", "dummy", "inactive"
32-
MQTT_BROKER = "192.168.1.1" # MQTT-Broker IP / MQTT broker IP
33-
MQTT_PORT = 1883 # Port
34-
MQTT_CLIENT_ID = "sensor_gh_1" # Client-ID / Client ID
35-
MQTT_TOPIC = "sensor/gh/sensor_outdoor" # Topic
36-
MQTT_USER = None # Benutzer (optional) / User (optional)
37-
MQTT_PASSWORD = None # Passwort (optional) / Password (optional)
32+
MQTT_MODE = "active"
33+
MQTT_BROKER = "192.168.1.100"
34+
MQTT_PORT = 1883
35+
MQTT_CLIENT_ID = "sensor_default"
36+
MQTT_TOPIC = "sensor/default"
37+
MQTT_USER = None
38+
MQTT_PASSWORD = None
3839

39-
# ------- MQTT Payload Layout ---------------------------------
40-
# Definiert die Felder und Reihenfolge des MQTT-Payloads.
41-
# Defines fields and order of MQTT payload.
42-
# → Einfach Felder ergänzen/entfernen, die in sensors.py erzeugt werden.
43-
# → Just add/remove fields present in sensors.py.
4440
MQTT_PAYLOAD_FIELDS = [
45-
"date", # Datum / Date
46-
"time", # Uhrzeit / Time
47-
"temp", # Temperatur / Temperature (°C)
48-
"pressure", # Luftdruck / Pressure (hPa)
49-
"humidity", # Luftfeuchte / Humidity (%)
50-
"lux", # Lichtstärke / Light intensity (Lux)
51-
# "soil", # Beispiel: Bodenfeuchte / Example: Soil moisture
52-
# "co2", # Beispiel: CO₂-Gehalt / Example: CO₂ level
41+
"date",
42+
"time",
43+
"temp",
44+
"pressure",
45+
"humidity",
46+
"lux",
5347
]
5448

5549
# ========== Sensor-Update-Intervall / Sensor data send interval ==========
56-
UPDATE_INTERVAL = 10 # Sekunden / Seconds
50+
UPDATE_INTERVAL = 10
5751

5852
# ========== LED-Konfiguration / LED pin setup ==========
59-
ONBOARD_LED = "LED" # Onboard-LED-Bezeichnung / Onboard LED name (constant in MicroPython)
60-
STATUS_LED = 16 # GPIO für Status-LED / GPIO for external status LED
53+
ONBOARD_LED = "LED"
54+
STATUS_LED = 16
6155

62-
# ========================================================================
63-
# === Sensor-Konfiguration mit Testmode / Sensor config with testmode ====
64-
# ========================================================================
56+
# === Sensor-Konfiguration mit Testmode / Sensor config with testmode ===
6557

6658
# ------ VEML7700 (Lichtsensor) / Light sensor ------
67-
VEML_MODE = "active" # "active" (echt), "dummy" (simuliert), "inactive" (aus)
68-
# # "active" (real), "dummy" (simulate), "inactive" (off)
69-
VEML_SDA = 0 # SDA-Pin für VEML7700 / SDA pin for VEML7700
70-
VEML_SCL = 1 # SCL-Pin / SCL pin
71-
VEML_PWR = 15 # Power-Pin / Power pin
72-
VEML7700_ADDRESS = 0x10 # I2C-Adresse / I2C address
73-
VEML7700_IT = 25 # Integrationszeit / Integration time (25, 50, 100, 200, 400, 800)
74-
VEML7700_GAIN = 1/8 # Gain: 1/8, 1/4, 1, 2
59+
VEML_MODE = "active"
60+
VEML_SDA = 0
61+
VEML_SCL = 1
62+
VEML_PWR = 15
63+
VEML7700_ADDRESS = 0x10
64+
VEML7700_IT = 25
65+
VEML7700_GAIN = 1/8
7566

7667
# ------ BME280 (Temp/RLF/Druck) / Temperature, humidity, pressure sensor ------
77-
BME_MODE = "active" # "active" (echt), "dummy" (simuliert), "inactive" (aus)
78-
# # "active" (real), "dummy" (simulate), "inactive" (off)
79-
BME_SDA = 2 # SDA-Pin / SDA pin
80-
BME_SCL = 3 # SCL-Pin / SCL pin
81-
BME_PWR = 14 # Power-Pin / Power pin
82-
BME280_ADDRESS = 0x76 # I2C-Adresse / I2C address
68+
BME_MODE = "active"
69+
BME_SDA = 2
70+
BME_SCL = 3
71+
BME_PWR = 14
72+
BME280_ADDRESS = 0x76

src/lib/sensors.py

Lines changed: 112 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -1,103 +1,66 @@
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
43
from veml7700_driver import VEML7700
54
from bme280_driver import BME280
5+
from machine import Pin, I2C
66
import time
7-
from collections import OrderedDict
8-
import state
97
import config
8+
import state
9+
import random
10+
from collections import OrderedDict
1011

1112
veml = None
1213
bme = 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 ---
10366
def 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 ---
11073
def 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 ---
12586
def 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

Comments
 (0)