Other
Site router swap runbook (Pi + Shelly on same Wi‑Fi)
Use when replacing the on-site travel router (e.g. TP‑Link) with a new unit (e.g. GL.iNet Mango) while the gate Pi and Shelly relay both join that router over Wi‑Fi.
Tye Gym reference: Pi hostname / Tailscale tyegym-gate-001; config in gitignored access-engine/device.env, pushed with repo-root deploy.sh. Record reserved IPs and router notes in Platform → Organization settings → Gate deployment config (YAML/JSON, platform admin only).
How the stack is wired
| Piece | Configuration | After router swap |
|---|---|---|
| Pi → cloud | device.env → deploy.sh writes access-engine/.env on the Pi | Unaffected if Pi gets internet (Tailscale + HTTPS). |
| Pi → Shelly | SHELLY_IP (preferred) or SHELLY_HOST in device.env | Must match Shelly’s new LAN IP if DHCP subnet or lease changes. |
| Shelly → router | Manual (Shelly app / AP setup / web UI) | Re-join Wi‑Fi if SSID/password or band changes. |
| Pi → router | OS Wi‑Fi (not in deploy.sh) | Re-join Wi‑Fi if SSID/password changes. |
The Pi does not discover Shelly automatically — it uses the IP baked into .env. A router swap often changes Shelly’s IP even when both devices “connect fine.”
Design rule (do this on every site)
On the new router, before cutover:
- Pick a stable LAN subnet (e.g.
192.168.8.0/24on Mango — note Mango’s default may differ from TP‑Link’s192.168.0.x/192.168.1.x). - Capture both Wi‑Fi MAC addresses (Pi + Shelly) while still on the old router — see Capture MAC addresses below. Without MACs you cannot reliably pre-configure GL.iNet (or any router) DHCP reservations.
- Add DHCP reservations (static leases) on the Mango before cutover:
pi.wifi_mac→pi.lan_ip(e.g.192.168.8.10)shelly.mac→shelly.lan_ip(e.g.192.168.8.20)
- Save MACs, reserved IPs, and router model in Organization settings → Gate deployment config (YAML) so the next swap does not depend on memory.
- Put
shelly.lan_ipinaccess-engine/device.envasSHELLY_IP=…and redeploy before or immediately after cutover.
Optional but reduces on-site work: use the same SSID and WPA password on the Mango as the old TP‑Link so Pi and Shelly reconnect without re-provisioning — still set static leases and verify SHELLY_IP.
Capture MAC addresses (Pi + Shelly)
Why: GL.iNet (and most travel routers) bind a fixed LAN IP to a client MAC. If you only note “Shelly was 192.168.1.100” on the old router, the new router may hand out a different IP after swap and the Pi’s SHELLY_IP will be wrong.
Record MACs in lowercase with colons (e.g. dc:a6:32:ab:cd:ef) — GL.iNet accepts this format in Clients → … → Bind IP or Network → DHCP → Static DHCP.
| Device | Where to read MAC | Command / UI |
|---|---|---|
| Pi (Wi‑Fi) | wlan0 hardware address | SSH: ip link show wlan0 → line link/ether … |
| Pi (Ethernet) | Only if the gate uses eth0 instead of Wi‑Fi | ip link show eth0 |
| Shelly | Wi‑Fi station MAC on the relay | Shelly app → device → Network / Device info; or old router DHCP client list (hostname often shelly…) |
| Cross-check | Old TP‑Link admin | Connected devices / DHCP leases — match by hostname (tyegym-gate-001, shelly…) or current IP |
Pi example (Tailscale SSH):
ssh porta@tyegym-gate-001 'ip link show wlan0 | awk "/link\\/ether/ {print \$2}"'
Paste into org deployment config (platform admin):
pi:
wifi_mac: dc:a6:32:aa:bb:cc
lan_ip: 192.168.8.10
shelly:
mac: c4:5b:be:xx:yy:zz
lan_ip: 192.168.8.20
Pre-configure GL.iNet Mango (before power-off of old router)
With MACs and target IPs from above:
- Admin UI → Network → LAN — set subnet (e.g.
192.168.8.1/24) and DHCP range. - Network → DHCP (or Clients → select device → Bind IP / “Static address”):
- Add lease: Pi
wifi_mac→pi.lan_ip - Add lease: Shelly
mac→shelly.lan_ip
- Add lease: Pi
- Wireless — create/clone 2.4 GHz SSID (Shelly usually needs 2.4 GHz; Pi can use the same SSID).
- Firewall / guest Wi‑Fi — disable AP isolation / client isolation on the gate SSID.
- Export or screenshot the reservation table and store with the deployment config YAML.
After cutover, both devices should pull the same IPs they were assigned in step 2 without retyping SHELLY_IP (still verify with ping + test_shelly_connection.py).
Phase 0 — Baseline (on old router, from laptop)
Record in the fleet / deployment notes (fleet-checkin-device-registry.md):
| Field | Where to get it |
|---|---|
| Router model / admin URL / password | Label / client |
| Wi‑Fi SSID, password, band (2.4 vs 5) | TP‑Link admin; Shelly is usually 2.4 GHz only |
| LAN subnet & DHCP range | Router LAN settings |
| Pi Wi‑Fi MAC (required for GL.iNet reservation) | ssh porta@tyegym-gate-001 → ip link show wlan0 (link/ether) |
| Pi current LAN IP | ip -4 addr show wlan0 |
| Shelly Wi‑Fi MAC (required for GL.iNet reservation) | Shelly app → device → network; or old router DHCP client list |
| Shelly current LAN IP | Shelly app or DHCP list |
SHELLY_IP in local device.env | Your laptop copy (must equal Shelly’s real IP) |
SHELLY_API, SHELLY_USER, SHELLY_PASSWORD | device.env |
| Tailscale status | tailscale status on Pi — confirm node online |
| Smoke test | From Pi: cd …/access-engine && ./venv/bin/python test_shelly_connection.py |
If test_shelly_connection.py fails before the swap, fix Shelly/network first.
Phase 1 — Prepare Mango (bench or on-site, old router still running)
- Flash/update Mango firmware if needed.
- LAN: Set subnet and DHCP range; enable DHCP reservation for Pi + Shelly MACs (from Phase 0).
- Wi‑Fi: Either:
- A — Same SSID/password as TP‑Link (fastest reconnect), or
- B — New SSID/password (plan time to reconfigure Pi Wi‑Fi + Shelly manually).
- 2.4 GHz: Ensure a 2.4 GHz AP exists (Shelly Mini / Plus often won’t stay on 5 GHz-only).
- WAN: Plug uplink (gym internet / modem). Confirm Mango gets internet (ping
1.1.1.1from admin UI). - Disable client isolation / “AP isolation” if enabled (Pi must reach Shelly on LAN).
- Do not power off the TP‑Link until Phase 3 — keep it as rollback.
Phase 2 — Update device.env (laptop, before cutover if IPs are pre-planned)
# access-engine/device.env (local, gitignored)
SHELLY_IP=192.168.8.20 # reserved Shelly IP on Mango
# SHELLY_API=rpc # Mini Gen3 / Plus — if already in use, keep unchanged
# SHELLY_USER=admin
# SHELLY_PASSWORD=...
If you are keeping the same Shelly IP on the same subnet and only swapping router hardware with cloned settings, you may skip changing SHELLY_IP — but verify the Shelly lease after swap anyway.
Phase 3 — Cutover (target ~30–45 min)
Order matters: router first, then confirm LAN, then Shelly, then Pi config deploy.
- Power off TP‑Link; power on Mango; wait for Wi‑Fi + DHCP stable.
- Shelly
- If same SSID/password: wait 2–5 min; check Shelly app — online?
- If offline or new SSID: Shelly AP mode → join new Wi‑Fi (manual, same as original install).
- Confirm Shelly has the reserved IP (app or Mango DHCP list).
- Pi
- If same SSID/password: Pi should reconnect; confirm via Tailscale (
ping tyegym-gate-001or SSH). - If new SSID: attach keyboard/monitor or pre-stage
wpa_supplicant/raspi-config/ DietPi Wi‑Fi — not handled bydeploy.sh.
- If same SSID/password: Pi should reconnect; confirm via Tailscale (
- From Pi (SSH via Tailscale):
ip -4 addr show wlan0 ping -c 2 <SHELLY_IP> cd ~/member-access-os/access-engine # or your deploy path ./venv/bin/python test_shelly_connection.py - From laptop (updates
.envon Pi fromdevice.env):PI_USER=porta PI_HOST=tyegym-gate-001 ./deploy.sh access-engine/device.env - Restart & watch:
ssh porta@tyegym-gate-001 'sudo systemctl restart member-access && sudo journalctl -u member-access -n 50 --no-pager' - Physical test: authorized tag/wallet tap → strike clicks; denied tap → no strike.
- Portal: Gate activity / heartbeat still updating for the facility access point.
Phase 4 — Rollback
If Shelly or Pi cannot join Mango within the visit window:
- Power off Mango; power on TP‑Link.
- Wait for Pi + Shelly to reconnect to old Wi‑Fi.
- If you already deployed new
SHELLY_IP, either redeploy olddevice.envor restore previousSHELLY_IPand rundeploy.shagain.
Keep the TP‑Link in the kit until one full business day passes with no gate faults.
Verification checklist
| # | Check | Pass |
|---|---|---|
| 1 | Mango has internet on WAN | |
| 2 | Pi online on Tailscale | |
| 3 | Pi wlan0 has expected IP | |
| 4 | Shelly online in Shelly app at reserved IP | |
| 5 | ping Shelly from Pi | |
| 6 | test_shelly_connection.py → HTTP 200 | |
| 7 | Live tap grants access + strike | |
| 8 | Live deny does not strike | |
| 9 | device.env SHELLY_IP matches Shelly LAN IP | |
| 10 | Pi + Shelly MACs recorded in org Gate deployment config | |
| 11 | GL.iNet DHCP reservations match those MACs → expected IPs | |
| 12 | Deployment log updated (router model, date, IPs, MACs) |
Common failures
| Symptom | Likely cause | Fix |
|---|---|---|
| Tap grants in logs, door silent | Wrong SHELLY_IP or SHELLY_API | Fix device.env, redeploy; test with test_shelly_connection.py |
| Pi online, Shelly offline | Shelly on wrong SSID / 5 GHz only / wrong password | Manual Shelly Wi‑Fi setup |
| Nothing on Tailscale | Pi Wi‑Fi not joined or Mango has no WAN | Fix Pi Wi‑Fi or Mango uplink first |
| Shelly works from app, Pi cannot ping | AP/client isolation or different VLAN | Disable isolation; same LAN for both |
| Worked on TP‑Link, broke on Mango | Subnet changed (192.168.1.x → 192.168.8.x) | Update SHELLY_IP + reservations |
Related
access-engine/device.env.example—SHELLY_*variableson-site-install-10-minute-runbook.md— pre-staged deploy mindsetfirst-client-preflight-checklist.md— §0 network, §7 relay smoke test