Consolidate Rust port requirements and remove refactor notes docs
This commit is contained in:
159
Requirements.md
159
Requirements.md
@@ -11,7 +11,31 @@ It is based on the current `lora-refactor` code state and captures:
|
||||
|
||||
Function names below are C++ references. Rust naming/layout may differ, but the behavior must remain equivalent.
|
||||
|
||||
## 2. System-Level Requirements
|
||||
## 2. Refactored Architecture Baseline
|
||||
|
||||
The `lora-refactor` branch split role-specific runtime from the previous large `main.cpp` into dedicated modules while keeping a single firmware image:
|
||||
|
||||
- `src/main.cpp` is a thin coordinator that:
|
||||
- detects role and initializes shared platform subsystems,
|
||||
- prepares role module configuration,
|
||||
- calls `begin()` once,
|
||||
- delegates runtime in `loop()`.
|
||||
- sender runtime ownership:
|
||||
- `src/sender_state_machine.h`
|
||||
- `src/sender_state_machine.cpp`
|
||||
- receiver runtime ownership:
|
||||
- `src/receiver_pipeline.h`
|
||||
- `src/receiver_pipeline.cpp`
|
||||
- receiver shared mutable state used by setup wiring and runtime:
|
||||
- `src/app_context.h` (`ReceiverSharedState`)
|
||||
|
||||
Sender state machine invariants must remain behavior-equivalent:
|
||||
- single inflight batch at a time,
|
||||
- ACK acceptance only for matching `batch_id`,
|
||||
- retry bounded by `BATCH_MAX_RETRIES`,
|
||||
- queue depth bounded by `BATCH_QUEUE_DEPTH`.
|
||||
|
||||
## 3. System-Level Requirements
|
||||
|
||||
- Role selection:
|
||||
- `Sender` when `GPIO14` reads HIGH.
|
||||
@@ -58,7 +82,7 @@ Function names below are C++ references. Rust naming/layout may differ, but the
|
||||
- history day-file resolution prefers local-date filenames and falls back to legacy UTC-date filenames.
|
||||
- history parser supports both current (`ts_utc,ts_hms_local,p_w,...`) and legacy (`ts_utc,p_w,...`) layouts.
|
||||
|
||||
## 3. Protocol and Data Contracts
|
||||
## 4. Protocol and Data Contracts
|
||||
|
||||
- `LoraMsgKind`:
|
||||
- `BatchUp=0`
|
||||
@@ -81,8 +105,13 @@ Function names below are C++ references. Rust naming/layout may differ, but the
|
||||
- `device.name`: `<device_id>`
|
||||
- `device.model`: `DD3-LoRa-Bridge`
|
||||
- `device.manufacturer`: `AcidBurns`
|
||||
- drift guards:
|
||||
- canonical value is `HA_MANUFACTURER` in `include/config.h`,
|
||||
- compile-time lock via `static_assert` in `include/config.h`,
|
||||
- script guard `test/check_ha_manufacturer.ps1`,
|
||||
- smoke test guard `test/test_refactor_smoke/test_refactor_smoke.cpp`.
|
||||
|
||||
## 4. Module and Function Requirements
|
||||
## 5. Module and Function Requirements
|
||||
|
||||
## `src/config.cpp`
|
||||
|
||||
@@ -335,15 +364,25 @@ Internal route/state functions to preserve behavior:
|
||||
- `test_receiver_loop`
|
||||
- decode test JSON, update display test markers, publish MQTT test topic.
|
||||
|
||||
## `src/main.cpp` (Core Orchestration)
|
||||
## `src/app_context.h`
|
||||
|
||||
These functions define end-to-end firmware behavior and must have equivalents:
|
||||
- `ReceiverSharedState`
|
||||
- retains receiver-owned shared status/fault/discovery state used by setup wiring and runtime.
|
||||
|
||||
## `src/sender_state_machine.h/.cpp` (Sender Runtime)
|
||||
|
||||
Public API:
|
||||
- `SenderStateMachineConfig`
|
||||
- `SenderStats`
|
||||
- `SenderStateMachine::begin(...)`
|
||||
- `SenderStateMachine::loop()`
|
||||
- `SenderStateMachine::stats()`
|
||||
|
||||
Behavior-critical internals (migrated from pre-refactor `main.cpp`) that must remain equivalent:
|
||||
- Logging/utilities:
|
||||
- `serial_debug_printf`
|
||||
- `bit_count32`
|
||||
- `abs_diff_u32`
|
||||
|
||||
- Meter-time anchoring and ingest:
|
||||
- `meter_time_update_snapshot`
|
||||
- `set_last_meter_sample`
|
||||
@@ -352,13 +391,9 @@ These functions define end-to-end firmware behavior and must have equivalents:
|
||||
- `meter_reader_task_entry`
|
||||
- `meter_reader_start`
|
||||
- `meter_reader_pump`
|
||||
|
||||
- Sender/receiver state setup and shared state:
|
||||
- `init_sender_statuses`
|
||||
- Sender state/data handling:
|
||||
- `update_battery_cache`
|
||||
- `battery_sample_due`
|
||||
|
||||
- Queue and sample batching:
|
||||
- `batch_queue_drop_oldest`
|
||||
- `sender_note_rx_reject`
|
||||
- `sender_log_diagnostics`
|
||||
@@ -367,8 +402,7 @@ These functions define end-to-end firmware behavior and must have equivalents:
|
||||
- `reset_build_counters`
|
||||
- `append_meter_sample`
|
||||
- `last_sample_ts`
|
||||
|
||||
- Fault tracking/publish:
|
||||
- Sender fault handling:
|
||||
- `note_fault`
|
||||
- `clear_faults`
|
||||
- `sender_reset_fault_stats`
|
||||
@@ -377,11 +411,40 @@ These functions define end-to-end firmware behavior and must have equivalents:
|
||||
- `age_seconds`
|
||||
- `counters_changed`
|
||||
- `publish_faults_if_needed`
|
||||
- Sender-specific encoding/scheduling:
|
||||
- `kwh_to_wh_from_float`
|
||||
- `float_to_i16_w`
|
||||
- `float_to_i16_w_clamped`
|
||||
- `battery_mv_from_voltage`
|
||||
- `compute_batch_ack_timeout_ms`
|
||||
- `send_batch_payload`
|
||||
- `invalidate_inflight_encode_cache`
|
||||
- `prepare_inflight_from_queue`
|
||||
- `send_inflight_batch`
|
||||
- `send_meter_batch`
|
||||
- `send_sync_request`
|
||||
- `resend_inflight_batch`
|
||||
- `finish_inflight_batch`
|
||||
- `sender_loop`
|
||||
|
||||
- Watchdog:
|
||||
- `watchdog_init`
|
||||
- `watchdog_kick`
|
||||
## `src/receiver_pipeline.h/.cpp` (Receiver Runtime)
|
||||
|
||||
Public API:
|
||||
- `ReceiverPipelineConfig`
|
||||
- `ReceiverStats`
|
||||
- `ReceiverPipeline::begin(...)`
|
||||
- `ReceiverPipeline::loop()`
|
||||
- `ReceiverPipeline::stats()`
|
||||
|
||||
Behavior-critical internals (migrated from pre-refactor `main.cpp`) that must remain equivalent:
|
||||
- Receiver setup/state:
|
||||
- `init_sender_statuses`
|
||||
- Fault handling/publish:
|
||||
- `note_fault`
|
||||
- `clear_faults`
|
||||
- `age_seconds`
|
||||
- `counters_changed`
|
||||
- `publish_faults_if_needed`
|
||||
- Binary helpers and ID conversion:
|
||||
- `write_u16_le`
|
||||
- `read_u16_le`
|
||||
@@ -391,39 +454,27 @@ These functions define end-to-end firmware behavior and must have equivalents:
|
||||
- `read_u32_be`
|
||||
- `sender_id_from_short_id`
|
||||
- `short_id_from_sender_id`
|
||||
|
||||
- Numeric normalization/sanitization:
|
||||
- `kwh_to_wh_from_float`
|
||||
- `float_to_i16_w`
|
||||
- `float_to_i16_w_clamped`
|
||||
- `battery_mv_from_voltage`
|
||||
|
||||
- Timeout and airtime-driven scheduling:
|
||||
- LoRa RX/TX pipeline:
|
||||
- `compute_batch_rx_timeout_ms`
|
||||
- `compute_batch_ack_timeout_ms`
|
||||
|
||||
- LoRa TX pipeline:
|
||||
- `send_batch_payload`
|
||||
- `send_batch_ack`
|
||||
- `invalidate_inflight_encode_cache`
|
||||
- `prepare_inflight_from_queue`
|
||||
- `send_inflight_batch`
|
||||
- `send_meter_batch`
|
||||
- `send_sync_request`
|
||||
- `resend_inflight_batch`
|
||||
- `finish_inflight_batch`
|
||||
|
||||
- LoRa RX reassembly/decode:
|
||||
- `reset_batch_rx`
|
||||
- `process_batch_packet`
|
||||
|
||||
- Role loop orchestration:
|
||||
- `setup`
|
||||
- `sender_loop`
|
||||
- `receiver_loop`
|
||||
- `loop`
|
||||
|
||||
## 5. Rust Porting Constraints and Recommendations
|
||||
## `src/main.cpp` (Thin Coordinator)
|
||||
|
||||
Current core orchestration requirements:
|
||||
- `setup`
|
||||
- initialize shared subsystems once,
|
||||
- instantiate role config and call role `begin`,
|
||||
- keep role-specific runtime out of this file.
|
||||
- `loop`
|
||||
- delegate to `SenderStateMachine::loop()` or `ReceiverPipeline::loop()` by role.
|
||||
- Watchdog wrapper remains in coordinator:
|
||||
- `watchdog_init`
|
||||
- `watchdog_kick`
|
||||
|
||||
## 6. Rust Porting Constraints and Recommendations
|
||||
|
||||
- Preserve wire compatibility first:
|
||||
- LoRa frame byte layout, CRC16, ACK format, payload schema v3.
|
||||
@@ -439,14 +490,14 @@ These functions define end-to-end firmware behavior and must have equivalents:
|
||||
- `FaultType`, `RxRejectReason`, `LoraMsgKind`.
|
||||
|
||||
Suggested Rust module split:
|
||||
- `config`, `ids`, `meter`, `power`, `time`, `lora_transport`, `payload_codec`, `batch`, `mqtt`, `wifi_cfg`, `sd_log`, `web`, `display`, `runtime`.
|
||||
- `config`, `ids`, `meter`, `power`, `time`, `lora_transport`, `payload_codec`, `sender_state_machine`, `receiver_pipeline`, `app_context`, `mqtt`, `wifi_cfg`, `sd_log`, `web`, `display`, `runtime`.
|
||||
|
||||
Suggested Rust primitives:
|
||||
- async task for meter reader + bounded channel (drop-oldest behavior).
|
||||
- explicit state structs for sender/receiver loops.
|
||||
- serde-free/manual codec for wire compatibility where needed.
|
||||
|
||||
## 6. Port Validation Checklist
|
||||
## 7. Port Validation Checklist
|
||||
|
||||
- Sender unsynced boot sends only sync requests.
|
||||
- ACK time bootstrap unlocks normal sender sampling.
|
||||
@@ -459,3 +510,21 @@ Suggested Rust primitives:
|
||||
- History endpoint reads current and legacy CSV layouts successfully.
|
||||
- History endpoint can read both local-date and legacy UTC-date day filenames.
|
||||
- MQTT state/fault payload fields match existing names and semantics.
|
||||
|
||||
## 8. Port Readiness Audit (2026-02-20)
|
||||
|
||||
Evidence checked on `lora-refactor`:
|
||||
- build verification:
|
||||
- `pio run -e lilygo-t3-v1-6-1`
|
||||
- `pio run -e lilygo-t3-v1-6-1-test`
|
||||
- drift guard verification:
|
||||
- `powershell -ExecutionPolicy Bypass -File test/check_ha_manufacturer.ps1`
|
||||
- refactor ownership verification:
|
||||
- sender state machine state/API present in `src/sender_state_machine.h/.cpp`,
|
||||
- receiver pipeline API present in `src/receiver_pipeline.h/.cpp`,
|
||||
- coordinator remains thin in `src/main.cpp`.
|
||||
|
||||
Findings:
|
||||
- Requirements are functionally met by current C++ baseline from static/code-build checks.
|
||||
- The old requirement ownership under `src/main.cpp` was stale; this document now maps that behavior to `sender_state_machine` and `receiver_pipeline`.
|
||||
- No wire/protocol or persistence contract drift found in this audit.
|
||||
|
||||
Reference in New Issue
Block a user