This release contains:
- A minimal v1 web UI (Studio + Engineering pages)
- A Go "engine" scaffold with:
- health endpoint
- websocket state stream (meters are truthful in dsp.mode=="live")
- /ws message types (minimal contract):
- Snapshot on connect: {type:"rc_state", rc:{"462":<0..1>,"463":<0..1>}, ts:}
- Meter updates (~20Hz): {type:"meters", data:{"462":<0..1>,"463":<0..1>, ...}, ts:}
- In live mode, the engine polls the DSP at meters.dsp_poll_hz (default 10Hz) and pushes the latest values at meters.publish_hz (default 20Hz).
- If the DSP reports meter values in dBFS (negative), the engine normalizes them using meters.db_floor (default -60): [db_floor..0] -> [0..1].
- (Legacy compatibility) {type:"snapshot"} + {type:"delta"} are still sent for older UIs.
- /ws message types (minimal contract):
- admin endpoints for update/rollback (script-backed)
- Install + service setup scripts
- Git publish helper script
- Faders: 101–110
- Mutes: 121–130
- VU meters: 401–410
Run: ./install.sh
-
v0.4.26: Build fix only (no functional changes): remove an unused Go import that could cause
go testto fail during install. -
v0.4.19:
- VU meters: align segmented thresholds to the printed scale (blue->green at -12; green spans -12..-6).
- Header: replace the top-right pill stack with date/time.
-
v0.4.18: VU meters: make the entire -12 to -6 dB range solid green (operator-friendly "target" zone).
-
v0.4.16: Prevent WLCB Status 5s poll from overwriting the fast (500ms) Recording row (fixes brief timecode back-jumps).
-
v0.4.17: Replace single-gradient VU fills with threshold-based segmented meters (prevents color leakage at low levels) + add brief yellow/red peak glow on fader meters.
-
v0.4.13: Recording status can be polled at 500ms without increasing external WLCB probes (new /api/wlcb/recording).
-
v0.4.15: Smooth recording timecode to prevent tiny backwards jumps caused by out-of-order UDP packets.
-
v0.4.12: Recording UX + robustness:
- Accept UDP payloads as either "," (spec) OR "()" (common Node-RED concatenation).
- Treat missing/"undefined" filename as "Recording".
- Move Recording row to the bottom of WLCB Status.
- Recording row never blinks red (dot still shows red/green).
-
v0.4.11: Add "Recording" telemetry input (UDP) for Node-RED: engine listens on UDP port 55123 (override: WLCB_RECORDING_UDP_PORT). WLCB Status shows "Not Recording" after 5s idle, or " ()" while packets arrive.
-
v0.4.06: WLCB Status card build fix (go test pass). No functional changes.
-
v0.4.10: UI polish: widen PlayIt Live and WLCB Status title pills for stronger visual presence.
-
v0.4.09: UI polish: re-centered PlayIt Live and WLCB Status title pills to match Speakers/Program styling.
-
v0.4.01: Donations: fix GOAL parsing by consulting GiveWP's public form-grid endpoint ("of $GOAL"), which is available even when the goal widget is rendered client-side on the donor-wall page.
-
v0.3.99: Donations: polish GOAL parsing for GiveWP by matching the explicit Goal label/value DOM pair (no heuristics). This makes "Raised $X of $Y for YEAR" reliably include the goal.
-
v0.3.97: Donations UI polish: make the "Raised" line visually match donation rows, and show "Raised $X of $Y for YEAR" when goal is available (with a conservative goal-scrape heuristic fallback).
-
v0.3.95: Studio (cosmetic): prevent PIL label wrap; refine AUTO/LIVE alignment; remove Speakers mute button; add WLCB Status card.
-
v0.3.95: Studio (cosmetic): removed Headphones card; moved Speakers next to PlayIt Live; donations panel expands; PIL label updated; AUTO/LIVE button aligned.
-
v0.3.95: Fix: Engine build regression in PlayIt Live proxy handler (compile/tests pass again).
-
v0.3.95: UI-only: Shrink fader strip vertical sizing so both top+bottom rows fit on 1920×1080 without scrolling.
-
v0.3.95: Hotfix: Studio page can omit the lower panels without breaking hydration. Guarded missing DOM elements (Reconnect / Test DSP buttons) so the UI doesn't throw and stall on "Connecting".
-
v0.3.95: UI-only: Studio page becomes a dedicated two-row fader console. Added a top fader row with placeholders for PIL / Headphones / Program and a LIVE Speakers fader+mute (RC 160/161). Removed the lower Studio-page panels (speakers slider, DSP health, meters) to keep the console uncluttered.
-
v0.3.95: UI-only: Mixer layout — all inter-group gaps are now uniform fixed width (including PC↔Zoom). Any extra horizontal room is left as unused edge space.
-
v0.3.95: UI-only: Layout polish — tightened inter-group gaps and added a small PC↔Zoom separation while preserving no scrolling and no vertical stacking.
-
v0.3.95: UI-only: Mixer fader bank regrouped with elastic gaps so cards stay in a single row with no scrolling and no vertical stacking:
Mic×4 | gap | CD×2 | gap | AUX | gap | BT | gap | PC+Zoom. -
v0.3.95: UI-only (superseded by v0.3.95): initial attempt to spread groups; could cause stereo cards to stack vertically.
-
v0.3.95: UI-only: stereo sources now show dual VU placeholders (L+R) behind the fader lane; UI build version is kept in sync with
VERSION. -
v0.3.95: Studio mixer faders updated with a glass handle (meters visible through) and added level markers on the per-channel VU lanes.
-
v0.3.95: Studio mixer visual blue neon skin pass (dark, flashy, high-tech) — scoped to mixer only; no behavior changes.
-
v0.3.95: Installer health checks are retry-based (tolerant of slow restarts) and print
systemctl/journalctldiagnostics on failure. -
v0.3.95: rc_allowlist repair is mawk-safe (POSIX awk) to avoid install-time awk syntax errors.
-
v0.3.95: Studio mixer (historical): fader positions were persisted in the browser (localStorage) to survive reloads. (Superseded by v0.3.95 DSP/engine-authoritative hydration.)
-
v0.3.95: Studio mixer: add source channel faders (CD1/CD2 grouped, AUX/Bluetooth/PC/Zoom individual cards).
-
v0.3.95: Installer/update self-repairs rc_allowlist to include fader RCs 101–110 so gain writes are not blocked.
-
v0.3.95: Studio mixer: Host fader now writes gain to RC 101 (phased rollout; others remain visual-only).
-
v0.3.95: Studio mixer polish: stronger muted neon red border + slightly brighter live green fill (visual-only).
-
v0.3.95: Studio mixer tactile polish: grabby fader feedback + neon MUTE states (green/live, red/muted) + clearer 0/-12 reference marks.
-
v0.3.95: Studio page now includes a touch-first mixer strip prototype (4 channels) with multitouch-style fader lanes and RC-backed MUTE buttons (operator intent only; faders are visual-only for now).
-
v0.3.95: Engineering now includes a Recent Runtime Events UI-only timeline to provide "When did this change?" context (engine connect/disconnect, engine version/mode changes, DSP health transitions, persisted config loads/saves, and runtime override changes).
-
v0.3.95: Fix: Header Update pill tooltip could still claim "Update available" when the system was up to date. The pill is now always visible as a shortcut to Engineering, and its tooltip/styling are driven only by normalized UI version comparisons (ignoring older engine booleans).
-
v0.3.95: Fix sticky "Update available" tooltip/pill when backend versions are formatted differently (e.g.
v0.3.95vs0.3.09) or an older engine setsupdateAvailable=trueincorrectly. -
v0.3.95: Runtime override badge now includes a tooltip explaining likely source (watchdog vs engine/runtime).
-
v0.3.95: Engineering page clarifies persisted vs runtime mode (label + runtime override badge).
-
v0.3.95: Engineering page config loads reliably after refresh; header shows both UI and engine versions.
-
v0.3.95: Fixes a regression where DSP write mode could fail to persist across refresh/restart if a prior release wrote the mode to the deprecated top-level
modefield (we now migrate it intodsp.mode). -
v0.3.95: Fixes an install-time build failure (
go test) in the/api/healthhandler (invalid nil check + wrong DSP mode field name). -
v0.3.95: Fixes a UI refresh issue where Engineering could show
mock (default)even when the engine's desired DSP write mode islive./api/confignow reports the engine's desired mode, avoiding confusing "flip back to mock" displays after refresh. -
v0.3.95: Fixes an install-time build failure (
go test) caused by an unused variable in the config loader warning path. -
v0.3.95: Fixes a v0.3.95 build failure (missing
DSPHealthSnapshot()compatibility shim) and keeps deprecated top-levelmodein sync withdsp.modewhen saving config to avoid apparent “reverts” after refresh. -
v0.3.95: Fixes unresponsive UI controls (JS syntax error), keeps “DSP Writes”/active mode accurate after refresh, and loads the effective config into the Engineering form without requiring a PIN.
-
v0.3.95: Engineering UI hardening — auto-load the saved config into the Engineering → Configuration form after a browser refresh (avoids the misleading "mock (default)" placeholder state).
-
v0.3.95: Hardening change:
/api/healthand/api/versionnow derivedesiredWriteMode/dspWriteModestrictly from the loaded YAML config (no DSP-health locks). This prevents curl timeouts/"Empty reply" symptoms in LIVE mode and gives the watchdog a deterministic, fast endpoint. -
v0.3.95: Fixes a config precedence bug where a stale
~/.StudioB-UI/config.jsoncould override a newerconfig.v1and keep the engine inmockmode. YAML now wins when it is newer, and the engine syncs JSON to match. -
v0.3.95: Fixes installer build/test failure caused by a
yamlPathvariable typo inengine/internal/config.go(no behavior change). -
Update UI: When an in-app Update completes, the Engineering page now auto-reloads the UI (cache-busted). The “Refresh now” button is still provided as a fallback.
-
v0.3.95: Engineering surfaces engine restart-required state more clearly, and provides a one-click Restart engine now button (admin-only) so you don't have to manually refresh while testing mode changes.
-
DSP control protocol is intentionally gated ("mock mode") until Engineering explicitly enables writes.
-
v0.3.95: Speaker Mute is plumbed through the explicit intent path: UI → intent → engine → (DSP write gate).
- Intents are append-logged to:
~/.StudioB-UI/state/intents.jsonl
- Intents are append-logged to:
-
v0.3.95: Speaker Mute can now perform a real DSP write when
dsp.mode=live. -
The engine uses the Symetrix SymNet Composer control protocol (port 48631).
- Control writes prefer TCP (clear ACK/NAK semantics).
- Meter polling uses UDP by default to avoid TCP session resets observed on some DSPs.
The engine issues:
CS 161 0(unmute) orCS 161 65535(mute) - This release is still strictly scoped to Speaker Mute only.
- Every intent is logged, and every DSP write attempt/result is also logged (append-only JSONL).
-
Update/Rollback are implemented as local git operations on the VM:
- Update: fetch + fast-forward main (or latest tag if configured) then reinstall
- Rollback: checkout a prior git tag and reinstall
GET /api/health— health + versionGET /api/state— full RC snapshot (debug)GET /api/studio/status— stable Studio UI contract (speaker + meters)POST /api/rc/<id>— set allowlisted RC value (debug / interim)POST /api/intent/speaker/mute— Speaker Mute via intent (logs action + timestamp)POST /api/reconnect— operator-safe reconnect (stub)
Repo (source of truth): /home/wlcb/devel/StudioB-UI
Runtime / config / logs (Node-RED style): /home/wlcb/.StudioB-UI/
config/config.ymlruntime/releases/<timestamp-tag>/runtime/current -> runtime/releases/<timestamp-tag>logs/state/
This repo is configured to auto-create GitHub Releases using Release Please.
- Merging to
mainupdates (or opens) a Release PR. - Merging the Release PR tags the repo (e.g.
v0.3.95) and triggers an Actions workflow that builds and uploadsStudioB-UI_vX.Y.Z.zipto the GitHub Release.
The StudioB-UI engine can check GitHub once per minute for releases/latest and queue the newest ZIP into the watched tmp/ folder.
- Journal:
sudo journalctl -u stub-ui-watchdog -f --no-pager - File:
/var/log/stub-ui-watchdog.log(rotated via logrotate)
Adds operator-visible Watchdog health and recent events. No automation behavior changes.
Adds inline visibility of watchdog restart reasons tied to systemd service status. No changes to restart or repair behavior.
Shows systemd "Active:" line and SubState for stub-ui-watchdog verbatim in the Engineering UI. Visibility-only.
Fixes a UI JavaScript syntax error that prevented navigation after v0.3.95.
Adds operator-visible DSP connection health detection. The system warns on stale or disconnected DSP links but does not perform automatic reconnects.
Adds a DSP health history timeline so operators can see recent DSP link state transitions (OK / Degraded / Disconnected) with timestamps. Visibility only; no automatic repair.
Adds an explicit operator-controlled 'Test DSP Now' action. This performs a single DSP connectivity test with a strict timeout and records the result in DSP health and history. No automatic polling or reconnect logic is introduced.
Adds an operator safety gate: if DSP health is Disconnected, DSP control actions are blocked and the UI warns the operator, offering a quick 'Test DSP Now' action. No automatic reconnect behavior is introduced.
Adds defense-in-depth: the engine refuses DSP control commands when DSP health is DISCONNECTED (in live mode). Also adds read-only DSP health and an explicit manual DSP connectivity test endpoint. No polling or auto-repair.
Hotfix for v0.3.95 build failure. Restores successful engine compilation and keeps DSP server-side guard behavior unchanged.
Wires the operator-controlled 'Test DSP Now' to the engine and displays DSP health + a recent timeline. Also adds defense-in-depth: UI and engine both block control commands when DSP is DISCONNECTED. DSP network traffic occurs only on explicit tests.
Hotfix for v0.3.95 build failure (invalid escaped quotes in Go source). No functional changes.
Hotfix for mock-mode workflows: manual 'Test DSP Now' now returns immediately without any network calls. UI also enforces a strict timeout so it never stays stuck on 'Testing…'.
Fixes a UI JavaScript error where DSP timeline rendering failed because a shared getJSON helper was not in scope. No backend or DSP behavior changes.
Adds explicit operator-visible handling for transitions from mock/simulate to live DSP mode. When live mode is entered without a validated DSP link, the UI shows a clear warning banner with manual actions. No automation or background DSP traffic is introduced.
Hotfix restoring the Engineering Configuration load/save helpers. Fixes a UI regression where the config panel could not load or save.
Hotfix for Engineering Configuration: fixes Save regression caused by a missing post-save helper (loadConfigFill/loadConfigPill). Save now completes and the mode pill updates immediately.
Improves LIVE transition visibility by showing the configured DSP endpoint (IP:Port), how long ago the DSP link was last validated, and a warning if DSP config changed since the last LIVE validation. No automation is introduced.
Adds a DSP health summary inside the Engineering Watchdog card so operators can see DSP mode, connection state, recent test time, failures, and LIVE validation context in one place. Visibility-only; no watchdog automation added.
-
mock (default):
- No DSP network traffic
- DSP state begins as UNKNOWN
- Use Test DSP Now to exercise UI + engine paths safely
-
live:
- DSP network traffic is allowed only when explicitly triggered
- Entering live mode does NOT auto-test the DSP
- A visible banner warns until validation is performed
- Switch
dsp.modetolivein Engineering → Configuration - Save configuration
- Observe LIVE warning banner
- Click Test DSP Now once
- Confirm DSP Health = OK and banner clears
- UNKNOWN: no validation performed yet
- OK: last validation succeeded
- Failures: count of consecutive failures
- Timeline: recent validation history
- Watchdog panel always reflects service state
- DSP (summary) shows:
- mode
- last test
- validation age (LIVE)
- config-changed warning if applicable
No automatic repairs or polling are performed. All actions remain explicit and operator-driven.
Fixes a mismatch where Engineering config could be saved but the running engine stayed in the old mode until restart. The engine now applies the validated config in-memory after a successful save, and LIVE transition warnings appear immediately when switching to live.
Hotfix for v0.3.95 compilation errors. Keeps the intended behavior: applying saved config to the running engine without restart.
Hotfix for v0.3.95 compilation errors. Keeps intended behavior: config Save applies immediately to the running engine.
- Adds an always-on, read-only DSP monitor loop so the UI continuously reflects DSP reachability.
- Saving config.yml hot-reloads the engine and API endpoints now reflect the active config immediately.
Hotfix for v0.3.95 build failure. Adds the missing always-on DSP monitor loop implementation and removes an unused import so the engine builds cleanly.
Hotfix for v0.3.95 compilation issue. The DSP monitor loop now receives the engine context when started.
Hotfix for v0.3.95 compilation error (undefined ctx). The DSP monitor loop no longer depends on a context and runs for the lifetime of the engine process under systemd.
Fixes a UI regression where DSP connectivity did not appear to update because the UI only refreshed DSP health on manual actions. The UI now polls /api/dsp/health on a short interval so the continuously updated engine-side DSP monitor status is visible.
Adds an explicit 'Enter LIVE Mode' action that enables DSP control writes only after an operator confirmation. DSP monitoring remains always-on and read-only; LIVE gating affects writes only.
Implements Option 1: the system connects/monitors DSP on startup and allows DSP control writes immediately when config dsp.mode is set to 'live' (no additional operator arming step).
Hotfix for v0.3.95: fixes a JavaScript syntax error that prevented the UI from initializing (buttons unresponsive). Option 1 behavior remains unchanged.
UI clarity update. The header now shows Engine mode separately from DSP connectivity state and DSP write mode, so operators can distinguish simulation state from real DSP connection/controls.
DSP-mode-only fix. StudioB-UI always monitors DSP connectivity on startup. The Engineering mode selector controls DSP write behavior via dsp.mode (mock/live). No new engine config fields were added.
The Engineering page edits the operator config file at ~/.StudioB-UI/config/config.v1 (persisted across updates). Mode changes are applied immediately by hot-reloading the running engine.
- DSP: Symetrix (host/port from config)
- Transport: UDP (prevents "connection reset by peer" failures some DSPs exhibit with rapid TCP polls)
- Meter controllers: 462 (L), 463 (R)
- Values are normalized to 0.0–1.0 using heuristics (0..1, 0..100, 0..65535, or dB using meters.db_floor).
- Transport: UDP (prevents "connection reset by peer" during rapid fader drags)
- Write command:
CS <controller> <0..65535>\r - Truth rule: after sending
CS, the engine performs aGS2readback and only reports success if the DSP reflects the requested value.