No description
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Robert Marshall ec581d6167
All checks were successful
Lint, type check and test / hassfest (push) Successful in 1m32s
Lint, type check and test / quality (push) Successful in 1m50s
Add project workflow to the agent context document (#2)
2026-09-05 20:16:45 +00:00
.forgejo/workflows Copy the integration into hassfest rather than bind-mounting it 2026-09-05 20:50:34 +01:00
custom_components/campervan Indent Python with tabs, enforced by .editorconfig 2026-09-05 20:51:27 +01:00
tests Indent Python with tabs, enforced by .editorconfig 2026-09-05 20:51:27 +01:00
.editorconfig The whole point of using tabs is to not enforce and indent size; it should be up to the renderer 2026-09-05 21:01:58 +01:00
.gitignore Scaffold the custom integration and its CI 2026-09-05 20:46:37 +01:00
CLAUDE.md Add project workflow to the agent context document 2026-09-05 21:15:46 +01:00
hacs.json Scaffold the custom integration and its CI 2026-09-05 20:46:37 +01:00
pyproject.toml Indent Python with tabs, enforced by .editorconfig 2026-09-05 20:51:27 +01:00
README.md Scaffold the custom integration and its CI 2026-09-05 20:46:37 +01:00
requirements-dev.txt Scaffold the custom integration and its CI 2026-09-05 20:46:37 +01:00

Campervan CAN bus

A Home Assistant custom integration for a campervan's CAN bus.

A Raspberry Pi running Home Assistant Core sits on the bus as node 0x01, talking to an MCP2515 module through SocketCAN. It discovers the van's controllers, presents them as devices and entities, and later commands them.

The controllers themselves, and the wire protocol they speak, live in CampervanControlSystems. docs/can-protocol.md there is the authority for everything on the wire; this repository is the second implementation of it, and when the two disagree the specification decides.

Status

Scaffolding. The integration installs, sets up against a named SocketCAN interface and unloads again. It does not yet open the bus, and it exposes no entities: PLATFORMS is deliberately empty.

Work is read-only first — discovery, entities, state, availability and alarms, with no command path at all — so that the hardware, the decode path and the entity model are proved before any bug can switch something on in a van.

Requirements

  • Home Assistant Core, not OS and not Supervised. There is no add-on and no Supervisor here; the integration is the whole answer.
  • A CAN interface up at 250 kbps, CAN 2.0B with 29-bit extended identifiers.
  • No internet connection, cloud service or NTP. The van may have no network at all beyond the bus.

Bringing up can0

The interface is host configuration, and this repository does not own it: the integration only needs to know what the interface is called. On a Pi with an MCP2515 module, in /boot/firmware/config.txt:

dtparam=spi=on
dtoverlay=mcp2515-can0,oscillator=<your module's crystal, in Hz>,interrupt=<its INT GPIO>

The oscillator frequency has to match the crystal actually fitted to the module. A wrong value does not fail loudly — it produces an interface that comes up and then never receives a valid frame.

Then, after a reboot:

sudo ip link set can0 up type can bitrate 250000
sudo ip link set can0 txqueuelen 128   # the 10-frame default drops bursts
ip -details -statistics link show can0

Make it persistent with systemd-networkd or your distribution's equivalent, so the bus is there before Home Assistant starts.

Installation

Copy custom_components/campervan into your Home Assistant config directory's custom_components/, restart, then add the integration and give it the interface name.

Development

uv venv --python 3.14 .venv
uv pip install --python .venv/bin/python -r requirements-dev.txt

.venv/bin/ruff check .            # lint
.venv/bin/ruff format .           # format
.venv/bin/mypy custom_components tests
.venv/bin/pytest

Python 3.14 is not a preference: it is what Home Assistant 2026.9 requires. pytest-homeassistant-custom-component is pinned exactly, because its fixtures track Home Assistant's internals and it pins the Home Assistant release it was built against.

hassfest runs in CI as a container, and needs a runner that can run one. hacs/action does not run: it validates a repository through the GitHub API, and this repository is on Forgejo. The layout checks that are ours to make are in tests/test_manifest.py instead.