feat(home-automation): Enhanced enterprise home automation stack with complete smart home platform#458
Conversation
… complete smart home platform - Replace basic setup with complete enterprise home automation solution - Add Home Assistant as central automation hub with 2000+ integrations - Add Zigbee2MQTT for 1000+ Zigbee device support without proprietary hubs - Add Mosquitto MQTT broker for reliable device communication - Add Node-RED for visual automation and complex logic - Add ESPHome for custom ESP32/ESP8266 device firmware - Add AppDaemon for Python-based advanced automations - Include optional monitoring stack (Grafana, Prometheus, databases) - Provide setup and validation scripts for easy deployment - Enterprise-grade features: health checks, resource limits, security hardening This enhanced solution provides a complete, production-ready smart home platform suitable for advanced homelabs and small businesses, offering multi-protocol support and enterprise features missing from the current implementation.
There was a problem hiding this comment.
Pull request overview
This PR expands the stacks/home-automation stack into a more comprehensive “enterprise” smart-home platform by adding setup/validation scripts, richer documentation, and a significantly expanded Docker Compose configuration (including optional services like ESPHome, AppDaemon, and monitoring components).
Changes:
- Added setup and validation bash scripts for bringing up and checking the stack.
- Replaced the prior minimal Compose setup with a much larger compose file including additional services, healthchecks, and a custom network.
- Added an extensive README and a new
.env.exampletemplate for configuration.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 18 comments.
Show a summary per file
| File | Description |
|---|---|
| stacks/home-automation/scripts/validate-home-automation.sh | New validation script to test container/service availability and basic connectivity. |
| stacks/home-automation/scripts/setup-home-automation.sh | New setup script to create directories/configs and start core services. |
| stacks/home-automation/README.md | New end-to-end documentation for installation, usage, and maintenance. |
| stacks/home-automation/docker-compose.yml | Expanded Compose stack with many additional services, bind mounts, healthchecks, and a custom bridge network. |
| stacks/home-automation/docker-compose.original.yml | Added a copy of the previous compose configuration for reference. |
| stacks/home-automation/.env.example | Added an environment template covering core + optional services and tuning flags. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if [ ! -f "$PROJECT_ROOT/docker-compose.home-automation.yml" ]; then | ||
| print_error "Not in home automation stack directory" | ||
| exit 1 |
There was a problem hiding this comment.
The script validates that $PROJECT_ROOT/docker-compose.home-automation.yml exists, but this stack uses docker-compose.yml (and no docker-compose.home-automation.yml exists). This makes the validator fail immediately; update the filename check (and any related references) to match the actual compose file name.
| if docker ps --filter "name=$container" --format "{{.Names}}" | grep -q "^$container\$"; then | ||
| local status=$(docker ps --filter "name=$container" --format "{{.Status}}") | ||
| if echo "$status" | grep -q "healthy\|Up"; then |
There was a problem hiding this comment.
docker ps --filter "name=$container" can match multiple containers (e.g., mosquitto and mosquitto-old), which can produce ambiguous/multi-line status results. Use an anchored name filter (Docker supports regex in the name filter) to ensure the check targets exactly one container.
| # Load environment variables | ||
| if [ -f .env.home-automation ]; then | ||
| export $(grep -v '^#' .env.home-automation | xargs) | ||
| fi |
There was a problem hiding this comment.
export $(grep ... | xargs) is unsafe for .env parsing (breaks on spaces/special chars, drops quotes, and can mis-handle values with #). Prefer set -a; source .env.home-automation; set +a (or a dedicated dotenv parser) to load environment variables reliably.
| volumes: | ||
| - ./data/mosquitto/config:/mosquitto/config | ||
| - ./data/mosquitto/data:/mosquitto/data | ||
| - ./data/mosquitto/log:/mosquitto/log | ||
| - ./config/mosquitto:/etc/mosquitto:ro |
There was a problem hiding this comment.
Mosquitto is configured with a bind-mount ./data/mosquitto/config:/mosquitto/config, which will be empty on first run and hide the image’s default /mosquitto/config/mosquitto.conf, causing Mosquitto to fail to start. Either mount the existing ./mosquitto.conf file to /mosquitto/config/mosquitto.conf or generate/copy a config file into data/mosquitto/config during setup.
| healthcheck: | ||
| test: [CMD-SHELL, "curl -sf http://localhost:8123/ || exit 1"] | ||
| test: ["CMD", "mosquitto_sub", "-h", "localhost", "-t", "\$SYS/broker/uptime", "-C", "1"] | ||
| interval: 30s |
There was a problem hiding this comment.
In this healthcheck command array, the topic is written as \$SYS/..., which will be passed literally to mosquitto_sub (subscribing to \$SYS/... instead of $SYS/...). Since this isn’t executed via a shell, the $ doesn’t need escaping here; remove the backslash so the topic is $SYS/broker/uptime.
| # Home Assistant minimal configuration | ||
| cat > "$PROJECT_ROOT/config/homeassistant/configuration.yaml" << 'EOF' | ||
| # Home Assistant configuration | ||
| default_config: | ||
|
|
There was a problem hiding this comment.
The setup script generates Home Assistant config under config/homeassistant/, but docker-compose.yml mounts ./data/homeassistant to /config. As-is, Home Assistant will not see the generated configuration. Align the generated paths with the bind mount (either generate into data/homeassistant or change the compose mount).
| cat > "$PROJECT_ROOT/config/zigbee2mqtt/configuration.yaml" << 'EOF' | ||
| # Zigbee2MQTT configuration | ||
| homeassistant: true | ||
| permit_join: false | ||
| mqtt: |
There was a problem hiding this comment.
The setup script writes Zigbee2MQTT configuration to config/zigbee2mqtt/configuration.yaml, but Zigbee2MQTT typically reads /app/data/configuration.yaml by default. Align the generated config location with the container’s config path (or adjust the compose mounts) so the generated configuration is actually used.
| # ESPHome - Firmware for ESP devices | ||
| esphome: | ||
| image: ghcr.io/esphome/esphome:latest | ||
| container_name: esphome | ||
| restart: unless-stopped |
There was a problem hiding this comment.
The README describes several services as “optional”, but they are defined unconditionally in docker-compose.yml with no Compose profiles (or split/override compose files) to make them opt-in. Consider using profiles or separate compose files so “optional” services don’t start by default.
| volumes: | ||
| ha-config: | ||
| node-red-data: | ||
| mosquitto-data: | ||
| mosquitto-logs: | ||
| homeassistant-data: | ||
| zigbee2mqtt-data: | ||
| mosquitto-data: | ||
| nodered-data: |
There was a problem hiding this comment.
The compose file declares named volumes here, but services are using bind mounts (./data/..., ./config/...) instead. This leaves unused volume declarations that can confuse operators; either switch services to use these named volumes or remove the unused volume entries.
| # InfluxDB for metrics storage (optional) | ||
| influxdb: | ||
| image: influxdb:latest | ||
| container_name: influxdb | ||
| restart: unless-stopped |
There was a problem hiding this comment.
influxdb:latest is InfluxDB 2.x, but the environment variables and healthcheck in this service are InfluxDB 1.x style. This combination is unlikely to work reliably; either pin to an InfluxDB 1.x image or update config/healthcheck to InfluxDB 2.x conventions (e.g., HTTP /health).
Enhanced enterprise home automation stack with Home Assistant, Zigbee2MQTT, MQTT broker, Node-RED, ESPHome, AppDaemon, and optional monitoring. This PR competes for the 30 bounty for Home Automation Stack improvement.