SmartestHome/stream-dock/install-ha-package.sh

113 lines
4.8 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# Put the Stream Dock's script package into Home Assistant, and make HA load it.
#
# Two halves, both idempotent:
# 1. copy ha-package/stream_dock.yaml into <HA config>/packages/
# 2. make sure configuration.yaml actually includes that directory — HA's default
# configuration.yaml does NOT enable packages, so without this step the file
# sits there being ignored, which is the single most likely way for this whole
# thing to look broken for no visible reason.
#
# Run it from the repo on any machine that can ssh to the container host:
# stream-dock/install-ha-package.sh
# or on the container host itself:
# stream-dock/install-ha-package.sh --local
#
# It does NOT restart Home Assistant. It reloads scripts and the YAML config over the
# REST API, which is enough for a package of scripts and costs nobody their dashboard.
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
# shellcheck source=/dev/null
source "${REPO_ROOT}/tools/lib/coreconfig.sh"
LOCAL=false
[[ "${1:-}" == "--local" ]] && LOCAL=true
core_load
HA_CONFIG_DIR="${HA_CONFIG_DIR:-/opt/smart-home/homeassistant}"
PACKAGE_SRC="${REPO_ROOT}/stream-dock/ha-package/stream_dock.yaml"
[[ -f "$PACKAGE_SRC" ]] || core_die "missing $PACKAGE_SRC"
# The include line, exactly as it has to appear. Written as a heredoc into a temp file
# and appended only when `packages:` is not already configured — appending a second
# packages: key to a YAML file that has one is a config error, not a merge.
read -r -d '' INCLUDE_SNIPPET <<'YAML' || true
# Added by stream-dock/install-ha-package.sh — lets HA load config/packages/*.yaml.
# If you already have a `homeassistant:` block, move `packages:` under it and delete
# this one; two top-level `homeassistant:` keys is a YAML error.
homeassistant:
packages: !include_dir_named packages
YAML
remote() {
if $LOCAL; then
bash -c "$1"
else
ssh "${CORE_CONTAINER_HOST_USER}@${CORE_CONTAINER_HOST_IP}" "$1"
fi
}
core_log "Installing stream_dock.yaml into ${HA_CONFIG_DIR}/packages/"
if $LOCAL; then
sudo mkdir -p "${HA_CONFIG_DIR}/packages"
sudo cp "$PACKAGE_SRC" "${HA_CONFIG_DIR}/packages/stream_dock.yaml"
else
remote "sudo mkdir -p '${HA_CONFIG_DIR}/packages'"
scp "$PACKAGE_SRC" "${CORE_CONTAINER_HOST_USER}@${CORE_CONTAINER_HOST_IP}:/tmp/stream_dock.yaml"
remote "sudo mv /tmp/stream_dock.yaml '${HA_CONFIG_DIR}/packages/stream_dock.yaml'"
fi
core_log "Checking configuration.yaml for a packages include"
if remote "sudo grep -qE '^[[:space:]]*packages:' '${HA_CONFIG_DIR}/configuration.yaml'"; then
echo " already configured — leaving configuration.yaml alone"
else
printf '%s\n' "$INCLUDE_SNIPPET" > /tmp/stream-dock-include.yaml
if $LOCAL; then
sudo cp "${HA_CONFIG_DIR}/configuration.yaml" "${HA_CONFIG_DIR}/configuration.yaml.bak-streamdock"
sudo tee -a "${HA_CONFIG_DIR}/configuration.yaml" < /tmp/stream-dock-include.yaml >/dev/null
else
scp /tmp/stream-dock-include.yaml "${CORE_CONTAINER_HOST_USER}@${CORE_CONTAINER_HOST_IP}:/tmp/stream-dock-include.yaml"
remote "sudo cp '${HA_CONFIG_DIR}/configuration.yaml' '${HA_CONFIG_DIR}/configuration.yaml.bak-streamdock' && sudo tee -a '${HA_CONFIG_DIR}/configuration.yaml' < /tmp/stream-dock-include.yaml >/dev/null && rm -f /tmp/stream-dock-include.yaml"
fi
rm -f /tmp/stream-dock-include.yaml
echo " appended (previous file kept as configuration.yaml.bak-streamdock)"
core_warn "adding a packages include changes how HA loads config — if HA refuses to"
core_warn "start, restore the .bak-streamdock file and add packages: under your own"
core_warn "existing homeassistant: block by hand"
fi
if [[ -z "${CORE_HA_TOKEN:-}" ]]; then
core_warn "secrets.ha_token is empty — skipping the reload. Restart Home Assistant, or"
core_warn "run Developer Tools -> YAML -> 'Reload all YAML configuration' yourself."
exit 0
fi
core_log "Reloading Home Assistant's YAML configuration"
# reload_all covers scripts and the package include in one call. A non-2xx here is not
# fatal to the install — the files are in place either way — so it reports rather than
# dies, and says what to do by hand.
if curl -fsS -X POST \
-H "Authorization: Bearer ${CORE_HA_TOKEN}" \
-H "Content-Type: application/json" \
-d '{}' \
"${CORE_HA_URL}/api/services/homeassistant/reload_all" >/dev/null; then
echo " reloaded"
else
core_warn "reload call failed — do it by hand in Developer Tools -> YAML, or restart HA"
fi
cat <<EOF
Now check the scripts exist before you bind a single dial:
Developer Tools -> Actions -> search 'Stream Dock'
Run 'Stream Dock: nudge one RGB channel' by hand against a real lamp with
channel: r, ticks: 3, step: 8 and watch the lamp go redder. If that works, the
Home Assistant half is done and everything left is on the desk.
EOF