Doc: error_flags.md — ajout byte 67 npm_status + plan implementation
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>
This commit is contained in:
@@ -1,49 +1,108 @@
|
|||||||
# Error Flags — UDP Payload Miotiq (Byte 66)
|
# Error Flags — UDP Payload Miotiq (Bytes 66-67)
|
||||||
|
|
||||||
## Principe
|
## Principe
|
||||||
|
|
||||||
Le byte 66 de la payload UDP (100 bytes) est utilise comme registre d'erreurs.
|
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
|
Chaque bit represente un etat d'erreur independant. Plusieurs erreurs peuvent
|
||||||
etre signalees simultanement.
|
etre signalees simultanement.
|
||||||
|
|
||||||
|
- **Byte 66** : erreurs systeme (RTC, capteurs)
|
||||||
|
- **Byte 67** : status NextPM (registre interne du capteur)
|
||||||
|
|
||||||
## Position dans la payload
|
## Position dans la payload
|
||||||
|
|
||||||
```
|
```
|
||||||
Bytes 0-65 : donnees capteurs (existant)
|
Bytes 0-65 : donnees capteurs (existant)
|
||||||
Byte 66 : error_flags (1 byte = 8 bits)
|
Byte 66 : error_flags (erreurs systeme)
|
||||||
Bytes 67-99 : reserved (initialises a 0xFF)
|
Byte 67 : npm_status (status NextPM)
|
||||||
|
Bytes 68-99 : reserved (initialises a 0xFF)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Definition des bits
|
---
|
||||||
|
|
||||||
| Bit | Masque | Nom | Description |
|
## Byte 66 — Error Flags (erreurs systeme)
|
||||||
|-----|--------|-------------------|--------------------------------------------------|
|
|
||||||
| 0 | 0x01 | RTC_DISCONNECTED | Module RTC DS3231 non detecte sur le bus I2C |
|
|
||||||
| 1 | 0x02 | RTC_RESET | RTC en date par defaut (annee 2000) |
|
|
||||||
| 2 | 0x04 | BME280_ERROR | Capteur BME280 non detecte ou erreur de lecture |
|
|
||||||
| 3 | 0x08 | NPM_ERROR | Capteur NextPM non detecte ou erreur Modbus |
|
|
||||||
| 4 | 0x10 | ENVEA_ERROR | Capteurs Envea non detectes ou erreur serie |
|
|
||||||
| 5 | 0x20 | NOISE_ERROR | Capteur bruit NSRT MK4 non detecte ou erreur |
|
|
||||||
| 6 | 0x40 | MPPT_ERROR | Chargeur solaire MPPT non detecte ou erreur |
|
|
||||||
| 7 | 0x80 | WIND_ERROR | Capteur vent non detecte ou erreur |
|
|
||||||
|
|
||||||
## Valeurs possibles (exemples)
|
Chaque bit represente une erreur detectee par le script d'envoi (`SARA_send_data_v2.py`).
|
||||||
|
|
||||||
| Valeur dec | Valeur hex | Signification |
|
| Bit | Masque | Nom | Description | Source |
|
||||||
|------------|------------|---------------------------------------|
|
|-----|--------|-------------------|--------------------------------------------------|-------------------------------|
|
||||||
| 0 | 0x00 | Aucune erreur |
|
| 0 | 0x01 | RTC_DISCONNECTED | Module RTC DS3231 non detecte sur le bus I2C | timestamp_table → 'not connected' |
|
||||||
| 1 | 0x01 | RTC deconnecte |
|
| 1 | 0x02 | RTC_RESET | RTC en date par defaut (annee 2000) | timestamp_table → annee 2000 |
|
||||||
| 2 | 0x02 | RTC reset (annee 2000) |
|
| 2 | 0x04 | BME280_ERROR | Capteur BME280 non detecte ou erreur de lecture | data_BME280 → valeurs a 0 |
|
||||||
| 3 | 0x03 | RTC deconnecte + RTC reset |
|
| 3 | 0x08 | NPM_ERROR | Capteur NextPM non detecte ou erreur communication| data_NPM → toutes valeurs a 0 |
|
||||||
| 4 | 0x04 | BME280 erreur |
|
| 4 | 0x10 | ENVEA_ERROR | Capteurs Envea non detectes ou erreur serie | data_envea → valeurs a 0 |
|
||||||
| 5 | 0x05 | RTC deconnecte + BME280 erreur |
|
| 5 | 0x20 | NOISE_ERROR | Capteur bruit NSRT MK4 non detecte ou erreur | data_noise → valeurs a 0 |
|
||||||
| 12 | 0x0C | BME280 erreur + NPM erreur |
|
| 6 | 0x40 | MPPT_ERROR | Chargeur solaire MPPT non detecte ou erreur | data_MPPT → valeurs a 0 |
|
||||||
| 255 | 0xFF | Toutes les erreurs (cas extreme) |
|
| 7 | 0x80 | WIND_ERROR | Capteur vent non detecte ou erreur | data_windMeter → valeurs a 0 |
|
||||||
|
|
||||||
## Implementation Python (capteur)
|
### 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
|
```python
|
||||||
# Constantes
|
# Constantes error_flags (byte 66)
|
||||||
ERR_RTC_DISCONNECTED = 0x01
|
ERR_RTC_DISCONNECTED = 0x01
|
||||||
ERR_RTC_RESET = 0x02
|
ERR_RTC_RESET = 0x02
|
||||||
ERR_BME280 = 0x04
|
ERR_BME280 = 0x04
|
||||||
@@ -53,22 +112,38 @@ ERR_NOISE = 0x20
|
|||||||
ERR_MPPT = 0x40
|
ERR_MPPT = 0x40
|
||||||
ERR_WIND = 0x80
|
ERR_WIND = 0x80
|
||||||
|
|
||||||
# Construction du flag
|
# Construction byte 66
|
||||||
error_flags = 0x00
|
error_flags = 0x00
|
||||||
|
|
||||||
if rtc_status == "disconnected":
|
if rtc_status == "disconnected":
|
||||||
error_flags |= ERR_RTC_DISCONNECTED
|
error_flags |= ERR_RTC_DISCONNECTED
|
||||||
|
|
||||||
if rtc_status == "reset":
|
if rtc_status == "reset":
|
||||||
error_flags |= ERR_RTC_RESET
|
error_flags |= ERR_RTC_RESET
|
||||||
|
if PM1 == 0 and PM25 == 0 and PM10 == 0:
|
||||||
|
error_flags |= ERR_NPM
|
||||||
|
# ... autres capteurs
|
||||||
|
|
||||||
if bme280_error:
|
payload.set_error_flags(error_flags)
|
||||||
error_flags |= ERR_BME280
|
|
||||||
|
|
||||||
# Ecriture dans la payload
|
# Construction byte 67 (lu depuis SQLite, ecrit par get_data_modbus_v3.py)
|
||||||
payload[66] = error_flags
|
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
|
## Parser Miotiq
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -104,13 +179,17 @@ payload[66] = error_flags
|
|||||||
4|wind_speed|hex2dec|m/s|x/10|
|
4|wind_speed|hex2dec|m/s|x/10|
|
||||||
4|wind_direction|hex2dec|degrees||
|
4|wind_direction|hex2dec|degrees||
|
||||||
2|error_flags|hex2dec|||
|
2|error_flags|hex2dec|||
|
||||||
32|reserved|skip|||
|
2|npm_status|hex2dec|||
|
||||||
|
30|reserved|skip|||
|
||||||
```
|
```
|
||||||
|
|
||||||
## Lecture cote serveur (exemple)
|
---
|
||||||
|
|
||||||
|
## Lecture cote serveur (exemple Python)
|
||||||
|
|
||||||
```python
|
```python
|
||||||
error_flags = int(parsed_value) # valeur decodee par Miotiq (0-255)
|
# Byte 66 — erreurs systeme
|
||||||
|
error_flags = int(parsed_error_flags)
|
||||||
|
|
||||||
rtc_disconnected = bool(error_flags & 0x01)
|
rtc_disconnected = bool(error_flags & 0x01)
|
||||||
rtc_reset = bool(error_flags & 0x02)
|
rtc_reset = bool(error_flags & 0x02)
|
||||||
@@ -121,14 +200,35 @@ noise_error = bool(error_flags & 0x20)
|
|||||||
mppt_error = bool(error_flags & 0x40)
|
mppt_error = bool(error_flags & 0x40)
|
||||||
wind_error = bool(error_flags & 0x80)
|
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:
|
if rtc_disconnected:
|
||||||
alert("RTC module deconnecte — verifier pile/cables I2C")
|
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
|
## Notes
|
||||||
|
|
||||||
- La valeur par defaut de la payload est 0xFF (tous bytes a 255), ce qui signifierait
|
- La payload est initialisee a 0xFF (tous bytes a 255). Le script doit explicitement
|
||||||
"toutes les erreurs". Le script doit explicitement ecrire 0x00 quand tout va bien.
|
ecrire 0x00 dans les bytes 66-67 quand tout va bien, sinon Miotiq interpretera
|
||||||
- Les flags sont cumulatifs : un capteur peut avoir plusieurs erreurs simultanement.
|
255 = toutes les erreurs.
|
||||||
- Ce systeme est extensible : si on a besoin de plus de 8 flags, on peut utiliser
|
- Le NPM status n'est pas encore lu par `get_data_modbus_v3.py`. Il faut d'abord
|
||||||
le byte 67 pour 8 flags supplementaires.
|
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).
|
||||||
|
|||||||
Reference in New Issue
Block a user