Files
Odoo-Modules/fusion_iot/pi/fp-iot-poller.service
gsinghpal 19a49acba0 feat(fusion_iot): live DS18B20 poller for Pi-side — first real tank reading in Odoo
Phase B kickoff — Pi hardware is wired up and posting readings to
Odoo via /fp/iot/ingest every 30 seconds. No more simulations;
this is real tank-temperature data.

New files:

- `pi/fp_iot_poller.py` — tiny systemd daemon. Reads every DS18B20
  under /sys/bus/w1/devices/28-* (kernel CRC-validated) and POSTs
  a batch to /fp/iot/ingest with the shared-secret token. Handles
  transient network failures by logging + retrying on the next
  30-second tick. Config in /etc/fp-iot/poller.conf (ODOO_URL,
  INGEST_TOKEN, INTERVAL_SECONDS).

- `pi/fp-iot-poller.service` — systemd unit with hardened sandbox
  (NoNewPrivileges, ProtectSystem=strict, ProtectHome, PrivateTmp,
  ReadOnlyPaths=/sys/bus/w1 /etc/fp-iot). Auto-starts on boot,
  restarts on failure.

- `scripts/fp_iot_setup_live_sensor.py` — one-shot entech
  initialiser: rotates the ingest token to a real random secret,
  picks a test tank + temperature parameter, creates the
  fp.tank.sensor record for serial 28-000000b276e4 with 15-35°C
  alert thresholds sized for bench testing.

Verified end-to-end: Pi reads probe → posts to Odoo → reading lands
in fp.tank.reading within 1s. 5 consecutive readings at 30s
cadence show smooth temperature trend (probe cooling from 27.25°C
to 26.06°C after being handled). in_spec flag correct, sensor
cache (last_reading_value / _at / _in_spec) updates on every
reading.

Not yet done — Phase B continued:
- Repackaged iot_drivers path (full Odoo IoT integration vs this
  simple HTTP path) — this poller is the minimal viable pilot.
- Multi-probe (scalable to N probes per Pi; code already supports,
  just need more hardware).
- Graduate to the proper iot.device + iot.box Odoo registration
  flow.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 14:59:20 -04:00

26 lines
605 B
Desktop File

[Unit]
Description=Fusion Plating IoT — DS18B20 poller
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/usr/bin/python3 /usr/local/bin/fp_iot_poller.py
Restart=on-failure
RestartSec=5
User=fp
Group=fp
# Poller only needs read access to /sys/bus/w1 + /etc/fp-iot; everything
# else locked down.
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
ReadOnlyPaths=/sys/bus/w1 /etc/fp-iot
# Journal-only logging — use `journalctl -u fp-iot-poller -f` to tail
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target