Skip to content

MQTT support with Home Assistant discovery (optional)#6

Merged
sethpjohnson merged 1 commit into
mainfrom
claude/mqtt-ha-support
Jul 17, 2026
Merged

MQTT support with Home Assistant discovery (optional)#6
sethpjohnson merged 1 commit into
mainfrom
claude/mqtt-ha-support

Conversation

@sethpjohnson

Copy link
Copy Markdown
Owner

Summary

Stacked on #5 (→ #4#3#2#1) — the sixth and final PR in the stack; merge in order. Off by default: setting nothing changes existing behavior.

Publishes controller status to MQTT and accepts commands, so the R730's fan state appears in Home Assistant as a self-registered device with full control parity.

  • Decoupled bridge (internal/mqtt, paho) consuming the same controller methods the HTTP API uses — so MQTT commands inherit every safety rule from the earlier tiers: min/max clamping, 24h override cap, critical-temp ramp override, hint validation. The controller package stays MQTT-unaware.
  • A flaky broker can't touch cooling: connect is fire-and-forget, publish/subscribe/stop are bounded (2s), and bridge teardown is sequenced after the Tier 1 BMC restore with a 3s bound. Verified live: SIGINT shows restore → MQTT teardown → exit in ~11ms.
  • HA Discovery: one device, 11 entities (6 sensors, 3 binary sensors, an override-speed number bounded to your configured min/max, a clear-override button), retained and republished on reconnect.
  • Per-tick retained state + Last Will: HA marks the device unavailable the instant the process dies — a free monitor for the fail-safe scenarios.
  • Shared validation: internal/validate extracted from the HTTP layer (verified byte-for-byte lossless) so HTTP and MQTT enforce identical rules. Retained command messages are dropped (logged once/topic) so a stray mosquitto_pub -r can't replay a stale command on every restart.

Review & verification

  • Principal review → APPROVED WITH SUGGESTIONS, then the one High-Priority item (retained-command replay) fixed pre-landing and APPROVED on a confirmation re-review (reviewer traced paho source to confirm the Retain bit is independent of Dup — the drop can never false-positive on a live command).
  • go vet + go test -race clean across all 8 packages; integration test drives a real paho client against a real in-process mochi broker (connect→discovery→command→state→LWT + retained-drop), stable across repeated runs.
  • Acceptance: PASS 9/9 live against a running broker — including a 100→80 clamped command round-trip, retained-drop across a restart, LWT on SIGKILL, and restore-before-teardown shutdown ordering.
  • Follow-ups filed: dex f5u9g234 (topic charset validation, shared WorkloadHint constructor, Subscribe-timeout retry).

⚠️ Security note (also in the README): MQTT command authority = broker access. Anyone who can publish to your broker can command the fans — use broker credentials/ACLs. Blast radius stays bounded by the controller-level clamps and the critical-temp override. No TLS in v1.

Task: dex e6fla2yl — MQTT / Home Assistant support

🤖 Generated with Claude Code

Publishes controller status to MQTT and accepts commands, so the R730's
fan state appears in Home Assistant as a self-registered device. Off by
default; zero behavior change when disabled.

- New internal/mqtt bridge (paho) consuming the same controller methods
  the HTTP API uses (GetStatus/SetOverride/ClearOverride/AddHint/
  RemoveHint), so MQTT commands inherit all safety rules: min/max
  clamping, 24h override cap, critical-temp ramp override, hint
  validation. The controller package stays MQTT-unaware.
- MQTT Discovery: one HA device with 11 entities (6 sensors, 3 binary
  sensors, an override-speed number bounded to min/max, a clear-override
  button), retained config republished on every (re)connect.
- Per-tick retained state JSON on monitoring.interval; availability topic
  with Last Will so HA marks the device unavailable the instant the
  process dies.
- Command topics (override/clear/hint, QoS 1) validated by a shared
  internal/validate package extracted from the HTTP layer so both
  enforce identical rules. Retained command messages are dropped (logged
  once per topic) to avoid stale commands replaying on reconnect.
- A hung or unreachable broker can never block the control loop or delay
  the shutdown restore(): connect is fire-and-forget, publish/subscribe/
  stop are bounded, and bridge teardown is sequenced after the BMC
  hand-back with a 3s bound.
- Config: mqtt section (default off, broker required when enabled,
  password json:"-", env overrides); README HA section; Unraid template
  MQTT fields; config.example.yaml documents the block and validates
  verbatim.

Design + plan: docs/superpowers/specs and docs/superpowers/plans.

Task: dex e6fla2yl - MQTT / Home Assistant support

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@sethpjohnson
sethpjohnson changed the base branch from claude/followups-review-mediums to main July 17, 2026 21:03
@sethpjohnson
sethpjohnson merged commit dbd1ab1 into main Jul 17, 2026
@sethpjohnson
sethpjohnson deleted the claude/mqtt-ha-support branch July 17, 2026 21:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant