Install missing reader libraries on first start
A freshly flashed device needed manual pip work before the reader would start. It now checks its dependencies, installs whatever is missing, and carries on. - bootstrap.py: import check, pip invocation, and a re-check that does not trust pip's exit code alone. Installs nothing when the libraries are already present, so a normal start does no network work. - --wheel-dir installs from local wheels with --no-index, for devices with no internet. --no-install-deps opts out entirely. - Outside a venv pip gets --break-system-packages, which Debian and Raspberry Pi OS require before touching the system Python. - reload_library() re-imports rdm6300 when it was installed at runtime, since the module-level import already ran and failed. - A failed install reports exit 2 and the exact manual command rather than raising; stdout is flushed so the explanation is not printed after the error when piped.
This commit is contained in:
@@ -30,6 +30,21 @@ $ rdm-card-reader
|
||||
(the reader library de-duplicates repeated reads while the card sits on the
|
||||
antenna) and once on removal.
|
||||
|
||||
### Startup sequence
|
||||
|
||||
1. **Check dependencies.** If `rdm6300` / `pyserial` cannot be imported, install
|
||||
them automatically and carry on. A fresh device needs no manual `pip` work.
|
||||
2. **Find the reader.** Resolve the serial port and open it, identifying the
|
||||
adapter by serial number or `by-id` rather than trusting `ttyUSB0`.
|
||||
3. **Start reading.** Read frames in a loop; each valid one becomes a card
|
||||
event.
|
||||
4. **Publish it.** In `--serve` mode the event is latched so a web page can
|
||||
claim it whenever it gets around to asking.
|
||||
|
||||
Steps 1 and 2 both fail *loudly with a reason* rather than starting up
|
||||
half-working, because a reader that silently picks the wrong port or runs
|
||||
without its library is worse than one that refuses to start.
|
||||
|
||||
---
|
||||
|
||||
## Install
|
||||
@@ -73,6 +88,8 @@ Also works as a module: `python -m rdm_card_reader`.
|
||||
| `--verbose-ports` | off | With `--list-ports`, show by-id / by-path detail |
|
||||
| `--demo` | – | Simulated reads; needs no hardware and no `rdm6300` |
|
||||
| `--demo-count` | `3` | Number of simulated reads in `--demo` |
|
||||
| `--no-install-deps` | off | Never install missing libraries automatically |
|
||||
| `--wheel-dir` | – | Install missing libraries from local wheels (offline) |
|
||||
| `--version` | – | Print the version |
|
||||
|
||||
With `--serve`: `--host` (`127.0.0.1`), `--bridge-port` (`8765`), `--mode`
|
||||
@@ -96,13 +113,43 @@ is what you want when piping into another program:
|
||||
{"event": "card_removed", "timestamp": "2026-10-01 14:56:54", "id": 12886197, "hex": "0x00C4A0B5", "type": 15, "checksum": 222, "is_valid": true, "port": "/dev/ttyAMA0"}
|
||||
```
|
||||
|
||||
### Automatic dependency install
|
||||
|
||||
On first start the reader checks that it can import its libraries and installs
|
||||
any that are missing, so a freshly flashed device works without manual setup:
|
||||
|
||||
```
|
||||
Reader library not found - checking dependencies...
|
||||
Missing reader dependencies: rdm6300
|
||||
Installing from PyPI ...
|
||||
Dependencies ready: rdm6300
|
||||
```
|
||||
|
||||
* Nothing is installed when the libraries are already present, so a normal start
|
||||
does no network work at all.
|
||||
* A failed install does not crash: it reports `exit 2` and tells you the exact
|
||||
command to run by hand.
|
||||
* Outside a virtualenv pip is given `--break-system-packages`, which Debian and
|
||||
Raspberry Pi OS require before they will touch the system Python.
|
||||
|
||||
For a device with **no internet**, put the wheels next to the app and install
|
||||
from there — no index is contacted:
|
||||
|
||||
```bash
|
||||
pip download rdm6300 pyserial -d wheels # on a machine with internet
|
||||
rdm-card-reader --serve --wheel-dir ./wheels
|
||||
```
|
||||
|
||||
To manage dependencies yourself, pass `--no-install-deps`.
|
||||
|
||||
### Exit codes
|
||||
|
||||
| Code | Meaning |
|
||||
| --- | --- |
|
||||
| `0` | Ran normally, or stopped with Ctrl+C |
|
||||
| `1` | No serial port could be opened |
|
||||
| `2` | The `rdm6300` library is not installed |
|
||||
| `2` | The `rdm6300` library is missing and could not be installed |
|
||||
| `3` | The port selector matched more than one adapter (refused to guess) |
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user