Repository navigation
Operations
See Host Networking for the current Linux container topology, loopback-only maintenance API, explicit add-on migration, listener ports and recovery rules.
This page covers day-to-day operational behavior for RoomGoblin.
cd /opt/classroom-hub
docker compose ps
curl -fsS http://127.0.0.1:3000/health
docker compose logs --tail=200Current expected services are classroom-control-hub and classroom-control-hub-maintenance. The previous Caddy/TLS service is intentionally absent.
LAN access is currently direct HTTP:
http://APPLIANCE-IP:3000/controller/
Restrict TCP/3000 to the trusted classroom/admin network. Keep TRUST_PROXY_HOPS=0 unless a reviewed reverse proxy is intentionally introduced later.
Display clients should reconnect automatically after network or backend interruptions. Verify display ID, direct HTTP/WebSocket connectivity to port 3000, version convergence, and current priority locks when a display is stale.
Morning Announcements are a highest-priority operation.
For Ant Media player URLs, HLS is the primary live-state signal when available:
- 200 + valid
#EXTM3U= LIVE - 404 = OFFLINE
- network/timeout/5xx = UNKNOWN/error
- blocked REST diagnostics do not override HLS
Two confirmed OFFLINE checks are required before ending an active automatic announcement.
When live status is detected, RoomGoblin pauses Background Music, clears/locks the target displays, starts the local HLS player fullscreen, and applies the saved announcement volume/unmute state.
The Announcement Volume slider in Morning Announcements • Live Watch applies to the active announcement immediately and saves the value for future sessions without reloading the stream.
If Clear Classroom or Reload Displays removes an active announcement, Resume Schedule / Resume Scheduled State restores the still-active priority announcement on its targets. When no announcement is active, the same action reconciles normal scheduled content.
Manual Play Announcements enters the same priority state as automatic Live Watch.
When announcements end:
- clear announcement content;
- release the announcement priority lock;
- mark announcement runtime inactive;
- consume deferred-trigger bookkeeping;
- re-evaluate current date/class/time;
- choose the newest currently applicable display automation independently per target;
- re-run those winning automations;
- reconcile/resume Background Music afterward.
This is a failsafe scheduler resync. Each display receives only its newest currently applicable winner. A failed automation re-run is recorded but must not strand the announcement lock or skip Background Music reconciliation. Do not restore stale snapshots or replay every earlier event blindly.
Operator-started video or explicitly audible web/voice/SFX content pauses scheduled automation and all currently playing Music Assistant players. Resume Scheduled State releases the takeover and reconciles managed Background Music; other players remain paused until deliberately restarted.
Background Music is independent of ordinary visual automation. Priority audio pauses it. Recovery checks actual Music Assistant player/group state and resumes only after priority release and display resync are complete.
Linked Class End Time timers follow the active selected class occurrence. Continuation chaining applies only to an explicitly linked continuation of the same underlying base period/class. Adjacent unrelated periods do not chain due only to time proximity.
Transition pseudo-classes are terminal standalone timer occurrences.
The backend /health endpoint validates database and scheduler state. If scheduler.ok=false, inspect the active SQLite schedule/automation records for malformed times or unsupported actions. Database-backed state is authoritative; editing only a legacy JSON mirror may not change readiness.
No-School > Remote > Half Day > 2-Hour Delay > 1-Hour Delay > Normal
No-school suppresses scheduled classroom operations and pauses cycle advancement. Remote days advance the cycle but suppress scheduled classroom operations while manual controls remain available.
Each integration reports independently. Pluto failure must not falsely mark MQTT/Govee offline. Slow optional hardware checks must not block initial Overview rendering.
Expected socket:
/run/classroom-control-hub/host-agent.sock
Verify host and maintenance-container access:
sudo systemctl status classroom-hub-host-agent.service --no-pager -l
sudo test -S /run/classroom-control-hub/host-agent.sock
sudo docker exec classroom-control-hub-maintenance ls -la /run/classroom-control-hub/MAINTENANCE_TOKEN must be non-empty and consistent across the Host Agent, main app, and maintenance service. Avoid printing the token in logs; compare presence/length instead.
Shared runtime directories should remain:
/opt/classroom-hub/data root:10001 0770
/opt/classroom-hub/data/backups root:10001 0700
Retain a verified operational backup or encrypted Full Recovery export first.
Copying a live checkout with cp -a is not a consistent SQLite backup.
sudo bash /opt/classroom-hub/deploy/update-production.sh --plan
sudo bash /opt/classroom-hub/deploy/update-production.shThe updater selects main and requires its exact published image pair before mutation; do not pull source first. Follow Main-based updates for the one-time legacy updater transition and pending-journal recovery.
For development rebuilds after a valid install:
docker compose build --no-cache
docker compose up -d --remove-orphans
docker compose ps
curl -fsS http://127.0.0.1:3000/healthKeep a known-good rollback snapshot until the new release is verified. --remove-orphans cleans up the legacy TLS container when moving forward from a Caddy release.
The web updater pins its current revert snapshot, verifies its SHA-256 digest, and restores matching data while the application is stopped. Pending update requests are kept in a root-only host journal and resume after a restart.
-
ESPHome devices — native enrollment, security boundaries, supported controls, and recovery behavior.
-
ESPHome discovery — automatic mDNS discovery and adoption of already-flashed devices.