From d3685c10b79f69368449428e087c220161c9c80e Mon Sep 17 00:00:00 2001 From: Brent Musat Date: Thu, 9 Jul 2026 00:14:52 -0500 Subject: [PATCH] Add homekit-ratgdo32 firmware detection and log streaming ESPHome exposes a fixed /events endpoint for detection; homekit-ratgdo32 doesn't, so it falls back to homekit's subscribe-then-stream flow instead. Also adds a docker-compose.yml and a homekit example in the README. --- README.md | 33 ++++++++++++++++++--------------- docker-compose.yml | 23 +++++++++++++++++++++++ ratgdo-logger.sh | 34 ++++++++++++++++++++++++---------- 3 files changed, 65 insertions(+), 25 deletions(-) create mode 100644 docker-compose.yml diff --git a/README.md b/README.md index 0f89044..e2a75f4 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,18 @@ Checking firmware type... 2025-08-01T12:20:03Z data: [D][ratgdo:214]: Learn state=INACTIVE ``` +The [homekit-ratgdo32](https://github.com/ratgdo/homekit-ratgdo32) firmware is also auto-detected: +```bash +$ ./ratgdo-logger.sh 10.0.1.192 +Pinging 10.0.1.192... +✅ Host 10.0.1.192 is reachable. +Checking firmware type... +✅ ratgdo-homekit detected +2026-07-09T03:56:48Z data: I (10:51:51.044) ratgdo-http: Call SetGDO handler for Key: garageLightOn, Value: 1 +2026-07-09T03:56:48Z data: I (10:51:51.059) ratgdo-comms: Light on command already pending; ignored duplicate request +2026-07-09T03:56:48Z data: V (10:51:51.073) ratgdo-http: SetGDO Complete +``` + ## Windows PowerShell * Usage: `.\ratgdo-logger.ps1 -HostName ` * To capture to a file append the command with: ` > my.log` @@ -51,20 +63,11 @@ docker run --rm -v ratgdo-log:/l busybox cat /l/ratgdo.log docker stop ratgdo-logger ``` -
-Compose/stack example +**Or with Docker Compose**, using the [docker-compose.yml](docker-compose.yml) in this repo: -```yaml -version: "3.8" -services: - ratgdo-logger: - image: ghcr.io/ratgdo/remote-logging:latest - environment: - HOST: "" - volumes: - - ratgdo-log:/log - restart: unless-stopped -volumes: - ratgdo-log: +```bash +HOST="" docker compose up -d ``` -
+ +See the comments at the top of that file for the full set of options, including +stopping/cleanup and building locally from source instead of using the published image. diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..b8b08c6 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,23 @@ +# Usage: +# HOST= docker compose up # uses the published ghcr.io image +# HOST= docker compose up --build # builds locally from this directory instead, +# # picking up uncommitted script/README edits +# (add -d or --detach to run in background) +# +# HOST= docker compose down # to stop and remove resources +# HOST= docker compose down -v # remove persistent volume as well + +services: + ratgdo-logger: + image: ghcr.io/ratgdo/remote-logging:latest + build: . + restart: unless-stopped + environment: + # required - which ratgdo device to connect to + HOST: "${HOST:?Set HOST to your ratgdo device's hostname or IP, e.g. HOST=ratgdo1.lan docker compose up --build}" + volumes: + # persists the log file across container restarts + - ratgdo-log:/log + +volumes: + ratgdo-log: diff --git a/ratgdo-logger.sh b/ratgdo-logger.sh index 9740097..68a1f1a 100755 --- a/ratgdo-logger.sh +++ b/ratgdo-logger.sh @@ -23,27 +23,41 @@ else echo "✅ Host $HOST is reachable." fi -# Check if http://HOST/events returns HTTP 200 (ESPHome detected) -URL="http://$HOST/events" echo "Checking firmware type..." -# Test if the /events endpoint exists using GET with a time limit of 2 second, -# since HEAD is not implemented. -STATUS_CODE=$(curl -m 2 -s -o /dev/null -w "%{http_code}" "$URL") +# ESPHome exposes a fixed /events SSE endpoint - test for that first, using +# GET with a time limit of 2 seconds since HEAD is not implemented. +STATUS_CODE=$(curl -m 2 -s -o /dev/null -w "%{http_code}" "http://$HOST/events") -# TO DO: add case for homekit firmware if [ "$STATUS_CODE" -eq 200 ]; then echo "✅ ratgdo-esphome detected" + URL="http://$HOST/events" + MATCH_EVENT="event: log" else - echo "❌ unknown firmware type" - exit 1 + # The homekit firmware has no fixed /events path - you subscribe first and + # it hands back a per-connection channel URL to stream from. The ID just + # needs to be reasonably unique, not a real UUID: the firmware stores and + # compares it as a plain string. + ID="$(date +%s)-$RANDOM" + SUB_PATH=$(curl -m 2 -s "http://$HOST/rest/events/subscribe?id=${ID}&log=1&heartbeat=0") + case "$SUB_PATH" in + /*) + echo "✅ ratgdo-homekit detected" + URL="http://$HOST${SUB_PATH}?id=${ID}" + MATCH_EVENT="event: logger" + ;; + *) + echo "❌ unknown firmware type" + exit 1 + ;; + esac fi # Begin log capture echo "$(date -u +"%Y-%m-%dT%H:%M:%SZ") Logging started" >>"$LOG_FILE" -curl -s --no-buffer $URL | while IFS= read -r line; do +curl -s --no-buffer "$URL" | while IFS= read -r line; do clean_line=$(printf "%s" "$line" | tr -d '\r') - if [[ "$clean_line" == "event: log" ]]; then + if [[ "$clean_line" == "$MATCH_EVENT" ]]; then read -r next_line next_line_clean=$(printf "%s" "$next_line" | tr -d '\r') timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")