modules/programs/agents/shared/skills/home-assistant-manager/SKILL.md
Expert-level Home Assistant configuration management with efficient deployment workflows (git and rapid scp iteration), remote CLI access via SSH and hass-cli, automation verification protocols, log analysis, reload vs restart optimization, and comprehensive Lovelace dashboard management for tablet-optimized UIs. Includes template patterns, card types, debugging strategies, and real-world examples.
npx skillsauth add MichaelVessia/nixos-config home-assistant-managerInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Expert-level Home Assistant configuration management with efficient workflows, remote CLI access, and verification protocols.
Before starting, verify the environment has:
ssh homeassistant via ~/.ssh/config)hass-cli installed locally/config directoryNote: HA OS requires login shell for ha commands (SUPERVISOR_TOKEN only set in login shells).
Use ssh homeassistant "bash -l -c 'ha core check'" instead of ssh homeassistant "ha core check".
All hass-cli commands use environment variables automatically:
# List entities
hass-cli state list
# Get specific state
hass-cli state get sensor.entity_name
# Call services
hass-cli service call automation.reload
hass-cli service call automation.trigger --arguments entity_id=automation.name
Important: Use bash -l -c '...' for ha commands (login shell required for SUPERVISOR_TOKEN).
# Check configuration validity
ssh homeassistant "bash -l -c 'ha core check'"
# Restart Home Assistant
ssh homeassistant "bash -l -c 'ha core restart'"
# View logs
ssh homeassistant "bash -l -c 'ha core logs'"
# Tail logs with grep
ssh homeassistant "bash -l -c 'ha core logs'" | grep -i error | tail -20
Use for changes you want in version control:
# 1. Make changes locally
# 2. Check validity
ssh homeassistant "bash -l -c 'ha core check'"
# 3. Commit and push
git add file.yaml
git commit -m "Description"
git push
# 4. CRITICAL: Pull to HA instance
ssh homeassistant "cd /config && git pull"
# 5. Reload or restart
hass-cli service call automation.reload # if reload sufficient
# OR
ssh homeassistant "bash -l -c 'ha core restart'" # if restart needed
# 6. Verify
hass-cli state get sensor.new_entity
ssh homeassistant "bash -l -c 'ha core logs'" | grep -i error | tail -20
Use scp for quick testing before committing:
# 1. Make changes locally
# 2. Quick deploy
scp automations.yaml homeassistant:/config/
# 3. Reload/restart
hass-cli service call automation.reload
# 4. Test and iterate (repeat 1-3 as needed)
# 5. Once finalized, commit to git
git add automations.yaml
git commit -m "Final tested changes"
git push
When to use scp:
When to use git:
ALWAYS assess if reload is sufficient before requiring a full restart.
hass-cli service call automation.reloadhass-cli service call script.reloadhass-cli service call scene.reloadhass-cli service call template.reloadhass-cli service call group.reloadhass-cli service call frontend.reload_themesALWAYS verify automations after deployment:
git add automations.yaml && git commit -m "..." && git push
ssh homeassistant "cd /config && git pull"
ssh homeassistant "bash -l -c 'ha core check'"
hass-cli service call automation.reload
hass-cli service call automation.trigger --arguments entity_id=automation.name
Why trigger manually?
sleep 3
ssh homeassistant "bash -l -c 'ha core logs'" | grep -i 'automation_name' | tail -20
Success indicators:
Initialized trigger AutomationNameRunning automation actionsExecuting step ...Error indicators:
Error executing scriptInvalid data for call_serviceTypeError, Template variable warningFor notifications:
For device control:
hass-cli state get switch.device_name
For sensors:
hass-cli state get sensor.new_sensor
If errors found:
What are Lovelace Dashboards?
.storage/ directory (e.g., .storage/lovelace.control_center)Critical Understanding:
.storage/lovelace_dashboardsRapid Iteration with scp (Recommended for dashboards):
# 1. Make changes locally
vim .storage/lovelace.control_center
# 2. Deploy immediately (no git commit yet)
scp .storage/lovelace.control_center homeassistant:/config/.storage/
# 3. Refresh browser (Ctrl+F5 or Cmd+Shift+R)
# No HA restart needed!
# 4. Iterate: Repeat 1-3 until perfect
# 5. Commit when stable
git add .storage/lovelace.control_center
git commit -m "Update dashboard layout"
git push
ssh homeassistant "cd /config && git pull"
Why scp for dashboards:
Complete workflow:
# Step 1: Create dashboard file
cp .storage/lovelace.my_home .storage/lovelace.new_dashboard
# Step 2: Register in lovelace_dashboards
# Edit .storage/lovelace_dashboards to add:
{
"id": "new_dashboard",
"show_in_sidebar": true,
"icon": "mdi:tablet-dashboard",
"title": "New Dashboard",
"require_admin": false,
"mode": "storage",
"url_path": "new-dashboard"
}
# Step 3: Deploy both files
scp .storage/lovelace.new_dashboard homeassistant:/config/.storage/
scp .storage/lovelace_dashboards homeassistant:/config/.storage/
# Step 4: Restart HA (required for registry changes)
ssh homeassistant "bash -l -c 'ha core restart'"
sleep 30
# Step 5: Verify appears in sidebar
Update .gitignore to track:
# Exclude .storage/ by default
.storage/
# Include dashboard files
!.storage/lovelace.new_dashboard
!.storage/lovelace_dashboards
Use Panel View when:
Use Sections View when:
Layout Example:
// Panel view - full width, no margins
{
"type": "panel",
"title": "Vacuum Map",
"path": "map",
"cards": [
{
"type": "custom:xiaomi-vacuum-map-card",
"entity": "vacuum.dusty"
}
]
}
// Sections view - organized, has ~10% margins
{
"type": "sections",
"title": "Home",
"sections": [
{
"type": "grid",
"cards": [...]
}
]
}
Mushroom Cards (Modern, Touch-Optimized):
{
"type": "custom:mushroom-light-card",
"entity": "light.living_room",
"use_light_color": true,
"show_brightness_control": true,
"collapsible_controls": true,
"fill_container": true
}
Mushroom Template Card (Dynamic Content):
{
"type": "custom:mushroom-template-card",
"primary": "All Doors",
"secondary": "{% set sensors = ['binary_sensor.front_door'] %}\n{% set open = sensors | select('is_state', 'on') | list | length %}\n{{ open }} / {{ sensors | length }} open",
"icon": "mdi:door",
"icon_color": "{% if open > 0 %}red{% else %}green{% endif %}"
}
\n in JSONTile Card (Built-in, Modern):
{
"type": "tile",
"entity": "climate.thermostat",
"features": [
{"type": "climate-hvac-modes", "hvac_modes": ["heat", "cool", "fan_only", "off"]},
{"type": "target-temperature"}
]
}
Counting Open Doors:
{% set door_sensors = [
'binary_sensor.front_door',
'binary_sensor.back_door'
] %}
{% set open = door_sensors | select('is_state', 'on') | list | length %}
{{ open }} / {{ door_sensors | length }} open
Color-Coded Days Until:
{% set days = state_attr('sensor.bin_collection', 'daysTo') | int %}
{% if days <= 1 %}red
{% elif days <= 3 %}amber
{% elif days <= 7 %}yellow
{% else %}grey
{% endif %}
Conditional Display:
{% set bins = [] %}
{% if days and days | int <= 7 %}
{% set bins = bins + ['Recycling'] %}
{% endif %}
{% if bins %}This week: {{ bins | join(', ') }}{% else %}None this week{% endif %}
IMPORTANT: Always use | int or | float to avoid type errors when comparing
Screen-specific layouts:
Grid Layout for Tablets:
{
"type": "grid",
"columns": 3,
"square": false,
"cards": [
{"type": "custom:mushroom-light-card", "entity": "light.living_room"},
{"type": "custom:mushroom-light-card", "entity": "light.bedroom"}
]
}
Problem 1: Dashboard Not in Sidebar
.storage/lovelace_dashboards and restart HAProblem 2: "Configuration Error" in Card
Problem 3: Auto-Entities Fails
card_param not supported by card typeentities parameter:
entities, vertical-stack, horizontal-stackgrid, glance (without specific syntax)Problem 4: Vacuum Map Has Margins/Scrolling
Problem 5: Template Type Errors
TypeError: '<' not supported between instances of 'str' and 'int'states('sensor.days') | int < 71. Browser Console (F12):
2. Validate JSON Syntax:
python3 -m json.tool .storage/lovelace.my_dashboard > /dev/null
3. Test Templates:
Home Assistant -> Developer Tools -> Template
Paste template to test before adding to dashboard
4. Verify Entities:
hass-cli state get binary_sensor.front_door
5. Clear Browser Cache:
{
"type": "grid",
"title": "Quick Controls",
"cards": [
{
"type": "custom:mushroom-template-card",
"primary": "All Doors",
"secondary": "{% set doors = ['binary_sensor.front_door', 'binary_sensor.back_door'] %}\n{% set open = doors | select('is_state', 'on') | list | length %}\n{{ open }} / {{ doors | length }} open",
"icon": "mdi:door",
"icon_color": "{% if open > 0 %}red{% else %}green{% endif %}"
},
{
"type": "tile",
"entity": "climate.thermostat",
"features": [
{"type": "climate-hvac-modes", "hvac_modes": ["heat", "cool", "fan_only", "off"]},
{"type": "target-temperature"}
]
}
]
}
{
"type": "grid",
"title": "Lights",
"columns": 3,
"cards": [
{
"type": "custom:mushroom-light-card",
"entity": "light.office_studio",
"name": "Office",
"use_light_color": true,
"show_brightness_control": true,
"collapsible_controls": true
}
]
}
{
"type": "panel",
"title": "Vacuum",
"path": "vacuum-map",
"cards": [
{
"type": "custom:xiaomi-vacuum-map-card",
"vacuum_platform": "Tasshack/dreame-vacuum",
"entity": "vacuum.dusty"
}
]
}
# Configuration (note: ha commands need login shell)
ssh homeassistant "bash -l -c 'ha core check'"
ssh homeassistant "bash -l -c 'ha core restart'"
# Logs
ssh homeassistant "bash -l -c 'ha core logs'" | tail -50
ssh homeassistant "bash -l -c 'ha core logs'" | grep -i error | tail -20
# State/Services
hass-cli state list
hass-cli state get entity.name
hass-cli service call automation.reload
hass-cli service call automation.trigger --arguments entity_id=automation.name
# Deployment
git add . && git commit -m "..." && git push
ssh homeassistant "cd /config && git pull"
scp file.yaml homeassistant:/config/
# Dashboard deployment
scp .storage/lovelace.my_dashboard homeassistant:/config/.storage/
python3 -m json.tool .storage/lovelace.my_dashboard > /dev/null # Validate JSON
# Quick test cycle
scp automations.yaml homeassistant:/config/
hass-cli service call automation.reload
hass-cli service call automation.trigger --arguments entity_id=automation.name
ssh homeassistant "bash -l -c 'ha core logs'" | grep -i 'automation' | tail -10
ha core checkConfiguration Change Needed
├─ Is this final/tested?
│ ├─ YES → Use git workflow
│ └─ NO → Use scp workflow
├─ Check configuration valid
├─ Deploy (git pull or scp)
├─ Needs restart?
│ ├─ YES → ha core restart
│ └─ NO → Use appropriate reload
├─ Verify in logs
└─ Test outcome
Dashboard Change Needed
├─ Make changes locally
├─ Deploy via scp for testing
├─ Refresh browser (Ctrl+F5)
├─ Test on target device
├─ Iterate until perfect
└─ Commit to git when stable
This skill encapsulates efficient Home Assistant management workflows developed through iterative optimization and real-world dashboard development. Apply these patterns to any Home Assistant instance for reliable, fast, and safe configuration management.
development
Restate the last message in plain human language, with no jargon.
testing
Fan out a batch of work items into one PR each via isolated worktree agents, review every PR before it opens, then babysit all PRs through green CI and review feedback. Use when the user wants to fan out PRs, dispatch parallel PR agents over a list of items, or run a batch of independent changes as separate PRs.
development
Dispatch user-visible coding or research agents through Herdr with Codex-Desktop-like thread ergonomics. Use when the user asks to use Herdr to spawn, dispatch, fan out, inspect, follow up with, or monitor agent workspaces/threads.
development
Generate self-contained HTML visualizations with Plannotator theming. Use for implementation plans, PR explainers, architecture diagrams, data tables, slide decks, and any visual explanation of technical concepts. Plans and PR explainers follow Plannotator's prescriptive approach; all other visual content delegates to nicobailon/visual-explainer.