[PR #4] [MERGED] Network widget + admin fixes #4

Closed
opened 2026-08-09 19:09:24 +02:00 by zaph0d · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/niels-emmer/wall-cast/pull/4
Author: @niels-emmer
Created: 3/22/2026
Status: Merged
Merged: 3/22/2026
Merged by: @niels-emmer

Base: mainHead: network


📝 Commits (8)

  • 9fc6299 feat(network): add Network widget with WAN, connectivity, DNS, hosts, speedtest
  • b107439 feat(admin): add network widget to rotator defaults and add-slot UI
  • bc82e2b feat(network): move router password to .env, add admin panel section
  • 10a2ada fix(network): pass shared.network through get_config() merge
  • dbd1f57 fix(network): remove divider + ETH badge to fit small slot
  • 5f3fbb6 fix(caster): add cooldown to prevent recast loop on false-negative status
  • 234e755 fix(admin): stop save from overwriting in-progress draft edits
  • 0ca11ba docs: update memory for network widget, caster fix, admin save fix

📊 Changes

16 files changed (+1022 additions, -16 deletions)

View changed files

📝 .env.example (+7 -0)
📝 backend/app/main.py (+2 -1)
backend/app/routers/network.py (+440 -0)
📝 backend/app/wall_config.py (+2 -0)
📝 backend/requirements.txt (+1 -0)
📝 caster/cast.py (+10 -1)
📝 config/wall-cast.example.yaml (+12 -0)
📝 docs/config-reference.md (+39 -0)
📝 docs/memory/INDEX.md (+17 -2)
📝 docs/memory/records/decision-log.md (+24 -0)
📝 frontend/src/admin/AdminPanel.tsx (+152 -12)
frontend/src/hooks/use-network.ts (+12 -0)
📝 frontend/src/types/api.ts (+38 -0)
📝 frontend/src/types/config.ts (+7 -0)
📝 frontend/src/widgets/base-registry.ts (+2 -0)
frontend/src/widgets/network/NetworkWidget.tsx (+257 -0)

📄 Description

Summary

  • Network widget — new network type widget showing WAN status (IP, uptime), external connectivity + latency, DNS server reachability (Cloudflare / Google), LAN host count (ethernet / wifi split), and live speedtest (Cloudflare, capped download/upload). Optional Zyxel VMG8825 router integration via DAL API (RSA+AES auth). Router password stored in ROUTER_PASSWORD env var, never in YAML.
  • Admin panel — rotator "Add slot" UIRotatorSection now has a Select + Add button so any widget type can be added to an existing rotator without hand-editing YAML. Also adds a ✕ remove button per slot.
  • Admin panel — network widget section — new "Network widget" section in General tab for router URL and username (saved to YAML). Password field is read-only with a note pointing to .env.
  • Admin panel — draft overwrite bug fixed — saving config then editing further would silently discard changes when the background refetch landed. Fixed by guarding the useEffect with draft === null and replacing invalidateQueries with setQueryData after save.
  • Caster — recast loop fixedcatt status returns a false negative immediately after cast_site completes, causing the caster to recast every 60 s and constantly reload the display (widgets flashing "unavailable"). Fixed with a per-screen last_cast_at cooldown (default 5 min, CAST_COOLDOWN env var).
  • get_config() merge fixshared.network was silently dropped from the merged config dict, so the network router always saw an empty config and never connected to the router. Added explicit forwarding.
  • Docs — memory index and decision log updated with all of the above.

Test plan

  • docker compose up --build -d on server — no build errors
  • Network widget appears in rotation on display
  • WAN row shows IP + uptime (requires ROUTER_PASSWORD in .env and router_url in YAML)
  • LAN row shows host count with eth/wifi split
  • Admin → General → Network widget section visible; URL + username save to YAML
  • Admin → Screens → rotator: "Add slot" dropdown shows available widget types; "network" not shown if already in rotation; ✕ removes slots
  • Save config, make further edits — edits are not lost (draft overwrite bug)
  • Caster log shows OK (cast Xs ago) instead of recasting every 60 s

🤖 Generated with Claude Code


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/niels-emmer/wall-cast/pull/4 **Author:** [@niels-emmer](https://github.com/niels-emmer) **Created:** 3/22/2026 **Status:** ✅ Merged **Merged:** 3/22/2026 **Merged by:** [@niels-emmer](https://github.com/niels-emmer) **Base:** `main` ← **Head:** `network` --- ### 📝 Commits (8) - [`9fc6299`](https://github.com/niels-emmer/wall-cast/commit/9fc62999436c018832f8fff01e1d8f9a0f07adfa) feat(network): add Network widget with WAN, connectivity, DNS, hosts, speedtest - [`b107439`](https://github.com/niels-emmer/wall-cast/commit/b10743985d84b351d8725e8119b82c5e4ec7c30b) feat(admin): add network widget to rotator defaults and add-slot UI - [`bc82e2b`](https://github.com/niels-emmer/wall-cast/commit/bc82e2bc871d94e165795a3a917c7f7478b34c7e) feat(network): move router password to .env, add admin panel section - [`10a2ada`](https://github.com/niels-emmer/wall-cast/commit/10a2adae404ecdc83daa563d15046136f4f980e1) fix(network): pass shared.network through get_config() merge - [`dbd1f57`](https://github.com/niels-emmer/wall-cast/commit/dbd1f57fb1de3316d19a75e3ce07ba7705c602b8) fix(network): remove divider + ETH badge to fit small slot - [`5f3fbb6`](https://github.com/niels-emmer/wall-cast/commit/5f3fbb6abfdbcdb91941bc3923295d660e6e0015) fix(caster): add cooldown to prevent recast loop on false-negative status - [`234e755`](https://github.com/niels-emmer/wall-cast/commit/234e755a8334242bdbc05d09f196a83415673b94) fix(admin): stop save from overwriting in-progress draft edits - [`0ca11ba`](https://github.com/niels-emmer/wall-cast/commit/0ca11ba4254bfdd0cc5283c447676d0c50562fa5) docs: update memory for network widget, caster fix, admin save fix ### 📊 Changes **16 files changed** (+1022 additions, -16 deletions) <details> <summary>View changed files</summary> 📝 `.env.example` (+7 -0) 📝 `backend/app/main.py` (+2 -1) ➕ `backend/app/routers/network.py` (+440 -0) 📝 `backend/app/wall_config.py` (+2 -0) 📝 `backend/requirements.txt` (+1 -0) 📝 `caster/cast.py` (+10 -1) 📝 `config/wall-cast.example.yaml` (+12 -0) 📝 `docs/config-reference.md` (+39 -0) 📝 `docs/memory/INDEX.md` (+17 -2) 📝 `docs/memory/records/decision-log.md` (+24 -0) 📝 `frontend/src/admin/AdminPanel.tsx` (+152 -12) ➕ `frontend/src/hooks/use-network.ts` (+12 -0) 📝 `frontend/src/types/api.ts` (+38 -0) 📝 `frontend/src/types/config.ts` (+7 -0) 📝 `frontend/src/widgets/base-registry.ts` (+2 -0) ➕ `frontend/src/widgets/network/NetworkWidget.tsx` (+257 -0) </details> ### 📄 Description ## Summary - **Network widget** — new `network` type widget showing WAN status (IP, uptime), external connectivity + latency, DNS server reachability (Cloudflare / Google), LAN host count (ethernet / wifi split), and live speedtest (Cloudflare, capped download/upload). Optional Zyxel VMG8825 router integration via DAL API (RSA+AES auth). Router password stored in `ROUTER_PASSWORD` env var, never in YAML. - **Admin panel — rotator "Add slot" UI** — `RotatorSection` now has a Select + Add button so any widget type can be added to an existing rotator without hand-editing YAML. Also adds a ✕ remove button per slot. - **Admin panel — network widget section** — new "Network widget" section in General tab for router URL and username (saved to YAML). Password field is read-only with a note pointing to `.env`. - **Admin panel — draft overwrite bug fixed** — saving config then editing further would silently discard changes when the background refetch landed. Fixed by guarding the `useEffect` with `draft === null` and replacing `invalidateQueries` with `setQueryData` after save. - **Caster — recast loop fixed** — `catt status` returns a false negative immediately after `cast_site` completes, causing the caster to recast every 60 s and constantly reload the display (widgets flashing "unavailable"). Fixed with a per-screen `last_cast_at` cooldown (default 5 min, `CAST_COOLDOWN` env var). - **`get_config()` merge fix** — `shared.network` was silently dropped from the merged config dict, so the network router always saw an empty config and never connected to the router. Added explicit forwarding. - **Docs** — memory index and decision log updated with all of the above. ## Test plan - [ ] `docker compose up --build -d` on server — no build errors - [ ] Network widget appears in rotation on display - [ ] WAN row shows IP + uptime (requires `ROUTER_PASSWORD` in `.env` and `router_url` in YAML) - [ ] LAN row shows host count with eth/wifi split - [ ] Admin → General → Network widget section visible; URL + username save to YAML - [ ] Admin → Screens → rotator: "Add slot" dropdown shows available widget types; "network" not shown if already in rotation; ✕ removes slots - [ ] Save config, make further edits — edits are not lost (draft overwrite bug) - [ ] Caster log shows `OK (cast Xs ago)` instead of recasting every 60 s 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
zaph0d 2026-08-09 19:09:24 +02:00
Sign in to join this conversation.
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
github-mirrors/wall-cast#4
No description provided.