canbus: furnace + water-heater status sensors (running + DSI fault)

Decode node 89 (furnace) read-only: Furnace Running (page-3 b0 bit0) and
Furnace DSI Fault (b0 bit5), same type-0x1E DSI encoding as the water
heater. The furnace is thermostat-controlled, not a Lippert load — it
sits on the bus only to report ignition state. Captures only ever showed
0x80 (off), so the 0x81 running / 0xA0 fault bytes are inferred by
parallel to node 95; confirm on the first real burn.

Add Water Heater Heating (node 95 page-3 x[3] bit7 = burner actively
firing) — distinct from the on/off switch, which only reflects "enabled".

Carry all three through the MQTT bridge to home HA, add the furnace
DSI-fault Octavia alert mirroring the water heater, and update the README
node map (89 was "unknown switched load"). Campsite + home Camper
dashboards updated live.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
wes
2026-06-13 00:19:46 -04:00
co-authored by Claude Opus 4.8
parent 5b9198878c
commit 6733a79390
4 changed files with 135 additions and 2 deletions
+41
View File
@@ -83,3 +83,44 @@ automation:
averted. Try to remember this feeling next time you eyeball the
tank gauge and say "eh, it's fine."
mode: single
# --- Furnace DSI fault (node 89). Same lockout scheme as the water heater
# (page-3 b0 bit5); see canbus/README.md. A furnace lockout means no forced-air
# heat — more urgent than the water heater on a cold night. ---
- id: camper_furnace_dsi_fault_discord
alias: "Camper: Furnace 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_furnace_dsi_fault
to: "on"
for: "00:00:10"
actions:
- action: rest_command.discord_server_alerts
data:
message: >-
<@321798967669030912> 🥶 **FURNACE DSI FAULT** — the furnace tried to
light and gave up. That means no heat. Same usual suspect: you're out
of propane (or the igniter died, but c'mon). It's in lockout — swap the
tank, then cycle the thermostat to relight before everything inside
hits ambient.
mode: single
- id: camper_furnace_dsi_fault_cleared_discord
alias: "Camper: Furnace DSI fault cleared → Discord"
triggers:
- trigger: state
entity_id: binary_sensor.onecontrol_can_furnace_dsi_fault
from: "on"
to: "off"
for: "00:00:10"
actions:
- action: rest_command.discord_server_alerts
data:
message: >-
✅ Furnace fault cleared — it's lighting again and making heat. Enjoy
the warmth, and maybe glance at the propane gauge once in a while like
a functioning adult.
mode: single
+55
View File
@@ -165,6 +165,43 @@ automation:
"device_class": "problem",
"availability_topic": "campsite/onecontrol/availability",
"device": {"identifiers": ["campsite_onecontrol"]}}
- action: mqtt.publish
data:
topic: "homeassistant/binary_sensor/campsite/furnace_dsi_fault/config"
retain: true
payload: >-
{"name": "Furnace DSI Fault",
"unique_id": "campsite_furnace_dsi_fault",
"state_topic": "campsite/binary_sensor/furnace_dsi_fault/state",
"payload_on": "ON", "payload_off": "OFF",
"device_class": "problem",
"availability_topic": "campsite/onecontrol/availability",
"device": {"identifiers": ["campsite_onecontrol"]}}
# Running/heating status binary sensors
- action: mqtt.publish
data:
topic: "homeassistant/binary_sensor/campsite/water_heater_heating/config"
retain: true
payload: >-
{"name": "Water Heater Heating",
"unique_id": "campsite_water_heater_heating",
"state_topic": "campsite/binary_sensor/water_heater_heating/state",
"payload_on": "ON", "payload_off": "OFF",
"device_class": "running",
"availability_topic": "campsite/onecontrol/availability",
"device": {"identifiers": ["campsite_onecontrol"]}}
- action: mqtt.publish
data:
topic: "homeassistant/binary_sensor/campsite/furnace_running/config"
retain: true
payload: >-
{"name": "Furnace Running",
"unique_id": "campsite_furnace_running",
"state_topic": "campsite/binary_sensor/furnace_running/state",
"payload_on": "ON", "payload_off": "OFF",
"device_class": "running",
"availability_topic": "campsite/onecontrol/availability",
"device": {"identifiers": ["campsite_onecontrol"]}}
# Awning
- action: mqtt.publish
data:
@@ -230,6 +267,21 @@ automation:
topic: "campsite/binary_sensor/onecontrol_system_fault/state"
retain: true
payload: "{{ 'ON' if is_state('binary_sensor.onecontrol_can_onecontrol_system_fault', 'on') else 'OFF' }}"
- action: mqtt.publish
data:
topic: "campsite/binary_sensor/furnace_dsi_fault/state"
retain: true
payload: "{{ 'ON' if is_state('binary_sensor.onecontrol_can_furnace_dsi_fault', 'on') else 'OFF' }}"
- action: mqtt.publish
data:
topic: "campsite/binary_sensor/water_heater_heating/state"
retain: true
payload: "{{ 'ON' if is_state('binary_sensor.onecontrol_can_water_heater_heating', 'on') else 'OFF' }}"
- action: mqtt.publish
data:
topic: "campsite/binary_sensor/furnace_running/state"
retain: true
payload: "{{ 'ON' if is_state('binary_sensor.onecontrol_can_furnace_running', 'on') else 'OFF' }}"
- action: mqtt.publish
data:
topic: "campsite/cover/awning/state"
@@ -300,6 +352,9 @@ automation:
entity_id:
- binary_sensor.onecontrol_can_water_heater_dsi_fault
- binary_sensor.onecontrol_can_onecontrol_system_fault
- binary_sensor.onecontrol_can_furnace_dsi_fault
- binary_sensor.onecontrol_can_water_heater_heating
- binary_sensor.onecontrol_can_furnace_running
conditions:
- condition: template
value_template: "{{ trigger.to_state.state in ['on', 'off'] }}"