Files
lippert-onecontrol/canbus/ha/dsi_fault_alert.yaml
T
wesandClaude Fable 5 2dd884af3c canbus: presence layer + departure failsafes
Water heater = occupancy truth. New Pi package campsite_presence.yaml:
rv_occupied + phones_on_campsite_wifi template sensors (wifi one stays
unavailable until the MikroTik integration lands — load-bearing for the
dead-man trigger), MQTT bridging home, a local notify-only dead-man
(heater on, no phones on WiFi 3h), and disabled pre-staged lot-light
automations for the future shed Shelly.

dsi_fault_alert.yaml gains the Octavia MQTT relay (campsite/octavia/say)
so home HA — which has no file access — can speak through the verified
webhook path.

Home-side (UI-managed, not in repo): quick failsafe (both out of the
enlarged 150m campsite zone 25 min → fans/lights off + summary ping) and
heater failsafe (2h → heater off with bridge round-trip confirmation).
Both verified live; fan states snapshot-restored after the test.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 16:56:30 -04:00

86 lines
3.4 KiB
YAML

# Water-heater DSI fault → Discord ping in the server-alerts channel.
#
# The CAN node decodes the heater's DSI lockout (node 95 page-3 b0 bit5 —
# see canbus/README.md); when the burner fails to light (usually an empty
# propane tank) the module latches the fault and this fires the webhook.
#
# Deploy to Pi: /config/packages/dsi_fault_alert.yaml
# Repo copy: canbus/ha/dsi_fault_alert.yaml
#
# ⚠️ FIRST DEPLOY NEEDS A FULL CORE RESTART. reload_all only re-reads config
# for integrations that are already set up; rest_command was a brand-new domain
# on this instance, so until the restart the service didn't exist and every
# automation fire died with "Action rest_command.discord_server_alerts not
# found" — while check_config said valid. Verify with:
# curl .../api/services | jq '[.[].domain] | index("rest_command")'
# Secret: discord_server_alerts_webhook in the Pi's /config/secrets.yaml
# (NOT the Gatus webhook — that one posts somewhere Wes doesn't
# read; this one is confirmed delivering to the alerts channel)
rest_command:
discord_server_alerts:
url: !secret discord_server_alerts_webhook
method: POST
content_type: "application/json; charset=utf-8"
payload: >-
{"username": "Octavia",
"content": {{ message | tojson }},
"allowed_mentions": {"users": ["321798967669030912"]}}
automation:
# --- Octavia relay: anything on the broker can speak through the one
# verified webhook path. Home HA's failsafe automations publish here
# (campsite/octavia/say, payload = the message) since home has no
# file/packages access for its own rest_command. ---
- id: campsite_octavia_relay
alias: "Octavia: MQTT relay"
triggers:
- trigger: mqtt
topic: "campsite/octavia/say"
conditions:
- condition: template
value_template: "{{ trigger.payload | length > 0 and trigger.payload | length < 1900 }}"
actions:
- action: rest_command.discord_server_alerts
data:
message: "{{ trigger.payload }}"
mode: queued
max: 5
- id: camper_dsi_fault_discord
alias: "Camper: DSI fault → Discord"
description: >-
10s 'for' debounces a single glitched broadcast frame; a real lockout
is latched by the module so it easily survives the wait.
triggers:
- trigger: state
entity_id: binary_sensor.onecontrol_can_water_heater_dsi_fault
to: "on"
for: "00:00:10"
actions:
- action: rest_command.discord_server_alerts
data:
message: >-
<@321798967669030912> 🔥 **WATER HEATER DSI FAULT** — hey dumbass,
you're out of propane again. (Or the igniter finally died, but let's be honest,
it's the propane.) The heater is in lockout — swap the tank, then
cycle the heater off/on to relight.
mode: single
- id: camper_dsi_fault_cleared_discord
alias: "Camper: DSI fault cleared → Discord"
triggers:
- trigger: state
entity_id: binary_sensor.onecontrol_can_water_heater_dsi_fault
from: "on"
to: "off"
for: "00:00:10"
actions:
- action: rest_command.discord_server_alerts
data:
message: >-
✅ DSI fault cleared — the water heater is lighting again. Crisis
averted. Try to remember this feeling next time you eyeball the
tank gauge and say "eh, it's fine."
mode: single