LSH-Core
Deterministic firmware core for Controllino-based Labo Smart Home nodes
 
Loading...
Searching...
No Matches
LSH-Core Documentation

LSH-Core

lsh-core is the deterministic firmware engine for the Labo Smart Home stack. It runs on the controller-side MCU, owns the physical topology, and executes the local logic for buttons, actuators, indicators, fallback behavior and the serial protocol spoken with lsh-bridge.

If you are new to the public LSH stack, start with the top-level repository before diving into the firmware API surface:

This hosted API site is published from the latest tagged release so it stays aligned with released artifacts. The repository main branch may move ahead between releases.

What This Documentation Covers

This Doxygen site combines three complementary sources:

  • the public API extracted from include/ and src/
  • the integration and operational guide from README.md
  • the generated wire-protocol reference from vendor/lsh-protocol/shared/lsh_protocol.md

Use the API reference when you need class- and method-level details, and use the README and protocol pages when you need the system contract around the library.

Runtime Invariants

The firmware is intentionally strict about a few invariants:

  • The configured topology is static between two controller boots.
  • Generated LSH_STATIC_CONFIG_* values define the exact runtime cardinality for actuators, buttons, indicators, network-click slots and auto-off entries. The C++ API still calls physical inputs Clickable objects because the same finite-state machine can model any button-like input.
  • Configurator::configure() is generated from TOML and directly assigns dense object indexes and manager-array slots. The generated path replaces hand-written registration code.
  • Registered object arrays are dense by contract. Debug/runtime setup validation rejects null holes and mismatched object indexes before the runtime loop starts.
  • Click actions, button scan routing, indicator refreshes and auto-off checks are generated from the static topology instead of traversing runtime link tables.
  • Generated button scanners pass compile-time flags and thresholds to the input FSM, and generated multi-actuator actions reuse one timestamp when switch-time bookkeeping is active.
  • Device IDs exposed on the wire are positive non-zero uint8_t values and must stay unique within their domain.
  • BOOT is the re-synchronization trigger used to invalidate cached models in the bridge and force a fresh details + state cycle.
  • Serial transport depends on the selected codec: JSON uses newline-delimited frames, while MsgPack uses a framed delimiter-and-escape transport on top of the pure payload bytes.
  • The protocol assumes a trusted environment. Authentication, encryption and hostile-peer hardening belong in the surrounding deployment rather than the payload contract.

Navigation

  • Start with README.md for the first-use path and project shape.
  • Use DOCS.md as the repository documentation map.
  • Read docs/static-toml-config.md for the schema v2 reference.
  • Read docs/cookbook.md for copyable configuration recipes.
  • Read docs/feature-flags.md for compile-time tuning knobs.
  • Inspect Configurator to understand how devices are declared and registered.
  • Inspect Clickable, Actuator and Indicator for the local I/O model.
  • Inspect src/util/constants/config.hpp for resource limits derived from the active user profile.
  • Inspect the generated protocol constants in src/communication/constants/protocol.hpp and src/communication/constants/static_payloads.hpp.
  • Inspect the generated protocol page included from vendor/lsh-protocol/shared/lsh_protocol.md for the canonical key map, command IDs and golden payload examples.

Design Notes

The codebase is optimized for embedded determinism:

  • fixed-capacity ETL containers instead of heap allocation
  • compact on-wire payloads
  • compile-time feature flags for timing, debugging and performance tuning
  • compile-time AVR pin binding when public device macros use constant pins on supported boards
  • explicit fallback behavior when the network path is unavailable

For AVR static profiles, the project defaults assume runtime speed first, SRAM second and flash third. That is why the reference TOML profiles prefer framed MsgPack and direct-port I/O even when they cost more flash than the equivalent JSON or Arduino helper path.

That optimization target matters when reviewing or extending the code. Prefer changes that preserve RAM predictability, keep performance-sensitive paths branch-light, and do not relax the boot/resync contract between lsh-core and lsh-bridge.