{"id":48908329,"url":"https://github.com/labodj/labo-smart-home","last_synced_at":"2026-05-13T15:02:12.100Z","repository":{"id":351544726,"uuid":"1211357515","full_name":"labodj/labo-smart-home","owner":"labodj","description":"Public landing page for the Labo Smart Home ecosystem: architecture, releases, and repository map.","archived":false,"fork":false,"pushed_at":"2026-04-15T12:21:18.000Z","size":3827,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-15T14:17:44.348Z","etag":null,"topics":["arduino","controllino","esp32","home-automation","homie","lsh","mqtt","node-red","smart-home"],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/labodj.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":"NOTICE","maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-15T10:06:49.000Z","updated_at":"2026-04-15T12:10:03.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/labodj/labo-smart-home","commit_stats":null,"previous_names":["labodj/labo-smart-home"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/labodj/labo-smart-home","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/labodj%2Flabo-smart-home","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/labodj%2Flabo-smart-home/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/labodj%2Flabo-smart-home/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/labodj%2Flabo-smart-home/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/labodj","download_url":"https://codeload.github.com/labodj/labo-smart-home/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/labodj%2Flabo-smart-home/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31905895,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-16T18:22:33.417Z","status":"ssl_error","status_checked_at":"2026-04-16T18:21:47.142Z","response_time":69,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arduino","controllino","esp32","home-automation","homie","lsh","mqtt","node-red","smart-home"],"created_at":"2026-04-16T22:01:26.122Z","updated_at":"2026-05-13T15:02:12.093Z","avatar_url":"https://github.com/labodj.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Labo Smart Home\n\nLabo Smart Home (`LSH`) is a wired, local-first home automation stack for installations\nwhere wall buttons, relays, and indicator LEDs need to remain responsive, predictable,\nand under local control.\n\nThe project grew out of a home installation that began during a renovation and kept\nevolving afterward. The core design goal has not changed: keep the wired controls\ndependable, then expose their state and commands cleanly through MQTT/Homie and the\norchestration layer instead of hiding the system inside a single opaque box.\n\nThe current reference installation uses **six Controllino Maxi PLCs**, each paired with\nan **ESP32 Wi-Fi bridge**. The PLCs handle physical I/O and local behavior. The bridges\npublish controller state over **MQTT** using the **Homie** device model. The\norchestration layer can run in **Node-RED** or as a headless **Node.js coordinator**.\n\nThis repository is the public entry point for LSH. It shows how the pieces fit together,\nwhere each component lives, which docs to read next, and now also hosts the stack\ncomposer that turns controller contracts into bridge firmware fragments, coordinator\nconfiguration and Node-RED node settings.\n\n## What LSH Is\n\nLSH is a reference stack for wired home automation. A Controllino controller keeps local\ninputs and outputs usable without the network. An ESP32 bridge publishes state and\naccepts commands over MQTT/Homie. A coordinator adds behavior that needs system-wide\ncontext, while a shared protocol package keeps compact payloads aligned across the\ncomponents.\n\nThe public repositories are installable packages rather than only source snapshots: the\ncontroller and bridge libraries are available through PlatformIO, and the orchestration\nlayer can be used either from Node-RED or as a standalone Node.js runtime.\n\nYou can adopt the stack in two ways. The recommended first route is the stack\nconfigurator: edit one controller TOML file, edit one stack TOML file, then generate the\nPlatformIO fragments and orchestration settings. The manual route is still available for\nexisting projects, but then you keep controller, bridge, MQTT, coordinator and Node-RED\nvalues aligned yourself.\n\nLSH is not a packaged plug-and-play smart-home product or the simplest path for a few\nWi-Fi bulbs. It fits projects whose maintainers are comfortable with electrical\nplanning, firmware builds, MQTT services, and gradual integration.\n\n## When LSH Fits\n\n- Your wired controls need to keep working when Wi-Fi or the MQTT broker is unavailable.\n- You prefer small components with clear boundaries over a single all-in-one automation\n  box.\n- You want command IDs, compact keys, and payload shapes defined in one place.\n- You already use, or can reasonably adopt, tools such as PlatformIO, MQTT, Homie,\n  Node.js, or Node-RED.\n- You are looking for a reference implementation shaped by real panels, timing\n  constraints, and maintenance work.\n\n## Current Installation\n\nThe photo below shows the current panel layout: a Controllino Maxi paired with an\ninternal ESP32 bridge, a dedicated controller-to-bridge link, and external USB service\nleads kept available for firmware maintenance.\n\n\u003cp\u003e\n  \u003cimg\n    src=\"./assets/photos/current-panel-overview.jpg\"\n    alt=\"Current panel with Controllino Maxi and ESP32 bridge\"\n    width=\"58%\"\n  \u003e\n\u003c/p\u003e\n\nThe early photos show how the project started: cable runs, controller bring-up and panel\nwork during the house renovation.\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003ctd width=\"50%\"\u003e\n      \u003cimg\n        src=\"./assets/photos/early-build-cable-bundle.jpg\"\n        alt=\"Early 2019 wiring stage with cable bundle and controller boards\"\n      \u003e\n    \u003c/td\u003e\n    \u003ctd width=\"50%\"\u003e\n      \u003cimg\n        src=\"./assets/photos/early-build-controllino-closeup.jpg\"\n        alt=\"Early Controllino installation close-up inside wall box\"\n      \u003e\n    \u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003eEarly wiring while bringing multiple cable runs into the system.\u003c/td\u003e\n    \u003ctd\u003eOne of the first Controllino-based installations during integration.\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\nFor details on power, UART, level shifting, and panel serviceability, read\n[HARDWARE_OVERVIEW.md](./HARDWARE_OVERVIEW.md).\n\n## Public Repositories\n\n| Repository                                                                             | Role                                                          | Latest public release                                                                                                                                                                                                                                                                                                                         |\n| -------------------------------------------------------------------------------------- | ------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| [`lsh-core`](https://github.com/labodj/lsh-core)                                       | Arduino/Controllino runtime for wired controller-side logic   | [![GitHub Release](https://img.shields.io/github/v/release/labodj/lsh-core?display_name=tag\u0026sort=semver)](https://github.com/labodj/lsh-core/releases/latest) [![PlatformIO Registry](https://badges.registry.platformio.org/packages/labodj/library/lsh-core.svg)](https://registry.platformio.org/libraries/labodj/lsh-core)                |\n| [`lsh-bridge`](https://github.com/labodj/lsh-bridge)                                   | ESP32 bridge for serial LSH protocol and MQTT/Homie exposure  | [![GitHub Release](https://img.shields.io/github/v/release/labodj/lsh-bridge?display_name=tag\u0026sort=semver)](https://github.com/labodj/lsh-bridge/releases/latest) [![PlatformIO Registry](https://badges.registry.platformio.org/packages/labodj/library/lsh-bridge.svg)](https://registry.platformio.org/libraries/labodj/lsh-bridge)        |\n| [`labo-smart-home-coordinator`](https://github.com/labodj/labo-smart-home-coordinator) | Standalone orchestration runtime for CLI and Node.js services | [![GitHub Release](https://img.shields.io/github/v/release/labodj/labo-smart-home-coordinator?display_name=tag\u0026sort=semver)](https://github.com/labodj/labo-smart-home-coordinator/releases/latest) [![npm](https://img.shields.io/npm/v/labo-smart-home-coordinator.svg)](https://www.npmjs.com/package/labo-smart-home-coordinator)         |\n| [`node-red-contrib-lsh-logic`](https://github.com/labodj/node-red-contrib-lsh-logic)   | Node-RED wrapper around the coordinator runtime               | [![GitHub Release](https://img.shields.io/github/v/release/labodj/node-red-contrib-lsh-logic?display_name=tag\u0026sort=semver)](https://github.com/labodj/node-red-contrib-lsh-logic/releases/latest) [![Node-RED Library](https://img.shields.io/badge/Node--RED-Library-8f0000.svg)](https://flows.nodered.org/node/node-red-contrib-lsh-logic) |\n| [`lsh-protocol`](https://github.com/labodj/lsh-protocol)                               | Shared protocol spec, generators, and golden payloads         | [![GitHub Release](https://img.shields.io/github/v/release/labodj/lsh-protocol?display_name=tag\u0026sort=semver)](https://github.com/labodj/lsh-protocol/releases/latest)                                                                                                                                                                         |\n\nOptional Home Assistant discovery is handled outside LSH by generic Homie discovery\nprojects, not by the LSH coordinator:\n\n| Repository                                                                                                                     | Role                                         | Latest public release                                                                                                                                                                                                                                                                                                                                                                                        |\n| ------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| [`homie-home-assistant-discovery`](https://github.com/labodj/homie-home-assistant-discovery)                                   | Standalone daemon or embeddable Node.js core | [![GitHub Release](https://img.shields.io/github/v/release/labodj/homie-home-assistant-discovery?display_name=tag\u0026sort=semver)](https://github.com/labodj/homie-home-assistant-discovery/releases/latest) [![npm](https://img.shields.io/npm/v/homie-home-assistant-discovery.svg)](https://www.npmjs.com/package/homie-home-assistant-discovery)                                                            |\n| [`node-red-contrib-homie-home-assistant-discovery`](https://github.com/labodj/node-red-contrib-homie-home-assistant-discovery) | Node-RED wrapper for Homie discovery         | [![GitHub Release](https://img.shields.io/github/v/release/labodj/node-red-contrib-homie-home-assistant-discovery?display_name=tag\u0026sort=semver)](https://github.com/labodj/node-red-contrib-homie-home-assistant-discovery/releases/latest) [![Node-RED Library](https://img.shields.io/badge/Node--RED-Library-8f0000.svg)](https://flows.nodered.org/node/node-red-contrib-homie-home-assistant-discovery) |\n\nMaintained infrastructure forks are available when needed, but they are supporting code\nrather than starting points. The\n[`homie-esp8266`](https://github.com/labodj/homie-esp8266) fork is published as\n[`labodj/homie-v5`](https://registry.platformio.org/libraries/labodj/homie-v5) for\nESP8266/ESP32 Arduino projects that need Homie 3.0.1 compatibility plus opt-in Homie\nv4/v5 discovery modes. The MQTT client fork lives at\n[`async-mqtt-client`](https://github.com/labodj/async-mqtt-client).\n\n## Runtime Shape\n\n```text\n+------------------+     +------------------+     +-------------+     +-----------------------------+\n| lsh-core         |\u003c---\u003e| lsh-bridge       |\u003c---\u003e| MQTT broker |\u003c---\u003e| coordinator / Node-RED node |\n| Controllino side |     | ESP32 bridge     |     | transport   |     | orchestration               |\n+------------------+     +------------------+     +-------------+     +-----------------------------+\n```\n\nPractical boundary summary:\n\n- `lsh-core` implements wired I/O, device topology, local click handling and compact\n  payload encoding.\n- `lsh-bridge` handles the serial handshake, MQTT transport, Homie exposure, cached\n  snapshot replay and bridge-side synchronization.\n- `labo-smart-home-coordinator` maintains registry state, watchdog logic, startup\n  recovery, and distributed click orchestration.\n- `node-red-contrib-lsh-logic` runs the coordinator inside Node-RED.\n- `lsh-protocol` keeps command IDs, compact keys, compatibility metadata, and generated\n  artifacts in sync across the components.\n\nHome Assistant is not part of the LSH runtime path. If you want Home Assistant MQTT\ndiscovery, attach a generic Homie discovery daemon or Node-RED discovery node to the\nHomie topics published by `lsh-bridge`.\n\nFor the exact MQTT topics, bootstrap rules, `PING`, `BOOT`, and network-click semantics,\nread [REFERENCE_STACK.md](./REFERENCE_STACK.md).\n\n## Start Reading\n\n- Use [DOCS.md](./DOCS.md) as the public documentation map.\n- Follow [GETTING_STARTED.md](./GETTING_STARTED.md) for a first end-to-end lab setup.\n- Use [STACK_CONFIG.md](./STACK_CONFIG.md) when you want one TOML file to generate\n  bridge, coordinator and Node-RED configuration from a controller profile.\n- Keep [TROUBLESHOOTING.md](./TROUBLESHOOTING.md) nearby once real MQTT traffic and\n  hardware are involved.\n\nIf you are evaluating LSH for adoption, keep the public examples close to the stock\nconfiguration for the first successful run. Avoid changing topics, codecs, device names,\nand hardware assumptions all at once. Get a clean controller-to-bridge-to-coordinator\nchain working first, then customize one layer at a time.\n\n## Technical Direction\n\nA few design choices have stayed consistent through the years:\n\n- wired controllers first, network second\n- local logic must keep working when Wi-Fi or the broker misbehaves\n- shared protocol contracts avoid copy-pasted constants\n- resource usage matters on both AVR and ESP32 targets\n- topology is treated as static between controller boots\n\nSince `lsh-core` v3.0.0, controller topology is configured from TOML and compiled into\noptimized static profiles. New adopters typically edit `lsh_devices.toml`; a device\nprofile no longer needs hand-written C++ topology code or hand-maintained actuator ID\nlookup tables.\n\nThe public stack composer adds the deployment layer on top of that controller profile.\n`lsh_stack.toml` keeps MQTT codec choices, Node-RED context exports and distributed\nnetwork-click actor targets outside the firmware TOML, while still generating the\nbridge/coordinator contract and exact Node-RED node settings. It also emits PlatformIO\nfragments for per-device controller environments and stack-wide bridge firmware\nprofiles, so every bridge device can run the same selected bridge binary while keeping\ndevice-specific uploads as IDE targets.\n\nThe normal starting point is one personal installation folder with two normal PlatformIO\nprojects inside it:\n\nIf `lsh-stack` is already installed:\n\n```bash\nlsh-stack new my-lsh-installation\ncd my-lsh-installation\nlsh-stack setup\n```\n\nFrom a GitHub Release, you can use the single-file launcher without checking out this\nrepository:\n\n```bash\npython /path/to/lsh-stack.pyz new my-lsh-installation\ncd my-lsh-installation\npython /path/to/lsh-stack.pyz setup\n```\n\nFrom a checkout of this repository, use the standard Python launcher script. On Windows,\nuse `py` instead of `python` if that is how Python is installed:\n\n```bash\npython /path/to/labo-smart-home/lsh-stack.py new my-lsh-installation\ncd my-lsh-installation\npython /path/to/labo-smart-home/lsh-stack.py setup\n```\n\nIf you only want to evaluate or build `lsh-core` firmware first, create a standalone\ncontroller project instead of the whole stack:\n\n```bash\nlsh-stack new-core my-lsh-core\ncd my-lsh-core\nplatformio run -e core_panel\n```\n\n`new` writes `core/platformio.ini` and `bridge/platformio.ini` once, then leaves those\nmanual files alone. If you already have only `lsh_stack.toml` and `lsh_devices.toml`,\n`setup` creates the missing core/bridge PlatformIO shells beside them without\noverwriting existing project files. Use either VSCode with the PlatformIO extension or\nthe `platformio` CLI if it is available. The `setup` command runs the normal first-use\nsequence: it installs/builds the starter core once when the PlatformIO CLI is available,\nregenerates `generated/`, checks the stack and prints the next build targets. The\nlower-level `generate` command still replaces only the files in `generated/`.\n\nRun `lsh-stack status` whenever you are unsure what has already been generated or which\ncommand should come next. It does not build firmware or rewrite files.\n\nFor local or symlinked controller checkouts, set `[core].tool`; generated controller\nenvironments then use the matching local `platformio_lsh_static_config.py` instead of a\n`.pio/libdeps` path.\n\nEdit `core/lsh_devices.toml` and `lsh_stack.toml`; treat `generated/` as disposable;\nkeep persistent manual extensions in `overrides/` or in the `core/` and `bridge/`\nPlatformIO files.\n\nFor Node-RED, install `node-red-contrib-lsh-logic`, add the node to a flow and follow\n`generated/node-red-setup.md`. The generator gives exact copy-paste values for the\n`lsh-logic` node, while MQTT broker settings and the surrounding flow stay in Node-RED.\n\nFor bridge builds and uploads, use the generated PlatformIO environments from the IDE or\nCLI. Profile tasks such as `bridge_littlefs` build one wide firmware shared by every\nbridge device. The same profile exposes `LSH OTA j1`, `LSH OTA j2` and `LSH OTA All`\ncustom targets for Homie/MQTT OTA in the PlatformIO IDE. For CLI use, the stack command\ncan build the default bridge profile and OTA-upload one device, a subset, or every\nbridge:\n\n```bash\nlsh-stack ota j1\nlsh-stack ota j1 j2\nlsh-stack ota\n```\n\nIf a prerequisite is missing, the command exits with the install command to run.\n\n## Public History\n\nLSH did not begin as a clean public multi-repo design. Early versions were much more\nmonolithic, and a lot of automation logic lived in large Node-RED flows. Over time, the\nproject was split into reusable pieces: controller runtime, ESP32 bridge runtime,\nprotocol source of truth, standalone coordinator and a thin Node-RED wrapper.\n\nThe repositories were published after years of real-world use, refactoring and cleanup.\nThis repository remains the reference-stack entry point, not a runtime peer like\n`lsh-core` or `lsh-bridge`. Its active software surface is intentionally small: the\n`lsh-stack` composer and the quality gates around the public documentation and examples.\nComponent release history still lives in the runtime repositories listed above.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flabodj%2Flabo-smart-home","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flabodj%2Flabo-smart-home","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flabodj%2Flabo-smart-home/lists"}