Home Assistant (HA) is the central hub for IoT automation in the new house. It needs to integrate with:
Zigbee devices (switches, sensors, buttons) via USB coordinator
Tapo cameras (RTSP/Tapo integration)
Unifi Protect (running on UDM)
Google Home (TTS announcements)
Sensi thermostats (cloud API)
The homelab has a defined Prod/Test/Dev architecture with Komodo-managed Docker hosts. Home Assistant must fit into this architecture while meeting its unique requirements.
Requirements
USB access — Zigbee coordinator must be physically attached to host
Network access — Must reach IoT VLAN (10.0.4.0/24) for cameras, Google Home, etc.
Unifi Protect access — Must reach UDM for Protect integration
Reliability — Automation failures directly impact daily life
Manageability — Should fit into existing GitOps/Komodo workflow where possible
Backup/Recovery — Must be recoverable quickly if host fails
Constraints
IoT VLAN (10.0.4.0/24) is isolated from other VLANs by design
Zigbee coordinator is USB-bound — cannot easily fail over to another host
Home Assistant does not support native clustering/HA
Decision
Deploy Home Assistant as a container on LenovoMini 1 (Prod Docker host) with USB passthrough for the Zigbee coordinator.
Phased Approach
Phase 1 — Bootstrap (RPi):
Run HA on existing Raspberry Pi 4
Place on Prod VLAN (10.0.1.0/24)
Configure firewall rules for IoT access
Validates the setup before full integration
Phase 2 — Production Migration:
Migrate HA to container on LenovoMini 1
USB passthrough for Zigbee coordinator
Komodo-managed deployment
Automated backups to UnRaid NAS
Options Considered
Option 1: Dedicated Raspberry Pi
Description: Run Home Assistant OS on a dedicated RPi 4.
Pros:
Simple setup
Direct USB access (no passthrough complexity)
Isolated from other workloads
Cons:
Another device to manage outside Komodo
SD card reliability concerns
Limited compute for future expansion (Frigate, etc.)
No integration with existing backup infrastructure
Verdict: Good for bootstrap, not ideal long-term.
Option 2: Container on Prod Docker Host (LenovoMini 1)
Description: Run HA as a Docker container on the existing Prod host, managed via Komodo.
Pros:
Better hardware (8th Gen i7, 16GB RAM, NVIDIA GPU)
Integrated with existing management (Komodo, GitOps)
Backups to UnRaid NAS
Network already on Prod VLAN with access to other services
GPU available for future Frigate integration
Cons:
USB passthrough required (adds configuration)
Shares resources with Plex/*arr (mitigated by resource limits)
Single point of failure (mitigated by backups)
Verdict: Best fit for long-term architecture.
Option 3: VM on ProxMox
Description: Run HA in a dedicated VM on the ProxMox host.
Pros:
Isolated resources
ProxMox has snapshot/backup features
Cons:
ProxMox is on Dev VLAN (10.0.3.0/24) — wrong network segment
USB passthrough to VM is more complex than Docker
Not on the Komodo-managed path
Verdict: Network placement is wrong. Rejected.
Option 4: Dedicated Mini Host on Prod VLAN
Description: Purchase a dedicated small device (NUC, mini PC) for HA.
Pros:
Dedicated to home automation
Direct USB, proper network placement
Cons:
Additional hardware cost
Another device outside existing management
Overkill given available capacity on LenovoMini 1
Verdict: Unnecessary given existing infrastructure.
Consequences
Positive
Integrated management: HA deployment is Komodo-managed, follows GitOps patterns
Better hardware: More headroom for future expansion (Frigate, more integrations)
Unified backups: HA config/data backed up to UnRaid alongside other Prod data
Network positioning: Prod VLAN has (or will have) appropriate access to IoT and UDM
Negative
USB passthrough complexity: Requires privileged container or explicit device mapping
Shared host: HA competes with Plex/*arr for resources (mitigated with resource limits)
Single point of failure: If LenovoMini 1 goes down, HA is down (mitigated by backups + quick restore)
Neutral
No native HA failover: Accepted limitation — most homelabs operate this way
Zigbee bound to host: Coordinator cannot fail over, but Zigbee direct bindings provide local fallback
Implementation
Phase 1: Bootstrap on RPi
Timeline: Immediate (while homelab is being set up)
Implement a warm/cold spare HA instance on the Test environment (LenovoMini 2) with automated failover capability. When the primary (Prod) instance has unfixable issues, a single-click remediation brings up the spare and updates network rules.
Option A: Scheduled rsync of /opt/homeassistant/config from Prod → Test (via NAS or direct)
Option B: Shared config on NAS mount (both read, only active writes)
Option C: Git-based config with HA Git integration
3. Zigbee Network Portability
Use Zigbee2MQTT (not ZHA) — stores network config in coordinator_backup.json
Backup can be restored to second coordinator
Devices don’t need re-pairing if network key is preserved
Caveat: Second coordinator must be same model or compatible
4. Firewall Automation (Ansible/Terraform)
# ansible playbook: failover-to-test.yml- name: Failover HA to Test environmenthosts: localhosttasks:
- name: Update UDM firewall - block Prod to IoTcommunity.general.udm_firewall_rule:
name: "Prod-to-IoT"state: disabled - name: Update UDM firewall - allow Test to IoTcommunity.general.udm_firewall_rule:
name: "Test-to-IoT"state: enabled - name: Start HA container on Testcommunity.docker.docker_container:
name: homeassistantstate: starteddelegate_to: lenovomini2 - name: Stop HA container on Prod (if reachable)community.docker.docker_container:
name: homeassistantstate: stoppeddelegate_to: lenovomini1ignore_errors: yes
5. Failback Procedure
Reverse the process when Prod is healthy
Sync any config changes from Test back to Prod
Re-enable Prod firewall rules, disable Test
Spare Modes
Mode
Standby State
Sync Frequency
Failover Time
Resource Usage
Cold Spare
Container stopped
Daily backup restore
~5-10 min
Minimal
Warm Spare
Container running (no IoT access)
Near real-time rsync
~1-2 min
Moderate
Recommendation: Start with Cold Spare. Warm Spare adds complexity for marginal time savings.
Triggering Failover
Manual (Phase 3a):
Single-click: Run Ansible playbook from Komodo UI or CLI
Human detects issue, initiates failover
Automated (Phase 3b, future):
Health check monitors HA (e.g., /api/ endpoint)
Consecutive failures trigger alert
Optional: Auto-failover after N failures (risky, needs tuning)
Prerequisites
Before implementing:
Hardware: Second Zigbee coordinator (~$25)
Network: Test VLAN firewall rules pre-configured (disabled)
Ansible: Playbooks for failover/failback
UDM API access: Ansible collection for Unifi or direct API calls
Zigbee2MQTT: Migrate from ZHA if using ZHA initially
Testing: Validate failover in controlled scenario
Risks & Mitigations
Risk
Mitigation
Zigbee devices don’t reconnect to second coordinator
Use Zigbee2MQTT with network backup; same coordinator model
Config drift between Prod and Test
Automated sync + Git-based config
Failover triggered unnecessarily
Manual trigger only (Phase 3a); conservative health checks (Phase 3b)
Firewall automation fails
Pre-test playbooks; manual fallback documented
Cost
Item
Cost
Second Zigbee coordinator
~$25
Time to implement
Medium
Ongoing maintenance
Low (once stable)
Decision
Defer to Phase 3. Implement after Phase 2 is stable and proven. The complexity is justified only after experiencing reliability issues or when uptime requirements increase.
Direct Zigbee binding (button controls switch without hub)
Configurable LED notification bar
Scene/multi-tap support
Mesh network extends coverage
Cons:
Higher per-switch cost
2.4GHz interference possible (manageable)
Z-Wave — Zooz Switches
Protocol: Z-Wave Plus Switch Cost: ~$30-35 Coordinator Cost: ~$35-45
Pros:
Works with existing dumb switch in 3-way config
Lower per-switch cost
Dedicated frequency (no WiFi interference)
Mature, reliable protocol
Cons:
Smaller device ecosystem
Wireless buttons limited and expensive ($40+)
Less feature-rich
Also Considered
Lutron Caseta: Excellent reliability, but requires proprietary bridge. Less flexible ecosystem.
WiFi switches: Cloud dependency or complex local setup. Doesn’t align with self-hosted goals.
Decision
Zigbee with Inovelli Blue switches.
Rationale
Accessory ecosystem: Zigbee buttons and sensors are significantly cheaper. $7 IKEA button vs $40+ Z-Wave compounds quickly.
Upgradeability: Largest device selection across manufacturers for future expansion.
Feature set: LED notifications, direct binding, scene control — useful for automations.
3-way handling: Single switch replacement works cleanly.
Implementation
Coordinator: Sonoff Zigbee 3.0 USB Dongle Plus
Integration: ZHA or Zigbee2MQTT (both well-supported)
Placement: Central location or USB extension to avoid interference
Home Assistant Automations
Workflow definitions for IoT automations. Copy/adapt these for Home Assistant.
Door Sensor Automations
Door Left Open Alert
Announces via Google Home when a door has been open for 5 minutes.
alias: "Alert - Door Left Open"description: "Announce when a door has been open too long"trigger:
- platform: stateentity_id:
- binary_sensor.front_door - binary_sensor.back_door - binary_sensor.office_door - binary_sensor.garage_entry_doorto: "on"for:
minutes: 5action:
- service: tts.google_translate_saytarget:
entity_id: media_player.living_room_speakerdata:
message: "{{ trigger.to_state.attributes.friendly_name }} has been open for 5 minutes."mode: parallel
Door Still Open Reminder
Repeats announcement every 5 minutes while an exterior door remains open.
alias: "Alert - Door Still Open Reminder"description: "Repeat reminder every 5 minutes while door is open"trigger:
- platform: stateentity_id:
- binary_sensor.front_door - binary_sensor.back_doorto: "on"for:
minutes: 5action:
- repeat:
while:
- condition: stateentity_id: "{{ trigger.entity_id }}"state: "on"sequence:
- service: tts.google_translate_saytarget:
entity_id: media_player.living_room_speakerdata:
message: "Reminder: {{ trigger.to_state.attributes.friendly_name }} is still open." - delay:
minutes: 5mode: parallel
Garage Entry Night Alert
Alerts when garage entry door opens at night, with camera snapshot.
Requires Tapo integration or generic camera with RTSP. Snapshots save to /config/www/ for web access.
Zigbee Events
Button events use zha_event (for ZHA) or mqtt triggers (for Zigbee2MQTT). Device IDs and commands vary by button model — check HA device page after pairing.
Receipt Automation
Receipt Fridge Launch — NFC App Launch
Tap the fridge NFC tag to open the receipt scanner app directly.
The NFC tag is the entry point. The app handles the actual capture and any per-receipt workflow.
Considerations:
If the app supports deep links or URL schemes, prefer that over a generic notification.
If people use different phones/scanner apps, map multiple notify targets or a choose block by person/presence.
Service Check / Router Status NFC
Router Status — NFC Status Page
Opens a locally hosted status page showing service health.
alias: "Status - Router NFC"description: "Serve local status page for router/service health"trigger:
- platform: nfctag_id: <router_status_nfc_uid>action:
- service: browser_mod.popupdata:
title: "Service Status"# Serve from a local/static endpoint; no external CDN depsurl: "/local/status/index.html"mode: single
Implementation notes:
Host status/index.html on the same host that serves HA or a lightweight internal web server.
Keep the page plain HTML with no external dependencies so it works when the internet is down.
Display gateway ping, DNS resolution result, Pi-hole stats, and a one-click router reboot if supported.
Consumable Replacement NFC
Consumable Tag — Reorder Trigger
Opens the replacement item’s reorder path.
alias: "Consumables - Replace"description: "Open consumable replacement action"trigger:
- platform: nfctag_id: <consumable_nfc_uid>action:
- service: browser_mod.popupdata:
title: "Replace Air Filter"# Prefer a stable local/HA endpoint; the destination can rotate behind this URLurl: "/local/consumables/air-filter.html"mode: single
Instead of encoding a retailer URL directly, use a stable local or Home Assistant destination so the reorder page can change without rewriting the tag.
Pi-hole Temporary Disable NFC
Pi-hole — 30 Minute Disable
Disables Pi-hole time-boxed for 30 minutes.
alias: "Pi-hole - Temp Disable 30m"description: "Disable Pi-hole for 30 minutes from NFC tap"trigger:
- platform: nfctag_id: <pihole_temp_disable_nfc_uid>action:
- service: rest_command.pihole_disable_30mmode: single
Time-box the disable window so ad-blocking is re-enabled automatically. Surface the remaining time on the local status page so the household can see the countdown.