Hardware device paths have two sources of truth — the NixOS module's defaults are wrong for every model, and warn misleadingly at boot #117

Open
opened 2026-09-29 21:20:58 +00:00 by padreug · 0 comments
Owner

Every douro boot logs:

bitspire-pre-start: Warning: Bill validator device /dev/ttyUSB0 not found

The validator is fine. It's a JCM iVIZION on /dev/ttyS0, and the app drives it correctly — same boot, a few seconds later:

[ATM] Validator device: /dev/ttyS0
[ATM] Dispenser device: /dev/ttyS1
INFO puloon connected
[HAL] Validator started

The warning comes from deploy/nixos/bitspire-atm.nix preStart checking cfg.billValidator.device, which is the module default /dev/ttyUSB0. The app doesn't use that value — it reads apps/machine/src/config/device.ts, keyed on VITE_LAMASSU_MACHINE_MODEL, where douro is validator /dev/ttyS0 (id003) and dispenser /dev/ttyS1 (puloon).

So the same fact is declared in two places and they disagree. The nix side is not just stale, it's unset: billValidator, billDispenser and camera are never assigned for any model — not in flake.nix, not in any hardware/*.nix, not in live.nix — so every machine runs on defaults of /dev/ttyUSB0, /dev/ttyUSB1, and billDispenser.enable = false (the douro plainly has a dispenser).

Those options feed exactly two consumers, neither authoritative:

  • the preStart warning above;
  • /etc/bitspire/config.env, which the module's own comment says is descriptive and NOT the runtime environment, since the flake mkForces EnvironmentFile to /var/lib/bitspire/.env. So it advertises BILL_VALIDATOR_DEVICE=/dev/ttyUSB0 to anyone who reads it looking for the truth.

Cost is real if small: it burned time while debugging the douro this week. The box looked like it had a missing validator on every boot, which is a plausible-sounding symptom for a machine that wasn't working, and it isn't true.

Cleanest fix is to delete the duplicate rather than sync it — drop billValidator / billDispenser / camera (or at least the device/type fields), the preStart check, and the hardware block in config.env, leaving device.ts as the single source of truth. The alternative — keeping the nix options and making them authoritative by passing them to the app — is a bigger change that inverts ownership, and nothing needs it today.

If the preStart check is worth keeping as an early warning, it should read the same table the app does rather than a parallel default.

Checked the open tracker first; no existing issue covers this.

Every douro boot logs: ``` bitspire-pre-start: Warning: Bill validator device /dev/ttyUSB0 not found ``` The validator is fine. It's a JCM iVIZION on `/dev/ttyS0`, and the app drives it correctly — same boot, a few seconds later: ``` [ATM] Validator device: /dev/ttyS0 [ATM] Dispenser device: /dev/ttyS1 INFO puloon connected [HAL] Validator started ``` The warning comes from `deploy/nixos/bitspire-atm.nix` preStart checking `cfg.billValidator.device`, which is the module default `/dev/ttyUSB0`. The app doesn't use that value — it reads `apps/machine/src/config/device.ts`, keyed on `VITE_LAMASSU_MACHINE_MODEL`, where douro is `validator /dev/ttyS0` (id003) and `dispenser /dev/ttyS1` (puloon). So the same fact is declared in two places and they disagree. The nix side is not just stale, it's unset: `billValidator`, `billDispenser` and `camera` are never assigned for any model — not in flake.nix, not in any `hardware/*.nix`, not in live.nix — so every machine runs on defaults of `/dev/ttyUSB0`, `/dev/ttyUSB1`, and `billDispenser.enable = false` (the douro plainly has a dispenser). Those options feed exactly two consumers, neither authoritative: - the preStart warning above; - `/etc/bitspire/config.env`, which the module's own comment says is descriptive and NOT the runtime environment, since the flake mkForces `EnvironmentFile` to `/var/lib/bitspire/.env`. So it advertises `BILL_VALIDATOR_DEVICE=/dev/ttyUSB0` to anyone who reads it looking for the truth. Cost is real if small: it burned time while debugging the douro this week. The box looked like it had a missing validator on every boot, which is a plausible-sounding symptom for a machine that wasn't working, and it isn't true. Cleanest fix is to delete the duplicate rather than sync it — drop `billValidator` / `billDispenser` / `camera` (or at least the device/type fields), the preStart check, and the hardware block in `config.env`, leaving `device.ts` as the single source of truth. The alternative — keeping the nix options and making them authoritative by passing them to the app — is a bigger change that inverts ownership, and nothing needs it today. If the preStart check is worth keeping as an early warning, it should read the same table the app does rather than a parallel default. Checked the open tracker first; no existing issue covers this.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
aiolabs/bitspire#117
No description provided.