diff options
Diffstat (limited to 'f3s')
| -rw-r--r-- | f3s/freebsd-hosts/shelly-fans/README.md | 55 | ||||
| -rw-r--r-- | f3s/freebsd-hosts/shelly-fans/shelly-fans-on | 44 | ||||
| -rw-r--r-- | f3s/freebsd-hosts/shelly-fans/shellyfans.rc | 29 |
3 files changed, 128 insertions, 0 deletions
diff --git a/f3s/freebsd-hosts/shelly-fans/README.md b/f3s/freebsd-hosts/shelly-fans/README.md new file mode 100644 index 0000000..85fd899 --- /dev/null +++ b/f3s/freebsd-hosts/shelly-fans/README.md @@ -0,0 +1,55 @@ +# f3s Rack Fans (Shelly Plug) + +The rack fans are powered by a **Shelly Plug M Gen 3** at `192.168.1.28`. Each +f-host (f0/f1/f2/f3) turns the plug on at boot so the fans always run while any +host is up. Turning the plug *off* is handled centrally by `wol-f3s shutdown-all` +(on earth / the Pis), not by the hosts. + +The plug has authentication enabled (HTTP digest, user `admin`). + +## Installed Files + +- `/usr/local/sbin/shelly-fans-on` calls the Shelly RPC API to switch the plug + on, retrying for ~60s in case networking or the plug is briefly unavailable. +- `/usr/local/etc/rc.d/shellyfans` runs the helper at boot, after networking + and after `f3skeys` (so the `/keys` USB stick is already mounted). +- `/keys/shelly_plug.secret` holds the plug password (first line). It lives on + the UFS USB key stick alongside the ZFS encryption keys — **not** in git and + not on the host's own disk. `/keys` is mounted read-only at boot, so adding + the file requires temporarily remounting read-write. + +## Host Configuration + +On each f-host install the scripts and enable the service: + +```sh +doas install -o root -g wheel -m 0555 shelly-fans-on /usr/local/sbin/shelly-fans-on +doas install -o root -g wheel -m 0555 shellyfans.rc /usr/local/etc/rc.d/shellyfans +doas sysrc shellyfans_enable=YES +``` + +Put the plug password on the USB key stick (mounted read-only at `/keys`): + +```sh +doas mount -u -o rw /keys +printf '%s\n' '<password>' | doas tee /keys/shelly_plug.secret >/dev/null +doas chmod 0400 /keys/shelly_plug.secret +doas chown root:wheel /keys/shelly_plug.secret +doas mount -u -o ro /keys +``` + +The same password file is placed on every host's stick (one shared plug). + +## Verification + +```sh +doas service shellyfans start +tail -f /var/log/messages | grep shellyfans # expect "Rack fans switched on" +``` + +After a reboot, confirm the plug reports `output:true`: + +```sh +curl -s --digest -u admin:"$(head -n1 /keys/shelly_plug.secret)" \ + 'http://192.168.1.28/rpc/Switch.GetStatus?id=0' +``` diff --git a/f3s/freebsd-hosts/shelly-fans/shelly-fans-on b/f3s/freebsd-hosts/shelly-fans/shelly-fans-on new file mode 100644 index 0000000..f41ef3d --- /dev/null +++ b/f3s/freebsd-hosts/shelly-fans/shelly-fans-on @@ -0,0 +1,44 @@ +#!/bin/sh +# Turn on the Shelly Plug M Gen 3 that powers the rack fans. +# +# Called at boot by the shellyfans rc service so the rack fans start whenever +# an f-host (f0/f1/f2/f3) comes up. The Shelly plug uses HTTP digest auth +# (user "admin"); the password is read from $SHELLY_PASS_FILE if present. +# +# The password lives on the UFS USB key stick mounted read-only at /keys, +# alongside the ZFS encryption keys. If the stick is missing the file will be +# unreadable and the fans simply will not be switched on (logged, non-fatal). +# +# Networking may not be fully ready the instant this runs at boot, and the +# plug itself may briefly be unreachable, so the call is retried a few times. + +# rc.d runs with a minimal PATH; curl lives in /usr/local/bin. +PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin +export PATH + +SHELLY_IP="${SHELLY_IP:-192.168.1.28}" +SHELLY_PASS_FILE="${SHELLY_PASS_FILE:-/keys/shelly_plug.secret}" + +PASS="" +if [ -r "$SHELLY_PASS_FILE" ]; then + PASS=$(head -n 1 "$SHELLY_PASS_FILE" | tr -d '\r\n') +fi + +AUTH="" +if [ -n "$PASS" ]; then + AUTH="--digest -u admin:$PASS" +fi + +i=0 +while [ "$i" -lt 12 ]; do + if curl -s --max-time 5 $AUTH \ + "http://${SHELLY_IP}/rpc/Switch.Set?id=0&on=true" >/dev/null 2>&1; then + logger -t shellyfans "Rack fans switched on via Shelly plug $SHELLY_IP" + exit 0 + fi + i=$((i + 1)) + sleep 5 +done + +logger -t shellyfans "Failed to reach Shelly plug $SHELLY_IP after retries" +exit 1 diff --git a/f3s/freebsd-hosts/shelly-fans/shellyfans.rc b/f3s/freebsd-hosts/shelly-fans/shellyfans.rc new file mode 100644 index 0000000..d1f4ddc --- /dev/null +++ b/f3s/freebsd-hosts/shelly-fans/shellyfans.rc @@ -0,0 +1,29 @@ +#!/bin/sh + +# PROVIDE: shellyfans +# REQUIRE: NETWORKING f3skeys +# KEYWORD: nojail + +. /etc/rc.subr + +name="shellyfans" +desc="Turn on the rack-fan Shelly plug at boot" +rcvar="shellyfans_enable" +start_cmd="shellyfans_start" +stop_cmd=":" + +: ${shellyfans_enable:="NO"} + +shellyfans_start() +{ + # Run in the background so a slow or unreachable plug cannot delay boot; + # the helper retries on its own. + if [ -x /usr/local/sbin/shelly-fans-on ]; then + /usr/local/sbin/shelly-fans-on & + else + logger -t shellyfans "/usr/local/sbin/shelly-fans-on is missing" + fi +} + +load_rc_config "$name" +run_rc_command "$1" |
