Files
nebuleair_pro_4g/loop/AUDIT_SARA_send_data_v2.md
paul_vua d5b2e9c6c3 v1.4.2 — Fix bug AT+USOWR leak dans payload UDP Miotiq
Corrige une desynchronisation serie qui causait l'envoi de la commande
AT+USOWR comme donnees UDP au lieu du payload capteurs. Ajout de flush
buffer serie, verification du prompt @, et abort propre a chaque etape.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 22:53:59 +01:00

4.3 KiB

Audit SARA_send_data_v2.py

Date: 2026-03-14

Correction deja appliquee

Bug AT+USOWR leak dans payload UDP Miotiq — Le device_id recu par Miotiq etait 41542b55534f5752 = AT+USOWR (la commande AT elle-meme).

Cause: desynchronisation serie entre le script et le modem. Le code envoyait les donnees binaires sans verifier que le modem avait bien envoye le prompt @.

Corrections appliquees dans la section UDP (send_miotiq):

  • ser_sara.reset_input_buffer() avant chaque commande AT critique
  • Verification que "@" in response avant d'envoyer les donnees binaires
  • Abort propre a chaque etape via socket_id = None si creation socket, connexion, ou prompt @ echoue
  • Retry AT+USOCR=17 apres un PDP reset reussi

Bugs critiques restants

1. Double \r sur plusieurs commandes AT

Certaines commandes AT ont \r dans le f-string ET un + '\r' lors du write, ce qui envoie \r\r au modem.

Lignes concernees:

  • Ligne 988: command = f'AT+CSQ\r' puis ser_sara.write((command + '\r')...)
  • Lignes 588, 628, 646, 656, 666, 674, 682, 690, 698: fonctions reset_server_hostname et reset_server_hostname_https
  • Lignes 1403, 1541, 1570, 1694, 1741: sections AirCarto et uSpot

Le modem tolere souvent le double \r, mais ca peut generer des reponses parasites dans le buffer serie et contribuer a des bugs de desynchronisation.

Correction: retirer le \r du f-string OU retirer le + '\r' dans le write. Choisir une convention unique.

2. Double guillemet dans AT+URDFILE (ligne 1402)

command = f'AT+URDFILE="aircarto_server_response.txt""\r'
#                                                    ^^ double "

Le " en trop peut causer une erreur AT ou une reponse inattendue.

Correction: command = f'AT+URDFILE="aircarto_server_response.txt"\r'

3. Crash si table SQLite vide (lignes 781-786, 820-826, 868-880)

rows = cursor.fetchall()
data_values = [row[2:] for row in rows]
averages = [round(sum(col) / len(col),1) for col in zip(*data_values)]

Si data_NPM, data_NPM_5channels ou data_envea est vide, data_values sera [] et le calcul d'average crashera (IndexError / division par zero).

Correction: ajouter un check if rows: avant le calcul, comme c'est deja fait pour BME280 (ligne 840), wind (ligne 912) et MPPT (ligne 936).

4. Overflow struct.pack sur valeurs negatives (class SensorPayload)

def set_npm_core(self, pm1, pm25, pm10):
    self.payload[10:12] = struct.pack('>H', int(pm1 * 10))  # H = unsigned 16-bit

Si un capteur retourne une valeur negative (erreur capteur, -1, etc.), struct.pack('>H', -10) leve struct.error. Concerne: set_npm_core, set_noise, set_envea, set_npm_5channels, set_wind, set_mppt (sauf battery_current et temperatures qui utilisent '>h' signe).

Correction: clamper les valeurs avant pack: max(0, int(value * 10)) pour les champs unsigned, ou verifier value >= 0 avant le pack.


Problemes importants

5. Port serie et SQLite jamais fermes

ser_sara (ligne 248) et conn (ligne 155) sont ouverts mais jamais fermes, meme dans le bloc except final (ligne 1755). Si le script crash, le port serie peut rester verrouille pour le prochain cycle.

Correction: ajouter un bloc finally apres le except (ligne 1757):

finally:
    ser_sara.close()
    conn.close()

6. Code mort dans reset_server_hostname_https (lignes 717-722)

if profile_id == 1:    # ligne 613
    ...
elif profile_id == 1:  # ligne 718 — jamais atteint car meme condition
    pass

Copie-colle de reset_server_hostname. Le elif est mort.

Correction: supprimer le bloc elif (lignes 717-722).


Resume

# Type Description Lignes
1 Bug Double \r sur commandes AT 988, 588+, ...
2 Bug Double guillemet AT+URDFILE 1402
3 Crash Table SQLite vide -> IndexError 781, 820, 868
4 Crash struct.pack overflow valeur negative SensorPayload
5 Cleanup Serial/SQLite jamais fermes (finally) 248, 155
6 Cleanup Code mort elif profile_id==1 717-722