From 9d14dc7feccd77a053995bfe3180b5c2df43d007 Mon Sep 17 00:00:00 2001 From: CyberMind-FR Date: Mon, 29 Dec 2025 16:42:25 +0100 Subject: [PATCH] zigbee2mqtt: enhance installer and add docs --- DOCS/embedded/zigbee2mqtt-docker.md | 128 ++++++++++++++++++ docs/ARCHITECTURE_NOTES.md | 86 +++++++++++- docs/embedded/zigbee2mqtt-docker.md | 128 ++++++++++++++++++ secubox-app-zigbee2mqtt/Makefile | 2 +- .../files/usr/sbin/zigbee2mqttctl | 24 +++- 5 files changed, 364 insertions(+), 4 deletions(-) create mode 100644 DOCS/embedded/zigbee2mqtt-docker.md create mode 100644 docs/embedded/zigbee2mqtt-docker.md diff --git a/DOCS/embedded/zigbee2mqtt-docker.md b/DOCS/embedded/zigbee2mqtt-docker.md new file mode 100644 index 00000000..69d6af9e --- /dev/null +++ b/DOCS/embedded/zigbee2mqtt-docker.md @@ -0,0 +1,128 @@ +# Docker Zigbee2MQTT on OpenWrt ARM64 + +**Version:** 1.0.0 +**Last Updated:** 2025-12-28 +**Status:** Active + +This guide explains how to deploy the SecuBox Zigbee2MQTT “app” (Docker-based) on OpenWrt ARM64 targets. It uses the `secubox-app-zigbee2mqtt` package (installer, CLI, procd service) together with the LuCI frontend (`luci-app-zigbee2mqtt`). + +--- + +## Prerequisites + +1. **OpenWrt 24.10.x ARM64** (ESPRESSObin, MOCHAbin, RPi4, etc.) with ≥ 256 MB free storage (Docker image + data dir). +2. **Kernel features**: cgroups (`/sys/fs/cgroup`), USB CDC ACM (`kmod-usb-acm`). +3. **Hardware**: Zigbee coordinator presented as `/dev/ttyACM0` (e.g., SONOFF ZBDongle-E/MG21). +4. **Network**: Reachable MQTT broker (local Mosquitto or remote `mqtt://host:1883`). +5. **Package feeds**: `docker`, `dockerd`, `containerd` available (`opkg update`). + +--- + +## Installation Steps + +```sh +opkg update +opkg install secubox-app-zigbee2mqtt luci-app-zigbee2mqtt +``` + +1. **Run prerequisite installer** (checks storage, cgroups, USB, installs Docker, pulls image, enables service): + ```sh + zigbee2mqttctl install + ``` +2. **Start the service**: + ```sh + /etc/init.d/zigbee2mqtt start # enable automatically via installer + ``` +3. **LuCI configuration** (optional UI flow): Services → SecuBox → Zigbee2MQTT. Adjust serial port, MQTT host/credentials, base topics, etc., then click “Apply”. + +The installer writes persistent data under `/srv/zigbee2mqtt/data` (config + DB) and exposes the Zigbee2MQTT web UI on port `8080` by default. + +--- + +## Command-Line Reference (`/usr/sbin/zigbee2mqttctl`) + +| Command | Description | +|---------|-------------| +| `install` | Full prerequisite setup (Docker packages, data dir, image pull, enable service). | +| `check` | Rerun prerequisite checks (storage, cgroups, USB module, serial device). | +| `update` | Pull the latest Zigbee2MQTT image and restart the enabled service. | +| `status` | Show Docker container status (`docker ps` filter). | +| `logs [-f]` | Stream Docker logs for the container. | +| `service-run` / `service-stop` | Internal commands used by the procd init script; not for manual invocation. | + +All commands must be run as root. + +--- + +## UCI Configuration (`/etc/config/zigbee2mqtt`) + +```uci +config zigbee2mqtt 'main' + option enabled '1' + option serial_port '/dev/ttyACM0' + option mqtt_host 'mqtt://127.0.0.1:1883' + option mqtt_username '' + option mqtt_password '' + option base_topic 'zigbee2mqtt' + option frontend_port '8080' + option channel '11' + option image 'ghcr.io/koenkk/zigbee2mqtt:latest' + option data_path '/srv/zigbee2mqtt' + option timezone 'UTC' +``` + +Edit via `uci` or the LuCI form; commit changes to restart automatically: +```sh +uci set zigbee2mqtt.main.mqtt_host='mqtt://192.168.1.10:1883' +uci commit zigbee2mqtt +/etc/init.d/zigbee2mqtt restart +``` + +--- + +## Validation & Smoke Tests + +- Quick prerequisite check: + ```sh + zigbee2mqttctl check + ``` +- Repository smoke test (runs service start/stop + optional MQTT pub/sub): + ```sh + ./scripts/smoke_test.sh + ``` +- Diagnostics bundle (general SecuBox): + ```sh + ./scripts/diagnose.sh + ``` + +--- + +## Troubleshooting + +| Symptom | Resolution | +|---------|------------| +| `zigbee2mqttctl install` reports “/sys/fs/cgroup missing” | Enable cgroups in kernel config or upgrade to a build with cgroup support. | +| USB coordinator not detected | Ensure `kmod-usb-acm` is installed, `cdc_acm` module loaded (`lsmod | grep cdc_acm`), and device appears under `/dev/ttyACM*`. Replug the dongle. | +| Docker not starting | Check `/etc/init.d/dockerd status`. If `docker info` fails, inspect `/var/log/messages` for storage driver errors. | +| MQTT authentication failures | Set `mqtt_username`/`mqtt_password` via UCI or LuCI and restart the service. | +| Port 8080 already used | Change `frontend_port` in UCI, commit, restart service. Update vhost mappings accordingly. | + +--- + +## Uninstall / Cleanup + +```sh +/etc/init.d/zigbee2mqtt stop +/etc/init.d/zigbee2mqtt disable +docker rm -f secbx-zigbee2mqtt 2>/dev/null +opkg remove luci-app-zigbee2mqtt secubox-app-zigbee2mqtt +rm -rf /srv/zigbee2mqtt +``` + +--- + +## Next Steps + +- Use `luci-app-vhost-manager` to publish the Zigbee2MQTT UI under HTTPS (see `luci-app-vhost-manager/README.md`). +- Integrate with the forthcoming SecuBox App Store by adding a manifest entry referencing this installer. +- Combine with profiles/wizards once those components are introduced per the project roadmap. diff --git a/docs/ARCHITECTURE_NOTES.md b/docs/ARCHITECTURE_NOTES.md index 5d4ea839..d1434ae1 100644 --- a/docs/ARCHITECTURE_NOTES.md +++ b/docs/ARCHITECTURE_NOTES.md @@ -4,4 +4,88 @@ **Last Updated:** 2025-12-28 **Status:** Active -This file mirrors the architecture summary maintained in `DOCS/ARCHITECTURE_NOTES.md`. See that copy for the canonical version. +These notes capture the current repository structure, conventions, and supporting tooling after scanning the tree (`luci-app-*`, `secubox-tools/`, `secubox-app-*`, `scripts/`), the root `README.md`, and the docs set (`docs/`, `DOCS/`, `TODO-ANALYSE.md`, `secubox-tools/README.md`, `scripts/README.md`, `docs/module-status.md`, `docs/claude.md`, `docs/documentation-index.md`). Treat this file as the canonical orientation guide before extending the platform. + +--- + +## 1. Repository Layout + +- **LuCI applications (`luci-app-*`)** + Each module ships a LuCI frontend (`htdocs/luci-static/resources/...`), RPCD backend (POSIX shell in `root/usr/libexec/rpcd/luci.`), menu + ACL JSON, optional CSS, and a module-specific README. Views follow the “menu path == file path” rule stressed in the documentation. + +- **Device/service packages (`secubox-app-*`)** + Native packages that install supporting services or CLIs (e.g., `secubox-app-zigbee2mqtt` installs `/etc/config/zigbee2mqtt`, `/etc/init.d/zigbee2mqtt`, and `/usr/sbin/zigbee2mqttctl`). These expose helpers that LuCI apps consume. + +- **Themes & shared assets** + `luci-theme-secubox` carries the design system (dark palette, `sh-*`/`sb-*` classes, Inter + JetBrains Mono). Every LuCI view imports `secubox-theme/secubox-theme.css` plus module-specific CSS as needed. + +- **Tooling (`secubox-tools/`)** + Contains validation (`validate-modules.sh`), build automation (`local-build.sh`), permission repair, deployment helpers, and debug loggers. These scripts mirror GitHub Actions workflows and should be reused for any new installer/test tooling. + +- **Automation/scripts (`scripts/`)** + Hosts documentation publishing helpers plus existing diagnostics/smoke scripts. New repo-wide diagnostics should live alongside them. + +- **Docs** + Two mirrored trees (`docs/` and uppercase `DOCS/`) feed MkDocs and the GitHub wiki. All Markdown follows the metadata template defined in `docs/documentation-index.md`. + +--- + +## 2. Target Platforms & Build System + +- **Supported OpenWrt targets:** ARM64 (aarch64-cortex-a53/a72/generic), x86_64, and legacy MIPS variants (per `secubox-tools/local-build.sh` + README badges). +- **Package formats:** `.ipk` for ≤24.10, `.apk` for 25.12/SNAPSHOT (handled automatically by `local-build.sh`). +- **CI:** GitHub workflows (`.github/workflows/build-openwrt-packages.yml`, `test-validate.yml`) validate and build all modules. Local parity is achieved via `secubox-tools/local-build.sh full`. +- **Validation:** `./secubox-tools/validate-modules.sh` runs seven structural checks (RPC naming, menu/view parity, permissions, JSON lint, etc.). `fix-permissions.sh` enforces 755 for RPCD scripts and 644 for CSS/JS. + +--- + +## 3. Configuration & Runtime Patterns + +- **UCI-first approach:** Every feature stores runtime state in `/etc/config/`. CLIs/editors mutate entries via `uci set/commit`, and procd services read from UCI (see `secubox-app-zigbee2mqtt` or `luci-app-vhost-manager`). +- **Service supervision:** Daemons use `/etc/init.d/` with `USE_PROCD=1`. Procd wrappers call helper CLIs (e.g., `/usr/sbin/zigbee2mqttctl service-run`). +- **RPCD backends:** Implemented in POSIX shell. Filename equals ubus object (`root/usr/libexec/rpcd/luci.zigbee2mqtt` => `object: 'luci.zigbee2mqtt'`). They orchestrate UCI, system utilities, Docker, etc. +- **LuCI frontends:** Built with `view.extend` and the SecuBox design components (stat cards, tab strips, forms). Each module includes `api.js` wrappers that call the matching ubus object. Auto-refresh uses `poll()` or manual timers. +- **Logging/diagnostics:** `secubox-log` helper aggregates module activity under `/var/log/seccubox.log`. Additional repo-wide diagnostics live under `scripts/diagnose.sh`. + +--- + +## 4. Network & Security Conventions + +- **Firewall & zones:** Modules such as `luci-app-client-guardian` and `luci-app-network-modes` manipulate UCI firewall sections. They always backup configs before applying and keep the LAN management path reachable. +- **Network modes:** `luci-app-network-modes` already models router/relay/AP/sniffer modes with wizards + rollback. Any future “profile” or “DMZ” work should reuse its UCI techniques and UI flow. +- **Reverse proxy:** `luci-app-vhost-manager` manages `/etc/config/vhosts`, renders nginx configs, handles basic auth, and integrates ACME. It is the baseline for any new vhost/TLS features. +- **Access control:** ACL JSON lives in `root/usr/share/rpcd/acl.d/`. `docs/permissions-guide.md` plus `DOCS/CODEX.md` enumerate the ubus permissions each module should request. + +--- + +## 5. Existing App Ecosystem (Snapshot) + +From `docs/module-status.md` and module READMEs: + +- **Core dashboards:** `luci-app-secubox`, `luci-app-system-hub`. +- **Security/monitoring:** CrowdSec, Netdata, Netifyd, WireGuard, Client Guardian, Auth Guardian. +- **Network orchestration:** Network Modes, Traffic Shaper, Bandwidth Manager, Media Flow, CDN Cache. +- **Device apps:** Zigbee2MQTT already ships as `secubox-app-zigbee2mqtt` + `luci-app-zigbee2mqtt`. +- **Reverse proxy:** `luci-app-vhost-manager`. + +These modules provide working references for RPC patterns, UI layouts, wizards, and integration with system services. + +--- + +## 6. Documentation Standards & Roadmap + +- Every Markdown file must include `Version/Last Updated/Status` headers (per `docs/documentation-index.md` and `TODO-ANALYSE.md`). +- Cross-link related docs (Quick Start ↔ Development Guidelines ↔ Codex). +- Archive stale docs under `docs/archive/`. +- `TODO-ANALYSE.md` tracks ongoing documentation work (version standardization, cross-references, architecture diagrams). Keep this file updated when touching docs. + +--- + +## 7. Key Takeaways for Future Work + +1. **Extend, don’t fork:** Build new features (Docker apps, App Store, wizard, DMZ mode) on top of existing packages (Zigbee2MQTT installer, Network Modes, VHost Manager) instead of introducing parallel systems. +2. **Reuse tooling:** Diagnostics, smoke tests, and installers should hook into `secubox-tools/` or `scripts/` so they can be invoked locally and in CI. +3. **Stay POSIX + UCI driven:** Shell scripts, UCI config, and procd remain the glue for Docker/LXC orchestration on resource-constrained routers. +4. **Document everything twice:** Update both `docs/` (MkDocs) and `DOCS/` (wiki) trees when adding guides such as the requested embedded notes. + +These notes should be revised whenever new components (App Store, wizard, profiles, DMZ, Docker/LXC frameworks) land so contributors always have an up-to-date architectural map. diff --git a/docs/embedded/zigbee2mqtt-docker.md b/docs/embedded/zigbee2mqtt-docker.md new file mode 100644 index 00000000..69d6af9e --- /dev/null +++ b/docs/embedded/zigbee2mqtt-docker.md @@ -0,0 +1,128 @@ +# Docker Zigbee2MQTT on OpenWrt ARM64 + +**Version:** 1.0.0 +**Last Updated:** 2025-12-28 +**Status:** Active + +This guide explains how to deploy the SecuBox Zigbee2MQTT “app” (Docker-based) on OpenWrt ARM64 targets. It uses the `secubox-app-zigbee2mqtt` package (installer, CLI, procd service) together with the LuCI frontend (`luci-app-zigbee2mqtt`). + +--- + +## Prerequisites + +1. **OpenWrt 24.10.x ARM64** (ESPRESSObin, MOCHAbin, RPi4, etc.) with ≥ 256 MB free storage (Docker image + data dir). +2. **Kernel features**: cgroups (`/sys/fs/cgroup`), USB CDC ACM (`kmod-usb-acm`). +3. **Hardware**: Zigbee coordinator presented as `/dev/ttyACM0` (e.g., SONOFF ZBDongle-E/MG21). +4. **Network**: Reachable MQTT broker (local Mosquitto or remote `mqtt://host:1883`). +5. **Package feeds**: `docker`, `dockerd`, `containerd` available (`opkg update`). + +--- + +## Installation Steps + +```sh +opkg update +opkg install secubox-app-zigbee2mqtt luci-app-zigbee2mqtt +``` + +1. **Run prerequisite installer** (checks storage, cgroups, USB, installs Docker, pulls image, enables service): + ```sh + zigbee2mqttctl install + ``` +2. **Start the service**: + ```sh + /etc/init.d/zigbee2mqtt start # enable automatically via installer + ``` +3. **LuCI configuration** (optional UI flow): Services → SecuBox → Zigbee2MQTT. Adjust serial port, MQTT host/credentials, base topics, etc., then click “Apply”. + +The installer writes persistent data under `/srv/zigbee2mqtt/data` (config + DB) and exposes the Zigbee2MQTT web UI on port `8080` by default. + +--- + +## Command-Line Reference (`/usr/sbin/zigbee2mqttctl`) + +| Command | Description | +|---------|-------------| +| `install` | Full prerequisite setup (Docker packages, data dir, image pull, enable service). | +| `check` | Rerun prerequisite checks (storage, cgroups, USB module, serial device). | +| `update` | Pull the latest Zigbee2MQTT image and restart the enabled service. | +| `status` | Show Docker container status (`docker ps` filter). | +| `logs [-f]` | Stream Docker logs for the container. | +| `service-run` / `service-stop` | Internal commands used by the procd init script; not for manual invocation. | + +All commands must be run as root. + +--- + +## UCI Configuration (`/etc/config/zigbee2mqtt`) + +```uci +config zigbee2mqtt 'main' + option enabled '1' + option serial_port '/dev/ttyACM0' + option mqtt_host 'mqtt://127.0.0.1:1883' + option mqtt_username '' + option mqtt_password '' + option base_topic 'zigbee2mqtt' + option frontend_port '8080' + option channel '11' + option image 'ghcr.io/koenkk/zigbee2mqtt:latest' + option data_path '/srv/zigbee2mqtt' + option timezone 'UTC' +``` + +Edit via `uci` or the LuCI form; commit changes to restart automatically: +```sh +uci set zigbee2mqtt.main.mqtt_host='mqtt://192.168.1.10:1883' +uci commit zigbee2mqtt +/etc/init.d/zigbee2mqtt restart +``` + +--- + +## Validation & Smoke Tests + +- Quick prerequisite check: + ```sh + zigbee2mqttctl check + ``` +- Repository smoke test (runs service start/stop + optional MQTT pub/sub): + ```sh + ./scripts/smoke_test.sh + ``` +- Diagnostics bundle (general SecuBox): + ```sh + ./scripts/diagnose.sh + ``` + +--- + +## Troubleshooting + +| Symptom | Resolution | +|---------|------------| +| `zigbee2mqttctl install` reports “/sys/fs/cgroup missing” | Enable cgroups in kernel config or upgrade to a build with cgroup support. | +| USB coordinator not detected | Ensure `kmod-usb-acm` is installed, `cdc_acm` module loaded (`lsmod | grep cdc_acm`), and device appears under `/dev/ttyACM*`. Replug the dongle. | +| Docker not starting | Check `/etc/init.d/dockerd status`. If `docker info` fails, inspect `/var/log/messages` for storage driver errors. | +| MQTT authentication failures | Set `mqtt_username`/`mqtt_password` via UCI or LuCI and restart the service. | +| Port 8080 already used | Change `frontend_port` in UCI, commit, restart service. Update vhost mappings accordingly. | + +--- + +## Uninstall / Cleanup + +```sh +/etc/init.d/zigbee2mqtt stop +/etc/init.d/zigbee2mqtt disable +docker rm -f secbx-zigbee2mqtt 2>/dev/null +opkg remove luci-app-zigbee2mqtt secubox-app-zigbee2mqtt +rm -rf /srv/zigbee2mqtt +``` + +--- + +## Next Steps + +- Use `luci-app-vhost-manager` to publish the Zigbee2MQTT UI under HTTPS (see `luci-app-vhost-manager/README.md`). +- Integrate with the forthcoming SecuBox App Store by adding a manifest entry referencing this installer. +- Combine with profiles/wizards once those components are introduced per the project roadmap. diff --git a/secubox-app-zigbee2mqtt/Makefile b/secubox-app-zigbee2mqtt/Makefile index e60e1c82..6c7cd3d0 100644 --- a/secubox-app-zigbee2mqtt/Makefile +++ b/secubox-app-zigbee2mqtt/Makefile @@ -1,7 +1,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=secubox-app-zigbee2mqtt -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_VERSION:=1.0.0 PKG_MAINTAINER:=CyberMind Studio PKG_LICENSE:=Apache-2.0 diff --git a/secubox-app-zigbee2mqtt/files/usr/sbin/zigbee2mqttctl b/secubox-app-zigbee2mqtt/files/usr/sbin/zigbee2mqttctl index 7607081a..91677bee 100644 --- a/secubox-app-zigbee2mqtt/files/usr/sbin/zigbee2mqttctl +++ b/secubox-app-zigbee2mqtt/files/usr/sbin/zigbee2mqttctl @@ -8,6 +8,10 @@ CONFIG="zigbee2mqtt" CONTAINER="secbx-zigbee2mqtt" OPKG_UPDATED=0 +warn() { printf '[WARN] %s\n' "$*" >&2; } +info() { printf '[INFO] %s\n' "$*"; } +err() { printf '[ERROR] %s\n' "$*" >&2; } + usage() { cat <<'EOF' Usage: zigbee2mqttctl @@ -99,6 +103,9 @@ check_prereqs() { check_cgroups || return 1 check_serial "$serial_port" ensure_packages kmod-usb-acm || return 1 + if ! lsmod 2>/dev/null | grep -q 'cdc_acm'; then + warn "cdc_acm kernel module is not loaded; USB coordinator may not be detected." + fi return 0 } @@ -106,6 +113,9 @@ ensure_docker() { ensure_packages containerd docker dockerd || return 1 /etc/init.d/dockerd enable >/dev/null 2>&1 /etc/init.d/dockerd start >/dev/null 2>&1 + if ! docker info >/dev/null 2>&1; then + warn "Docker daemon not ready yet. Retry once dockerd has finished starting." + fi } generate_configuration() { @@ -146,13 +156,15 @@ cmd_install() { ensure_dir "$data_path" generate_configuration pull_image + uci set ${CONFIG}.main.enabled='1' + uci commit ${CONFIG} /etc/init.d/zigbee2mqtt enable - echo "Zigbee2MQTT prerequisites installed. Enable with: /etc/init.d/zigbee2mqtt start" + info "Installation complete. Start with: /etc/init.d/zigbee2mqtt start" } cmd_check() { check_prereqs - echo "Prerequisite check completed." + info "Prerequisite check completed." } cmd_update() { @@ -167,10 +179,18 @@ cmd_update() { } cmd_status() { + if ! command -v docker >/dev/null 2>&1; then + err "docker command missing. Run zigbee2mqttctl install first." + return 1 + fi docker ps -a --filter "name=$CONTAINER" } cmd_logs() { + if ! command -v docker >/dev/null 2>&1; then + err "docker command missing." + return 1 + fi docker logs "$@" "$CONTAINER" }