canbus: replace BLE integration with CAN node in HA + MQTT bridge home
The campsite HAOS Pi now runs the ESPHome CAN node natively ("OneControl
CAN", *.onecontrol_can_*); the BLE integration is fully torn out (config
entry, custom_components on the Pi, stale MQTT registry orphans) and the
camper dashboard rewritten — water-pump tile dropped on purpose (pump is
panel-only), awning + fault sensors added.
New canbus/ha/mqtt_bridge_onecontrol.yaml (deployed to the Pi as
packages/mqtt_bridge.yaml) bridges the CAN entities to the home broker
via MQTT Discovery, same pattern as the gazebo bridge. Kept the old
unique_ids so home entity ids and recorder history carried over; added
an availability topic and explicit command-topic allowlists (3 switches
+ awning — a future debug entity must not become remotely controllable
for free). Round-trip verified from home HA.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+67
-18
@@ -9,6 +9,32 @@ Read `README.md` first — it has the full message-format documentation, the nod
|
||||
map for this coach, and the wiring procedure. This file is just the current
|
||||
state + what's left.
|
||||
|
||||
## FLASHED & READ-VERIFIED (2026-06-12, afternoon)
|
||||
|
||||
The node is built, flashed over USB, on the bus, and on WiFi
|
||||
(`192.168.69.18`, hostname `onecontrol-canbus`, adoptable via the API key in
|
||||
`secrets.yaml`). **All 11 read entities verified live over the native API**:
|
||||
battery 13.27 V, tanks fresh 0 / black 33 / grey1 33 / grey2 100 %, interior
|
||||
lights on, exterior/heater off, both fault flags clear, awning idle.
|
||||
|
||||
What changed this session:
|
||||
- `secrets.yaml` filled (WiFi + fallback AP from the shared gazebo proxy creds).
|
||||
- **Battery voltage decode finished** (remaining-work item 4): matches the
|
||||
page-`0x11` `00 2B …` telemetry frame, `b2..b3` BE / 256 — reads 13.27 V.
|
||||
- **Toolchain fixes** (ESPHome moved since the last build; it no longer compiled):
|
||||
the `g_node_type` array global's bare `{}` initializer was ambiguous (named the
|
||||
type), and the awning cover enum is `COVER_OPERATION_OPENING/CLOSING` (no `IS_`).
|
||||
- **Dual `on_frame` trigger** — this build filters `on_frame` by frame type, so a
|
||||
single `use_extended_id: true` trigger only saw the 29-bit frames; the 11-bit
|
||||
read broadcasts (tanks/lights/heater/awning) were silently dropped. Added a
|
||||
second `use_extended_id: false` trigger sharing the same lambda via a YAML
|
||||
anchor. (This was the exact risk the bus-config note called out.)
|
||||
- **Logger** — raised the `canbus` component to INFO and silenced the per-frame
|
||||
dump; at DEBUG it logged ~50 frames/s and saturated the 115200 serial link.
|
||||
|
||||
Still TODO (needs the operator in the loop — see "Remaining work" items 5–6):
|
||||
command-path verification (toggle a light) and the attended awning test.
|
||||
|
||||
## Current status (2026-06-12)
|
||||
|
||||
- **Message format documented and confirmed against live captures.** The bus is
|
||||
@@ -42,31 +68,54 @@ state + what's left.
|
||||
|
||||
## Remaining work (in order)
|
||||
|
||||
1. **`secrets.yaml`** — copy `esphome/secrets.yaml.example`, fill in WiFi, the
|
||||
ESPHome `api_key`, and the fallback-AP password. It's git-ignored.
|
||||
2. **First flash over USB:** `esphome run esphome/onecontrol-canbus.yaml` (pick
|
||||
the serial port). OTA after that. Mirrors the gazebo-fan-proxy workflow.
|
||||
3. **Confirm the read entities populate** in HA once it's on the bus: the four
|
||||
tanks and the two light switches publish from the page-3 broadcasts. Watch the
|
||||
DEBUG frame dump (`logger: level: DEBUG`) to confirm frames are decoded; drop
|
||||
to INFO when happy.
|
||||
4. **Finish the two open read items in the YAML lambda:**
|
||||
- **Battery voltage** — rides a 29-bit telemetry frame (src `7D`/`AE`,
|
||||
page `0x11`), bytes 2–3 big-endian / 256 = volts. Match that frame and
|
||||
publish `battery_voltage`. (See README "29-bit extended frames".)
|
||||
1. ~~**`secrets.yaml`**~~ — DONE. WiFi + fallback-AP creds filled from the shared
|
||||
gazebo proxy; the `api_key` was already set.
|
||||
2. ~~**First flash over USB**~~ — DONE (`/dev/ttyUSB0`). OTA from here on.
|
||||
Note: this laptop's user isn't in the `uucp` group, so the serial node needed
|
||||
`chmod 666 /dev/ttyUSB0` (resets on replug) — irrelevant for OTA.
|
||||
3. ~~**Confirm the read entities populate**~~ — DONE. All 11 verified live over the
|
||||
native API (see status block above). NB: ESPHome 2026.5 doesn't echo
|
||||
`publish_state` at DEBUG over serial, so a quiet serial log is normal — read the
|
||||
states over the API, not the console.
|
||||
4. **Open read items in the YAML lambda:**
|
||||
- ~~**Battery voltage**~~ — DONE; reads 13.27 V.
|
||||
- Optionally add **water pump (`61`)** and **water heater (`95`)** — both are
|
||||
ordinary switched loads, same decode + command path as the lights.
|
||||
5. **Verify the command path** from HA: toggle Interior/Exterior Lights and the
|
||||
Water Heater. The `send_load_command` script + `on_frame` handler do the
|
||||
exchange and send the opcode.
|
||||
ordinary switched loads, same decode + command path as the lights. (Heater is
|
||||
already exposed; pump stays command-blocked.)
|
||||
5. ~~**Verify the command path**~~ — DONE (Interior + Exterior lights, on & off,
|
||||
each a confirmed challenge→response→opcode exchange on the serial log, with the
|
||||
read-back flipping to match). Switches are now `optimistic:false` so HA shows
|
||||
ground truth. **Confirmed module behaviour:** after a successful session the
|
||||
module enforces a **~2 s cooldown** — a second command to the same load sooner
|
||||
gets no challenge and is dropped (opcode-independent, module-side, not a bug).
|
||||
The arm retry was widened to 8×150 ms to absorb the odd dropped frame on the
|
||||
busy bus. Heater is wired the same way but wasn't actuated (avoid cycling gas
|
||||
ignition casually); it should behave identically.
|
||||
6. **Attended awning test (motor — watch it move).** The Awning `cover` is wired
|
||||
(open/close/stop). On the first run, confirm: (a) which direction open/close
|
||||
actually go, (b) whether one command runs to the travel limit or only moves
|
||||
while commands stream. If it under-travels, change `send_load_command` to
|
||||
stream the opcode (repeat until Stop) — only after watching it. The single-shot
|
||||
default can't run the motor away.
|
||||
7. **(Optional) Surface at the campsite HA + bridge home** like the gazebo fans /
|
||||
OneControl BLE devices, if you want these in the home dashboard too.
|
||||
7. ~~**Surface at the campsite HA**~~ — DONE (2026-06-12). Added to the campsite
|
||||
HAOS Pi (`192.168.69.10`) as ESPHome config entry "OneControl CAN"; all 11
|
||||
entities (`*.onecontrol_can_*`) live. The old BLE integration is **fully torn
|
||||
out**: config entry deleted, `custom_components/lippert_onecontrol` removed
|
||||
from the Pi, 11 stale `campsite_onecontrol_*` MQTT registry orphans purged
|
||||
(home broker had no retained discovery topics — they were registry-only). The
|
||||
camper dashboard (`lovelace.dashboard_camper`) was rewritten to the new
|
||||
entities; the water-pump tile was dropped (pump is panel-only by design) and
|
||||
awning + both fault sensors added.
|
||||
8. ~~**Bridge home via MQTT**~~ — DONE (2026-06-12 evening). The Pi package
|
||||
`/config/packages/mqtt_bridge.yaml` was rewritten against the CAN entities
|
||||
(repo copy: `canbus/ha/mqtt_bridge_onecontrol.yaml`); it publishes MQTT
|
||||
Discovery + state to cyrion's Mosquitto (192.168.88.69) and relays commands
|
||||
back, same pattern as the gazebo bridge. Same `unique_id`s kept for surviving
|
||||
loads, so home HA entity ids + history carried over (`*.campsite_onecontrol_*`);
|
||||
water pump / cover_2 / cover_3 retained topics cleared (entities auto-removed
|
||||
on home); awning + both fault sensors added, plus an availability topic
|
||||
(`campsite/onecontrol/availability`) the old bridge lacked. Home Overview
|
||||
"Camper" view updated to match. Command round-trip verified from home HA.
|
||||
|
||||
The DSI fault is already decoded and wired in (see below) — no capture needed.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user