feat(iot): repackaged Odoo iot modules + Fusion Plating sensor wrapper

Phase A of the IoT initiative — gets the server-side infrastructure
in place before the Raspberry Pi hardware arrives, so the iot admin
UI + /fp/iot/ingest endpoint are ready to accept the first real
temperature reading as soon as the Pi is wired up.

New top-level folder: fusion_iot/

1. **iot_base/** — Odoo S.A. iot_base module, copied from
   RePackaged-Odoo verbatim. LGPL-3 upstream, no changes needed.

2. **iot/** — Odoo S.A. iot module, repackaged:
   - `models/update.py` neutralised (removed the publisher_warranty
     IoT-Box-counting report that phones home to odoo.com for
     enterprise licence enforcement)
   - `iot_handlers/lib/load_worldline_library.sh` deleted (proprietary
     Worldline payment lib fetch from download.odoo.com, not needed)
   - `wizard/add_iot_box.py._connect_iot_box_with_pairing_code` —
     upstream called odoo.com's iot-proxy to resolve pairing codes;
     replaced with a no-op. Pi-side iot_drivers proxy registers
     directly with this Odoo server instead.
   - Manifest rebranded with an explicit changelog preamble.

3. **fusion_plating_iot/** — new plating-specific wrapper:
   - `fp.tank.sensor` — maps an iot.device (or a direct-HTTP-ingest
     sensor) to a fusion.plating.tank + fusion.plating.bath.parameter.
     Supports DS18B20, PT100/1000, pH, conductivity, level. Per-sensor
     alert_min/max overrides.
   - `fp.tank.reading` — append-only time-series. On create, evaluates
     against sensor's alert range. On in-spec → out-of-spec TRANSITION,
     auto-raises a fusion.plating.quality.hold (once per excursion,
     no spam during sustained out-of-spec).
   - `POST /fp/iot/ingest` — shared-secret HTTP endpoint for sensors
     bypassing the Pi proxy. Token via X-FP-IOT-Token header OR body.
     Accepts single-reading or batch payloads.
   - Menu under Plating → Operations → Sensors & Readings.
   - Tank form inherits get a Sensors tab inline.

Deployed to entech. Verified end-to-end:
- Install: iot_base + iot + fusion_plating_iot all 'installed'
- Smoke test: in-spec → out-of-spec → hold raised (HOLD-0010);
  continued excursion → NO duplicate hold; back-in-spec → NEW
  excursion → NEW hold (HOLD-0011) ✓
- HTTP endpoint: correct token → 200 accepted; wrong token → 401;
  unknown device_serial → 404; batch payload → 200 accepted=N ✓

Phase B (when Raspberry Pi hardware arrives): DS18B20 iot_handler
driver for the Pi-side iot_drivers proxy + systemd service on
vanilla Raspberry Pi OS + first live reading from physical probe.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsinghpal
2026-04-19 10:46:45 -04:00
parent c118b7c6b5
commit 6e964c230f
419 changed files with 76449 additions and 0 deletions

View File

@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg id="b" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 280 280"><g id="bk"><path d="m159.0514,166.4647v45.4805c0,8.0118,5.6248,11.2592,12.5632,7.2533l7.3486-4.2428c1.4494-.8367,3.2685-.2011,3.2685,1.4726s.8052,2.4082-.6442,3.2451l-76.6594,44.0872c-1.4494.8369-2.6243.1585-2.6243-1.5151s1.175-3.7087,2.6243-4.5456l7.3485-4.2427c6.9386-4.0058,12.5632-13.7483,12.5632-21.7601v-45.4805l34.2114-19.7519Z" style="fill:#fff;"/><path d="m51.9497,261.9687c-6.2441-.001-11.1357-5.1182-11.1357-11.6504v-117.2051c0-4.9541,2.7656-9.8799,6.8809-12.2588L222.1928,20.1084c1.7764-1.0254,3.7627-1.5654,5.748-1.5654,6.2451,0,11.1367,5.1172,11.1367,11.6504v117.2051c0,4.957-2.7676,9.8848-6.8877,12.2617l-174.4912,100.7422c-1.7764,1.0254-3.7637,1.5664-5.749,1.5664h0Z" style="fill:#fff;"/><path d="m159.0514,211.9454c0,8.0116,5.6248,11.2588,12.5632,7.2532l7.3486-4.2431c.7123-.4109,1.3563-.4524,1.8292-.1938-.0071-.0182-.0127-.0306-.0127-.0306l-15.1936-7.5875-6.5347,3.773v1.0287Z" style="fill:#fbdbd0;"/><path d="m102.3039,262.2455c0-1.6735,1.175-3.7087,2.6244-4.5455l7.3485-4.2427c6.9386-4.006,12.5633-13.7486,12.5633-21.7601v-12.024l-13.7338,7.6997c-1.3291,7.1812-6.3386,14.8845-12.2856,18.3182l-6.8245,3.9399c-1.4814.8555-2.9737,4.866-2.9737,4.866,0,0,13.0602,9.0804,14.0115,9.4334.0079.0027.015-.0009.0227.0009-.4645-.2786-.7526-.8596-.7526-1.6859Z" style="fill:#fbdbd0;"/><path d="m54.6983,246.1829l174.4948-100.7447c1.0407-.6007,1.8842-2.2125,1.8842-3.5998V24.6334c0-1.3875-.8435-2.0253-1.8842-1.4244L54.6983,123.9535c-1.0405.6009-1.884,2.2125-1.884,3.6v117.205c0,1.3875.8435,2.0251,1.884,1.4244Z" style="fill:#374874;"/><path d="m135.6312,207.6134l12.6291-7.2915c.5638-.3255,1.021-1.1989,1.021-1.9507h0c0-.7519-.4572-1.0974-1.021-.7718l-12.6291,7.2915c-.5639.3255-1.021,1.1989-1.021,1.9507h0c0,.7519.4571,1.0974,1.021.7718Z" style="fill:#150035;"/><path d="m135.224,208.4898c.2583,0,.5263-.0745.7844-.2238l12.6286-7.2907c.7972-.4605,1.3981-1.5797,1.3981-2.6037,0-.6715-.266-1.2105-.7294-1.4786-.4222-.2454-.9396-.2247-1.4217.0521l-12.6295,7.2926c-.7972.4605-1.3981,1.5797-1.3981,2.6037,0,.6724.2661,1.2115.7294,1.4786.1965.1138.4133.1697.6382.1697Z" style="fill:#374874;"/><path d="m36.8518,124.6135v124.6879c0,2.482.7746,4.2728,2.0156,5.1551,5.9679,5.1524,11.24,6.5979,11.2486,6.6002-1.5801-.694-2.6042-2.6316-2.6042-5.4853v-124.6874c0-2.7634.9576-5.7785,2.4525-8.2537l-11.0756-5.5377c-1.2529,2.3238-2.0367,5.0247-2.0367,7.5209Z" style="fill:#c1dbf6;"/><path d="m223.332,10.1785c-.02-.0109-.0414-.0182-.0617-.0287-.0105-.0046-.0206-.0091-.0312-.0141l-.0007.0009c-1.1282-.5513-2.5562-.4505-4.1129.4487L43.4462,112.0136c-1.7698,1.0219-3.3732,2.8824-4.5577,5.079l11.0756,5.5377c1.1323-1.8746,2.5722-3.4401,4.1419-4.3462L229.7854,16.8553c1.6782-.9686,3.2052-1.0078,4.3692-.3032h0s-4.4295-3.5094-10.8226-6.3736Z" style="fill:#fbdbd0;"/><path d="m219.1256,10.5855l10.6598,6.27,6.5945,4.9854v124.688c0,4.8555-2.9525,10.4966-6.5945,12.5991l-70.7339,40.8389v10.9497l6.5347-3.7729s15.1948,7.6138,15.1951,7.6138h0c.4954.2656,2.2558,4.0791.8063,4.916,0,0-77.5577,44.2529-78.5317,44.2529-.0032,0-.0056-.0005-.0071-.0015h0c-.0005-.0005-14.0264-9.4277-14.0264-9.4277,0,0,1.4923-4.0107,2.9737-4.8662l6.8245-3.9399c5.8607-3.3838,10.8033-10.9136,12.218-18.0044l-56.9325,32.8706c-.9247.5337-1.8032.7842-2.6006.7842-.4977,0-.964-.0977-1.3901-.2852h-.0002.0002s.0003.0005.0004.0005c-.0297-.0083-5.2926-1.458-11.2484-6.6001-1.241-.8823-2.0156-2.6733-2.0156-5.1553v-124.688c0-2.4961.7838-5.1968,2.0367-7.5205,1.1845-2.1968,2.7879-4.0571,4.5577-5.0791L219.1256,10.5855M50.1158,261.0567h.0001-.0001M219.1444,5.9556l-2.0187,1.166L41.4462,108.5498c-2.337,1.3491-4.4957,3.709-6.0786,6.6445-1.6224,3.0093-2.5159,6.354-2.5159,9.4189v124.688c0,3.6382,1.2484,6.5703,3.5214,8.2861,5.8486,5.0127,11.0894,6.8408,12.4113,7.2466.8602.3369,1.774.5073,2.721.5073,1.5347,0,3.0822-.4438,4.5997-1.3193l46.0001-26.5586c-1.5844,2.0049-3.402,3.6768-5.2846,4.7637l-6.8245,3.9395c-2.2551,1.3027-3.8129,4.4907-4.7227,6.9355l-1.0997,2.9556,2.6172,1.7593c11.7263,7.8818,13.7325,9.23,14.1479,9.502l-.0018.0029.9698.603,1.149.0015q1.3527,0,14.636-7.4248c6.5602-3.6738,15.6337-8.7954,26.9681-15.2222,19.2927-10.9395,38.7161-22.021,38.91-22.1318,1.6778-.9688,2.6108-2.7329,2.5776-4.8501-.0278-1.772-1.1071-5.7949-3.4759-7.0649l-1.4295-.7666-.0619.0176c-3.751-1.8794-13.8021-6.916-13.8021-6.916l-1.9262-.9653-1.8658,1.0776-.5347.3086v-1.7119l68.734-39.6846c4.8995-2.8281,8.5944-9.7339,8.5944-16.063V19.8506l-1.5878-1.2007-6.5944-4.9854-.1847-.1396-.1996-.1172-10.6598-6.27-2.0092-1.1821h0Z" style="fill:#374874;"/></g></svg>

After

Width:  |  Height:  |  Size: 4.5 KiB