Skip to content

Move to the shared gx-projector-client library (v2 contract) - #2

Open
nuketownada wants to merge 4 commits into
joshperry:masterfrom
nuketownada:gx-client-v2
Open

Move to the shared gx-projector-client library (v2 contract)#2
nuketownada wants to merge 4 commits into
joshperry:masterfrom
nuketownada:gx-client-v2

Conversation

@nuketownada

Copy link
Copy Markdown

Rewires dusa onto the shared gx-projector-client library (pinned v0.1.0), upgrading it from the v1 backcompat contract to gx-device-projector v2. Companion to joshperry/patroclus branch gx-client-v2 — both boards now share one implementation of the registration/liveness/cookie/rebind contract.

What changes

  • v2 registration: non-retained device/tanksensor/Status with services: {tag: {type, init}} dicts (the dict shape is the v1/v2 discriminator). Board-authored init per tank carries the static identity values — CustomName, FluidType, Capacity (m³) — which leave the periodic Proxy publish; only Level, Remaining, Status flow per-cycle now.
  • Ghost-tank bug structurally fixed: the MQTT will is now a retained "0" on device/tanksensor/online (published "1" retained on connect, before registration). The old will was non-retained on /Status, so a dead sensor left ghost tanks on the GX — the same bug patroclus already fixed, now impossible by construction.
  • Cookie re-announce + rebind: subscribes device/_host/cookie; a cookie change (not baseline) triggers a jittered (20–220 ms) re-registration rebuilt from current state; a re-announce reply with changed instances signals a full reconnect.
  • State machine slimmed: STATE_REGISTER removed — gxClient.connect() runs the whole handshake prologue; WAIT_REGISTRATION polls gxSession.bound() under the existing 10 s timeout, and timeout now redoes the full handshake on a fresh connection. Timeouts/reconnect delays unchanged.
  • Deleted the hand-rolled registration/DBus-parse/will plumbing (~90 net lines removed); setBufferSize(512) dropped — the lib floors the buffer at 1024 (512 was borderline for the 3-tank DBus reply).
  • WDT compatibility guard: the installed espressif32 7.0.1 toolchain ships arduino-esp32 2.0.17 (IDF 4.4), whose API is esp_task_wdt_init(timeout, panic); HEAD used the IDF5-only esp_task_wdt_reconfigure. Now guarded on ESP_ARDUINO_VERSION_MAJOR >= 3 so both cores build.
  • Version bump v1.0.0v2.0.0.

Rollout note

dusa has no OTA path — this needs a USB flash. After the board comes up on v2, run the cutover on the GX to clear the stale v1 retained registration:

ssh root@venus.local
bin/cutover-board-to-v2.sh tanksensor

(Otherwise a logicd restart re-reads the old retained v1 /Status and strands the board Connected=0.)

Builds clean: pio run -e xiao_esp32s3 — RAM 15.1%, Flash 27.2%.

Co-Authored-By: Joshua Perry josh@6bit.com

nuketownada and others added 4 commits February 16, 2026 18:57
Registration state wasn't cleared on WiFi disconnect — device would
skip re-registration and publish on stale topic paths. Also re-resolve
MQTT hostname on broker disconnect in case IP changed.

30s hardware WDT reboots device if loop() stalls.

Removed: unused ESPmDNS include, lastPublishedLevel tracking,
lastHeartbeatTime, HEARTBEAT_INTERVAL_MS, ADC_MAX, ADC_VREF.

Co-Authored-By: Joshua Perry <josh@6bit.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Device runs a web server on port 80 after WiFi connects.
Push firmware with: curl -F "firmware=@firmware.bin" http://dusa.local/update

No reverse connection (unlike espota), so no workstation firewall needed.
mDNS init is idempotent — safe across WiFi reconnects.

Co-Authored-By: Joshua Perry <josh@6bit.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the hand-rolled v1 registration/MQTT-contract code with
GxProjectorClient (github.com/nuketownada/gx-projector-client v0.1.0),
upgrading dusa from logicd's v1 backcompat to the v2 contract:

- Registration is now NON-retained with {type,init} service dicts; the
  DBus reply binds all three tanks strictly (all-or-nothing).
- Liveness moves onto a retained device/<id>/online topic with the MQTT
  will = retained "0". This structurally fixes the ghost-tank bug: the
  old will was NON-retained, so a sensor dying while the driver was
  down left its retained connected:1 Status behind forever.
- Tank identity (CustomName/FluidType/Capacity) moves off the periodic
  Proxy publish into board-authored registration init; the Proxy now
  carries only Level/Remaining/Status.
- STATE_REGISTER is gone: gxClient.connect() runs the whole handshake
  prologue, and a registration timeout redoes it on a fresh connection.
- The library also brings the state-host cookie re-announce and
  instance-rebind legs dusa never had.

Also guards the watchdog setup for arduino-esp32 2.x (IDF 4.4) vs 3.x,
so the project builds on the stock espressif32 platform. Bumps to
v2.0.0.

After flashing, run bin/cutover-board-to-v2.sh tanksensor on the GX to
clear the stale retained v1 Status.

Co-Authored-By: Joshua Perry <josh@6bit.com>
The deployed tanksensor board predates the OTA server (ad223f8), so the v2
flash is necessarily over USB -- make it the last one:

- GET /version returns {"version","client_id"} (same shape as patroclus;
  used by rollout sanity checks before/after a push)
- GET / serves the manual-upload form
- UPLOAD_FILE_ABORTED now calls Update.abort() so a dropped upload doesn't
  leave the updater wedged
- platformio.ini restructured to patroclus's common-[env] pattern with an
  [env:ota] custom upload (curl POST to http://dusa.local/update); usage:
  pio run -e ota -t upload

Co-Authored-By: Joshua Perry <josh@6bit.com>
@nuketownada

Copy link
Copy Markdown
Author

Deployed: this branch (8a5c26c) is now running on the tanksensor board — flashed 2026-07-02 over the GX's USB (esptool on venus.local, serial-starter paused during the write; no physical access needed). v2 registration verified: 3 tanks created with init applied (instances 1/2/3 preserved), levels flowing, retained state reduced to device/tanksensor/online 1, stale v1 Status cleared. OTA endpoint live at http://dusa.local/version — future updates are pio run -e ota -t upload; no more USB flashes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant