#!/bin/bash set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" APPDATA="$SCRIPT_DIR/appdata" STACK_DIR="$SCRIPT_DIR/docker-compose-files/homeassistant" GLOBAL_ENV="$SCRIPT_DIR/.env" STACK_ENV="$STACK_DIR/.env" TMP_DIR="$(mktemp -d)" trap 'rm -rf "$TMP_DIR"' EXIT # Parse a single value from multiple .env files safely (last match wins) get_env_value() { local key="$1" local value="" for f in "$GLOBAL_ENV" "$STACK_ENV"; do if [[ -f "$f" ]]; then line=$(grep -E "^${key}=" "$f" 2>/dev/null | tail -1) || true if [[ -n "$line" ]]; then value="${line#*=}" if [[ "$value" =~ ^\"(.*)\"[[:space:]]*(#.*)?$ ]]; then value="${BASH_REMATCH[1]}" elif [[ "$value" =~ ^\'(.*)\'[[:space:]]*(#.*)?$ ]]; then value="${BASH_REMATCH[1]}" fi fi fi done printf '%s' "$value" } echo "==> Checking required environment variables" REQUIRED_VARS=(TZ SLZB06_HOST CADDY_HOST_IP DOCKERLOGGING_MAXFILE DOCKERLOGGING_MAXSIZE) MISSING=() for var in "${REQUIRED_VARS[@]}"; do if [[ -z "$(get_env_value "$var")" ]]; then MISSING+=("$var") fi done if [[ ${#MISSING[@]} -gt 0 ]]; then echo "Error: missing required variables in .env or $STACK_DIR/.env:" for var in "${MISSING[@]}"; do echo " - $var"; done exit 1 fi # Build a minimal .env containing only the variables each template needs. write_minimal_env() { local tmp_env="$1"; shift : > "$tmp_env" for var in "$@"; do local val val=$(get_env_value "$var") printf '%s="%s"\n' "$var" "$val" >> "$tmp_env" done } echo "==> Creating appdata directories at $APPDATA" sudo mkdir -p \ "$APPDATA/homeassistant" \ "$APPDATA/mqtt/config" echo "==> Copying mosquitto.conf" sudo cp "$STACK_DIR/config/mosquitto.conf" "$APPDATA/mqtt/config/mosquitto.conf" sudo chmod 644 "$APPDATA/mqtt/config/mosquitto.conf" echo "==> Substituting zigbee2mqtt configuration" write_minimal_env "$TMP_DIR/env.zigbee2mqtt" SLZB06_HOST "$SCRIPT_DIR/substitute_env.sh" \ "$STACK_DIR/config/zigbee2mqtt_configuration.yaml" \ "$TMP_DIR/zigbee2mqtt_configuration.yaml" \ "$TMP_DIR/env.zigbee2mqtt" echo "==> Substituting Home Assistant configuration" write_minimal_env "$TMP_DIR/env.ha" CADDY_HOST_IP "$SCRIPT_DIR/substitute_env.sh" \ "$STACK_DIR/config/ha_configuration.yaml" \ "$TMP_DIR/ha_configuration.yaml" \ "$TMP_DIR/env.ha" sudo cp "$TMP_DIR/ha_configuration.yaml" "$APPDATA/homeassistant/configuration.yaml" sudo chmod 644 "$APPDATA/homeassistant/configuration.yaml" echo "==> Copying Home Assistant automations" sudo cp "$STACK_DIR/config/ha_automations.yaml" "$APPDATA/homeassistant/automations.yaml" sudo chmod 644 "$APPDATA/homeassistant/automations.yaml" echo "==> Generating docker-compose.homeassistant.yml" write_minimal_env "$TMP_DIR/env.compose" TZ DOCKERLOGGING_MAXFILE DOCKERLOGGING_MAXSIZE "$SCRIPT_DIR/substitute_env.sh" \ "$STACK_DIR/template.yaml" \ "$SCRIPT_DIR/docker-compose.homeassistant.yml" \ "$TMP_DIR/env.compose" echo "==> Seeding Zigbee2MQTT named volume" docker compose -f "$SCRIPT_DIR/docker-compose.homeassistant.yml" run --rm --no-deps \ --entrypoint /bin/sh \ -v "$TMP_DIR/zigbee2mqtt_configuration.yaml:/source/configuration.yaml:ro" \ zigbee2mqtt -ec ' if [ -f /app/data/configuration.yaml ]; then echo " Preserving existing live Zigbee2MQTT configuration" else cp /source/configuration.yaml /app/data/configuration.yaml echo " Seeded Zigbee2MQTT configuration" fi ' echo "" echo "Done. To deploy:" echo " docker compose -f $SCRIPT_DIR/docker-compose.homeassistant.yml up -d"