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.
Expert-level Home Assistant configuration management with efficient workflows, remote CLI access, and verification protocols.
Before starting, verify the environment has:
[email protected])hass-cli installed locally/config directoryAll 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
# Check configuration validity
ssh [email protected] "ha core check"
# Restart Home Assistant
ssh [email protected] "ha core restart"
# View logs
ssh [email protected] "ha core logs"
# Tail logs with grep
ssh [email protected] "ha core logs | grep -i error | tail -20"
Use for changes you want in version control:
# 1. Make changes locally
# 2. Check validity
ssh [email protected] "ha core check"
# 3. Commit and push
git add file.yaml
git commit -m "Description"
git push
# 4. CRITICAL: Pull to HA instance
ssh [email protected] "cd /config && git pull"
# 5. Reload or restart
hass-cli service call automation.reload # if reload sufficient
# OR
ssh [email protected] "ha core restart" # if restart needed
# 6. Verify
hass-cli state get sensor.new_entity
ssh [email protected] "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 [email protected]:/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 [email protected] "cd /config && git pull"
ssh [email protected] "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 [email protected] "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 [email protected]:/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 [email protected] "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 [email protected]:/config/.storage/
scp .storage/lovelace_dashboards [email protected]:/config/.storage/
# Step 4: Restart HA (required for registry changes)
ssh [email protected] "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.control_center > /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
ssh [email protected] "ha core check"
ssh [email protected] "ha core restart"
# Logs
ssh [email protected] "ha core logs | tail -50"
ssh [email protected] "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 [email protected] "cd /config && git pull"
scp file.yaml [email protected]:/config/
# Dashboard deployment
scp .storage/lovelace.my_dashboard [email protected]:/config/.storage/
python3 -m json.tool .storage/lovelace.my_dashboard > /dev/null # Validate JSON
# Quick test cycle
scp automations.yaml [email protected]:/config/
hass-cli service call automation.reload
hass-cli service call automation.trigger --arguments entity_id=automation.name
ssh [email protected] "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.