This is an old revision of the document!
OnAirScreen 1.0.0 — Release Notes
Release date: September 2026
Previous baseline: 0.9.8
Version 1.0.0
OnAirScreen 1.0.0 is the first major version after years of 0.9 in real studios. What 0.9.8 made a connected broadcast companion — Web-UI, MQTT, top-of-hour countdown — 1.0.0 puts on the same screen: loudness, AoIP, analog clock faces, mixer GPI, and Stream Deck.
Since 0.9.8, the work has gone into audio, studio workflow, remote control, and day-to-day reliability. Whether you run OnAirScreen on a studio PC, a Raspberry Pi behind the monitor, or headless in the rack — this is the release that meters the programme, talks to the mixer, and stays controllable from the desk.
If you have been waiting for meters on the on-air display: this is it.
Highlights at a Glance
| Area | What's new |
|---|---|
| Audio meters | Stereo L/R, programme LUFS (EBU R128), or both |
| AoIP | Local sound card, Axia Livewire, or AES67 (SAP / pasted SDP) |
| Clocks | Digital, Analog, Numbers, Studio, Railway, and 24h faces |
| Raspberry Pi | Mixer GPI via GPIO — up to eight inputs to LEDs and AIR timers |
| Remote | Bitfocus Companion / Stream Deck, OSC, Web-UI with settings |
| Alarms | TOO LOUD and Silence Detection on the current audio source |
| Quality | PySide6, crash logs, CPU-friendly meters on Raspberry Pi |
| Docs & licence | Updated manuals; OnAirScreen Source-Available License (OASL 1.0) |
New Features
Audio Meters & Loudness
Studios asked for meters on the on-air display. 1.0.0 has them, full height on the left, configured under Settings → Audio Meters:
- Layouts: L/R only, programme LUFS only, or both (
Audio/layout:lr/lufs/both) - Stereo L/R bars with RMS fill and peak overlay
- Display units: dBFS, dBTP (true peak), BBC PPM (Type IIa, marks 1–7)
- Programme LUFS bar (EBU R128): momentary M with a short-term S tick
- Optional gated Integrated I + LRA — off until you start a session
- Peak hold marker (default 1.5 s, can be disabled)
- Display style Solid or Bargraph
- LUFS reference peg via presets (EBU R128 −23, ATSC A/85 −24, AES −16/−18, Custom)
- Adjustable meter width (up to 201 px; extra width thickens the L/R bars)
Default for new installs is L/R + LUFS (both), unit dBTP, Too Loud on.
Integrated I + LRA stays off until started, so a show can sit on M/S all day and only open a gated session when you need it:
| Method | Command / Action |
|---|---|
| UDP / HTTP | LUFSI:START, LUFSI:STOP, LUFSI:TOGGLE, LUFSI:RESET |
| Web-UI | Loudness I+LRA tile (live I and LRA) |
| MQTT | {base_topic}/lufs/integrated/set — Home Assistant switch + reset button |
| OSC | /oas/lufs/integrated, /oas/lufs/integrated/reset |
| Main screen | Right-click / long-press → Start I+LRA, Stop I+LRA, Reset I+LRA |
LUFSI:RESET restarts a running session, or hides frozen I/LRA when the session is stopped. /api/status includes lufsIntegrated, lufsI, and lra.
Audio Sources: Local, Livewire, AES67
The same meters can follow a local sound card or the studio AoIP network:
- Local Input — PortAudio capture (mic/line)
- Livewire — Axia Livewire AoIP multicast: advertised sources while Settings are open (
239.192.255.3UDP 4001), or channel 1–32767 (channel N →239.192.0.0+NUDP 5004, L24/48 kHz stereo) - AES67 — multicast RTP via SAP (
239.255.255.255and RFC 2974224.2.127.254UDP 9875) or a pasted SDP; L16/L24 at 44.1/48/96 kHz; meters use the first two channels
A shared AoIP Interface selects the NIC for Livewire/AES67 IGMP join (empty = system route). After Apply, capture continues from the stored channel or multicast address even if advertisements stop.
The Web-UI settings overlay has the same Livewire Source and AES67 Stream dropdowns with live discovery and Paste SDP.
TOO LOUD & Silence Detection
TOO LOUD (optional): when true peak exceeds the threshold, show an on-screen warning (priority 1) or trigger LED 1–4. The dBTP ceiling peg uses that threshold.
Silence Detection watches the current audio source (Local / Livewire / AES67):
- Sample-peak dBFS threshold, duration (default 10 s), and recovery time
- Optional on-screen WARN
- Optional HTTP GET on trigger
- Option to treat a missing device or stream as silence (on by default)
- API boolean
silencein/api/statusand WebSocket - MQTT
{base_topic}/silence/active— Home Assistant binary sensor
Clock Faces
The clock can match the room. Choose a face in Settings (dropdown, not Digital/Analog radio buttons). LEDs, timers, meters, and branding stay put.
| Face | Look |
|---|---|
| Digital | LED digits and seconds ring |
| Analog | Classic ticks and hands, no numerals |
| Analog Numbers | 1–12 on the classic analog face |
| Analog Studio | White face with black 1–12 |
| Analog Railway | Station clock with a red ring second hand |
| Analog 24h smooth | Cream face, black 1–12 and red 13–24, sweeping second |
| Analog 24h ticking | Same 24h face with a ticking second hand |
Setting: Clock/face. Remote: CONF:Clock:face= with digital, analog, analog_numbers, analog_studio, analog_railway, analog_24h_smooth, or analog_24h_ticking. Legacy CONF:Clock:digital=False still selects the classic analog face.
Time source remains local clock, NTP, software PTPv2, or SMPTE LTC — as in 0.9.8. The OS clock is never set.
Raspberry Pi GPIO (Mixer GPI)
On Raspberry Pi, mixer GPI contacts can light the LEDs and start the AIR timers — up to eight inputs. Configure under Settings → GPIO. Included with the Raspberry Pi shop build and the SD image.
- Map each GPI to LED1–4, AIR1–4, AIR3/AIR4 Reset, or a custom API command
- Modes: level, rising, falling, or both; invert and debounce
- Factory mapping for a two-wire mixer GPI: GPI1 BCM 17 → LED1 (ON AIR), GPI2 BCM 27 → AIR3 (radio timer)
- Pi GPIO is 3.3 V — use a PC817 isolation module for mixer GPI (5–24 V / open collector); dry relays to GND may be wired directly
- Wiring diagrams and pinout links are in the manuals
GPIO is local hardware, not a network API. Packaged builds load system python3-gpiozero / python3-lgpio.
Bitfocus Companion & Stream Deck
The dedicated astrastudio-OnAirScreen Companion module is the recommended Stream Deck path:
- Commands over HTTP (default port 8010):
GET /api/command?cmd=LED1:ON - Live status over WebSocket (HTTP port + 1, default 8011), with poll fallback to
/api/status - OSC is not required
- Presets for LED1–4, AIR1–4 with live time on the button (MIC = AIR1), TOTH, Reset AIR3/4, NOW / NEXT / WARN, Silence, Loudness I+LRA, Reset I+LRA
- Variables such as
$(oas:air1_time),$(oas:lufs_i),$(oas:lra) - Connection status shows instance name and version (e.g.
Studio-1 · 1.0.0)
Module: companion-module-astrastudio-onairscreen. Generic OSC remains as an alternative.
OSC Remote Control
OSC on UDP port 8000 (enable under Settings → Network). Prefix /oas. Integers 1/0 mean ON/OFF; no argument means TOGGLE.
| Address | Function |
|---|---|
/oas/led{1-4} | LED |
/oas/air{1-4} | AIR timer |
/oas/air{3-4}/reset | Reset AIR3/AIR4 |
/oas/air3/toh | Top-of-Hour |
/oas/text/now, /next, /warn | Text fields |
/oas/lufs/integrated | Start/stop I+LRA |
/oas/command | Raw API command |
Queries reply to the UDP sender. Optional status push to Companion Generic OSC (Send Host / Send Port).
Web-UI: Settings, Studio Look, Live Status
The browser remote from 0.9.8 is now a full control surface:
- Settings overlay (gear): edit all OnAirScreen settings from the browser, Apply, preset load/save
- Optional PIN (
Network/websettingspin) — Remote Control stays unprotected; settings can sit behind a PIN - Flat studio look: CI blue, square inputs, settings tabs on the left like the desktop dialog
- Live Loudness I+LRA tile and silence alarm in status
- AIR3 time input (
m:ss,m,ss, or seconds) and count-up vs. countdown in the status tile - Persistent connection badge: Live / Polling / Offline
- Keys
1–4toggle LEDs (ignored while typing) - Add to Home Screen on iPhone/Android uses the OnAirScreen icon
- Livewire / AES67 discovery and Paste SDP, matching the desktop dialog
Studio Interaction
The main screen is meant to be used with a mouse or a touch panel:
- Double-click toggles fullscreen
- Left-click on status LEDs and AIR timers toggles them (same as the hotkeys)
- Right-click / long-press: Toggle Fullscreen, Settings, Start/Stop/Reset I+LRA (when meters apply), Quit OnAirScreen
- Option to always start in fullscreen, even if the last session was windowed (
General/always_start_fullscreen, default off) - On-screen WARN
QUITTING ONAIRSCREENwhile the app is shutting down (Q, context menu, or Ctrl+C / SIGINT)
Instance Name, TOTH, Fonts, Logs
- DNS-safe instance name (Settings → General, default
Studio-1, max 32 characters) so each OnAirScreen can be identified by location. Shown in the Web-UI,/api/status(instance), MQTT{base_topic}/instance/state, and as a Home Assistant sensor. HA device name becomesOnAirScreen (Studio-1). Remote:CONF:General:instancename=TEXT - AIR3 shows ▲ (count-up) or ▼ (count-down) under the timer icon
- AIR3 shows the TOTH label while top-of-hour countdown is active, then restores the configured label. The label is configurable (
Timers/TimerTOTHText); default is TOTH - Bundled Noto Sans (Regular, Bold, Italic, Bold Italic) alongside Roboto
- Persistent log folder with rotating
onairscreen.log, crash reports for uncaught Python exceptions, andfault.logfor native faults. About tab shows the path and can open the folder. After a crash, the next start shows a dialog (open log folder; auto-closes after 30 seconds) - Automatic update checks also run every 24 hours while OnAirScreen is running; the new-version dialog still appears only at startup
- Settings window opens at 700×800 and can be resized freely; Network tab (UDP, HTTP, multicast, MQTT, OSC) sits after General; GPIO and Audio Meters have their own tabs
API Enhancements
LUFSI:START/STOP/TOGGLE/RESETvia UDP, HTTP, OSC, MQTT, Web-UI, and Companion/api/statusaddsinstance,silence,lufsIntegrated,lufsI,lra, andcountDownon AIR timers (truewhile AIR3/AIR4 is counting down)CONF:Clock:face=andCONF:General:instancename=- MQTT / Home Assistant: Silence binary sensor, Instance sensor, Loudness I+LRA switch and reset, I (LUFS) and LRA (LU) sensors
- Network settings grouped under Settings → Network
Bug Fixes
| Issue | Fix |
|---|---|
| Clock froze after an NTP timeout | NTP results are delivered on the GUI thread; a watchdog restarts a dead clock timer |
| Digital clock aborted when a time sample had no SMPTE frame count | Clock accepts samples without a frame count |
| NTP lock LED stayed green when the server was unreachable | LED follows the actual lock state |
Date ignored Formatting/dateFormat | Date uses the configured format |
| Digital AM/PM clock showed 0 at midnight | 12-hour mapping displays 12 |
| Opening Settings painted a running AIR/TOTH timer as inactive or 0:00 | Timer display stays live while Settings are open |
| Opening Settings / Apply segfaulted on Raspberry Pi | Mouse handling no longer crashes the packaged app |
| Main-screen hotkeys stopped working | Shortcuts reach Qt again |
| Windows: Settings → Fonts access-violated on first open | Font database warmed at startup; filter installed after widgets exist |
| Weather widget text shadows missing under PySide6 | Drop-shadow effects are parented so they are not garbage-collected |
| AoIP source change without RTP froze the last level | Meters drop to the floor instead of holding the previous value |
| I+LRA burned a CPU core on long sessions | History stays in a NumPy buffer; gated I refreshes about once per second |
| Audio meters were heavy on Raspberry Pi / software rendering | Bars paint from cached pixmaps; DSP runs only when the layout needs it |
| LED and AIR on/off colours applied late | Colour changes take effect immediately after Apply |
| Raspberry Pi GPIO failed in the packaged app | System gpiozero / lgpio loaded; freeze stdlib gaps fixed |
| Web-UI WebSocket did not recover after HTTP polling | Socket is restored automatically |
| Web-UI AIR / loudness buttons overflowed on phones | Layout fits the viewport |
| LUFS heading clipped in the L/R + LUFS layout | Heading no longer clipped left or right |
| Autoflash / timedflash LED blink in Web-UI | Blink restored |
| Startup crashed listing host addresses under PySide6 | Address listing works |
| Audio-device Refresh missed newly plugged inputs | PortAudio re-scan on Refresh |
Fresh install without Audio/layout fell back to L/R only | Default layout is L/R + LUFS |
| MQTT reconnect / AES67 capture continued during quit | Capture and reconnect stop cleanly on quit |
Under the Hood
This release does not change how OnAirScreen looks on air by default — it makes the stack maintainable, safer to ship, and lighter on a Pi:
- Qt binding switched from PyQt6 to PySide6
- OnAirScreen Source-Available License (OASL 1.0): source may be used, modified, and redistributed; compiled/binary redistribution requires written permission. Shop builds remain the supported way to run OnAirScreen
- Crash reporting: uncaught main-thread exceptions and Qt fatal messages write a report, then quit; thread/asyncio errors are logged without exiting
- Meter and loudness CPU work cut on software-rendered displays (pixmap cache, gated I, skip unused DSP)
- Raspberry Pi GPIO in the freeze: system gpiozero/lgpio, no bundled copies of those stacks
- Settings layouts: Network tab, two-column Audio Meters, aligned Network / Time Source forms
python-osc>= 1.10.2- GitHub README presents shop builds as the supported runtime; the repository is documented as source-available for audit and contributors
Upgrade Notes
- Settings are preserved — existing configuration files stay compatible
- Configs with
Audio/unit=lufsand nolayoutkey migrate to programme LUFS (layout=lufs) and L/R unit dBTP - Fresh installs default to L/R + LUFS, dBTP, and Too Loud on
- MQTT stays off until you enable it. Home Assistant Autodiscovery picks up the new loudness, silence, and instance entities
- OSC is off by default (UDP 8000). Companion does not need OSC when the HTTP module is used
- Web-UI stays at
http://your-host:8010/(default). Settings overlay can use an optional PIN - GPIO is Raspberry Pi only (shop
deband SD image) - Licence is OASL 1.0 (no longer presented as open source / GPL). Third-party notices cover PySide6/Qt (LGPLv3), Roboto and Noto Sans (SIL OFL), and the analog clock BSD example
- Shop customers update with the Update Key from the customer portal
- For Raspberry Pi / packaged builds: use the latest image or binary from astrastudio.de
Manuals: User Manual (English) · Bedienungsanleitung (Deutsch)
Thank You
OnAirScreen 1.0.0 is for everyone who ran the 0.9 builds on air, filed bugs, tested betas, and said what the screen still needed. Years of that work is in this version.
Happy broadcasting!
— Sascha Ludwig / astrastudio.de
OnAirScreen is source-available under OASL 1.0. Official builds are in the shop. Support the project via a shop licence, PayPal, Buy Me a Coffee, or Ko-fi.