diff --git a/NOTEPAD.md b/NOTEPAD.md index 9748dca..15f5794 100644 --- a/NOTEPAD.md +++ b/NOTEPAD.md @@ -86,6 +86,16 @@ Deferring because out of scope is fine, but don't mention deferring than. `crypto.hash is not a function` — Vite 7 wants Node 20.12+ and the host has 18. The Docker image builds fine, so it only bites local bundling; `bunx tsc` still type-checks. +- FEAT/NODE: the connectors only read. Enable the write paths with someone watching: + WF-RAC `setAirconStat` (needs an operatorId registered with the unit first, which is + itself a write) and Art-Net `transmit`. +- FEAT/NODE: the second WF-RAC unit (the one Node-RED addresses with operatorId "0") + closes the connection on an anonymous read. It likely wants an account registered; + the first unit answers without one. +- CHORE/NODE: `wfrac` reports `mode` as "unknown" while the unit is off, because the + mode bits hold a value outside the known set. Faithful to the reference decoder, but + "off" would read better. + ## Blocked - FEAT/UI: a "Bug" icon on the node error bubble opening the logs panel at that node's diff --git a/ROADMAP.md b/ROADMAP.md index 1ceb4ee..ff8bb02 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -52,6 +52,11 @@ external interfaces. See `docs/architecture/structure.canvas` → *Backend – M packages found through the `fluksio.node_types` entry point group; the contract is documented in `docs/connectors/` with a working skeleton at `connector-skeleton/`. The registry follows later +- [x] First real connectors written against that contract from outside the engine: + WF-RAC aircon, calendar, UniFi presence and Art-Net, in `connectors/`. + Built by `make connectors` and installed into the image. Reading only for + now — the aircon package cannot produce a command and Art-Net keeps its + packets off the wire until `transmit` is switched on - [x] Node lifecycle as a protocol (`start`/`stop`/`report_health` on `Node`), replacing the controller's per-type isinstance chains — the same hooks a connector implements, validated on the built-in nodes first diff --git a/backend/Dockerfile b/backend/Dockerfile index aed3f72..661ff24 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -40,6 +40,15 @@ RUN --mount=type=cache,target=/root/.cache/uv \ --mount=type=bind,source=pyproject.toml,target=pyproject.toml \ uv sync --frozen --package app +# Connectors are ordinary installed packages found through the +# `fluksio.node_types` entry point. `make connectors` builds them into here; +# an image with none is the normal case. +COPY ./backend/connector-wheels /tmp/connector-wheels +RUN --mount=type=cache,target=/root/.cache/uv \ + sh -c 'ls /tmp/connector-wheels/*.whl >/dev/null 2>&1 \ + && uv pip install --python /app/.venv/bin/python /tmp/connector-wheels/*.whl \ + || echo "no connectors bundled"' + WORKDIR /app/backend/ # Single worker on purpose: the process hosts the flow engine, and a second diff --git a/backend/connector-wheels/.gitignore b/backend/connector-wheels/.gitignore new file mode 100644 index 0000000..704d307 --- /dev/null +++ b/backend/connector-wheels/.gitignore @@ -0,0 +1 @@ +*.whl diff --git a/backend/connector-wheels/.gitkeep b/backend/connector-wheels/.gitkeep new file mode 100644 index 0000000..11a9083 --- /dev/null +++ b/backend/connector-wheels/.gitkeep @@ -0,0 +1,3 @@ +Connector wheels built by `make connectors` at the workspace root land here and +are installed into the image. Kept empty in git: a connector is an installed +package, not part of the app.