Initial commit

This commit is contained in:
2026-04-17 01:33:23 +02:00
commit 1f6543bd7a
28 changed files with 2556 additions and 0 deletions

View File

@@ -0,0 +1,37 @@
# Acceptance Template
Date:
Technician:
Firmware build:
Host build:
## Core Checks
- [ ] System starts from cold boot
- [ ] All 6 nodes discovered
- [ ] All 18 outputs configured
- [ ] All outputs confirm 106 LEDs
- [ ] Global brightness change is visible immediately
- [ ] Blackout works and recovers cleanly
- [ ] Preset recall works under load
- [ ] Node reconnect works during active show
- [ ] 8-hour soak run completed without critical fault
## Mapping Checks
- [ ] Walking pixel test completed on every output
- [ ] Start pixel confirmed for every output
- [ ] Direction confirmed for every output
- [ ] Color order confirmed for every output
- [ ] Top, middle, bottom assignment confirmed on every node
- [ ] No mismatch between configured mapping and observed physical behavior
## Observations
- Notes:
- Exceptions:
- Follow-up actions:

85
docs/architecture.md Normal file
View File

@@ -0,0 +1,85 @@
# Architecture
## Goal
Build a live-capable LED control platform that keeps realtime output deterministic while letting operators change scenes, brightness, tests, and presets without UI jitter leaking into the hot path.
## Layer Split
1. Control layer
- Operator workflow
- Presets and topology editing
- Monitoring and diagnostics
- Never the timing master for LED output
2. Realtime engine
- Owns the monotonic clock
- Computes scene state, transitions, and dirty regions
- Produces transport-ready commands or pixel frames
3. Transport and node layer
- Discovery, heartbeat, config sync, sequencing, and recovery
- Control protocol and realtime protocol stay separate
- Latest realtime state wins, stale frames may be dropped
4. ESP32 firmware
- Receives commands
- Maintains local buffers
- Drives three independent outputs per node
- Handles watchdog and reconnect logic locally
## Runtime Model
- Logic tick target: 120 Hz
- Frame synthesis target: 60 Hz
- Network send target: 40-60 Hz, profile dependent
- Preview target: 10-15 Hz
Preview and telemetry are explicitly degradable. Realtime output is not.
## Modes
### Distributed Scene Mode
- Default operating mode
- Host sends scene parameters, time basis, seed, palette, and transitions
- Nodes render locally for low bandwidth and better resilience
### Frame Streaming Mode
- Used for mapping tests, debugging, and effects that cannot run node-local
- Host sends explicit output frames
- Kept logically separate so it does not contaminate the primary scene pipeline
## Mapping Model
The project configuration separates mapping into three layers:
1. Hardware mapping
- Node ID
- Top, middle, bottom output
- Physical output label
- Driver channel reference
- LED count, direction, color order, enable flag
2. Layout mapping
- Optional row and column placement
- Optional preview transforms only
3. Group mapping
- Explicit groups for artistic control and fast operator access
The current example config intentionally keeps layout mapping empty because the old XML is only a spatial reference and the final node-to-room placement must still be confirmed on real hardware.
## Validation Gates
The codebase deliberately blocks activation when these remain unresolved:
- `UART 6`, `UART 5`, `UART 4` still marked as `pending_validation`
- output validation state is not `validated`
- LED count deviates from 106
- node outputs are missing top, middle, or bottom
- driver references are ambiguous or duplicated per node
## Planned Next Steps
1. Add the actual UI adapter on top of `infinity_host`
2. Implement UDP transport with separate control and realtime sockets
3. Connect firmware driver backends after hardware validation
4. Add deterministic effect registry shared between host planning and firmware capability negotiation

40
docs/build_and_deploy.md Normal file
View File

@@ -0,0 +1,40 @@
# Build and Deploy
## Host Side
Required tools:
- Rust stable toolchain
- `cargo`
Suggested commands:
```powershell
cargo test
cargo run -p infinity_host -- validate --config config/project.example.toml --mode structural
cargo run -p infinity_host -- plan-boot-scene --config config/project.example.toml --preset-id safe_static_blue
```
Before any live activation, run:
```powershell
cargo run -p infinity_host -- validate --config config/project.example.toml --mode activation
```
Activation mode is expected to fail until the hardware mapping has been confirmed and the config is updated from `pending_validation` to concrete driver references.
## Firmware Side
Required tools:
- ESP-IDF
- Xtensa or RISC-V toolchain matching the actual ESP32 variant
Suggested layout:
- `firmware/esp32_node/`
- build with `idf.py build`
- flash with `idf.py -p <serial-port> flash monitor`
The firmware skeleton is intentionally conservative. It will not silently select a backend for `UART 6`, `UART 5`, or `UART 4`.

87
docs/config_schema.md Normal file
View File

