v1.12.0: transmission CO2 S88 dans le payload UDP Miotiq (byte 81)

Débloque le WIP S88->Miotiq. Spec serveur reçue: byte 81-82 = CO2 (ISO_17,
uint16 ppm). Source = Senseair S88 (vrai CO2 NDIR).

- SensorPayload.set_co2() -> bytes 81-82 (uint16, clamp 0..65535)
- lecture data_S88 (derniere ligne) si config S88 active, puis set_co2
- defaut 0xFFFF = capteur absent
- canal UDP Miotiq uniquement (CSV/JSON non touches)
- error_flags.md: byte-map a jour (81-82 = CO2)

CCS811 (TVOC/eCO2) NON transmis: pas encore de champ dans la spec Miotiq.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
PaulVua
2026-06-02 16:55:54 +02:00
parent 13c266d694
commit dad953acdc
4 changed files with 41 additions and 5 deletions

View File

@@ -243,9 +243,10 @@ send_uSpot = config.get('send_uSpot', False) #envoi sur M
npm_5channel = config.get('npm_5channel', False) #5 canaux du NPM
envea_cairsens= config.get('envea', False)
wind_meter= config.get('windMeter', False)
bme_280_config = config.get('BME280', False)
bme_280_config = config.get('BME280', False)
mppt_charger = config.get('MPPT', False)
NOISE_sensor = config.get('NOISE', False)
s88_sensor = config.get('S88', False)
#update device id in the payload json
payload_json["nebuleairid"] = device_id
@@ -373,7 +374,14 @@ class SensorPayload:
self.payload[62:64] = struct.pack('>H', int(speed * 10))
if direction is not None:
self.payload[64:66] = struct.pack('>H', int(direction))
def set_co2(self, co2_ppm):
"""Set CO2 (bytes 81-82, uint16 ppm) — ISO_17 in the Miotiq spec.
Source: Senseair S88 (true NDIR CO2). Default stays 0xFFFF (constructor
fills 0xFF) = sensor absent. NOT for CCS811 eCO2 (a derived value)."""
if co2_ppm is not None:
self.payload[81:83] = struct.pack('>H', max(0, min(int(co2_ppm), 65535)))
def set_error_flags(self, flags):
"""Set system error flags (byte 66)"""
self.payload[66] = flags & 0xFF
@@ -1073,7 +1081,19 @@ try:
payload.set_noise(
cur_leq=cur_LEQ, # current LEQ (dBA)
cur_level=cur_level # current level (dBA)
)
)
# S88 CO2 sensor (Senseair S88, NDIR) -> byte 81-82 (ISO_17, uint16 ppm)
if s88_sensor:
print("Getting S88 CO2 value")
cursor.execute("SELECT * FROM data_S88 ORDER BY rowid DESC LIMIT 1")
last_row = cursor.fetchone()
if last_row and last_row[1] is not None:
co2_ppm = last_row[1]
print(f"CO2 (S88): {co2_ppm} ppm")
payload.set_co2(co2_ppm)
else:
print("No S88 data available in the database.")
#print("Verify SARA connection (AT)")