A tidy-up of main.py with the same MQTT, NVS and screen contract, so that
the next person can read it. Verified on the PC with a stubbed device
environment driving every branch (65 checks: boot from empty storage, each
card type, positive / negative / foreign / undecodable replies, the 10 s
timeout, lamp and reset topics, MQTT / WiFi / reader recovery, heartbeat,
OTA accept and reject paths); nothing here can run on the device itself.
Removed without changing behaviour: every commented-out line, duplicate and
unused imports, the timestamp helper and reset-UID constant nobody used,
the seen_uids set with its uid_count/uid_<n> NVS bookkeeping (never read for
anything; old keys stay in flash, ignored), labels that were "updated" but
never created, the serial recomputed on every pass, callback locals leaking
into globals, and the non-blocking WiFi reconnect that the blocking one on
the next line always overrode. Widgets now live in `ui` under plain names
(label_set / set_msg tolerate a widget not yet drawn, which is what lets
setup() read NVS before the screen exists); lamp colours are a table.
Deliberate small changes, all in the box's favour:
- Reads only card blocks 10 (type) and 12 (operator id). Blocks 4-9 held
fields that stopped being published long ago. RFIDUnit.read() authenticates
the block's own sector each call, so the reads do not depend on each other.
- A Reset card fires once per tap (tap_handled). Before, one left on the
reader re-sent RESET after every server reply.
- A failed heartbeat publish drops the MQTT client so the throttled reconnect
runs. Before, it flagged the RFID reader for a rebuild and never touched
MQTT.
- No NVS write on every Product tap - it rewrote identical values.
- The serial is drawn at boot instead of "SR: LOADING..." until WiFi
finished; "RECIEVED" fixed on screen.
- The personal hotspots (EHTISHAM, A16, okay., StormFiber) are gone: this is
a public repo. One alternative network and one alternative broker remain
commented, as the convention says.
Kept on purpose: an Operator message still carries the PREVIOUS card's uid.
That is a server-facing contract and changes separately.
version.txt is NOT bumped - nothing reaches a box until it is.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>