Commit Graph

4 Commits (133cfbac1edd5b26dc527f8ad1dfa57d9dbb5ed8)

Author SHA1 Message Date
m.faisal 133cfbac1e The box program carried 160 lines of dead code and a public repo held hotspot passwords
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>
2026-09-15 16:41:35 +05:00
m.faisal 0d7c5781b0 Boxes were updating from a dead GitHub repo and talking to the old broker
The program pointed its boot-time update check at a personal GitHub repo
(husbananjum/m5core-s3-UIMETRIX-Z87) that now answers 404 for both
version.txt and main.py, so every box on that build has been failing its
check on every boot - harmlessly, but no release could ever reach them. It
also had the broker at 192.168.87.11, while the boxes on the floor (and the
UiMetrix server) are on 192.168.2.174.

Updates now come from this repo on the company Gitea, through its anonymous
raw-file URLs. For that the program is committed as main.py - the name the
device downloads and runs - instead of "M5-Stack Code for Uimetrix.txt", and
version.txt is added. The old broker stays as a commented line, the way the
earlier networks are kept.

- A push to main that also bumps version.txt IS a release now; every box that
  follows Gitea installs it at its next boot. Leave version.txt alone until
  main.py is ready for the floor.
- No box follows Gitea yet: the ones with OTA code still point at the dead
  GitHub URL, and the ones on the floor run a build without OTA at all. Each
  needs one USB copy of this main.py; after that they update by themselves.
- version.txt starts at 2.0. Nobody knows the highest number ever published
  on GitHub, and a box's NVS may hold a number it never actually ran; if any
  box shows a higher V... on its screen, bump version.txt above it.
- A box freshly copied over USB still has its old NVS version (or the default
  1.0), so on its first boot it downloads the identical main.py once and
  resets. Expected, not a loop.
- The repo stores LF; the CRLF seen in a Windows checkout is core.autocrlf.
  Gitea serves the stored LF bytes, which is what the device compiles.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 16:15:03 +05:00
muhammad.faique 4d487d3c58 Install downloaded firmware during OTA update
check_for_update() wrote the download to main_ota_temp.py, stamped the new
version in NVS and reset, but never replaced main.py. Devices therefore kept
running the old program while reporting the newest version, so no OTA release
ever reached the field.

The routine now validates the download (HTTP 200, minimum size, setup/loop
present, compiles), keeps the running program as main_prev.py for manual
rollback, renames the download to main.py, and records the version only after
the swap succeeds. A rejected download or failed swap leaves the old program
and version in place so the next boot retries.

CLAUDE.md describes the new flow and the field caveat: devices on the old
build need one manual USB copy first, and the next version.txt must exceed any
number already published because their NVS may claim a version they never ran.

.gitignore drops the __pycache__ left by PC-side syntax checks.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-11 16:42:07 +05:00
muhammad.faique 7050a7ef51 Add M5Stack RFID reader firmware and developer guide
Import the UiMetrix tag-reader firmware (UIFlow 2.0 MicroPython script) as
exported from the device, plus a CLAUDE.md describing the OTA release path,
the MQTT contract with the UiMetrix server and the scan/ACK lifecycle.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 16:01:34 +05:00