# Error Flags — UDP Payload Miotiq (Bytes 66-67) ## Principe Les bytes 66 et 67 de la payload UDP (100 bytes) sont utilises comme registres d'erreurs. Chaque bit represente un etat d'erreur independant. Plusieurs erreurs peuvent etre signalees simultanement. - **Byte 66** : erreurs systeme (RTC, capteurs) - **Byte 67** : status NextPM (registre interne du capteur) ## Position dans la payload ``` Bytes 0-65 : donnees capteurs (existant) Byte 66 : error_flags (erreurs systeme) Byte 67 : npm_status (status NextPM) Bytes 68-99 : reserved (initialises a 0xFF) ``` --- ## Byte 66 — Error Flags (erreurs systeme) Chaque bit represente une erreur detectee par le script d'envoi (`SARA_send_data_v2.py`). | Bit | Masque | Nom | Description | Source | |-----|--------|-------------------|--------------------------------------------------|-------------------------------| | 0 | 0x01 | RTC_DISCONNECTED | Module RTC DS3231 non detecte sur le bus I2C | timestamp_table → 'not connected' | | 1 | 0x02 | RTC_RESET | RTC en date par defaut (annee 2000) | timestamp_table → annee 2000 | | 2 | 0x04 | BME280_ERROR | Capteur BME280 non detecte ou erreur de lecture | data_BME280 → valeurs a 0 | | 3 | 0x08 | NPM_ERROR | Capteur NextPM non detecte ou erreur communication| data_NPM → toutes valeurs a 0 | | 4 | 0x10 | ENVEA_ERROR | Capteurs Envea non detectes ou erreur serie | data_envea → valeurs a 0 | | 5 | 0x20 | NOISE_ERROR | Capteur bruit NSRT MK4 non detecte ou erreur | data_noise → valeurs a 0 | | 6 | 0x40 | MPPT_ERROR | Chargeur solaire MPPT non detecte ou erreur | data_MPPT → valeurs a 0 | | 7 | 0x80 | WIND_ERROR | Capteur vent non detecte ou erreur | data_windMeter → valeurs a 0 | ### Detection des erreurs Les scripts de collecte (`get_data_modbus_v3.py`, `get_data_v2.py`, etc.) ecrivent des **0** en base SQLite quand un capteur ne repond pas. Le script d'envoi (`SARA_send_data_v2.py`) lit ces valeurs et peut detecter l'erreur quand toutes les valeurs d'un capteur sont a 0. Pour le RTC, le champ `timestamp_table` contient directement `'not connected'` ou une date en annee 2000 quand le module est deconnecte ou reinitialise. ### Exemples de valeurs | Valeur dec | Hex | Signification | |------------|------|---------------------------------------| | 0 | 0x00 | Aucune erreur | | 1 | 0x01 | RTC deconnecte | | 2 | 0x02 | RTC reset (annee 2000) | | 5 | 0x05 | RTC deconnecte + BME280 erreur | | 9 | 0x09 | RTC deconnecte + NPM erreur | | 255 | 0xFF | Toutes les erreurs (cas extreme) | --- ## Byte 67 — NPM Status (registre interne NextPM) Le capteur NextPM possede un registre de status sur 9 bits (registre Modbus). On stocke les 8 bits bas dans le byte 67. Ce registre est lu directement depuis le capteur via Modbus, pas depuis SQLite. | Bit | Masque | Nom | Description | Severite | |-----|--------|-----------------|-----------------------------------------------------------------------|----------------| | 0 | 0x01 | SLEEP_STATE | Capteur en veille (commande sleep). Seule la lecture status autorisee | Info | | 1 | 0x02 | DEGRADED_STATE | Erreur mineure confirmee. Mesures possibles mais precision reduite | Warning | | 2 | 0x04 | NOT_READY | Demarrage en cours (15s apres mise sous tension). Mesures non fiables | Info | | 3 | 0x08 | HEAT_ERROR | Humidite relative > 60% pendant > 10 minutes | Warning | | 4 | 0x10 | TRH_ERROR | Capteur T/RH interne hors specification | Warning | | 5 | 0x20 | FAN_ERROR | Vitesse ventilateur hors plage (tourne encore) | Warning | | 6 | 0x40 | MEMORY_ERROR | Acces memoire impossible, fonctions internes limitees | Warning | | 7 | 0x80 | LASER_ERROR | Aucune particule detectee pendant > 240s, possible erreur laser | Warning | Note : le bit 8 du registre NextPM (DEFAULT_STATE — ventilateur arrete apres 3 tentatives) ne tient pas dans un byte. Si necessaire, il peut etre combine avec le bit 0 (SLEEP_STATE) car les deux indiquent un capteur inactif. ### Exemples de valeurs | Valeur dec | Hex | Signification | |------------|------|--------------------------------------------| | 0 | 0x00 | Capteur OK, mesures fiables | | 4 | 0x04 | Demarrage en cours (NOT_READY) | | 8 | 0x08 | Erreur humidite (HEAT_ERROR) | | 32 | 0x20 | Erreur ventilateur (FAN_ERROR) | | 128 | 0x80 | Possible erreur laser (LASER_ERROR) | | 40 | 0x28 | HEAT_ERROR + FAN_ERROR | --- ## Implementation ### Etape 1 : Lire le status NPM depuis le capteur Le script `NPM/get_data_modbus_v3.py` doit etre modifie pour : 1. Lire le registre de status du NextPM (adresse Modbus a determiner) 2. Stocker le status byte dans une nouvelle colonne SQLite (ex: `npm_status` dans `data_NPM`) ### Etape 2 : Construire les flags dans SARA_send_data_v2.py ```python # Constantes error_flags (byte 66) ERR_RTC_DISCONNECTED = 0x01 ERR_RTC_RESET = 0x02 ERR_BME280 = 0x04 ERR_NPM = 0x08 ERR_ENVEA = 0x10 ERR_NOISE = 0x20 ERR_MPPT = 0x40 ERR_WIND = 0x80 # Construction byte 66 error_flags = 0x00 if rtc_status == "disconnected": error_flags |= ERR_RTC_DISCONNECTED if rtc_status == "reset": error_flags |= ERR_RTC_RESET if PM1 == 0 and PM25 == 0 and PM10 == 0: error_flags |= ERR_NPM # ... autres capteurs payload.set_error_flags(error_flags) # Construction byte 67 (lu depuis SQLite, ecrit par get_data_modbus_v3.py) npm_status = get_npm_status_from_db() # 0-255 payload.set_npm_status(npm_status) ``` ### Etape 3 : Ajouter les methodes dans SensorPayload ```python def set_error_flags(self, flags): """Set system error flags (byte 66)""" self.payload[66] = flags & 0xFF def set_npm_status(self, status): """Set NextPM status register (byte 67)""" self.payload[67] = status & 0xFF ``` --- ## Parser Miotiq ``` 16|device_id|string|||W 2|signal_quality|hex2dec|dB|| 2|version|hex2dec|||W 4|ISO_68|hex2dec|ugm3|x/10| 4|ISO_39|hex2dec|ugm3|x/10| 4|ISO_24|hex2dec|ugm3|x/10| 4|ISO_54|hex2dec|degC|x/100| 4|ISO_55|hex2dec|%|x/100| 4|ISO_53|hex2dec|hPa|| 4|noise_cur_leq|hex2dec|dB|x/10| 4|noise_cur_level|hex2dec|dB|x/10| 4|max_noise|hex2dec|dB|x/10| 4|ISO_03|hex2dec|ppb|| 4|ISO_05|hex2dec|ppb|| 4|ISO_21|hex2dec|ppb|| 4|ISO_04|hex2dec|ppb|| 4|ISO_08|hex2dec|ppb|| 4|npm_ch1|hex2dec|count|| 4|npm_ch2|hex2dec|count|| 4|npm_ch3|hex2dec|count|| 4|npm_ch4|hex2dec|count|| 4|npm_ch5|hex2dec|count|| 4|npm_temp|hex2dec|°C|x/10| 4|npm_humidity|hex2dec|%|x/10| 4|battery_voltage|hex2dec|V|x/100| 4|battery_current|hex2dec|A|x/100| 4|solar_voltage|hex2dec|V|x/100| 4|solar_power|hex2dec|W|| 4|charger_status|hex2dec||| 4|wind_speed|hex2dec|m/s|x/10| 4|wind_direction|hex2dec|degrees|| 2|error_flags|hex2dec||| 2|npm_status|hex2dec||| 30|reserved|skip||| ``` --- ## Lecture cote serveur (exemple Python) ```python # Byte 66 — erreurs systeme error_flags = int(parsed_error_flags) rtc_disconnected = bool(error_flags & 0x01) rtc_reset = bool(error_flags & 0x02) bme280_error = bool(error_flags & 0x04) npm_error = bool(error_flags & 0x08) envea_error = bool(error_flags & 0x10) noise_error = bool(error_flags & 0x20) mppt_error = bool(error_flags & 0x40) wind_error = bool(error_flags & 0x80) # Byte 67 — status NextPM npm_status = int(parsed_npm_status) npm_sleep = bool(npm_status & 0x01) npm_degraded = bool(npm_status & 0x02) npm_not_ready = bool(npm_status & 0x04) npm_heat_err = bool(npm_status & 0x08) npm_trh_err = bool(npm_status & 0x10) npm_fan_err = bool(npm_status & 0x20) npm_mem_err = bool(npm_status & 0x40) npm_laser_err = bool(npm_status & 0x80) # Alertes if rtc_disconnected: alert("RTC module deconnecte — verifier pile/cables I2C") if npm_fan_err: alert("NextPM: ventilateur hors plage — maintenance requise") if npm_laser_err: alert("NextPM: possible erreur laser — verifier le capteur") ``` --- ## Notes - La payload est initialisee a 0xFF (tous bytes a 255). Le script doit explicitement ecrire 0x00 dans les bytes 66-67 quand tout va bien, sinon Miotiq interpretera 255 = toutes les erreurs. - Le NPM status n'est pas encore lu par `get_data_modbus_v3.py`. Il faut d'abord ajouter la lecture du registre de status Modbus et le stocker en SQLite. - Les flags du byte 66 sont determines par le script d'envoi en analysant les valeurs lues depuis SQLite (toutes a 0 = capteur en erreur).