From 4a928b70673898ebb9d9fd7deb3b70c8be3a9702 Mon Sep 17 00:00:00 2001 From: ryan Date: Sun, 3 Aug 2025 19:44:41 -0700 Subject: [PATCH] Update CLAUDE.md and fix final Tortoise handler return value MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add dashboard development commands (just dashboard, mix phx.server) - Document Dashboard.Application and Dashboard.MqttSubscriber components - Add comprehensive dashboard section with MQTT configuration details - Include critical implementation notes for Tortoise handler return values - Fix handle_message to return {:ok, state} instead of [] to prevent crashes 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- CLAUDE.md | 25 ++++++++++++++++++++++ dashboard/lib/dashboard/mqtt_subscriber.ex | 4 ++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 5ec9696..7c0c3cd 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -23,6 +23,10 @@ mix test test/systant_test.exs # Enter development shell (via Nix) nix develop + +# Run dashboard (Phoenix LiveView) +cd dashboard && mix phx.server +# or use justfile: just dashboard ``` ### Production @@ -41,6 +45,8 @@ This is an Elixir OTP application that serves as a systemd daemon for MQTT-based ### Core Components - **Systant.Application** (`lib/systant/application.ex`): OTP application supervisor that starts the MQTT client - **Systant.MqttClient** (`lib/systant/mqtt_client.ex`): GenServer that handles MQTT connection, publishes stats every 30 seconds, and listens for commands +- **Dashboard.Application** (`dashboard/lib/dashboard/application.ex`): Phoenix LiveView dashboard application +- **Dashboard.MqttSubscriber** (`dashboard/lib/dashboard/mqtt_subscriber.ex`): Real-time MQTT subscriber that feeds data to the LiveView dashboard - **Configuration**: MQTT settings configurable via environment variables or config files ### Key Libraries @@ -73,6 +79,25 @@ The NixOS module supports: - Systemd service with security hardening - Auto-restart and logging to systemd journal +## Dashboard + +The project includes a Phoenix LiveView dashboard (`dashboard/`) that provides real-time monitoring of all systant instances. + +### Dashboard Features +- Real-time host status updates via MQTT subscription +- LiveView interface showing all connected hosts +- Automatic reconnection and error handling + +### Dashboard MQTT Configuration +- Subscribes to `systant/+/stats` to receive updates from all hosts +- Uses hostname-based client ID: `systant-dashboard-${hostname}` to avoid conflicts +- Connects to `mqtt.home:1883` (same broker as systant instances) + +### Important Implementation Notes +- **Tortoise Handler**: The `handle_message/3` callback must return `{:ok, state}`, not `[]` +- **Topic Parsing**: Topics may arrive as lists or strings, handle both formats +- **Client ID Conflicts**: Use unique client IDs to prevent connection instability + ### Future Plans - Integration with Home Assistant via custom MQTT integration - Expandable command handling for host-specific automation diff --git a/dashboard/lib/dashboard/mqtt_subscriber.ex b/dashboard/lib/dashboard/mqtt_subscriber.ex index 5001cfb..e706d26 100644 --- a/dashboard/lib/dashboard/mqtt_subscriber.ex +++ b/dashboard/lib/dashboard/mqtt_subscriber.ex @@ -63,7 +63,7 @@ defmodule Dashboard.MqttSubscriber do {:ok, state} end - def handle_message(topic, payload, _state) do + def handle_message(topic, payload, state) do topic_parts = if is_binary(topic), do: String.split(topic, "/"), else: topic case topic_parts do ["systant", hostname, "stats"] -> @@ -83,7 +83,7 @@ defmodule Dashboard.MqttSubscriber do _ -> :ok end - [] + {:ok, state} end @impl true