ha-dashgen
Dashboards as code. A TypeScript model of the house goes in, three deployed dashboards come
out, and check refuses to let a dashboard reference an entity that does not exist or quietly
lose a control the previous one had.
Commands
scripts/ha-dashgen build # model -> JSON in <overlay>/config/home-assistant/dashboards/
scripts/ha-dashgen check # build + validate against the LIVE instance (exit 1 on a problem)
scripts/ha-dashgen ensure # create any dashboard that does not exist yet
scripts/ha-dashgen deploy # build, back up each dashboard, then push
Needs AXON_HOME_ROOT (or AXON_OVERLAY_ROOT) and, for anything touching the instance, an
unlocked BW_SESSION — it shells out to ha-cli and ha-dashboard, which own the credentials.
What check actually checks
- Every entity reference exists on the running instance, including IDs inside Jinja.
- No control appears on two peer views. The
startview is exempt: it is a shortcut surface, so a favourite tile pointing at a light that also lives in Räume is intended. - Nothing was silently dropped. It diffs against
dashboards/baseline-<date>/and fails on any entity the old dashboard had that the new one lacks, unlessmodel.tslists it indeliberatelyDroppedwith a reason. A stale entry — declared dropped but back on a view — also fails.
Run check before deploy. deploy always backs up to dashboards/pre-deploy/ first;
lovelace/config/save overwrites in one shot with no undo.
Gotchas
Each of these was found the expensive way against HA 2026.6.3 with a probe dashboard, and the first four blank the entire view, not just the offending card, with nothing in the browser console:
condition: templatein aconditionalcard renders "Konfigurationsfehler".- A template in section
visibilityhides the section even when it is{{ 1 == 1 }}. Put the logic in abinary_sensorand usecondition: state, which works. custom:mushroom-template-card: a staticsecondaryrenders, a templated one comes out empty, and inside aconditionalthe card takes the view with it.mushroom-chips-cardis fine. Prefer a nativetilewhose entity is a klartext sensor.- A
weatherentity as a view badge, and abinary_sensorbadge. View-level badges are not used at all for this reason; heading badges are fine. picture-glancewithcamera_imageandpicture-entityon a camera both render nothing here, atcamera_viewliveorauto. Cameras are plain tiles that open the live stream on tap.column_spangreater than the view'smax_columnscollapses the grid to a blank page.- A dashboard
url_pathmust contain a hyphen. HA rejectszuhause, acceptsmein-zuhause. notify:platforms are not reloadable. A new notify group needs a full restart, notautomation.reload.
Boundary
Never put a real entity ID, room name, device or household fact in this Pack. Those belong in
<overlay>/capabilities/home-assistant/dashboards/model.ts, which is the only file that should
need editing to change what the dashboards show.