Differences
This shows you the differences between two versions of the page.
| Next revision | Previous revision | ||
| oas:changelog [26.12.2022 12:44] – created - external edit 127.0.0.1 | oas:changelog [27.09.2026 02:22] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ====== Changelog ====== | ||
| + | |||
| + | All notable changes to OnAirScreen. Source: OnAirScreen '' | ||
| < | < | ||
| - | # Changelog | ||
| All notable changes to this project will be documented in this file. | All notable changes to this project will be documented in this file. | ||
| + | </ | ||
| - | ## 0.9.5 | + | ===== TBA ===== |
| + | |||
| + | < | ||
| ### Changed | ### Changed | ||
| + | |||
| + | - The settings chapter in the English and German manuals follows the Settings tab order | ||
| + | </ | ||
| + | |||
| + | ===== 1.0.10 ===== | ||
| + | |||
| + | < | ||
| + | ### Added | ||
| + | |||
| + | - MIDI input maps Note and CC messages from one interface to LEDs and AIR timers (Settings → GPIO → MIDI), with Learn, On/Off, Oneshot, or Toggle, and On/Off rows in GPIO Logic | ||
| + | |||
| + | ### Changed | ||
| + | |||
| + | - Settings reopen the last GPIO sub-tab (Raspberry Pi, Axia Livewire, MIDI, or Logic) instead of always showing Axia Livewire | ||
| + | - MIDI Oneshot honors Invert: a press sends OFF instead of ON | ||
| + | - MIDI settings rows flash when a Note or CC arrives that matches an enabled row | ||
| + | - Unnamed MIDI rows appear in GPIO Logic as MIDI1–MIDI8 | ||
| + | - The MIDI row highlight keeps the label width, so the row no longer shifts | ||
| + | - Web Settings groups each GPIO input and each Logic rule into its own band, so the fields that belong together are easier to see | ||
| + | - Web Settings groups Timer, Network, and General fields the same way: each AIR timer and LED, plus Station, Clock, MQTT, OSC, and SNMP | ||
| + | - Web Settings groups Audio Meter fields into Input, Meters, LUFS, Peak Hold, Too Loud, and Silence | ||
| + | |||
| + | ### Fixed | ||
| + | |||
| + | - A listen port that is already in use is reported in a dialog. HTTP, WebSocket, UDP, OSC, and SNMP no longer only leave a traceback in the log | ||
| + | - The Web Settings PIN field takes the cursor as soon as the prompt appears | ||
| + | - The empty "no other OnAirScreens" | ||
| + | - Changing the LUFS Reference Preset in the web settings now updates the LUFS Reference value to that preset | ||
| + | - A GPI with no action stays without an action. Raspberry Pi and Livewire inputs can feed Logic rules without also sending the default LED or AIR command | ||
| + | - The test run no longer opens Settings windows or modal dialogs that have to be clicked away. Hotkey and window-geometry tests supply the license fields those paths now read | ||
| + | </ | ||
| + | |||
| + | ===== 1.0.9 ===== | ||
| + | |||
| + | < | ||
| + | ### Changed | ||
| + | |||
| + | - Hardware ID is derived with an application-specific keyed hash. Computers activated with the 1.0.8 beta must be activated again. | ||
| + | </ | ||
| + | |||
| + | ===== 1.0.8 ===== | ||
| + | |||
| + | < | ||
| + | ### Added | ||
| + | |||
| + | - GPIO Logic rules combine Raspberry Pi and Livewire inputs with AND or OR, and turn the chosen LEDs and AIR timers on or off only when that combined level changes | ||
| + | - Web Settings can import a license file from disk, and Updates actions show a dialog for success, errors, and license return | ||
| + | - Paid builds require a hardware-bound license: 14 days full use, then restricted mode (no fullscreen, GPIO, or audio meters; settings are not saved; window max 1280×800; exit after 15 minutes). Activate online or with a license file. One seat, one year by default, renewable. Return the license in the app to move it. | ||
| + | |||
| + | ### Changed | ||
| + | |||
| + | - Update check, the update key, and license activation are on their own Settings tab, with one full-width button per action | ||
| + | - The Updates tab says whether this computer can renew online now, or must import a new license file when the current one expires | ||
| + | - The update key is saved as soon as activation succeeds, without pressing Apply | ||
| + | - Shop manuals state that one license covers one PC or one Raspberry Pi | ||
| + | - Manuals point to support when the standard per-computer activation does not fit a use case | ||
| + | - macOS shop builds are signed with an Apple Developer ID and notarized; Gatekeeper no longer blocks the first launch | ||
| + | |||
| + | ### Fixed | ||
| + | |||
| + | - Web Settings keeps the Updates license panel when switching tabs, so the tab no longer renders empty and the license status line no longer throws | ||
| + | - Freeing a license seat deactivates that computer on the next update check, including startup and Check now. The local license is removed and OnAirScreen switches to restricted mode | ||
| + | - A paid build checks the update key at startup even when update checks are off. An invalid key removes the local license immediately and switches to restricted mode. Later automatic checks and the deactivation notice are skipped; Check now still runs | ||
| + | - After a license return and a new activation, the window keeps the last size that fit the screen | ||
| + | </ | ||
| + | |||
| + | ===== 1.0.7 ===== | ||
| + | |||
| + | < | ||
| + | ### Changed | ||
| + | |||
| + | - GPIO Custom command uses the same pencil editor as Links (Settings and Web UI) | ||
| + | - Links Custom command is edited from a pencil icon; the icon is highlighted when a command is set | ||
| + | ><> | ||
| + | ### Fixed | ||
| + | |||
| + | - Settings Links no longer leaves a blank gap between the instance hint and the nearby-screen list | ||
| + | - Web Settings Links instance hint stays in place so Add as replica / Use as source no longer shove the form | ||
| + | - Links mapping Custom field is extra API commands when the source is active; Local target **Custom only** skips LED/ | ||
| + | - Links Follow all disables Local target and Invert (full status copy does not use them) | ||
| + | - Links replica and source grids fit the Settings width without a horizontal scrollbar | ||
| + | - Add as replica / Use as source fill the next empty row; a notice is shown when all 8 are in use | ||
| + | - Links instance dropdowns no longer show Studio-1 or Studio-2 as the empty placeholder | ||
| + | - Web Settings hints wrap on the full row; Links Replicas/ | ||
| + | - Settings Links instance fields are nearby-screen dropdowns so each replica/ | ||
| + | - Link replicas no longer show host-local WARN copy (quit, reboot, shutdown, NTP) | ||
| + | - Link status is pushed on change (replicas and mapped sources); the HTTP poll is only a slow retry, not a per-screen chatter loop | ||
| + | - Replica LEDs and other runtime status push immediately instead of waiting for the 400 ms poll | ||
| + | - Link replicas and sources follow the instance name on the LAN; a stored host is only a fallback if discovery misses them | ||
| + | - Web UI Links matches Settings: Nearby list, Add as replica / Use as source, Replicas and Sources grids | ||
| + | - Settings Links keep the Nearby selection when the peer list refreshes | ||
| + | - Web UI and Settings Apply reject an instance name already used on the LAN and show the collision warning | ||
| + | </ | ||
| + | |||
| + | ===== 1.0.6 ===== | ||
| + | |||
| + | < | ||
| + | ### Added | ||
| + | |||
| + | - Settings **Links**: discover other OnAirScreens by instance name (multicast) or host/port; add replicas for 1→n full runtime status (LEDs, AIR, NOW/ | ||
| + | - Settings warn when another OnAirScreen on the LAN uses the same instance name; discovery no longer picks one host at random | ||
| + | - Right-click menu shows the current OnAirScreen version as info | ||
| + | - Raspberry Pi SD-card image allows passwordless host reboot and shutdown from OnAirScreen | ||
| + | |||
| + | ### Fixed | ||
| + | |||
| + | - Weather widget stays on the AIR LED column width; long city names are elided instead of pushing the clock | ||
| + | - Weather widget shows the searched city name instead of the OpenWeatherMap station or neighborhood name | ||
| + | - Weather widget keeps the current city when switching °C / °F / K (Apply uses the dialog city ID, not a stale settings read) | ||
| + | - Web UI Instance Name accepts at most 32 characters | ||
| + | - HTTP server no longer does reverse DNS on bind or request logging (avoids multi-second stalls) | ||
| + | </ | ||
| + | |||
| + | ===== 1.0.5 ===== | ||
| + | |||
| + | < | ||
| + | ### Added | ||
| + | |||
| + | - Application log starts with a Starting OnAirScreen line (version and distribution) | ||
| + | </ | ||
| + | |||
| + | ===== 1.0.4 ===== | ||
| + | |||
| + | < | ||
| + | ### Fixed | ||
| + | |||
| + | - Linux PTP logs whether the 319/320 bind helper is missing or failed | ||
| + | - Linux PTP bind helper receives the comm socket on stdin | ||
| + | </ | ||
| + | |||
| + | ===== 1.0.3 ===== | ||
| + | |||
| + | < | ||
| + | ### Added | ||
| + | |||
| + | - Web UI and API command `FULLSCREEN: | ||
| + | - Reboot and Shutdown buttons in Settings → About and the Web UI (with confirmation); | ||
| + | - GPIO (Raspberry Pi and Livewire) can map one input to several preset actions plus semicolon-separated custom commands | ||
| + | |||
| + | ### Changed | ||
| + | |||
| + | - add SNMP enterprise OID IANA PEN 66873 (`.1.3.6.1.4.1.66873`); | ||
| + | - SNMP MIB is published on the wiki (`onairscreen: | ||
| + | |||
| + | ### Fixed | ||
| + | |||
| + | - Closing the main window while Settings is still open now exits the app | ||
| + | - Linux/ | ||
| + | </ | ||
| + | |||
| + | ===== 1.0.2 ===== | ||
| + | |||
| + | < | ||
| + | ### Added | ||
| + | |||
| + | - SNMPv2c/v3 agent (GET/ | ||
| + | - Axia Livewire GPIO LWRP: follow GPI/GPO on a device over TCP 93 (read-only), | ||
| + | |||
| + | ### Changed | ||
| + | |||
| + | - Weather widget backgrounds use a new photographic set for OpenWeatherMap icons 01d–50n | ||
| + | |||
| + | ### Fixed | ||
| + | |||
| + | - SNMP GET for NOW/ | ||
| + | - SNMP agent no longer logs an asyncio error when OnAirScreen quits | ||
| + | - Timer dialog accepts `2:10` as well as `2,10` and `2.10` | ||
| + | - Timer dialog selects the existing value when opened with Enter | ||
| + | - Weather widget labels stay readable on bright photo backgrounds (soft shadow + overlay) | ||
| + | - Web settings: GPIO Custom Command is disabled unless Action is Custom | ||
| + | - Web settings GPIO row fields are disabled unless that GPI Enable is on | ||
| + | - Desktop GPIO row fields are disabled unless that GPI On checkbox is on | ||
| + | </ | ||
| + | |||
| + | ===== 1.0.1 ===== | ||
| + | |||
| + | < | ||
| + | ### Added | ||
| + | |||
| + | - Axia Livewire GPIO (multicast): | ||
| + | - Main-window hotkey overlay (`H`, or right-click / long-click → **Hotkeys**): | ||
| + | |||
| + | ### Changed | ||
| + | |||
| + | - PTP: retry UDP 319/320 bind when the ports are in use or permission is denied; log the cause; lock LED and WARN show `PTP ERROR` until bind succeeds | ||
| + | - German manual links to the English GPG wiki page (`gpg-en`); the German GPG how-to is removed | ||
| + | </ | ||
| + | |||
| + | ===== 1.0.0 ===== | ||
| + | |||
| + | < | ||
| + | First stable 1.0.0. Changes since 0.9.8 are listed in the 1.0.0beta sections below. | ||
| + | </ | ||
| + | |||
| + | ===== 1.0.0beta15 ===== | ||
| + | |||
| + | < | ||
| + | ### Changed | ||
| + | |||
| + | - Require python-osc >=1.10.2 | ||
| + | |||
| + | ### Fixed | ||
| + | |||
| + | - LED and AIR timer on and off color changes take effect immediately after Apply | ||
| + | </ | ||
| + | |||
| + | ===== 1.0.0beta14 ===== | ||
| + | |||
| + | < | ||
| + | ### Added | ||
| + | |||
| + | - Analog clock faces Analog Numbers (1–12 on the classic analog face), Analog Studio (white face with 1–12), Analog Railway (station clock with a red ring second hand), Analog 24h ticking, and Analog 24h smooth (cream face with 1–12 and 13–24) | ||
| + | - Clock face setting `Clock/ | ||
| + | - README and manuals show screenshots of all clock faces | ||
| + | |||
| + | ### Changed | ||
| + | |||
| + | - Clock mode in Settings and the Web UI is a dropdown instead of Digital/ | ||
| + | - Context menu Start/ | ||
| + | - `CONF: | ||
| + | |||
| + | ### Fixed | ||
| + | |||
| + | - I/LRA no longer burns a CPU core on long sessions: history stays in a NumPy buffer, blocks below −70 LUFS are not stored, and gated I is refreshed about once per second | ||
| + | </ | ||
| + | |||
| + | ===== 1.0.0beta12 ===== | ||
| + | |||
| + | < | ||
| + | ### Added | ||
| + | |||
| + | - Settings option to always start in fullscreen mode, even if the last session was windowed (`General/ | ||
| + | |||
| + | ### Changed | ||
| + | |||
| + | - GitHub README presents shop builds as the supported way to run OnAirScreen; | ||
| + | - Automatic update checks also run every 24 hours while OnAirScreen is running; the new-version dialog appears only at startup | ||
| + | - Audio meter width can be set up to 201 px (L/R bars were previously capped around 117 px) | ||
| + | - Installation chapter in the manuals covers Windows MSI, macOS Gatekeeper, Linux packages, and flashing the Raspberry Pi SD image | ||
| + | - Manuals use an annotated main-screen screenshot | ||
| + | |||
| + | ### Fixed | ||
| + | |||
| + | - Long-press on the main screen no longer uses deprecated Qt mouse-position APIs | ||
| + | </ | ||
| + | |||
| + | ===== 1.0.0beta11 ===== | ||
| + | |||
| + | < | ||
| + | ### Added | ||
| + | |||
| + | - Long-click / long-press on the main screen opens the same context menu as right-click | ||
| + | |||
| + | ### Fixed | ||
| + | |||
| + | - Raspberry Pi GPIO import of system gpiozero no longer fails for missing freeze stdlib modules (`colorsys`, | ||
| + | </ | ||
| + | |||
| + | ===== 1.0.0beta10 ===== | ||
| + | |||
| + | < | ||
| + | ### Fixed | ||
| + | |||
| + | - Raspberry Pi GPIO works in the packaged app by loading system `python3-gpiozero` / `python3-lgpio` (the freeze does not bundle them) | ||
| + | </ | ||
| + | |||
| + | ===== 1.0.0beta9 ===== | ||
| + | |||
| + | < | ||
| + | ### Added | ||
| + | |||
| + | - Raspberry Pi GPIO inputs map mixer GPI contacts to LEDs and AIR timers (Settings → GPIO), with wiring diagrams and pinout links in the manuals | ||
| + | |||
| + | ### Changed | ||
| + | |||
| + | - GPIO wiring diagrams in the manuals show a PC817 module with silkscreen terminals `IN1`–`IN8` / `GND` and `OUT1`–`OUT8` / `GND` | ||
| + | </ | ||
| + | |||
| + | ===== 1.0.0beta8 ===== | ||
| + | |||
| + | < | ||
| + | ### Added | ||
| + | |||
| + | - Left-click on status LEDs and AIR timers toggles them (same as the hotkeys) | ||
| + | - Right-click **Quit OnAirScreen** on the main screen | ||
| + | - On-screen WARN `QUITTING ONAIRSCREEN` while the app is shutting down | ||
| + | - Web UI Add to Home Screen on iPhone/ | ||
| + | |||
| + | ### Changed | ||
| + | |||
| + | - Web UI uses a flat studio look: CI color blue, square inputs, and settings tabs on the left like the desktop dialog | ||
| + | - Web UI theme, settings, and version controls scroll with the page instead of staying pinned to the corners | ||
| + | |||
| + | ### Fixed | ||
| + | |||
| + | - Web UI AIR timer and loudness buttons no longer overflow the viewport on phones | ||
| + | - Web UI home-screen icon is an opaque 180×180 PNG at the site root so iOS picks it up | ||
| + | - Ctrl+C / SIGINT shows the same `QUITTING ONAIRSCREEN` WARN as Q and the context menu | ||
| + | - Opening Settings / Apply no longer segfaults on Raspberry Pi: the Python mouse event filter is gone; main-screen children let double-click and right-click through to the window | ||
| + | - Audio meter heading " | ||
| + | </ | ||
| + | |||
| + | ===== 1.0.0beta7 ===== | ||
| + | |||
| + | < | ||
| + | ### Changed | ||
| + | |||
| + | - Settings window opens at 700×800 and can be resized freely (height is no longer capped at 800px) | ||
| + | |||
| + | ### Fixed | ||
| + | |||
| + | - Settings tabs (except General) scroll vertically in the UI; content stays within the window width instead of shifting sideways | ||
| + | - Audio meters use much less CPU on Raspberry Pi and other software-rendered displays: bars paint from cached pixmaps, and true-peak / BBC PPM / LUFS DSP runs only when the current meter setup needs it | ||
| + | - Opening Settings no longer segfaults: the main-screen mouse filter watches the application instead of installing on every new child widget | ||
| + | - Replaced deprecated `QColor.setNamedColor()` with `QColor.fromString()` | ||
| + | - Web UI: Instance/ | ||
| + | |||
| + | ### Added | ||
| + | |||
| + | - Right-click **Start I+LRA** and **Stop I+LRA** on the main screen (when meters are enabled) | ||
| + | - Web UI settings overlay (gear, top right): edit all OnAirScreen settings, optional PIN (`Network/ | ||
| + | - Web UI Audio Meters: **Livewire Source** and **AES67 Stream** dropdowns with live discovery and **Paste SDP**, matching the desktop Settings dialog | ||
| + | </ | ||
| + | |||
| + | ===== 1.0.0beta6 ===== | ||
| + | |||
| + | < | ||
| + | ### Changed | ||
| + | |||
| + | - Default TOTH timer label is `TOTH` instead of `TOTH Timer` | ||
| + | |||
| + | ### Fixed | ||
| + | |||
| + | - Windows: opening **Settings → Fonts** no longer access-violates on first open. The mouse event filter is installed after widgets exist, and the font database is warmed at startup | ||
| + | - Main-screen hotkeys work again. The mouse event filter no longer consumes `ShortcutOverride` and key events, so `QShortcut` still reaches Qt | ||
| + | </ | ||
| + | |||
| + | ===== 1.0.0beta5 ===== | ||
| + | |||
| + | < | ||
| + | ### Added | ||
| + | |||
| + | - Persistent log folder with rotating `onairscreen.log`, | ||
| + | - After a crash, the next start shows a dialog (open log folder, auto-closes after 30 seconds with a progress bar) | ||
| + | |||
| + | ### Changed | ||
| + | |||
| + | - Uncaught main-thread exceptions and Qt fatal messages write a crash report, then quit (no dialog at crash time). Thread and asyncio errors are logged without exiting. | ||
| + | |||
| + | ### Fixed | ||
| + | |||
| + | - Fresh installs without `Audio/ | ||
| + | - Settings audio-device Refresh re-scans PortAudio so newly plugged or unplugged inputs appear immediately | ||
| + | </ | ||
| + | |||
| + | ===== 1.0.0beta4 ===== | ||
| + | |||
| + | < | ||
| + | ### Changed | ||
| + | |||
| + | - OnAirScreen Source-Available License (OASL 1.0): source may be used, modified, and redistributed; | ||
| + | - Application file headers point to OASL; Settings License tab shows OASL plus third-party notices | ||
| + | </ | ||
| + | |||
| + | ===== 1.0.0beta3 ===== | ||
| + | |||
| + | < | ||
| + | ### Added | ||
| + | |||
| + | - TOTH Timer label text is configurable (`Timers/ | ||
| + | - Bundled Noto Sans (Regular, Bold, Italic, Bold Italic) as an additional font family alongside Roboto | ||
| + | - Web-UI Loudness I+LRA tile shows live I (LUFS) and LRA (LU); `lufsI` / `lra` in `/ | ||
| + | |||
| + | ### Fixed | ||
| + | |||
| + | - Weather widget text shadows work again under PySide6 (drop-shadow effects are parented so they are not garbage-collected) | ||
| + | - AoIP source change without RTP now drops the meters to the floor instead of freezing on the previous level | ||
| + | |||
| + | ### Changed | ||
| + | |||
| + | - Settings **Network** and **Time Source** tabs align labels and fields in a shared two-column form layout | ||
| + | - License dialog and `THIRD_PARTY_LICENSES.md` now document PySide6/Qt (LGPLv3), the analog clock BSD example, and Roboto (SIL OFL) instead of PyQt GPL | ||
| + | - Application BSD text removed from `LICENSE` and the Settings license tab pending the forthcoming source license | ||
| + | - Default audio meter layout is L/R plus programme LUFS (`both`); default width is 115px and the maximum is 150px | ||
| + | </ | ||
| + | |||
| + | ===== 1.0.0beta2 ===== | ||
| + | |||
| + | < | ||
| + | ### Fixed | ||
| + | |||
| + | - Digital clock no longer aborts when a time sample has no SMPTE frame count | ||
| + | - Startup no longer crashes when listing host addresses under PySide6 | ||
| + | |||
| + | ### Changed | ||
| + | |||
| + | - Qt binding switched from PyQt6 to PySide6 | ||
| + | - Settings window opens at 700×800 and is capped at 800px height so it fits smaller screens, audio meters tab uses two columns | ||
| + | - Station and slogan color pickers in Settings no longer show a live preview | ||
| + | - dBTP meter hides the orange ceiling peg when the Too Loud indicator is off | ||
| + | </ | ||
| + | |||
| + | ===== 1.0.0beta1 ===== | ||
| + | |||
| + | < | ||
| + | ### Added | ||
| + | |||
| + | - Meter layouts: L/R only, programme LUFS only, or both (`Audio/ | ||
| + | - Programme LUFS bar (EBU R128): momentary M with a short-term S tick (I and LRA stay off until started) | ||
| + | - Optional gated Integrated I + LRA (off until started): `LUFSI: | ||
| + | - MQTT Home Assistant: Loudness I+LRA switch and reset button (`{base}/ | ||
| + | - Right-click **Reset I+LRA** on the main screen (when meters are enabled); `LUFSI: | ||
| + | - Existing configs with `Audio/ | ||
| + | - AIR3 shows ▲ (count-up) or ▼ (count-down) under the timer icon | ||
| + | - AIR3 shows `TOTH Timer` while top-of-hour countdown is active, then restores the configured label | ||
| + | - Web-UI: AIR3 time input (`m:ss`, `m,ss`, or seconds) and count-up vs. countdown in the status tile | ||
| + | - Web-UI: silence alarm and loudness I+LRA in live status; keys `1`–`4` toggle LEDs (ignored while typing) | ||
| + | - Web-UI: persistent connection badge (Live / Polling / Offline) | ||
| + | - `countDown` in `/ | ||
| + | - Bitfocus Companion HTTP module (`astrastudio-OnAirScreen`) as the recommended Stream Deck path; Generic OSC remains as an alternative | ||
| + | - OSC remote control on UDP port 8000 (`/ | ||
| + | - Settings **Network** tab (after General) for UDP, HTTP, multicast, MQTT, and OSC; **General** / **Advanced** tab titles no longer include “Settings” | ||
| + | - Silence Detection on the current audio source (Local / Livewire / AES67): dBFS threshold, duration (default 10 s), recovery time, optional OAS WARN, optional HTTP GET on trigger | ||
| + | - Silence alarm as API boolean (`silence` in `/ | ||
| + | - Option to treat a missing device/ | ||
| + | - DNS-safe instance name (Settings **General**, | ||
| + | - `CONF: | ||
| + | - Double-click on the main screen toggles fullscreen | ||
| + | - Right-click context menu on the main screen: Toggle Fullscreen, Settings | ||
| + | |||
| + | ### Changed | ||
| + | |||
| + | - Default meter width is 79 px (extra width still thickens the L/R bars) | ||
| + | - `CONF: | ||
| + | - Default audio meter unit is dBTP; TooLoud is enabled by default | ||
| + | |||
| + | ### Fixed | ||
| + | |||
| + | - Clock no longer freezes after an NTP timeout: NTP results are delivered on the GUI thread, and a watchdog restarts a dead clock timer | ||
| + | - Clock watchdog no longer aborts when a time sample is missing | ||
| + | - Opening Settings no longer paints a running AIR timer (including TOTH) as inactive or resets its displayed time to 0:00 | ||
| + | - Web-UI restores the WebSocket after falling back to HTTP polling | ||
| + | - Opening Settings again brings the existing window to the front instead of reloading it | ||
| + | </ | ||
| + | |||
| + | ===== 0.9.9beta1 ===== | ||
| + | |||
| + | < | ||
| + | ### Added | ||
| + | |||
| + | - Stereo audio meters on the left (on by default, Local Input): L/R bars with RMS fill and peak overlay | ||
| + | - Display units: **dBFS**, **dBTP** (true peak), **LUFS** (momentary), | ||
| + | - Peak hold marker (default 1.5 s, can be disabled) and display style **Solid** or **Bargraph** | ||
| + | - LUFS reference peg via presets (EBU R128 −23, ATSC A/85 −24, AES −16/ | ||
| + | - Adjustable meter width (extra width goes into thicker L/R bars) | ||
| + | - Optional **TOO LOUD** action: on-screen warning (priority 1) or trigger LED 1–4 when true peak exceeds the threshold; dBTP ceiling peg uses that threshold | ||
| + | - Audio sources: **Local Input** (PortAudio), | ||
| + | - Shared **AoIP Interface** for Livewire/ | ||
| + | - Livewire: advertised sources listed while Settings are open (`239.192.255.3` UDP 4001); pick a name or enter channel 1–32767 (channel *N* → `239.192.0.0+N` UDP 5004, L24/48 kHz stereo) | ||
| + | - AES67: SAP discovery on `239.255.255.255` and RFC 2974 `224.2.127.254` UDP 9875 while Settings are open; live stream list (None / SAP / pasted SDP); L16/L24 at 44.1/48/96 kHz, meters use the first two channels | ||
| + | - Settings **Audio Meters** tab and `CONF: | ||
| + | |||
| + | ### Fixed | ||
| + | |||
| + | - Date display follows the configured `Formatting/ | ||
| + | - Digital AM/PM clock: midnight displays as 12 (12-hour mapping) | ||
| + | - NTP lock LED no longer stays green when the server is unreachable | ||
| + | - Autoflash / timedflash LED regression and Web-UI blink | ||
| + | - MQTT reconnect and AES67 capture restart stop during application quit | ||
| + | </ | ||
| + | |||
| + | ===== 0.9.8 ===== | ||
| + | |||
| + | < | ||
| + | ### Added | ||
| + | |||
| + | - Persist windowed position and size across restarts (`Window/ | ||
| + | - OpenWeatherMap city search in Settings: type a city name next to City ID, Find, pick a match | ||
| + | - Mask Update Key, MQTT password, and OpenWeatherMap API key; slashed-eye toggle reveals them | ||
| + | - Time Source settings tab: Local System Clock, NTP Server, PTPv2 IEEE 1588-2008, or LTC | ||
| + | - NTP and PTP steer an independent display clock (monotonic timebase); the OS clock is never set | ||
| + | - PTP: software slave on 224.0.1.129 UDP 319/320, configurable interface (independent of AoIP) and domain 0–255 | ||
| + | - LTC: Leo Bodnar LBE-1110 USB-serial SMPTE reader, or SMPTE LTC decoded from a local PortAudio input (Left/ | ||
| + | - LTC audio uses its own capture device (not Audio Meters / Livewire / AES67); opening the same device for meters and LTC can fail on some hosts | ||
| + | - LTC unlock WARN (`Clock not LTC synchronized` etc.) is optional and off by default; the `LTC NOT LOCKED` LED always remains | ||
| + | - AES67: SAP discovery on `239.255.255.255` and RFC 2974 `224.2.127.254` (UDP 9875) | ||
| + | - PTP: apply TAI−UTC only when the master announces the PTP timescale (fixes ~37s offset vs software ptp4l) | ||
| + | - NTP Check settings moved from General to the Time Source tab | ||
| + | - Clock lock LED (bottom right, seconds-LED size): green when the selected time source is locked, red when not; caption `PTP LOCK` / `NTP LOCK` / `LTC LOCK` (or `NOT LOCKED`) | ||
| + | - NTP Server field stays enabled when Time Source is NTP, even if NTP-Check is off | ||
| + | - Top-of-Hour countdown for Radio Timer (AIR3): wall-clock synchronized countdown to the next full hour (display format M:SS) | ||
| + | - Top-of-Hour: | ||
| + | - Top-of-Hour: | ||
| + | - Top-of-Hour: | ||
| + | - Top-of-Hour: | ||
| + | - Top-of-Hour: | ||
| + | - API: `TOGGLE` for LED1–4, AIR1, AIR2, and AIR4 (same ON/ | ||
| + | - German and English user manuals (`BEDIENUNGSANLEITUNG.md`, | ||
| + | - Refactoring: | ||
| + | - Refactoring: | ||
| + | - Refactoring: | ||
| + | - Refactoring: | ||
| + | - Refactoring: | ||
| + | - Refactoring: | ||
| + | - Refactoring: | ||
| + | - Refactoring: | ||
| + | - Error Handling: Unified error handling system with custom exception hierarchy | ||
| + | - Error Handling: Custom exceptions for all error types (Network, Command, Configuration, | ||
| + | - Error Handling: Consistent logging strategy with log_exception() helper function | ||
| + | - Error Handling: HTTP error response mapping based on exception types | ||
| + | - Error Handling: Comprehensive exception handling in network.py, command_handler.py, | ||
| + | - Tests: Unit tests for exceptions module (26 tests covering all exception types and logging helper) | ||
| + | - MQTT integration with Home Assistant Autodiscovery support | ||
| + | - MQTT: LED switches (LED1-4) for controlling LEDs via MQTT | ||
| + | - MQTT: AIR timer switches (AIR1-4) for starting/ | ||
| + | - MQTT: AIR timer sensors (AIR1-4 Time) for displaying elapsed time in seconds | ||
| + | - MQTT: Reset buttons (AIR3/AIR4 Reset) for resetting timers | ||
| + | - MQTT: Text entities (NOW, NEXT, WARN) for setting text fields | ||
| + | - MQTT: Automatic status updates after state changes | ||
| + | - MQTT: Automatic reconnection and autodiscovery re-publishing on reconnect | ||
| + | - Settings: MQTT configuration (Server, Port, Username, Password, Device Name) | ||
| + | - MQTT: Base topic automatically generated from " | ||
| + | - Web-UI: Dark Mode support with theme toggle button and automatic persistence | ||
| + | - Web-UI: Warning priority system with support for NTP warnings (priority -1), normal warnings (priority 0), medium priority (1), and high priority (2) | ||
| + | - Web-UI: Display NTP warnings in Current Status section with blue color coding | ||
| + | - Web-UI: X button to delete warnings directly from status display (for priority 0-2) | ||
| + | - Web-UI: Improved Current Status layout - organized in rows (LED1-4, AIR1-4, NOW/NEXT) | ||
| + | - Web-UI: Compact design for NOW/NEXT status items and input fields | ||
| + | - Web-UI: AIR Timer Controls now show timer labels (Mic, Phone, etc.) directly on buttons | ||
| + | - Web-UI: NOW/NEXT input fields placed side by side (50% width each) | ||
| + | - Settings: Preset/ | ||
| + | - Settings: UI buttons for preset management (Save, Load, Delete) | ||
| + | - Settings: Log level configuration (DEBUG, INFO, WARNING, ERROR, CRITICAL, NONE) with ComboBox in General settings | ||
| + | - Command-line: | ||
| + | - Tests: Comprehensive unit test coverage for defaults.py (17 tests for get_default() function) | ||
| + | - Tests: Comprehensive unit test coverage for weatherwidget.py (23 tests for WeatherWidget class) | ||
| + | - Tests: Comprehensive unit test coverage for clockwidget.py (25 tests for ClockWidget class) | ||
| + | - Tests: Extended test coverage for start.py with 11 tests for set_log_level() function | ||
| + | - Security: Comprehensive input validation for all network commands (UDP/HTTP) | ||
| + | - Security: Text input sanitization for NOW, NEXT, WARN commands (removes control characters, dangerous patterns) | ||
| + | - Security: Command value validation for LED, AIR, CMD commands (validates allowed values) | ||
| + | - Security: Length limits for text inputs (500 chars for NOW/ | ||
| + | - Security: Input validation for CONF commands (stationname, | ||
| + | - Refactoring: | ||
| + | - Refactoring: | ||
| + | - Refactoring: | ||
| + | - Refactoring: | ||
| + | - Refactoring: | ||
| + | - Refactoring: | ||
| + | - Refactoring: | ||
| + | - Refactoring: | ||
| + | |||
| + | ### Changed | ||
| + | |||
| + | - Fonts settings: family combo (includes bundled Roboto), separate size, bold, and per-row reset instead of the native font dialog | ||
| + | - LED1–4 default font size is 32pt | ||
| + | - Default UI font is now bundled Roboto (FreeSans removed); existing FreeSans settings are mapped to Roboto | ||
| + | - Audio meters are enabled by default with Local Input (`device`) as the source | ||
| + | - Require Python 3.11 or newer; bump websockets to >=17.1 | ||
| + | - Clock: Digital clock second LEDs and colon now repaint aligned to wall-clock second boundaries (removes visible lag at second rollover) | ||
| + | - Refactoring: | ||
| + | - Refactoring: | ||
| + | - Refactoring: | ||
| + | - Code Quality: Removed unnecessary backward compatibility code after refactoring | ||
| + | - Code Quality: Simplified initialization code using for loops for LED and AIR timer setup | ||
| + | - Error Handling: Replaced generic Exception handling with specific custom exceptions throughout codebase | ||
| + | - Error Handling: Standardized error logging with consistent format and context information | ||
| + | - Error Handling: Improved HTTP error responses with appropriate status codes based on error types | ||
| + | - Web-UI: Fixed dark mode flash on page reload by setting theme immediately in HTML head | ||
| + | - Web-UI: Restructured status display for better organization and space efficiency | ||
| + | - Command Handler: Enhanced WARN command to support priority format (WARN: | ||
| + | - MainScreen: Implemented priority-based warning system with array index mapping | ||
| + | - MainScreen: Updated process_warnings() to display highest priority warning (excluding NTP if others exist) | ||
| + | - MainScreen: Simplified update_ntp_status() to use priority -1 directly | ||
| + | - API: get_status_json() now returns warnings array with priorities in addition to legacy warn field | ||
| + | </ | ||
| + | |||
| + | ===== 0.9.7beta4 ===== | ||
| + | |||
| + | < | ||
| + | ### Added | ||
| + | |||
| + | - WebSocket support for Web-UI: Real-time status updates via WebSocket connections (replaces HTTP polling) | ||
| + | - Integration tests for network communication (UDP, HTTP, WebSocket) | ||
| + | - Extended unit tests for timer_manager, | ||
| + | - Test tools: cmdtest_multicast.py and diagnose_multicast.py for multicast testing and diagnostics | ||
| + | - Central configuration file (defaults.py) for all default values | ||
| + | - Type hints and docstrings throughout codebase | ||
| + | - Context manager (settings_group) for QSettings group operations | ||
| + | |||
| + | ### Changed | ||
| + | |||
| + | - Network: Improved multicast support for macOS - UDP server now explicitly joins on loopback interface too | ||
| + | - Network: Improved socket configuration for reliable multicast sending on macOS | ||
| + | - Network: HTTP server now uses ReusableHTTPServer with SO_REUSEADDR to prevent TIME_WAIT issues | ||
| + | - Security: Replaced os.system() with subprocess.run() for secure system command execution | ||
| + | - Error handling: Enhanced error handling for network operations, timer input parsing, and color validation | ||
| + | - Error handling: Graceful degradation when resources (fonts, templates) are missing | ||
| + | - Makefile: Follow symlinks when searching for rcc tool in Homebrew installations | ||
| + | - Fixed: IP addresses now correctly displayed at startup | ||
| + | </ | ||
| + | |||
| + | ===== 0.9.7beta3 ===== | ||
| + | |||
| + | < | ||
| + | ### Added | ||
| + | |||
| + | - Web-UI: Complete web-based remote control interface accessible via HTTP | ||
| + | - Web-UI: Real-time status display for LEDs, AIR timers, and text fields (NOW/ | ||
| + | - Web-UI: LED control buttons with toggle functionality | ||
| + | - Web-UI: AIR timer controls with start/stop and reset (for AIR3/AIR4) buttons | ||
| + | - Web-UI: Text input controls for NOW, NEXT, and WARN messages | ||
| + | - Web-UI: REST-style API endpoints (/ | ||
| + | - Web-UI: Version and distribution information displayed in top-right corner | ||
| + | - Web-UI: Modal dialog with overlay for connection errors (always visible, dims background) | ||
| + | - Web-UI: Clear buttons for NOW/NEXT text inputs | ||
| + | - Web-UI: Current NOW/ | ||
| + | - API: Status endpoint now includes version and distribution information | ||
| + | |||
| + | ### Changed | ||
| + | |||
| + | - Web-UI: HTML template moved from network.py to separate templates/ | ||
| + | - Web-UI: Connection error modal now disables all controls when connection is lost | ||
| + | - Network: HTTP server now supports Web-UI in addition to command API | ||
| + | - Network: Improved thread-safety for GUI operations from HTTP thread using pyqtSignal | ||
| + | </ | ||
| + | |||
| + | ===== 0.9.7beta2 ===== | ||
| + | |||
| + | < | ||
| + | ### Added | ||
| + | |||
| + | - Event logging system for tracking LED changes, AIR timer events, commands, warnings, and system events | ||
| + | - Tooltips for all settings widgets to improve user experience | ||
| + | |||
| + | ### Changed | ||
| + | |||
| + | - Fixed weather widget API calls when widget is disabled or no API key is configured | ||
| + | - Removed unused font button | ||
| + | </ | ||
| + | |||
| + | ===== 0.9.7beta1 ===== | ||
| + | |||
| + | < | ||
| + | ### Added | ||
| + | |||
| + | - Command test scripts for HTTP and UDP testing (utils/ | ||
| + | - Show version, distribution and settings path in about dialog | ||
| + | - Fonts/ | ||
| + | |||
| + | ### Changed | ||
| + | |||
| + | - Major code refactoring: | ||
| + | - Use context manager for QSettings groups | ||
| + | - Consolidated text setters and timer reset methods | ||
| + | - Consolidated AIR reset and start_stop methods | ||
| + | - Consolidated LED toggle methods | ||
| + | - Consolidated set_station_color() and set_slogan_color() methods | ||
| + | - Consolidated set_led1-4() methods into generic method | ||
| + | - Split restore_settings_from_config() into smaller methods | ||
| + | - Optimized led_logic() method | ||
| + | - Optimized font setup in restore_settings_from_config() | ||
| + | - Modernized string formatting to f-strings | ||
| + | - Refactored parse_cmd() using command pattern | ||
| + | - Added logging, type hints, and docstrings throughout codebase | ||
| + | - Fixed crash when UDP/HTTP ports are empty | ||
| + | - Updated copyright strings | ||
| + | - Updated settings.ui | ||
| + | </ | ||
| + | |||
| + | ===== 0.9.6 beta2 ===== | ||
| + | |||
| + | < | ||
| + | ### Added | ||
| + | |||
| + | - options to change icons on all 4 timers | ||
| + | </ | ||
| + | |||
| + | ===== 0.9.6 beta1 ===== | ||
| + | |||
| + | < | ||
| + | ### Added | ||
| + | |||
| + | - option for preferred logo position | ||
| + | </ | ||
| + | |||
| + | ===== 0.9.5 ===== | ||
| + | |||
| + | < | ||
| + | ### Changed | ||
| + | |||
| - fixed textclock when hour == 12 | - fixed textclock when hour == 12 | ||
| - fixed wrong default font size for slogan | - fixed wrong default font size for slogan | ||
| Line 14: | Line 710: | ||
| ### Added | ### Added | ||
| + | |||
| - french localization for textclock | - french localization for textclock | ||
| - left LEDs are now customizable (text/ | - left LEDs are now customizable (text/ | ||
| Line 22: | Line 719: | ||
| - added option to select between no/ | - added option to select between no/ | ||
| - added logo to analog clock | - added logo to analog clock | ||
| + | </ | ||
| - | ## 0.9.4 | + | ===== 0.9.4 ===== |
| + | |||
| + | < | ||
| ### Changed | ### Changed | ||
| + | |||
| - fixed crash when OWM API responds with strange JSON | - fixed crash when OWM API responds with strange JSON | ||
| - OWM API uses https now | - OWM API uses https now | ||
| - | - fixed calling API error when WeatherWidget is disabled (Thanks to https:// | + | - fixed calling API error when WeatherWidget is disabled (Thanks to [ywiskerke](https:// |
| - | - added dutch language support (Thanks to https:// | + | - added dutch language support (Thanks to [ywiskerke](https:// |
| - fixed wrong hour in xx:45 textclock display | - fixed wrong hour in xx:45 textclock display | ||
| + | </ | ||
| - | ## 0.9.3 | + | ===== 0.9.3 ===== |
| + | |||
| + | < | ||
| ### Added | ### Added | ||
| + | |||
| - Alt-S now resets stream timer | - Alt-S now resets stream timer | ||
| - added enable/ | - added enable/ | ||
| Line 39: | Line 744: | ||
| - fixed logo size calculation for portrait format logos | - fixed logo size calculation for portrait format logos | ||
| - customizable font and size for various elements | - customizable font and size for various elements | ||
| + | </ | ||
| - | ## 0.9.2 | + | ===== 0.9.2 ===== |
| + | |||
| + | < | ||
| ### Changed | ### Changed | ||
| + | |||
| - Fix crash when timer value is not numeric | - Fix crash when timer value is not numeric | ||
| - Fix show/hide of weather widget | - Fix show/hide of weather widget | ||
| Line 49: | Line 758: | ||
| ### Added | ### Added | ||
| + | |||
| - HTTP API | - HTTP API | ||
| - Update check support | - Update check support | ||
| - Show/hide LED1-4 | - Show/hide LED1-4 | ||
| - Show/hide TextClock | - Show/hide TextClock | ||
| + | </ | ||
| - | ## 0.9.1 beta4 | + | ===== 0.9.1 beta4 ===== |
| + | |||
| + | < | ||
| ### Changed | ### Changed | ||
| + | |||
| - Fix window resize when displaying long text in NOW/ | - Fix window resize when displaying long text in NOW/ | ||
| + | </ | ||
| - | ## 0.9.1 beta3 | + | ===== 0.9.1 beta3 ===== |
| + | |||
| + | < | ||
| ### Added | ### Added | ||
| + | |||
| - this changelog | - this changelog | ||
| - selectable blinking/ | - selectable blinking/ | ||
| ### Changed | ### Changed | ||
| + | |||
| - Fix update of weatherwidget when location is changed | - Fix update of weatherwidget when location is changed | ||
| </ | </ | ||