diff --git a/README.md b/README.md index 96f5bc1..4d4f39d 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,8 @@ A Raspberry Pi reads a magnetic sensor on the door and pushes state changes to a Pi (door sensor) ──webhook──> Cache ──webhook──> Discord / Zulip | polls Pi <-+ + | + +──webhook──> Pi relay ──webhook──> Home Assistant ``` ## Layout @@ -23,3 +25,10 @@ Pi (door sensor) ──webhook──> Cache ──webhook──> Discord / Zulip Each directory has its own README with setup and configuration details. For hosted deployment, another repo such as `../extremist-software` imports `noisebell.nixosModules.default`. That host repo provides deployment-specific values like domains, ports, and the Pi address, while the Noisebell module itself points `agenix` at the encrypted files in `secrets/` and consumes the decrypted runtime files on the target machine. + +Useful commands: + +- `./scripts/nhs` redeploys the remote cache host using the local checkout as the flake input +- `scripts/deploy-pios-pi.sh pi@100.66.45.36` redeploys the Raspberry Pi OS machine + +The full Home Assistant relay workflow is documented in `pi/README.md`. diff --git a/pi/README.md b/pi/README.md index 8271391..76b26eb 100644 --- a/pi/README.md +++ b/pi/README.md @@ -102,6 +102,12 @@ From your laptop: scripts/deploy-pios-pi.sh pi@noisebell-pi.local ``` +If Home Assistant is on a fixed LAN IP, set that explicitly during deploy: + +```sh +HOME_ASSISTANT_BASE_URL=http://10.21.0.43:8123 scripts/deploy-pios-pi.sh pi@100.66.45.36 +``` + If you only know the IP: ```sh @@ -186,13 +192,15 @@ The optional relay service accepts authenticated webhooks from cache-service and |---|---|---| | `NOISEBELL_RELAY_PORT` | `8090` | HTTP port for the relay webhook endpoint | | `NOISEBELL_RELAY_BIND_ADDRESS` | `0.0.0.0` | HTTP bind address | -| `NOISEBELL_RELAY_TARGET_BASE_URL` | `http://homeassistant.local:8123` | Base URL for Home Assistant | +| `NOISEBELL_RELAY_TARGET_BASE_URL` | `http://10.21.0.43:8123` | Base URL for Home Assistant | | `NOISEBELL_RELAY_TARGET_WEBHOOK_ID` | required | Home Assistant webhook ID | | `NOISEBELL_RELAY_INBOUND_API_KEY` | required | Bearer token expected from cache-service | | `NOISEBELL_RELAY_RETRY_ATTEMPTS` | `3` | Forward retry count | | `NOISEBELL_RELAY_RETRY_BASE_DELAY_SECS` | `1` | Exponential backoff base delay | | `NOISEBELL_RELAY_HTTP_TIMEOUT_SECS` | `10` | Outbound request timeout | +If `.local` resolution is reliable on your Pi, you can override the deploy default with `HOME_ASSISTANT_BASE_URL=http://homeassistant.local:8123`. + Example cache target for the relay: ```nix @@ -206,6 +214,65 @@ Example cache target for the relay: } ``` +## Home Assistant workflow + +The working Home Assistant path is: + +```text +Pi door sensor -> cache-service -> Pi relay -> Home Assistant webhook automation +``` + +This keeps cache-service as the fanout source while still letting Home Assistant stay LAN-only. + +Setup summary: + +1. Pi still posts raw door events to cache via `NOISEBELL_ENDPOINT_URL` +2. cache-service fans out to `http://noisebell-pi:8090/webhook` using `relay-webhook-secret.age` +3. `noisebell-relay` forwards the payload to Home Assistant using `homeassistant-webhook-id.age` +4. Home Assistant automation triggers on the webhook and switches devices based on `trigger.json.status` + +Payload received by Home Assistant: + +```json +{ + "status": "open", + "timestamp": 1774336193 +} +``` + +Example Home Assistant automation: + +```yaml +alias: noisebell +description: "" +triggers: + - trigger: webhook + allowed_methods: + - POST + local_only: false + webhook_id: "-roWWM0JVCWSispwyHXlcKtjI" +conditions: [] +actions: + - if: + - condition: template + value_template: "{{ trigger.json.status == 'open' }}" + then: + - action: switch.turn_on + target: + entity_id: switch.mini_smart_plug_socket_1 + else: + - if: + - condition: template + value_template: "{{ trigger.json.status == 'closed' }}" + then: + - action: switch.turn_off + target: + entity_id: switch.mini_smart_plug_socket_1 +mode: single +``` + +Important: Home Assistant webhook IDs are exact. If the automation shows a leading `-`, keep that same leading `-` in `homeassistant-webhook-id.age`. + ## API All endpoints require `Authorization: Bearer `. diff --git a/scripts/deploy-pios-pi.sh b/scripts/deploy-pios-pi.sh index 21e2eb2..21a0d21 100755 --- a/scripts/deploy-pios-pi.sh +++ b/scripts/deploy-pios-pi.sh @@ -3,6 +3,7 @@ set -euo pipefail TARGET_HOST=${1:-pi@noisebell-pi.local} DEPLOY_HOSTNAME=${DEPLOY_HOSTNAME:-noisebell-pi} +HOME_ASSISTANT_BASE_URL=${HOME_ASSISTANT_BASE_URL:-http://10.21.0.43:8123} SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd) REPO_ROOT=$(cd -- "$SCRIPT_DIR/.." && pwd) RELEASE_ID=${RELEASE_ID:-$(date +%Y%m%d-%H%M%S)} @@ -65,7 +66,7 @@ scp "${SSH_OPTS[@]}" "$TMP_DIR/homeassistant-webhook-id" "$TARGET_HOST:$REMOTE_T scp "${SSH_OPTS[@]}" "$TMP_DIR/tailscale-auth-key" "$TARGET_HOST:$REMOTE_TMP_DIR/tailscale-auth-key" echo "Installing service and Tailscale on $TARGET_HOST..." -ssh "${SSH_OPTS[@]}" "$TARGET_HOST" "DEPLOY_HOSTNAME='$DEPLOY_HOSTNAME' REMOTE_RELEASE_DIR='$REMOTE_RELEASE_DIR' REMOTE_CURRENT_LINK='$REMOTE_CURRENT_LINK' REMOTE_TMP_DIR='$REMOTE_TMP_DIR' bash -s" <<'EOF' +ssh "${SSH_OPTS[@]}" "$TARGET_HOST" "DEPLOY_HOSTNAME='$DEPLOY_HOSTNAME' HOME_ASSISTANT_BASE_URL='$HOME_ASSISTANT_BASE_URL' REMOTE_RELEASE_DIR='$REMOTE_RELEASE_DIR' REMOTE_CURRENT_LINK='$REMOTE_CURRENT_LINK' REMOTE_TMP_DIR='$REMOTE_TMP_DIR' bash -s" <<'EOF' set -euo pipefail sudo apt-get update @@ -114,7 +115,7 @@ sudo chmod 600 /etc/noisebell/noisebell.env sudo tee /etc/noisebell/noisebell-relay.env >/dev/null <<'ENVEOF' NOISEBELL_RELAY_PORT=8090 NOISEBELL_RELAY_BIND_ADDRESS=0.0.0.0 -NOISEBELL_RELAY_TARGET_BASE_URL=http://homeassistant.local:8123 +NOISEBELL_RELAY_TARGET_BASE_URL=$HOME_ASSISTANT_BASE_URL NOISEBELL_RELAY_RETRY_ATTEMPTS=3 NOISEBELL_RELAY_RETRY_BASE_DELAY_SECS=1 NOISEBELL_RELAY_HTTP_TIMEOUT_SECS=10