ha-dashboards
Skill1 starsChanged 40 days agoMITView on GitHub
Build and edit Home Assistant Lovelace dashboards for Brandon - new cards/views, restructuring layout, card-mod styling, Mushroom/Bubble custom cards, "make this look better", "is there a better way to display X". Use for any change to his HA dashboards. For automations/scripts use ha-automations; for "why did X misbehave" use ha-debug.
In this repository9 other files it gives its agents.
- blogSkill
- closeSkill
- ha-automationsSkill
- ha-debugSkill
- superchargeSkill
- update-skillsSkill
- upstream-contribSkill
- wled-docsSkill
- writing-voiceSkill
The file
We split this skill into the rules it gives an agent
2 rules. About 0 are common, 0 are distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈0
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 17
The full config often exceeds the token limit: When ha_config_get_dashboard dumps to a file, probe/extract with python (no jq on his box), …
- Very specific: line 40
Sensor sources: never use AIR-1 onboard temp/humidity as a room's authoritative reading (MCU self-heating, and they're recorder-excluded) - …
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Home Assistant Dashboard Building
Brandon expects this done autonomously through the HA MCP server. Do not ask him to open the UI editor, paste YAML, or copy config - you have direct read/write access to his instance. Also load home-assistant-best-practices for the card-type/domain reference.
Mechanics (the parts that bite)
- His default dashboard is
lovelace(title "Harvey", path/lovelace/home= view 0).ha_config_get_dashboard(list_only=True)to confirm targets. - He edits live and drags cards constantly. Re-fetch a fresh
config_hashimmediately before every write; never carry a hash across a gap. After a write timeout, re-read the hash before retrying - the write may or may not have applied. After any HA restore/rollback, re-verify hashes and content before trusting the config is what you left. - Address cards by heading/title, never by section index. Index positions go stale the moment he drags something; an index-targeted edit has landed on the wrong room's card before.
- Edit with
python_transform, not full-config replacement - surgical, can't clobber unrelated cards. python_transformbansdef/FunctionDef(VALIDATION_FAILED "Forbidden node type"). Inline logic as comprehensions: multi-condition drop filters go in one[c for c in cards if not (...)].- The full config often exceeds the token limit. When
ha_config_get_dashboarddumps to a file, probe/extract with python (no jq on his box), don't Read the whole thing. - Search has blind spots.
ha_config_get_dashboard(card_type=/entity=/heading=)skipspicture-elementselementsand entity ids inside Jinja;ha_searchskips dashboards entirely unlesssearch_types=["dashboard"]. To find every reference, dump full config and grep/python. - Never change a view's layout type (sections ↔ masonry ↔ grid) unless he explicitly asks - not even while fixing something else or answering "why are there gaps". He reverted an unrequested masonry switch angrily. Related: masonry does NOT honor card order past the first row (placement is height-balanced per column), so exact multi-row layouts in masonry are a losing fight - sections is his layout.
The preview-then-swap loop (his flow for look-and-feel)
For subjective visual changes ("looks better?", "a dropdown or?"), don't replace the original in place. Add a labeled preview card alongside it:
- Append a preview card (or a
vertical-stackwith aheading"Preview: X") right below the existing block. Show alternatives as "Preview A / Preview B". - He looks at the live view and reacts ("I like the chips", "too spaced out", "too tall").
- Tune, or on approval: swap the chosen design into the real block and delete every preview card (filter by heading so none orphan).
For a mechanical/obvious change just make it - and when the destination is obvious from an established pattern (same card format as a sibling room), just put it there; don't ask "where do you want it".
Uncertain third-party card behavior gets verified BEFORE touching his live dashboard. His sharpest correction came from three live trial-and-error "fixes" to a custom card in a row - fetch the card's actual source (or build/test locally) and prove the behavior first, then apply once.
His aesthetic (settled preferences, June-July 2026)
- Compact everything. Fixed compact card width (~220-260px), never divide full width by card count; a few cards left-aligned with empty space after is fine. Density via card-mod:
ha-card { --spacing: 4px; --icon-size: 26px; --card-primary-font-size: 13px; --card-secondary-font-size: 11px; }. Target: a view fits one screen without scrolling. - Many one-column sections, one per logical category, no
column_span, modest inner grids (2-up) - keeps HA's section editor drag/reorder/resize working. Group by device category, worst-first within each group. - No redundant chrome: no "all healthy" banners when stats already say it, no headings/labels for blocks he already recognizes ("i dont want the 'Lights' thing at all"). Empty-state and summary rows belong INSIDE an auto-entities template (append/fallback cards), never in
conditionalcards - Lovelace conditional cards don't supportcondition: templateand render red error boxes. - Near-binary / tightly-bounded sensors get a compact
mini-graph-card(big current value + short sparkline, height shrunk to ~42px from the 100px default), NOT a full ApexCharts timeline ("such a huge step just to show 0 or 1 or 2"). - Camera-adjacent status (locks, gates, motion, person/vehicle/package) goes in badges overlaid on the camera card (picture-glance style), not as tile rows below - he rolled this out dashboard-wide. Gotcha: an inactive/off badge that's the only badge renders nearly invisible with default styling - force an explicit icon.
- Sensor sources: never use AIR-1 onboard temp/humidity as a room's authoritative reading (MCU self-heating, and they're recorder-excluded) - prefer his ecobee/Zooz/BTHome/IKEA room sensors.
Card recipes that won (and the gotchas inside them)
- Battery pills (A/B tested):
custom:bubble-card(card_typebutton, button_typestate) beat a chrome-less slim-bar list. Per-device: colored.bubble-icon+ tinted.bubble-icon-containerby charge threshold viastyles,scrolling_effect: false(marquee on long names reads as broken),show_attributewithbattery_type_and_quantity, forced.bubble-button-background { opacity: 1; background-color: var(--ha-card-background) }(his theme makes bubble's background transparent), NO fixed pill height (two-line names need to breathe). 2 pills per section column. - Mushroom chips full-width:
alignmentonly does start/center/end. Control spread with card-mod on.chip-container:width: 100% !important+justify-content. His tuned ladder:space-between(too spread) →space-evenly(better) → settled onjustify-content: center+gap: 16px. - Bubble Card v3.2.0+ pop-ups are standalone: one
custom:bubble-cardwithcard_type: pop-up, its ownhashandcards:list; a separate button withtap_action: navigateto#hashopens it. The legacy "pop-up as first card of a stack" pattern triggers a migration nag. - Inline lock buttons: a
tileforlock.*withfeatures: [{type: lock-commands}]. He liked it on the Batteries view but rejected the added height on camera-row door cards - the height impact depends on context, so preview it rather than assuming. - auto-entities:
filter.templatereturning a list of mushroom-template-card dicts, sorted by asort_keykey (mushroom ignores extra keys). Display names viadevice_attr(entity_id, 'name_by_user')with attribute fallback so renames show immediately. - Percentage fill bar: card-mod
background-image: linear-gradient(to right, <tint> P%, rgba(0,0,0,0) P%)-background-image, notbackground, so the theme card color survives. Tint by threshold. - Custom cards installed (check resources before recommending): mushroom, bubble-card, button-card, apexcharts, mini-graph, card-mod, auto-entities, flower-card, and more.
Verify
Screenshots: the PC's Playwright browser was signed in to HA on 2026-10-24, but on 2026-11-06 http://192.168.1.252:8123 sent it to the login page, so navigate once and check before relying on it (Claude never types the HA password); the built-in browser pane is not and the ha-mcp screenshot beta is off. browser_navigate to the view, wait ~20 s (Bubble and templates load late), browser_take_screenshot into .playwright-mcp/, then Read the PNG. fullPage does nothing on HA (the view scrolls inside an inner container): to see a whole view, resize the viewport taller, and to check "fits on one screen" measure hui-grid-section bottoms at 1920x945 and 2560x1305. Relative screenshot filenames land in ~/development, not .playwright-mcp/; pass an absolute path. Sections columns cap at 500 px wide, so image-heavy cards (printer art) grow tall on big monitors; a @media (min-width: 900px) card-mod max-width: calc((100vh - Npx) / ratio) keeps them on screen. ha-mcp 8.7.0 freezes HA for ~60 s on every dashboard write (and on describe=True): after saving, it validates cards by running every custom card's JS in QuickJS, and quickjs-ng runs a full gc.collect() under the GIL after each call, which starves HA's event loop (go2rtc killed, UniFi/NVR/MQTT/Frigate drop). Upstream issue homeassistant-ai/ha-mcp#2744, fixed by PR #2737 in 9.0.0 (dev builds only as of 2026-10-25). Measured 2026-10-25: a one-line ha-mcp patch gave a 21 s ping hang then 42 s disconnect; the same save via the frontend took 53 ms with no stall. ha-mcp 9.1.0 was installed by 2026-11-06 (the fix shipped in 9.0.0), but the 3D Printer rebuild that day still wrote through Playwright, which worked well and is the proven path: hass.callWS({type:'lovelace/config', url_path:null, force:true}), change the config in JS, then hass.callWS({type:'lovelace/config/save', url_path:null, config}). Reads and searches through ha-mcp are fine. On 2026-11-06 a python_transform write through ha-mcp 9.1.0 (new view on kitchen-tablet) committed and verified with no stall anyone noticed (not measured).
card-mod patches Mushroom/Bubble shadow DOM, so styling can silently break on an upgrade. Never claim a dashboard change shipped without looking at the live result - tell him to hard-refresh (card-mod caches), or pull a screenshot if available. State plainly what you changed and what you observed.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

