Byte 66: erreurs systeme (RTC, BME280, NPM, Envea, bruit, MPPT, vent)
Byte 67: status NextPM (sleep, degraded, not_ready, heat, trh, fan,
memory, laser) — copie directe du registre interne capteur.
Inclut le plan d'implementation en 3 etapes et le parser Miotiq.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
235 lines
9.0 KiB
Markdown
235 lines
9.0 KiB
Markdown
# 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).
|