Skip to content

Test stations get serials from the server, not from their own files

Decided 2026-09-19 with Angel: "let's implement this solution. I like talking over the network… maybe each time that we talk to the server, we reserve a group of serial numbers… I want to be able to do any OS." More than one tester is planned; start with one.

The decision

A small tester API on the Plex server hands out serial numbers and receives every test run. The ERP becomes the record of each unit; the NAS keeps the raw logs.

  • Serials are reserved in blocks. Each call tops up a station's local pool (e.g. 20 serials), so testing continues when the network is down. Format stays MMYY####, and from 2026-09-19 the count is one sequence for every product (Angel: no repeated serial numbers, whatever the board), so a serial identifies a unit on its own. The server is the only place that issues numbers, so no number of stations can collide. A reserved serial that is never used is simply a gap. That's allowed; a reused one is not.
  • A serial follows the board's chip ID. The same chip always gets the same serial, whichever station asks. A replaced MCU is a recorded "chip replaced on serial X" event; the new chip inherits the serial.
  • The ERP enforces it too: SERIAL_NUMBER_GLOBALLY_UNIQUE is on again since the sequence is global. Boards labelled before 2026-09-19 may repeat a number across products.
  • Two stages, one serial. A readable board receives its serial during production testing. A failed board whose chip cannot be read receives a permanent label-only serial before it can enter Quarantine; a later readable chip links to that same serial. The post-coating test reuses the serial and prints the finished bag label.
  • Every run is sent, pass or fail, including runs before the board has a serial (keyed by chip ID, attached to the serial once it exists), rework actions and retests.
  • Store and forward. The tester writes locally first (outbox), then sends. Nothing is lost when the network drops.
  • ERP:
  • Pre-coating PASS or an explicit Quarantine disposition creates the unit as one unfinished build output on the product's open build order. Robot materials are consumed by physical stage; a quarantined pretest board does not consume terminals, radio, coating or final packing.
  • Each run becomes a test result on that serial (templates pre_coating, post_coating).
  • Post-coating PASS completes the output into Finished goods.
  • Raw logs land on /mnt/storage/EmbeddedEra/test-data/<product>/, inside SnapRAID parity, the NVMe precious copy and the restic history.
  • Reporting is independent of the ERP mirror. The tester SQLite index is copied read-only into Grafana's reports database every minute. An accepted run remains visible with its ERP status and reason even when an older unit lacks the pre-coating PASS required to create ERP stock.
  • Secrets stay on the server. A station holds a Cloudflare Access service token plus its own station key, both revocable per station. It never holds the ERP token.
  • Any OS. The tester client is plain Python; data and config live in the OS's standard application-data folder, never in the repo.

Why not the alternatives

  • Each tester keeps its own serial file (what we had until 2026-09-19). Two stations would hand out the same number, and the only backup was a git push of the log folder.
  • Testers talk to the ERP directly. Every PC would hold an ERP token, and the MMYY#### rules would be copied into every tester.
  • Syncthing to the NAS. A good backup, but it can't stop two stations issuing the same serial.

Where it lives

  • The API is a separate app in the assistant codebase (~/assistant), run on its own port and published as tester.embeddedera.com behind a service-token-only Access app. Built on the sandbox branch against the sandbox ERP first (see sandbox-workflow).
  • The client lives in EmbeddedEra/Universal_Tester host-api/universal_tester/production/.

Related: universal-tester, mrp, sandbox-workflow.

Amendment 2026-10-21: serials only on PASS

Angel: "keep serial numbers for when the board fails… let's try to not even assign it… when we quarantine them, that's where we print the receipt… but we don't serialize them." A serial is issued when a board first passes, not before a test and not for a failed board; the Brother serial sticker prints on PASS only. A failed or quarantined board is identified by chip ID and run ID, then by its Quarantine ID; the receipt and Zebra label carry the QID, no serial. A repaired board gets its serial at its first pass and it attaches to its existing case. This replaces the "failed board whose chip cannot be read receives a permanent label-only serial" part of "Two stages, one serial". Server plan: tester-quarantine-no-serial-server-plan. Evidence: 27 of 27 failing attempts since 2026-09-26 got a serial, and 12 of 16 failing boards later passed on retest.