feat: add documentation for pi relay and home automation
This commit is contained in:
parent
4f7ac0e7d7
commit
3dcd3f00d8
3 changed files with 80 additions and 3 deletions
|
|
@ -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
|
Pi (door sensor) ──webhook──> Cache ──webhook──> Discord / Zulip
|
||||||
|
|
|
|
||||||
polls Pi <-+
|
polls Pi <-+
|
||||||
|
|
|
||||||
|
+──webhook──> Pi relay ──webhook──> Home Assistant
|
||||||
```
|
```
|
||||||
|
|
||||||
## Layout
|
## Layout
|
||||||
|
|
@ -23,3 +25,10 @@ Pi (door sensor) ──webhook──> Cache ──webhook──> Discord / Zulip
|
||||||
Each directory has its own README with setup and configuration details.
|
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.
|
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`.
|
||||||
|
|
|
||||||
69
pi/README.md
69
pi/README.md
|
|
@ -102,6 +102,12 @@ From your laptop:
|
||||||
scripts/deploy-pios-pi.sh pi@noisebell-pi.local
|
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:
|
If you only know the IP:
|
||||||
|
|
||||||
```sh
|
```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_PORT` | `8090` | HTTP port for the relay webhook endpoint |
|
||||||
| `NOISEBELL_RELAY_BIND_ADDRESS` | `0.0.0.0` | HTTP bind address |
|
| `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_TARGET_WEBHOOK_ID` | required | Home Assistant webhook ID |
|
||||||
| `NOISEBELL_RELAY_INBOUND_API_KEY` | required | Bearer token expected from cache-service |
|
| `NOISEBELL_RELAY_INBOUND_API_KEY` | required | Bearer token expected from cache-service |
|
||||||
| `NOISEBELL_RELAY_RETRY_ATTEMPTS` | `3` | Forward retry count |
|
| `NOISEBELL_RELAY_RETRY_ATTEMPTS` | `3` | Forward retry count |
|
||||||
| `NOISEBELL_RELAY_RETRY_BASE_DELAY_SECS` | `1` | Exponential backoff base delay |
|
| `NOISEBELL_RELAY_RETRY_BASE_DELAY_SECS` | `1` | Exponential backoff base delay |
|
||||||
| `NOISEBELL_RELAY_HTTP_TIMEOUT_SECS` | `10` | Outbound request timeout |
|
| `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:
|
Example cache target for the relay:
|
||||||
|
|
||||||
```nix
|
```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
|
## API
|
||||||
|
|
||||||
All endpoints require `Authorization: Bearer <token>`.
|
All endpoints require `Authorization: Bearer <token>`.
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ set -euo pipefail
|
||||||
|
|
||||||
TARGET_HOST=${1:-pi@noisebell-pi.local}
|
TARGET_HOST=${1:-pi@noisebell-pi.local}
|
||||||
DEPLOY_HOSTNAME=${DEPLOY_HOSTNAME:-noisebell-pi}
|
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)
|
SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
|
||||||
REPO_ROOT=$(cd -- "$SCRIPT_DIR/.." && pwd)
|
REPO_ROOT=$(cd -- "$SCRIPT_DIR/.." && pwd)
|
||||||
RELEASE_ID=${RELEASE_ID:-$(date +%Y%m%d-%H%M%S)}
|
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"
|
scp "${SSH_OPTS[@]}" "$TMP_DIR/tailscale-auth-key" "$TARGET_HOST:$REMOTE_TMP_DIR/tailscale-auth-key"
|
||||||
|
|
||||||
echo "Installing service and Tailscale on $TARGET_HOST..."
|
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
|
set -euo pipefail
|
||||||
|
|
||||||
sudo apt-get update
|
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'
|
sudo tee /etc/noisebell/noisebell-relay.env >/dev/null <<'ENVEOF'
|
||||||
NOISEBELL_RELAY_PORT=8090
|
NOISEBELL_RELAY_PORT=8090
|
||||||
NOISEBELL_RELAY_BIND_ADDRESS=0.0.0.0
|
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_ATTEMPTS=3
|
||||||
NOISEBELL_RELAY_RETRY_BASE_DELAY_SECS=1
|
NOISEBELL_RELAY_RETRY_BASE_DELAY_SECS=1
|
||||||
NOISEBELL_RELAY_HTTP_TIMEOUT_SECS=10
|
NOISEBELL_RELAY_HTTP_TIMEOUT_SECS=10
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue