v1.10.1: OTA installe les deps pip + filtre lectures parasites CCS811
Découvert en vérif SSH sur nebuleair-pro100 : le timer CCS811 échouait en ModuleNotFoundError car l'OTA fait git pull mais ne réinstallait jamais les dépendances pip (installation_part1.sh ne tourne qu'à l'install neuve). - requirements.txt: source unique de vérité des deps Python - installation_part1.sh: install via requirements.txt (chemin relatif au script, le repo n'est pas encore cloné dans /var/www à cette étape) - update_firmware.sh: nouvelle étape 2a, pip install -r requirements.txt (idempotent) -> les capteurs déjà déployés récupèrent les libs manquantes à l'OTA - CCS811/write_data.py + get_data.py: skip des lectures eCO2 < 400 ppm (échantillon 0/0 parasite juste après init du driver, plancher physique = 400) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -76,9 +76,13 @@ def main():
|
||||
print(json.dumps({"error": "CCS811 data not ready (warming up?)"}))
|
||||
return
|
||||
|
||||
eco2 = ccs811.eco2
|
||||
tvoc = ccs811.tvoc
|
||||
print(json.dumps({"eCO2": int(eco2), "TVOC": int(tvoc)}))
|
||||
eco2 = int(ccs811.eco2)
|
||||
tvoc = int(ccs811.tvoc)
|
||||
# eCO2 floor is 400 ppm; a sub-400 value is a not-yet-settled sample.
|
||||
if eco2 < 400:
|
||||
print(json.dumps({"error": "CCS811 reading not settled (warming up?)"}))
|
||||
return
|
||||
print(json.dumps({"eCO2": eco2, "TVOC": tvoc}))
|
||||
except Exception as e:
|
||||
print(json.dumps({"error": f"CCS811 read error: {e}"}))
|
||||
|
||||
|
||||
@@ -78,6 +78,13 @@ def main():
|
||||
eco2 = int(ccs811.eco2)
|
||||
tvoc = int(ccs811.tvoc)
|
||||
|
||||
# eCO2 has a physical floor of 400 ppm. Just after the driver (re)inits,
|
||||
# the CCS811 can return a 0/0 sample before its first valid measurement is
|
||||
# ready — those are spurious, drop them (next 10 s tick will retry).
|
||||
if eco2 < 400:
|
||||
print(f"CCS811: reading not settled (eCO2={eco2}), skipping.")
|
||||
return
|
||||
|
||||
cursor.execute("SELECT last_updated FROM timestamp_table LIMIT 1")
|
||||
row = cursor.fetchone()
|
||||
rtc_time_str = row[0]
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
{
|
||||
"versions": [
|
||||
{
|
||||
"version": "1.10.1",
|
||||
"date": "2026-06-02",
|
||||
"changes": {
|
||||
"features": [],
|
||||
"improvements": [
|
||||
"OTA installe désormais les dépendances Python. Nouveau requirements.txt (source unique de vérité), installé par installation_part1.sh (install neuve, chemin relatif au script car le repo n'est pas encore cloné) ET par update_firmware.sh (nouvelle étape 2a, idempotent). Corrige le trou découvert sur nebuleair-pro100 : l'OTA faisait git pull sans réinstaller pip, donc la lib adafruit-circuitpython-ccs811 manquait et le timer CCS811 échouait en ModuleNotFoundError. Tous les capteurs récupéreront automatiquement les libs manquantes à la prochaine MAJ."
|
||||
],
|
||||
"fixes": [
|
||||
"CCS811: filtrage des lectures parasites eCO2 < 400 ppm (plancher physique du capteur). Juste après l'init du driver, le CCS811 renvoie parfois un échantillon 0/0 avant sa 1ère mesure valide — ces lignes ne sont plus écrites en base (write_data.py) ni affichées (get_data.py), le tick suivant réessaie."
|
||||
],
|
||||
"compatibility": []
|
||||
},
|
||||
"notes": "Vérifié en SSH sur nebuleair-pro100 : capteur détecté en I2C à 0x5A, lib installée, données eCO2/TVOC qui remontent. Rappel: le CCS811 a besoin de ~20 min de warm-up et ~48h de burn-in initial pour des valeurs stables."
|
||||
},
|
||||
{
|
||||
"version": "1.10.0",
|
||||
"date": "2026-06-02",
|
||||
|
||||
@@ -26,8 +26,11 @@ info "Updating package list and installing necessary packages..."
|
||||
sudo apt update && sudo apt install -y git gh apache2 sqlite3 php php-sqlite3 python3 python3-pip jq autossh i2c-tools python3-smbus python3-rpi.gpio || error "Failed to install required packages."
|
||||
|
||||
# Install Python libraries
|
||||
# requirements.txt lives next to this script (the repo isn't cloned to
|
||||
# /var/www yet at this point), so resolve it relative to the script location.
|
||||
info "Installing Python libraries..."
|
||||
sudo pip3 install pyserial requests adafruit-circuitpython-bme280 adafruit-circuitpython-ccs811 crcmod psutil gpiozero ntplib adafruit-circuitpython-ads1x15 nsrt-mk3-dev pytz --break-system-packages || error "Failed to install Python libraries."
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
sudo pip3 install -r "$SCRIPT_DIR/requirements.txt" --break-system-packages || error "Failed to install Python libraries."
|
||||
|
||||
# Install Tailscale (for remote SSH access via Headscale tailnet)
|
||||
info "Installing Tailscale..."
|
||||
|
||||
16
requirements.txt
Normal file
16
requirements.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
# NebuleAir Pro 4G - dépendances Python.
|
||||
# Source unique de vérité, installée à l'install neuve (installation_part1.sh)
|
||||
# ET à chaque OTA (update_firmware.sh, étape 2b) pour que les capteurs déjà
|
||||
# déployés récupèrent toute nouvelle lib lors de la mise à jour.
|
||||
# pip skippe ce qui est déjà satisfait => idempotent.
|
||||
pyserial
|
||||
requests
|
||||
adafruit-circuitpython-bme280
|
||||
adafruit-circuitpython-ccs811
|
||||
crcmod
|
||||
psutil
|
||||
gpiozero
|
||||
ntplib
|
||||
adafruit-circuitpython-ads1x15
|
||||
nsrt-mk3-dev
|
||||
pytz
|
||||
@@ -62,6 +62,21 @@ if [ -f "/var/www/nebuleair_pro_4g/VERSION" ]; then
|
||||
print_status "Firmware version: $(cat /var/www/nebuleair_pro_4g/VERSION)"
|
||||
fi
|
||||
|
||||
# Step 2a: Install/update Python dependencies (self-heal)
|
||||
# OTA does a git pull but historically never (re)installed pip deps, so a new
|
||||
# sensor lib introduced by an update (e.g. adafruit-circuitpython-ccs811) was
|
||||
# missing on already-deployed sensors and the timer failed with ModuleNotFound.
|
||||
# requirements.txt is the single source of truth; pip skips already-satisfied
|
||||
# packages so this is idempotent and only pulls newly-added libs.
|
||||
print_status ""
|
||||
print_status "Step 2a: Installing/updating Python dependencies..."
|
||||
if [ -f "/var/www/nebuleair_pro_4g/requirements.txt" ]; then
|
||||
sudo pip3 install -r /var/www/nebuleair_pro_4g/requirements.txt --break-system-packages
|
||||
check_status "Python dependencies install"
|
||||
else
|
||||
print_status "⚠ requirements.txt not found, skipping dependency install"
|
||||
fi
|
||||
|
||||
# Step 2: Update database (schema migration + config keys)
|
||||
# create_db.py is idempotent (CREATE TABLE IF NOT EXISTS + ALTER TABLE ADD COLUMN
|
||||
# wrapped in try/except). Required to add tables introduced after the sensor was
|
||||
|
||||
Reference in New Issue
Block a user