Ajoute un test 'Power Supply' au Self Test pour détecter une
sous-tension du Pi (cause fréquente de capteurs USB instables,
corruptions SD, reboots). Endpoint launcher.php?type=throttled
+ script power/get_throttled.py (lancé via sudo python3, déjà
whitelisté — pas de modif sudoers). Affiché en tête des résultats
et dans le rapport copiable.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Fix Envea Gas Sensors: scan physique via detect_envea_device (read_ref.py)
sur ttyAMA3/4/5 au lieu de juste vérifier envea_sondes_table.connected=1.
L'ancien check disait Passed même sans sonde branchée car read_value_v2.py -d
imprime un en-tête de debug non vide et utilise "Failed" pas "error".
- Ajout Firmware Version dans les logs et le rapport (via firmware_version
déjà retourné par get_config_sqlite, pas d'AJAX supplémentaire).
- Renommage titre modal "Modem Self Test" -> "Self Test" (couvre aussi
capteurs et RTC, pas uniquement le modem).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Au lieu d'afficher l'erreur Apache "404 Not Found" qui faisait croire
à un bug, le modal indique maintenant que le log n'existe que lorsqu'une
tentative de connexion WiFi a déjà eu lieu. Inclut aussi un échappement
HTML basique du contenu et limite l'affichage aux 1000 dernières lignes.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Ajoute un bouton 'WiFi connect logs' dans logs.html qui ouvre un modal
avec le contenu de logs/wifi_connect.log (créé en v1.9.3). Permet de
diagnostiquer une tentative de connexion WiFi sans passer en SSH.
Le contenu est chargé à l'ouverture du modal (pas au chargement de la
page) pour éviter de saturer la limite de 6 connexions du navigateur
sur la page Journal.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bugs corrigés:
- launcher.php passait SSID/PASS au shell sans escapeshellarg(): un
mot de passe avec $/&/;/espace cassait silencieusement la commande
avant que nmcli ne soit appelé. Cause probable des retours clients
"ça bloque au cliquer sur Se connecter".
- wifi.html n'encodait pas SSID/PASS dans l'URL: caractères &/+/=
corrompaient la requête.
Observabilité:
- Nouveau fichier logs/wifi_connect.log avec timestamps stricts
- launcher.php log la requête entrante (IP, longueurs SSID/PASS)
- connexion.sh: fonction log_wc(), snapshots NM avant/après,
capture stdout+stderr nmcli, code retour explicite, fallback SSID
dérivé du serial si deviceName indisponible.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- admin.html: nouveau card 'Reseau Tailscale' avec statut connecte/deconnecte,
IP tailnet, hostname, serveur Headscale et bouton Actualiser
- admin.html: bloc deroulant pour consulter les 50 dernieres lignes du log
bootstrap (logs/tailscale_bootstrap.log)
- launcher.php: nouvelles actions get_tailscale_info (status + IP + hostname
via sudo tailscale ip/status) et get_tailscale_log (tail -n 50)
Complete la v1.9.0 avec la visibilite UI necessaire pour valider/diagnostiquer
la connexion Tailscale sur chaque capteur sans avoir a passer en SSH.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Ajoute la version firmware sous le nom du capteur dans la sidebar, visible
sur toutes les pages. Permet d'identifier d'un coup d'oeil le chemin de
mise a jour disponible (online git pull vs offline ZIP upload >= v1.4.0).
- launcher.php: get_config_sqlite injecte firmware_version (lu depuis VERSION)
- sidebar.html: ajout d'un <small> sous sideBar_sensorName (statique)
- topbar-logo.js: peuple .sideBar_firmwareVersion via le fetch existant +
MutationObserver (aucun nouveau fetch -> respecte la limite 6 connexions)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sur les anciens capteurs sans regle sudoers NOPASSWD pour
/var/www/nebuleair_pro_4g/*, l'update echouait avec un message
sudo cryptique.
Nouveau:
- preflight_sudo_check() en PHP teste 'sudo -n -l <script>' avant
de lancer l'update (online ou offline)
- Si KO: la route retourne error_type=sudoers_missing avec un
message clair et la sortie technique de sudo
- L'UI affiche une alerte warning structuree avec etapes numerotees,
contenu du fichier /etc/sudoers.d/nebuleair pret a coller, et un
bouton 'Copier le contenu' (presse-papier)
- Echec immediat (<1s) au lieu d'attendre le timeout du script
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
L'upload offline avait deux defauts vs l'update online:
- pas de self-heal des services (pas de Step 3c equivalent)
- ancienne UX synchrone (spinner sans feedback pendant 60-90s)
Maintenant:
- update_firmware_from_file.sh: nouveau Step 4c qui appelle
setup_services.sh (alignement avec online)
- launcher.php upload_firmware: lance le script en background et
reutilise le mecanisme log/done de l'update online
- admin.html uploadFirmware: apres l'upload du ZIP, bascule sur
le meme systeme de polling/progress que l'online (avec mapping
d'etapes specifique au script offline)
- Detection de fin par substring 'completed successfully!' (matche
les 2 markers finaux differents)
Fix au passage: le bouton 'Upload & Install' restait bloque sur
'Installing...' apres succes.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
L'ancien flow etait un AJAX bloquant qui attendait ~90s sans aucun
retour visuel autre qu'un spinner.
Nouveau flow:
- Backend: launcher.php lance update_firmware.sh en background
(route update_firmware_start) et expose une route de polling
incremental (update_firmware_progress) avec offset.
- Frontend: progress bar Bootstrap animee + label de l'etape en
cours + timer mm:ss / estimation, plus streaming des logs
toutes les 700ms.
- Sous-etape Step 3c (la plus longue): interpolation fine de la
progression en comptant les 'Started X' (services demarres).
- Logs techniques masques par defaut dans <details>, ouverts
automatiquement en cas d'echec pour faciliter le debug.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Les requetes MIN/MAX(timestamp) sur les tables capteur etaient
faussees par les lignes accumulees pendant le bug RTC (v1.7.4):
la chaine 'not connected' > toute date ISO en tri ASCII, donc
MAX() retournait 'not connected' au lieu de la vraie date la
plus recente.
Fix: WHERE timestamp != 'not connected' dans les requetes MIN/MAX.
Les lignes 'not connected' restent en base, elles sont juste
ignorees pour le calcul des bornes temporelles affichees.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Ajout dans le tableau admin et dans les listes allowed restart/toggle:
- rtc_save_to_db.service
- nebuleair-wifi-powersave.timer
- nebuleair-cpu-power.service
Aussi: nebuleair-noise-data.timer etait dans get_systemd_services
mais absent des listes restart/toggle (les boutons n'auraient pas
fonctionne). Corrige.
Nouveau: support d'un display_name explicite par service (override
optionnel) pour les noms qui ne suivent pas la convention
'nebuleair-*-data.timer'.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Les capteurs en production envoient 0x01 sur le byte 9 (ancien protocol_version).
Cote serveur: 0x00 et 0x01 = data normal, 0x02 = ping test.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- SensorPayload: byte 9 passe de protocol_version (0x01) à command (0x00 par défaut)
- Nouveau set_command() method (0x00=data normal, 0x01=ping test)
- Nouveau script SARA/sara_ping_miotiq.py: envoie payload 100 bytes avec command=1,
puis écoute la réponse descendante Miotiq pendant 15s via AT+USORD
- Endpoint launcher.php sara_ping_miotiq
- Bouton "Ping Miotiq" dans la section tests Miotiq (page modem)
- Mise à jour error_flags.md avec la nouvelle map complète du payload
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Nouveau script SARA/sara_check_pdp.py: vérifie si PDP est déjà actif avant d'agir
- Si PDP actif: affiche OK + IP sans toucher à la config
- Si PDP inactif: active automatiquement + affiche résultat
- Logs AT bruts accessibles via bouton collapse
- Endpoint launcher.php sara_check_pdp
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Nouveau script SARA/sara_test_udp.py (test socket UDP vers 192.168.0.20:4242)
- Section "Tests Miotiq (UDP)" avec PSD setup, test socket, placeholder aller-retour
- Masque les tests HTTP/Send message quand send_miotiq est actif
- Endpoint launcher.php sara_test_udp
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Bouton Reset Hardware (GPIO 16) avec verification ATI apres redemarrage
- Bandeau d'alerte rouge quand mode configuration actif (transmission desactivee)
- Reset automatique de modem_config_mode a 0 au boot (SARA/reboot/start.py)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Meme modele que NPM: ecriture en base avec valeurs a 0 et noise_status=0xFF
si capteur deconnecte, flag ERR_NOISE (bit 5) dans byte 66 UDP, messages
explicites sur page capteurs et self-test.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Quand npm_status = 0xFF (aucune reponse du capteur), affiche
"Capteur deconnecte" au lieu de lister tous les flags d'erreur.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adapte le self-test au nouveau format retourne par get_data_modbus_v3.py
(npm_status numerique decode bit par bit au lieu de notReady/fanError/etc.)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- NPM: mode --dry-run (print JSON sans ecriture en base)
- launcher.php: endpoint npm appelle get_data_modbus_v3.py --dry-run
- sensors.html: affichage PM + temp + humidite + status NPM decode
- Suppression unite ug/m3 sur le champ status
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Colonne Status avec badge vert 'OK' si 0, badge orange '0xXX'
si erreur. Inclus dans le download CSV.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Detecte rtc_module_time='not connected', affiche un warning
avec icone attention + message 'Verifiez la pile et les cables I2C'.
Le champ RTC passe en bordure rouge. Distingue clairement
deconnexion hardware vs simple desynchronisation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Le mDNS utilise le hostname systeme (aircarto), pas le deviceName
de la DB (NebuleAir-pro034). Ajout de /html/ dans l'URL aussi.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Coherent avec le changement fait sur la page Admin Clock.
Le self-test affiche l'ecart en minutes/secondes si desync.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Indique de faire d'abord une mise a jour via WiFi pour debloquer
l'upload hors-ligne (la MAJ en ligne corrige la config PHP).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- RTC time mis en avant (label bold, input large, bordure bleue)
- Ajout champ Browser time (UTC) avec heure de l'appareil
- System time replie dans un details/summary (non utilise)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
L'heure du navigateur (PC/Mac/tablette) est fiable meme sans internet
grace a la pile interne. Plus pertinent que system time Linux qui
n'est pas utilise par le capteur et peut etre faux sans NTP.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Le fetch get_config_sqlite dans topbar-logo.js au DOMContentLoaded
saturait les 6 connexions par domaine du navigateur.
Retour au topbar-logo.js v1.4.4 d'origine. Le badge hotspot est
maintenant gere dans le window.onload de wifi.html.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Repart du code v1.4.4 qui fonctionne (elementsToLoad, config.json,
window.onload) et ajoute proprement: bouton oublier reseau, cards
contextuelles, infos WiFi detaillees, scan ameliore avec cache notice.
Ne touche PAS au systeme de chargement d'origine.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Retour a l'etat 408ab76. Les tentatives d'optimisation du nombre
de fetch (sidebar unique, config partagee, sequencement) causaient
des blocages sur Chrome/Firefox. On garde les features (forget wifi,
hotspot badge, UI wifi) mais on revient au chargement d'origine.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Deplace le fetch get_config_sqlite de DOMContentLoaded vers
window.onload dans topbar-logo.js. Les requetes sont maintenant
sequencees: DOMContentLoaded (sidebar+topbar+i18n) -> onload
(config) -> event (internet/scan). Max 3-4 requetes simultanees.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
window.onload attend que les ressources initiales soient chargees,
liberant les slots HTTP avant de lancer les AJAX (internet, scan).
Reutilise la config deja fetched par topbar-logo.js via window global.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
applyTranslations modifie le DOM -> declenche MutationObserver
-> re-appelle applyConfig + applyTranslations -> boucle infinie.
Le re-apply reste dans le callback fetch sidebar de chaque page.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Les textes data-i18n de la sidebar etaient vides car les traductions
s'appliquaient avant que la sidebar soit chargee via fetch.
topbar-logo.js re-applique maintenant les traductions via son
MutationObserver, ce qui corrige le probleme sur toutes les pages.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- topbar-logo.js expose la config via event 'nebuleair-config-ready'
- wifi.html ecoute l'event au lieu de re-fetcher get_config_sqlite
- Supprime le doublon load_ethernet_info (get_internet fait deja tout)
- Passe de ~9 requetes simultanees a ~5 au chargement
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Reduit de 3 a 2 les fetch au DOMContentLoaded, liberant un slot
de connexion HTTP. Corrige le blocage "pending" cause par la limite
de 6 connexions simultanees par domaine dans Chrome/Firefox.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
L'appel nmcli dans get_config_sqlite bloquait les workers Apache.
Le statut WiFi est maintenant gere uniquement par les scripts shell
(connexion.sh, forget_wifi.sh, boot_hotspot.sh).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Si nmcli est lent ou bloque, on garde la valeur DB au lieu de
freezer toutes les pages.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>