Add documentation about tests

This commit is contained in:
Lorow
2025-12-14 16:23:59 +01:00
parent a25275a47f
commit 139486be01

116
README.md
View File

@@ -13,12 +13,12 @@ Firmware and tools for OpenIris — WiFi, UVC streaming, and a Python setup C
- Python tools for setup over USB serial:
- `tools/switchBoardType.py` — choose a board profile (builds the right sdkconfig)
- `tools/setup_openiris.py` — interactive CLI for WiFi, MDNS/Name, Mode, LED PWM, Logs, and a Settings Summary
- Composite USB (UVC + CDC) when UVC mode is enabled (`GENERAL_INCLUDE_UVC_MODE`) for simultaneous video streaming and command channel
- LED current monitoring (if enabled via `MONITORING_LED_CURRENT`) with filtered mA readings
- Configurable debug LED + external IR LED control with optional error mirroring (`LED_DEBUG_ENABLE`, `LED_EXTERNAL_AS_DEBUG`)
- Autodiscovered perboard configuration overlays under `boards/`
- Command framework (JSON over serial / CDC / REST) for mode switching, WiFi config, OTA credentials, LED brightness, info & monitoring
- Single source advertised name (`CONFIG_GENERAL_ADVERTISED_NAME`) used for both UVC device name and mDNS hostname (unless overridden at runtime)
- Composite USB (UVC + CDC) when UVC mode is enabled (`GENERAL_INCLUDE_UVC_MODE`) for simultaneous video streaming and command channel
- LED current monitoring (if enabled via `MONITORING_LED_CURRENT`) with filtered mA readings
- Configurable debug LED + external IR LED control with optional error mirroring (`LED_DEBUG_ENABLE`, `LED_EXTERNAL_AS_DEBUG`)
- Autodiscovered perboard configuration overlays under `boards/`
- Command framework (JSON over serial / CDC / REST) for mode switching, WiFi config, OTA credentials, LED brightness, info & monitoring
- Single source advertised name (`CONFIG_GENERAL_ADVERTISED_NAME`) used for both UVC device name and mDNS hostname (unless overridden at runtime)
---
@@ -69,8 +69,8 @@ We're using UV to manage our tools, grab and install it from [here](https://docs
Once installed, you'll be able to just run the commands below and UV will take care of setting up everything.
### 1) Pick your board (loads the default configuration)
Boards are autodiscovered from the `boards/` directory. First list them, then pick one:
Windows (cmd):
@@ -86,7 +86,9 @@ macOS/Linux (bash):
uv run ./tools/switchBoardType.py --list
uv run ./tools/switchBoardType.py --board seed_studio_xiao_esp32s3 --diff
```
Notes:
- Use `--list` to see all detected board keys.
- Board key = relative path under `boards/` with `/` replaced by `_` (and duplicate tail segments collapsed, e.g. `project_babble/project_babble` -> `project_babble`).
- `--diff` shows what will change vs the current `sdkconfig`.
@@ -96,8 +98,8 @@ Notes:
- Set the target (e.g., ESP32S3).
- Build, flash, and open the serial monitor.
- (Optional) For UVC mode ensure `GENERAL_INCLUDE_UVC_MODE=y`. If you want device to boot directly into UVC: also set `START_IN_UVC_MODE=y`.
- Disable WiFi services for pure wired builds: `GENERAL_ENABLE_WIRELESS=n`.
- (Optional) For UVC mode ensure `GENERAL_INCLUDE_UVC_MODE=y`. If you want device to boot directly into UVC: also set `START_IN_UVC_MODE=y`.
- Disable WiFi services for pure wired builds: `GENERAL_ENABLE_WIRELESS=n`.
### 3) Use the Python setup CLI (recommended)
@@ -137,7 +139,9 @@ What the CLI can do:
- The UVC device name is based on the MDNS hostname.
## Advertised Name (UVC + mDNS)
`CONFIG_GENERAL_ADVERTISED_NAME` (Kconfig) defines the base name announced over:
- USB UVC descriptor (appears in OS camera list)
- mDNS hostname / service name
@@ -150,10 +154,10 @@ Runtime override: If the setup CLI (or a JSON command) provides a new device nam
- Fast WiFi setup: in the CLI, go to “WiFi settings” → “Automatic setup”, then check “status”.
- Change name/MDNS: set the device name in the CLI, then replug USB — UVC will show the new name.
- Adjust brightness/LED: set LED PWM in the CLI.
- Switch to UVC mode over commands (CDC/serial):
`{"commands":[{"command":"switch_mode","data":{"mode":"uvc"}}]}` then reboot.
- Read filtered LED current (if enabled):
`{"commands":[{"command":"get_led_current"}]}`
- Switch to UVC mode over commands (CDC/serial):
`{"commands":[{"command":"switch_mode","data":{"mode":"uvc"}}]}` then reboot.
- Read filtered LED current (if enabled):
`{"commands":[{"command":"get_led_current"}]}`
---
@@ -162,19 +166,62 @@ Runtime override: If the setup CLI (or a JSON command) provides a new device nam
- `main/` — entry point
- `components/` — modules (Camera, WiFi, UVC, CommandManager, …)
- `tools/` — Python helper tools (board switch, setup CLI, scanner)
If you want to dig deeper: commands are mapped via the `CommandManager` under `components/CommandManager/...`.
- `tests/` - Hardware in the loop tests, with support for different boards and automatic skips if a board can't perform a given test
If you want to dig deeper: commands are mapped via the `CommandManager` under `components/CommandManager/...`.
---
## Running Hardware In The Loop Tests
In order to run the tests, you'll need to setup a couple of things:
- copy the `.env.example` file in `/tests/` and rename it to `.env`. Then, open it and fill out the network details - SSID and Password.
- plug in your board to your pc and wait for it to boot.
- open the terminal (`ctrl/cmd + j` in VSC) and head over to `/tests/` directory.
Once there, you can invoke the tests with `UV` like so:
```cmd
uv run pytest --board=<your board name> --connection=COM<the number your board connected to>
```
This will auto select every test we have, connect to your board automatically and have pytest skip tests that don't fit your board.
For example, tests involving switching modes to UVC and testing commands over there are disabled for esp32 based boards as only esp32s3 can do it. Same goes for WiFi for FaceFocus Boards.
If you see any fails, you can try rerunning them one by one with:
```cmd
uv run pytest --board=<your board name> --connection=COM<the number your board connected to> -k name_of_the_test
```
Or rerun every single failed test like so:
```cmd
uv run pytest --board=<your board name> --connection=COM<the number your board connected to> --lf
```
Sometimes tests will fail due to timeouts, this is normal.
You should see the tests starting to go off, with any luck - all of them passing, your board should also start reacting to the changes - reboots, blinking lights etc are **expected** as we're performing hardware in the loop tests.
### Warning:
After the testing session ends **WE WILL RESET THE BOARD**, any changes you've made yourself to it will be lost. This is done to ensure that the test we perform are unaffected by any changes done by said tests.
If we skipped that, tests involving adding fake networks would break some that rely on the board connecting to real ones in a timely manner, for example.
There is currently no way to skip that behavior.
## Troubleshooting
### USB Composite (UVC + CDC)
When UVC support is compiled in, the device enumerates as a composite USB device:
- UVC interface: video streaming (JPEG frames)
- CDC (virtual COM): command channel accepting newlineterminated JSON objects
Example newlineterminated JSON commands over CDC (one per line):
```
{"commands":[{"command":"ping"}]}
{"commands":[{"command":"get_who_am_i"}]}
@@ -182,34 +229,40 @@ Example newlineterminated JSON commands over CDC (one per line):
```
Chained commands in a single request (processed in order):
```
{"commands":[
{"command":"set_mdns","data":{"hostname":"tracker"}},
{"command":"set_wifi","data":{"name":"main","ssid":"your_network","password":"password","channel":0,"power":0}}
]}
```
Responses are JSON blobs flushed immediately.
---
### Monitoring (LED Current)
Enabled with `MONITORING_LED_CURRENT=y` plus shunt/gain settings. The task samples every `CONFIG_MONITORING_LED_INTERVAL_MS` ms and maintains a filtered moving average over `CONFIG_MONITORING_LED_SAMPLES` samples. Use `get_led_current` command to query.
### Debug & External LED Configuration
| Kconfig | Effect |
|---------|--------|
| LED_DEBUG_ENABLE | Enables/disables discrete status LED GPIO init & drive |
| LED_EXTERNAL_CONTROL | Enables PWM control for IR / external LED |
| LED_EXTERNAL_PWM_DUTY_CYCLE | Default duty % applied at boot (0100) |
| LED_EXTERNAL_AS_DEBUG | Mirrors only error patterns onto external LED (0%/50%) when debug LED absent or also for redundancy |
| Kconfig | Effect |
| --------------------------- | --------------------------------------------------------------------------------------------------- |
| LED_DEBUG_ENABLE | Enables/disables discrete status LED GPIO init & drive |
| LED_EXTERNAL_CONTROL | Enables PWM control for IR / external LED |
| LED_EXTERNAL_PWM_DUTY_CYCLE | Default duty % applied at boot (0100) |
| LED_EXTERNAL_AS_DEBUG | Mirrors only error patterns onto external LED (0%/50%) when debug LED absent or also for redundancy |
### Board Profiles
Each file under `boards/` overlays `sdkconfig.base_defaults`. The merge order: base → board file → (optional) dynamic WiFi overrides via `switchBoardType.py` flags. Duplicate trailing segment directories collapse to unique keys.
- UVC doesnt appear on the host?
- Switch mode to UVC via CLI tool, replug USB and wait 20s.
### Adding a new board configuration
1. Create a new config file under `boards/` (you can nest folders): for example `boards/my_family/my_variant`.
2. Populate it with only the `CONFIG_...` lines that differ from the shared defaults. Shared baseline lives in `boards/sdkconfig.base_defaults` and is always merged first.
3. The board key the script accepts will be the relative path with `/` turned into `_` (example: `boards/my_family/my_variant` -> `my_family_my_variant`).
@@ -217,24 +270,27 @@ Each file under `boards/` overlays `sdkconfig.base_defaults`. The merge order: b
5. If you accidentally create two files that collapse to the same key the last one found wins—rename to keep keys unique.
Tips:
- Use `--diff` after adding a board to sanitycheck only the intended keys change.
- For WiFi overrides on first flash: add none—pass `--ssid` / `--password` when switching if needed.
---
## Troubleshooting
### LED Status / Error Patterns
The firmware uses a small set of LED patterns to indicate status and blocking errors. When `LED_DEBUG_ENABLE` is disabled and `LED_EXTERNAL_AS_DEBUG` is enabled the external IR LED mirrors ONLY error patterns (0%/50% duty). Nonerror patterns are not mirrored.
| State | Visual | Category | Timing Pattern (ms) | Meaning |
|-------|--------|----------|---------------------|---------|
| LedStateNone | ![idle](docs/led_patterns/idle.svg) | idle | (off) | No activity / heartbeat window waiting |
| LedStateStreaming | ![stream](docs/led_patterns/streaming.svg) | active | steady on | Streaming running (UVC or WiFi) |
| LedStateStoppedStreaming | ![stopped](docs/led_patterns/stopped.svg) | inactive | steady off | Streaming intentionally stopped |
| CameraError | ![camera error](docs/led_patterns/camera_error.svg) | error | 300/300 300/700 (loop) | Camera init/runtime failure (check sensor, ribbon, power) |
| WiFiStateConnecting | ![wifi connecting](docs/led_patterns/wifi_connecting.svg) | transitional | 400/400 (loop) | WiFi associating / DHCP pending |
| WiFiStateConnected | ![wifi connected](docs/led_patterns/wifi_connected.svg) | notification | 150/150×3 then 600 off | WiFi connected successfully |
| WiFiStateError | ![wifi error](docs/led_patterns/wifi_error.svg) | error | 200/100 500/300 (loop) | WiFi failed (auth timeout or no AP) |
| State | Visual | Category | Timing Pattern (ms) | Meaning |
| ------------------------ | --------------------------------------------------------- | ------------ | ---------------------- | --------------------------------------------------------- |
| LedStateNone | ![idle](docs/led_patterns/idle.svg) | idle | (off) | No activity / heartbeat window waiting |
| LedStateStreaming | ![stream](docs/led_patterns/streaming.svg) | active | steady on | Streaming running (UVC or WiFi) |
| LedStateStoppedStreaming | ![stopped](docs/led_patterns/stopped.svg) | inactive | steady off | Streaming intentionally stopped |
| CameraError | ![camera error](docs/led_patterns/camera_error.svg) | error | 300/300 300/700 (loop) | Camera init/runtime failure (check sensor, ribbon, power) |
| WiFiStateConnecting | ![wifi connecting](docs/led_patterns/wifi_connecting.svg) | transitional | 400/400 (loop) | WiFi associating / DHCP pending |
| WiFiStateConnected | ![wifi connected](docs/led_patterns/wifi_connected.svg) | notification | 150/150×3 then 600 off | WiFi connected successfully |
| WiFiStateError | ![wifi error](docs/led_patterns/wifi_error.svg) | error | 200/100 500/300 (loop) | WiFi failed (auth timeout or no AP) |
---