No description
  • Go 64.8%
  • TypeScript 32.9%
  • CSS 1.1%
  • Dockerfile 0.6%
  • JavaScript 0.3%
  • Other 0.3%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
nick f3e565b736
All checks were successful
CI/CD / Go vet, lint & test (push) Successful in 1m7s
CI/CD / Frontend lint, typecheck & build (push) Successful in 15s
CI/CD / Build & push control-center image (push) Successful in 36s
CI/CD / Deploy to Dockhand (push) Successful in 14s
Merge pull request 'feat: home dashboard — Node-RED Funktionen als Control-Center-Integration' (#1) from feature/nodered-integration into main
2026-09-21 23:57:01 +02:00
.forgejo/workflows feat: control center — Go/PocketBase MQTT bridge + React/shadcn dashboard (door sensor first) 2026-09-20 18:24:52 +02:00
backend feat: home dashboard — heating, lights, washer, weather, NOAH, door alerts 2026-09-21 23:55:02 +02:00
docker feat: home dashboard — heating, lights, washer, weather, NOAH, door alerts 2026-09-21 23:55:02 +02:00
frontend feat: home dashboard — heating, lights, washer, weather, NOAH, door alerts 2026-09-21 23:55:02 +02:00
.gitignore feat: control center — Go/PocketBase MQTT bridge + React/shadcn dashboard (door sensor first) 2026-09-20 18:24:52 +02:00
.mise.toml feat: control center — Go/PocketBase MQTT bridge + React/shadcn dashboard (door sensor first) 2026-09-20 18:24:52 +02:00
README.md feat: control center — Go/PocketBase MQTT bridge + React/shadcn dashboard (door sensor first) 2026-09-20 18:24:52 +02:00

control-center

Home control center for the Z-Wave network: a live dashboard of all nodes (currently: the door sensor with open/closed state, node status, last activity, and temperature).

Public: https://control-center.barbara8.de (auth required; default accounts admin@barbara8.de / user@barbara8.de, passwords seeded as Dockhand stack secrets)

Architecture

zwave-js-ui (narrow) ──publish──▶ mosquitto (narrow, tcp://100.113.11.77:1883, topic zwave/#)
                                        │  (Tailscale)
                                        ▼
                          control-center (UM890, one container)
                          ├─ Go + embedded PocketBase
                          │   ├─ MQTT bridge: parses zwave-js-ui topics,
                          │   │   learns topic-ref → node-id from `status`,
                          │   │   upserts `zwave_nodes` records
                          │   ├─ REST API: /api/nodes, /api/nodes/{id}, /api/me,
                          │   │   /api/system (auth via PocketBase tokens)
                          │   └─ serves the React SPA statically
                          └─ React 19 + Vite + Tailwind v4 + shadcn/ui
                              (bun toolchain, 5 s polling)
  • Topic model (zwave-js-ui): zwave/<loc>/<name>/…, zwave/<name>/… or zwave/nodeID_<id>/…. Only the …/status topic carries the node id, so the bridge learns a ref→node-id map and resolves everything else against it; value topics that arrive before their node's status (initial retained burst) are buffered per ref and flushed on learn.
  • Door state: Access Control CC (113) Door_state_simple / Door_state; 22 (0x16) = open, 23 (0x17) = closed (zwave-js enum DoorState).
  • Data: PocketBase collections are rule-denied; access is exclusively through the authenticated custom API. Migrations are Go code (backend/migrations/, run on boot).
  • Secrets: ADMIN_PASSWORD / USER_PASSWORD are Dockhand stack secrets (isSecret:true, seeded once out-of-band). CI only ever sends the non-secret image ref.

Layout

backend/      Go service (DDD layout: domain / application / infrastructure)
frontend/     React SPA (bun, Vite, Tailwind v4, shadcn/ui in src/components/ui)
docker/       Dockerfile (multi-stage), docker-compose.yml (stack source of
              truth), deploy.ts (two-step Dockhand deployer), entrypoint.sh
docs/         (API notes)

Local development

# backend (needs a reachable MQTT broker)
cd backend
go test ./...
ADMIN_PASSWORD=x USER_PASSWORD=y MQTT_URL=tcp://100.113.11.77:1883 \
  go run ./cmd/server serve --http 127.0.0.1:8080

# frontend (proxies /api to :8080)
cd frontend
bun install
bun run dev

Deployment

Pattern D (see ../AGENTS.md): CI builds the single image code.schwanke.it/home/control-center/control-center:<sha> and deploys the control-center Dockhand stack on UM890 (env 3) via docker/deploy.ts. Ingress: control-center.barbara8.de (Caddy on narrow via the caddy-ingress-controller labels in the compose).

First-time bootstrap (done): the stack + its two secret env vars were seeded out-of-band via the Dockhand API before the first CI deploy.