@@ -0,0 +1,87 @@
# Config Schema
## Primary File
The example project file is [config/project.example.toml](../config/project.example.toml).
## Root Objects
- `metadata`
- `topology`
- `transport_profiles`
- `safety_profiles`
- `presets`
## `metadata`
- `project_name`
- `schema_version`
- `default_transport_profile`
- `default_safety_profile`
## `topology`
- `expected_node_count`
- `outputs_per_node`
- `leds_per_output`
- `nodes`
- `layout_panels`
- `groups`
## `topology.nodes[]`
- `node_id`
- `display_name`
- `network.reserved_ip`
- `network.telemetry_label`
- `outputs`
## `topology.nodes[].outputs[]`
Required:
- `panel_position`
- `physical_output_name`
- `driver_channel.kind`
- `driver_channel.reference`
- `led_count`
- `direction`
- `color_order`
- `enabled`
- `validation_state`
Optional:
- `logical_panel_name`
## Activation Rules
Structural validation accepts `pending_validation` so the system can model unresolved wiring.
Activation validation rejects any output that is still:
- `driver_channel.kind = "pending_validation"`
- `validation_state != "validated"`
This is intentional and prevents accidental deployment against guessed hardware assumptions.
## Groups
`topology.groups[]` keeps grouping explicit and simple:
- `group_id`
- `tags`
- `members[] = { node_id, panel_position }`
## Layout
`topology.layout_panels[]` is optional and only needed for preview or spatial effects:
- `node_id`
- `panel_position`
- `row`
- `column`
- `rotation_degrees`
- `mirror_x`
- `mirror_y`

View File

@@ -0,0 +1,26 @@
# Legacy XML Reference
Source reviewed:
- `c:\Users\janni\Nextcloud\Documents\Infinity Vis\sample_data\infinity_mirror_mapping_clean.xml`
Useful facts extracted from the legacy file:
- 3 rows by 6 columns logical preview layout
- 18 total tiles
- 106 LEDs per tile
- legacy transport metadata mentions WLED, Art-Net, and per-tile IP addresses
- each tile is described as four perimeter segments summing to 106 LEDs
What this file is **not** used for:
- it is not the new hardware-mapping schema
- it is not proof of the final ESP32 node-to-panel assignment
- it does not validate `UART 6`, `UART 5`, or `UART 4`
- it should not be imported as a generic slice engine
Recommended use:
- use it as a preview and spatial-reference aid only
- manually transfer final room layout after the new hardware mapping is physically validated

67
docs/protocol.md Normal file
View File

@@ -0,0 +1,67 @@
# Protocol
## Design Rules
- Separate control traffic from realtime traffic
- Version every envelope
- Keep realtime messages disposable
- Prefer idempotent control commands
- Let nodes recover independently after packet loss or reconnect
## Control Protocol
Purpose:
- Discovery
- Heartbeat
- Config sync
- Preset recall
- Panic and blackout
- Telemetry
Current envelope model:
- `protocol_version`
- `sequence`
- `sent_at_millis`
- `message`
Current control messages:
- `discovery_hello`
- `discovery_ack`
- `config_sync`
- `heartbeat_request`
- `heartbeat`
- `preset_recall`
- `blackout`
`config_sync` carries the authoritative per-node hardware assignment so the node can reject invalid activation before the first frame.
## Realtime Protocol
Purpose:
- Scene parameters for distributed rendering
- Explicit pixel frames for frame streaming mode
- Resync requests
Current realtime messages:
- `scene_parameters`
- `pixel_frame`
- `resync_request`
## Delivery Semantics
- Control messages must be small and replay-safe where possible
- Realtime messages use latest-state-wins semantics
- Nodes may drop stale realtime frames rather than replay them
- A reconnecting node must request or receive a clean config sync before resuming output
## DDP Compatibility
DDP is treated as an optional compatibility shell for frame streaming mode only.
The internal model is intentionally broader than DDP because the preferred operating path is distributed scene mode with time-based parameters and node-local rendering.

37
docs/testing.md Normal file
View File

@@ -0,0 +1,37 @@
# Testing
## Unit Tests
Host-side unit tests currently cover:
- fixed LED count validation
- duplicate driver reference rejection
- activation guard against unresolved hardware mapping
- protocol envelope version stamping
## Planned Integration Tests
1. Host to node config sync
2. Host to node preset recall during load
3. Reconnect and resync after heartbeat timeout
4. Frame streaming fallback without scene-mode support
## Soak Tests
Target procedure:
1. Run a continuous scene loop for 8 hours
2. Rotate presets on a schedule
3. Simulate packet loss and node reconnects
4. Log dropped frames, reconnect count, and jitter
## Hardware Validation Tests
Required before live deployment:
1. Walking pixel test across all 106 LEDs on each of the 18 outputs
2. Start pixel verification per output
3. Direction verification per output
4. Color order verification per output
5. Final confirmation of which physical channel maps to top, middle, and bottom on every node

View File

@@ -0,0 +1,14 @@
# Validation Open Points
These items must be resolved before the system can move from structural validation to activation validation:
1. Confirm the real meaning of `UART 6`, `UART 5`, and `UART 4`.
2. Confirm the exact LED chipset and required output timing backend.
3. Confirm whether every output truly has exactly 106 active LEDs, with no dummy or reserve pixels.
4. Confirm color order for each output.
5. Confirm direction and start pixel for each output.
6. Confirm which physical node controls which installed top, middle, and bottom panel.
7. Confirm whether transport runs over dedicated Wi-Fi or wired Ethernet.
8. Confirm whether DDP compatibility is optional or mandatory in the first deployment.
9. Confirm whether the first production UI is Tauri, egui, or another adapter on top of the host core.