Vérif terrain sur pro100 : à 100 kHz le CCS811 renvoie des valeurs corrompues 0x8000 (32768) par clock-stretching, et le modèle oneshot-reset-toutes-les-10s ne donne que le 1er échantillon post-init (garbage). Refonte : - CCS811/daemon.py: service long-running (Type=simple, Restart=always). Init 1x, boucle lecture/écriture 10s, filtre eCO2 dans [400,8192], re-init auto sur erreurs I2C répétées. Remplace write_data.py (supprimé). - CCS811/get_data.py: lit la dernière ligne data_CCS811 au lieu du capteur (évite la collision I2C avec le daemon -> corruption observée). - setup_services.sh: service daemon + self-heal suppression de l'ancien .timer; activation hors boucle timers. - launcher.php: .timer -> .service (map statut + allowedServices x2). - update_firmware.sh: redémarre le daemon à l'OTA. - doc: README (archi daemon + I2C 10kHz confirmé requis), CLAUDE.md, changelog. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
41 lines
1.2 KiB
Python
41 lines
1.2 KiB
Python
'''
|
|
Live value for the web "Get Data" button (CCS811 air-quality sensor).
|
|
Prints {"eCO2": <ppm>, "TVOC": <ppb>, "timestamp": <str>} or {"error": "<msg>"}.
|
|
|
|
IMPORTANT: this does NOT read the I2C sensor. The CCS811 is owned by the
|
|
long-running daemon (CCS811/daemon.py); opening the bus here would collide with
|
|
it and corrupt the sensor. Instead we return the most recent row the daemon
|
|
stored in data_CCS811. TVOC is the primary measurement.
|
|
|
|
Usage: /usr/bin/python3 /var/www/nebuleair_pro_4g/CCS811/get_data.py
|
|
'''
|
|
|
|
import json
|
|
import sqlite3
|
|
|
|
DB_PATH = "/var/www/nebuleair_pro_4g/sqlite/sensors.db"
|
|
|
|
|
|
def main():
|
|
try:
|
|
conn = sqlite3.connect(DB_PATH, timeout=5)
|
|
cursor = conn.cursor()
|
|
cursor.execute(
|
|
"SELECT timestamp, eCO2, TVOC FROM data_CCS811 ORDER BY timestamp DESC LIMIT 1"
|
|
)
|
|
row = cursor.fetchone()
|
|
conn.close()
|
|
except Exception as e:
|
|
print(json.dumps({"error": f"DB read error: {e}"}))
|
|
return
|
|
|
|
if not row:
|
|
print(json.dumps({"error": "No CCS811 data yet (daemon warming up?)"}))
|
|
return
|
|
|
|
print(json.dumps({"timestamp": row[0], "eCO2": int(row[1]), "TVOC": int(row[2])}))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|