Changelog
All notable changes to this project are documented in this file. The format is based on Keep a Changelog and the project currently tracks releases under the 2.x series.
[2.12.18] - 2025-11-26
Fixed
- Redirected the policy docs URLs to the canonical
/termsand/privacyroutes and updated the documentation index to point to those pages so users no longer see divergent copies of the legal notices.
[2.12.17] - 2025-11-25
Fixed
- Redirect permission-denied responses to the dashboard blueprint's admin route so settings pages (including
/settings/alert-feeds) return a proper 403 flow instead of a 500 BuildError when the non-namespaced endpoint is unavailable.
[2.12.15] - 2025-11-22
Changed
- Downsampled the continuous EAS monitor to 8 kHz (with automatic resampling from higher-rate sources) so SAME FSK decoding runs at an efficient rate without wasting CPU on unnecessary bandwidth.
- Surfaced both the source and decoder sample rates in the monitor status API so operators can verify the tap is resampling correctly instead of assuming 22.05 kHz.
[2.12.14] - 2025-11-22
Fixed
- Matched the streaming decoder sample rate to the active ingest source so SAME correlation and preamble detection run at the correct frequency instead of drifting off-sync when sources run at 44.1 kHz.
- Exposed the ingest-driven sample rate in the broadcast adapter stats returned with the EAS monitor status so operators can confirm the tap is aligned with the source.
[2.12.13] - 2025-12-05
Fixed
- Added broadcast subscription health (queue depth, underruns, last audio time) to the continuous monitor API so the dashboard shows when audio is actually flowing and operators can see the tap is healthy instead of guessing through empty fields.
- Throttled repetitive buffer underrun warnings from the monitor's broadcast adapter while still counting them for visibility, preventing log spam when sources are temporarily quiet.
- Exposed broadcast queue stats and the currently active source in
/api/audio/metricsso VU meters can distinguish "no signal" from transport failures and display accurate runtime state.
[2.12.12] - 2025-12-05
Fixed
- Filled the continuous monitor status API with the streaming decoder's health, rate, and sync metrics so every dashboard field renders and operators can confirm the monitor is actively processing audio.
- Tagged live audio metrics with each source's runtime status so the VU meters reflect whether inputs are running instead of dimming as if they were offline.
[2.12.10] - 2025-12-04
Changed
- Added a selectable streaming mode on the audio monitor that prefers the built-in HTTPS stream by default and only opts into Icecast when operators explicitly choose it, reducing stalls when external ports are blocked.
[2.12.9] - 2025-12-04
Fixed
- Filter placeholder artwork metadata values (e.g.,
null,undefined, root-only paths) in the audio monitor so browsers stop
/null images from the dashboard host.[2.12.8] - 2025-12-03
Fixed
- Corrected the default Icecast external port variable so Icecast URLs use the configured
ICECASTEXTERNALPORTrather than
[2.12.7] - 2025-12-02
Fixed
- Hardened the SDR audio monitoring stack by adding an auto-healing ingest controller that restarts stalled/error sources,
[2.12.6] - 2025-12-01
Fixed
- Added a differential RBDS symbol slicer so FM demodulation correctly reconstructs PI/PS/RadioText metadata and keeps the latest
- Hardened the SoapySDR receiver implementation by mapping stream error codes (including SOAPYSDRNOT_LOCKED) to descriptive
[2.12.5] - 2025-11-30
Changed
- Disabled the CAP poller's optional SDR capture orchestration by default so its RadioManager hooks stay idle unless the poller
CAPPOLLERENABLE_RADIO environment flag, and exposed a
--radio-captures/--no-radio-captures CLI switch so operators can explicitly opt into capture requests when they actually
want files.[2.12.4] - 2025-11-29
Fixed
- Forced OLED templates with manually positioned lines to default to no-wrapping in the renderer so preview cards and physical
[2.12.3] - 2025-11-29
Fixed
- Updated the OLED layout migration to use uniquely named bind parameters so Alembic can compile the update statement without colliding with column names, preventing the
bindparam() name 'name' is reservedfailure during upgrades.
[2.12.2] - 2025-11-29
Fixed
- Added an automatic SoapySDR fallback that retries opening receivers without the serial filter when the initial connection fails, letting Airspy radios initialize even if the driver rejects the serialized arguments.
- Updated the OLED layout migration to JSON-serialize
template_databefore persisting it to PostgreSQL so upgrades no longer crash withcan't adapt type 'dict'errors.
[2.12.1] - 2025-11-27
Changed
- Rebuilt the EAS Station wordmark as an inline SVG partial that inherits theme colors for its accent bars and lettering, so the logo automatically matches whichever palette operators choose without filters or manual assets.
- Updated the navigation bar and hero sections on the Help, About, Privacy, Terms, and Version pages to consume the new partial, eliminating duplicate markup and keeping the refreshed layout consistent in every mode.
[2.12.0] - 2025-11-27
Added
- Introduced two new UI themes, Midnight and Tide, complete with theme-switcher entries and CSS variable palettes so operators can choose between a deep slate dark mode and a crisp coastal light mode.
- Published NOAA, FEMA IPAWS, and ARRL resource badges plus a curated "Trusted Field Resources" section on the Help page so the most requested links are visual, organized, and no longer broken.
Changed
- Modernized the Help & Operations Guide layout with hero quick links, an operations flow mini-timeline, refreshed typography, and a reorganized assistance section for a more professional flow.
- Added dedicated Help-page utility styles that sharpen quick-link tiles, timeline steps, and resource cards, ensuring the guide matches the rest of the dashboard polish.
[2.11.7] - 2025-11-18
Changed
- Added a refresh-status meta block on the dashboard map card that now shows the last update time, refresh source, and a live
- Replaced the fixed interval timer with a scheduler that pauses during manual refreshes, resumes after success or failure, and
- Updated the dashboard refresh action so manual, automatic, keyboard, and debug triggers all share the same code path,
[2.11.6] - 2025-11-23
Removed
- Dropped the
DEFAULTAREATERMSenvironment variable, the accompanying admin editor entry, and the template references so
Changed
- Default location snapshots now seed
area_termswith an empty list rather than mirroring the removed environment variable,
[2.11.5] - 2025-11-23
Fixed
- Removed the CAP poller's area-term fallback so alerts only appear on
/alertswhen their SAME or UGC codes match the
[2.11.4] - 2025-11-22
Fixed
- Fixed duplicate DOM element declarations on the Weekly Test Automation page that threw JavaScript errors and prevented saved
[2.11.3] - 2025-11-21
Fixed
- Ensured the RWT scheduler always opens a Flask application context before touching the
[2.11.2] - 2025-11-20
Added
- Added an offline alert self-test harness plus
scripts/runalertself_test.pyso operators can replay bundled RWT captures,
- Folded the alert self-test harness into the Tools → Alert Verification dashboard so operators can replay bundled or custom
Changed
- Consolidated the alert self-test workflow into the Alert Verification dashboard so operators validate decoding, analytics,
[2.10.0] - 2025-11-18
Added
- Added comprehensive
utilities.csswith gradient, card, badge, spacing, layout, typography, shadow, border, visibility, and animation utilities - Created reusable template component partials in
templates/components/for metric cards, stat cards, page headers, status badges, and data lists - Built new professional version page (
/help/version) with tabbed interface featuring Overview, Changelog, Features, System Info, and JSON API tabs - Added
changelog_parser.pyutility to parse CHANGELOG.md files and extract structured version history - Integrated git commit information display (hash, branch, date, message) on version page
- Added visual timeline visualization for changelog with animated current version marker
- Added comprehensive feature matrix showing all installed system components and their availability status
- Added copy-to-clipboard functionality for JSON API output
Changed
- Updated
base.htmltemplate to include all CSS files in proper order: design-system, base, components, utilities, layout, and enhancements - Replaced basic version page with comprehensive tabbed interface showing full release history from parsed CHANGELOG.md
- Enhanced version route in
routes_monitoring.pyto include git metadata and parsed changelog data - Standardized gradient usage across all templates with new utility classes (.gradient-primary, .gradient-success, etc.)
- Improved version page accessibility with URL hash-based tab navigation
Fixed
- Fixed inconsistent gradient implementations across templates by centralizing in utilities.css
- Fixed missing CSS files (design-system.css, components.css) not being loaded in base template
- Improved dark theme compatibility for version page components
[Unreleased]
Added
- Clarified the commercial license offer notes pricing covers software only and excludes any hardware costs.
- Extended
/api/systemstatusand/api/systemhealthwith hostname, primary IPv4, uptime, and primary-interface metadata
- Surfaced the Weekly Test Automation console with a county management side panel, Broadcast navigation entry, and in-product callouts so operators can edit RWT schedules and default SAME codes entirely from the UI.
- Added a curated OLED showcase rotation (system overview, alerts, network beacon, IPAWS poll watch, audio health, and audio
--display-type flag to scripts/createexamplescreens.py for targeted installs.
- Enforced Argon Industria OLED reservations by blocking BCM pins 2, 3, 4, and 14 (physical header block 1-8) from GPIO configuration, greying them out in the GPIO Pin Map, and surfacing guidance in setup, environment, and hardware docs.
- Provisioned default OLED status screens with system, alert, and audio telemetry plus on-device button shortcuts (short press to advance rotation, long press for a live snapshot).
- Added Argon Industria SSD1306 OLED module support with full configuration tooling and display workflows
- Introduced
appcore/oled.pywith luma.oled-based controller, newOLED*environment variables, and runtime initialization hooks - Extended screen renderer, manager, and
/api/screensendpoints with anoleddisplay type alongside LED and VFD rotations - Updated admin Environment editor, setup wizard, and hardware reference docs for OLED installation and configuration guidance
- Added interactive GPIO Pin Map page (System → GPIO Pin Map) to visualize the 40-pin header and
GPIOPINBEHAVIOR_MATRIX.
- Added multi-pin GPIO configuration loader with persistent environment editor support, ensuring
- Added IPAWS poll debug export endpoints for Excel and PDF with UI buttons on
/debug/ipawsfor rapid sharing of poll runs. - Added comprehensive analytics and compliance enhancements with trend analysis and anomaly detection
- Implemented
app_core/analytics/module with metrics aggregation, trend analysis, and anomaly detection - Created
MetricSnapshot,TrendRecord, andAnomalyRecorddatabase models for time-series analytics - Built
MetricsAggregatorto collect metrics from alert delivery, audio health, receiver status, and GPIO activity - Implemented
TrendAnalyzerwith linear regression, statistical analysis, and forecasting capabilities - Added
AnomalyDetectorusing Z-score based outlier detection, spike/drop detection, and trend break analysis - Created comprehensive API endpoints at
/api/analytics/*for metrics, trends, and anomalies - Built analytics dashboard UI at
/analyticswith real-time metrics, trend visualization, and anomaly management - Added
AnalyticsSchedulerfor automated background processing of metrics aggregation and analysis - Documented complete analytics system architecture and usage in
app_core/analytics/README.md - Published comprehensive compliance reporting playbook in
docs/compliance/reporting_playbook.mdwith workflows for weekly/monthly test verification, performance monitoring, anomaly investigation, and regulatory audit preparation
Fixed
- Removed caching from
/api/audio/metricsand set explicit no-store headers so VU meters and live audio telemetry refresh in
- Hardened backup API endpoints by validating backup names to block path traversal before
- Removed the CAP poller's area-term fallback so
/alertsonly surfaces entries that explicitly name the configured SAME or
- Ensured the continuous EAS monitor auto-initializes on demand so the audio monitoring page no longer stalls when the monitor
- Added comprehensive audio ingest pipeline for unified capture from SDR, ALSA, and file sources
- Implemented
app_core/audio/ingest.pywith pluggable source adapters and PCM normalization - Added peak/RMS metering and silence detection with PostgreSQL storage
- Built web UI at
/settings/audio-sourcesfor source management with real-time metering - Exposed configuration for capture priority and failover in environment variables
Fixed
- Documented the Weekly Test Automation county list regression addressed in 2.11.4 so QA can trace the scheduler fix through the
- Added FCC-compliant audio playout queue with deterministic priority-based scheduling
- Created
appcore/audio/playoutqueue.pywith Presidential > Local > State > National > Test precedence - Built
appcore/audio/outputservice.pybackground service for ALSA/JACK playback - Implemented automatic preemption for high-priority alerts (e.g., Presidential EAN)
- Added playout event tracking for compliance reporting and audit trails
- Added comprehensive GPIO hardening with audit trails and operator controls
- Created unified
app_utils/gpio.pyGPIOController with active-high/low, debounce, and watchdog timers - Added
GPIOActivationLogdatabase model tracking pin activations with operator, reason, and duration - Built operator override web UI at
/admin/gpiowith authentication and manual control capabilities - Documented complete hardware setup, wiring diagrams, and safety practices in
docs/hardware/gpio.md - Added comprehensive security controls with role-based access control (RBAC), multi-factor authentication (MFA), and audit logging
- Implemented four-tier role hierarchy (Admin, Operator, Analyst, Viewer) with granular permission assignments
- Added TOTP-based MFA enrollment and verification flows with QR code setup
- Created comprehensive audit log system tracking all security-critical operations with retention policies
- Built dedicated security settings UI at
/settings/securityfor managing roles, permissions, and MFA - Added database migrations to auto-initialize roles and assign them to existing users
- Documented security hardening procedures in
docs/MIGRATION_SECURITY.md - Redesigned EAS Station logo with modern signal processing visualization
- Professional audio frequency spectrum visualization with animated elements
- Radar/monitoring circular grid overlay for technical aesthetic
- Animated signal waveform with alert gradient effects
- Deep blue to cyan gradient representing signal monitoring and alert processing
- SVG filters for depth, glow effects, and contemporary design polish
Fixed
- Restored SSL certificate and private key export downloads by mounting the Let's Encrypt
/etc/letsencrypt and
/app-config/certs for domain materials before returning actionable guidance.
- Converted the Stream Profiles interface to the shared base layout with Bootstrap 5 modal
- Reduced excessive whitespace in dark themes by introducing theme-aware layout spacing
- Ensure the 20251107 decoded audio segment migration only adds the
- Allow fresh installations to run Alembic migrations without errors by skipping the
location_settings table has not
been created yet.
- Prevent SDR audio monitors from returning HTTP 503 errors by restoring persisted adapters before serving playback, start/stop,
- Force dark-mode typography and link treatments to use the light contrast palette when
data-theme-mode="dark"is active so
- Remove the auto-injected skip navigation anchors so the navbar's leading section only presents the wordmark and health status
- Improved readability of dark UI themes by brightening background surfaces, borders, and text contrast variables shared across the design system, and by mapping the design system colors to each theme's palette so custom dark presets retain their intended contrast.
- Surface actionable diagnostics when GPIO hardware is inaccessible, highlighting missing
- Replaced the deprecated
RPi.GPIObackend withgpiozerooutput devices and ensured typing imports
- Ensured Docker Compose publishes nginx ports on both IPv4 and IPv6 addresses so external scanners can reach the HTTPS endpoint over IPv6.
- Reduced nginx static asset cache lifetime from 24 hours to five minutes so freshly deployed frontend changes appear without manual cache purges.
- Prevented alert verification page timeouts by offloading audio decoding to a background worker and persisting progress/results for UI polling.
- Added Raspberry Pi 5-compatible
lgpiofallback for GPIO control so BCM pins configured as active-high no longer enter an error state whenRPi.GPIOis unavailable.
Changed
- Refined the theming system with higher-contrast logo treatments and added Aurora, Nebula, and Sunset presets to expand the built-in palette while keeping the wordmark legible across gradients.
- Renamed the "EAS Workflow" console to Broadcast Builder and linked the Weekly Test Automation page throughout the Broadcast menu and workflow hero banner so automation tooling is obvious to operators.
- Consolidated stream support in Audio Sources system - Removed stream support from RadioReceiver model and UI, centralizing all HTTP/M3U stream configuration through the Audio Sources page where StreamSourceAdapter already provided full functionality
- Removed
sourcetypeandstreamurlfields from RadioReceiver database model - RadioReceiver now exclusively handles SDR hardware (RTL-SDR, Airspy)
- Added Stream (HTTP/M3U) option to Audio Sources UI dropdown
- Added stream configuration fields (URL, format) to Audio Sources modal
- Updated navigation to point to
/settings/audioinstead of deprecated/audio/sourcesroute - Clear separation of concerns: Radio = RF hardware, Audio = all audio ingestion sources
Fixed
- Restored
/statsdashboard data by providing CAP alert history, reliability metrics, and polling debug visibility in/logs. - Fixed Audio Sources page not loading sources - Corrected missing element IDs and event listeners that prevented audio sources from displaying on
/settings/audiopage - Fixed element IDs to match JavaScript expectations (
active-sources-count,total-sources-count,sources-list) - Fixed modal IDs to match JavaScript (
addSourceModal,deviceDiscoveryModal) - Added event listeners for Add Source, Discover Devices, and Refresh buttons
- Added toast container for notification display
- Removed deprecated
/audio/sourcespage route - Fixed JSON serialization errors in audio APIs - Backend was returning -np.inf (negative infinity) for dB levels when no audio present, causing "No number after minus sign in JSON" errors in frontend
- Added
sanitizefloat()helper that converts infinity/NaN to valid numbers (-120.0 dB for silence) - Applied sanitization to all audio API endpoints:
/api/audio/sources,/api/audio/metrics,/api/audio/health - Ensures all API responses are valid JSON that browsers can parse
- Fixed Add Audio Source button not working - Form element IDs didn't match JavaScript expectations
- Changed form ID from
audioSourceFormtoaddSourceForm - Changed container ID from
deviceParamsContainertosourceTypeConfig - Updated field IDs to match JavaScript (
sourceName,sampleRate,channels,silenceThreshold,silenceDuration) - Added missing
silenceDurationfield for silence detection configuration - Fixed audio source delete, start, and stop operations failing with 404 errors
- Added
encodeURIComponent()to all fetch URLs for proper URL encoding of source names with special characters - Added
sanitizeId()helper to create safe HTML element IDs (replaces special chars with underscores) - Fixed onclick handler escaping to prevent JavaScript injection vulnerabilities
- Updated
updateMeterDisplay()to use sanitized IDs when finding meter elements - Fixed DOM element ID mismatches - JavaScript was looking for elements with IDs that didn't exist in HTML template
- Changed
healthScore→overall-health-score - Changed
silenceAlerts→alerts-count - Added hidden
overall-health-circleandalerts-listelements required by JavaScript - Fixed Edit Audio Source button failing - Edit modal didn't exist in HTML template
- Added complete
editSourceModalwith all required fields (priority, silence threshold/duration, description, enabled, auto-start) - Source name and type are readonly (can't be changed after creation)
- Fixed device discovery modal to have
discoveredDevicesdiv for JavaScript - Added detailed error messages for audio source failures - Users now see exactly why sources fail instead of generic "error" status
- Added
error_messagefield toAudioSourceAdapterto track failure details - Stream connection failures show max reconnection attempts message
- Missing dependencies show installation instructions (e.g., "install pydub")
- Error messages displayed in red alert boxes on source cards
- Added disconnected status alert showing reconnection attempts
- Fixed numpy float32 JSON serialization error - Audio APIs were returning 500 errors due to numpy types not being JSON-serializable
- Updated
sanitizefloat()to detect and convert numpy.floating and numpy.integer types to Python float - Fixes "Object of type float32 is not JSON serializable" errors on
/api/audio/sourcesand/api/audio/metrics - Fixed numpy bool_ JSON serialization error - Audio APIs were returning intermittent 500 errors due to numpy boolean types not being JSON-serializable
- Added
sanitizebool()helper to convert numpy.bool_ types to Python bool - Applied to all boolean fields: silencedetected, clippingdetected, enabled, autostart, acknowledged, resolved, isactive, ishealthy, errordetected
- Fixes "Object of type bool is not JSON serializable" errors on
/api/audio/metrics,/api/audio/health, and/api/audio/alerts - Added pydub dependency for MP3/AAC/OGG stream decoding from HTTP/Icecast sources
- Added
pydub==0.25.1to requirements.txt (requires ffmpeg system package already in Dockerfile) - Fixed module import paths in scripts/manualeasevent.py and scripts/manualalertfetch.py by adding repository root to sys.path
- Fixed CSRF token protection in password change form (security settings)
- Fixed audit log pagination to cap per_page parameter at 1000 to prevent DoS attacks
- Fixed timezone handling to use timezone-aware UTC timestamps instead of naive datetime.utcnow()
- Fixed migration safety with defensive checks for permission lookup to handle missing permissions gracefully
- Fixed markdown formatting in MIGRATION_SECURITY.md with proper heading levels and code block language specs
Changed
- Enhanced AGENTS.md with bug screenshot workflow, documentation update requirements, and semantic versioning conventions
- Reorganized root directory by moving development/debug scripts to scripts/deprecated/ and utility scripts to scripts/
- Removed README.md.backup file from repository
- Improved error logging to use logger.exception() instead of logger.error() in 8 locations across security routes for better debugging
Added
- Added an admin location reference view that summarises the saved NOAA zone catalog
- Added a public forecast zone catalog loader that ingests the bundled
assets/z_05mr24.dbf file into a dedicated reference table, exposes a
tools/synczonecatalog.py helper, and validates admin-supplied zone codes
against the synchronized metadata.
- Added an interactive
.envsetup wizard available at/setup, with a CLI
tools/setup_wizard.py), so operators can generate secrets,
database credentials, and location defaults before first launch without
editing text files by hand.
- Added a repository
VERSIONmanifest, shared resolver, andtests/testreleasemetadata.pyguardrail so version bumps and changelog updates stay synchronised for audit trails. - Added
tools/inplaceupgrade.pyfor in-place upgrades that pull, rebuild, migrate, and restart services without destroying volumes, plustools/createbackup.pyto snapshot.env, compose files, and a Postgres dump with audit metadata before changes. - Introduced a compliance dashboard with CSV/PDF exports and automated
- Enabled the manual broadcast builder to target county subdivisions and the
- Introduced a dedicated Audio Archive history view with filtering, playback,
- Surfaced archived audio links throughout the alert history and detail pages so
- Added a
manualeasevent.pyutility that ingests raw CAP XML (e.g., RWT/RMT tests),
- Introduced the
EASMANUALFIPS_CODESconfiguration setting to control which
- Bundled the full national county/parish FIPS registry for manual activations and
- Cataloged the nationwide SAME event code registry together with helper utilities so
- Added a CLI helper (
tools/generatesampleaudio.py) to create demonstration SAME audio
- Delivered an in-app Manual Broadcast Builder on the EAS Output tab so operators can generate SAME headers, attention tones (EAS dual-tone or 1050 Hz), optional narration, and composite audio without leaving the browser.
- Archived every manual EAS activation automatically, writing audio and summary
- Unlocked an in-app first-run experience so the Admin panel exposes an
- Introduced optional Azure AI speech synthesis to append narrated voiceovers when the
[2.9.0] - 2025-11-15
Added
- OLED alert rotations now preempt normal playlists when
skiponalertis enabled, prioritizing the most severe alert and
/api/alertsnow returns each alert's source and (when available) the cached EAS narration text, allowing custom OLED/LED
[2.8.0] - 2025-02-15
Fixed
- Prevented the
20251113addserialmodetoledsign_statusAlembic migration from
TypeError: execute() takes 2 positional arguments but 3 were given by
issuing the default value backfill through the SQLAlchemy bind connection instead
of op.execute, ensuring upgrades complete cleanly before the app starts.
- Added an offline pyttsx3 text-to-speech provider so narration can be generated without
- Authored dedicated
docs/reference/ABOUT.mdanddocs/guides/HELP.mddocumentation describing the system mission, software stack, and operational playbooks, with cross-links from the README for quick discovery. - Exposed in-app About and Help pages so operators can read the mission overview and operations guide directly from the dashboard navigation.
- Distributed a
docker-compose.embedded-db.ymloverlay so application services
alerts-db PostGIS container or connect to an
existing deployment without editing the primary compose file.
- Documented open-source dependency attributions in the docs and surfaced
Changed
- Documented why the platform remains on Python 3.12 instead of the new Python 3.13 release across the README and About surfaces,
- Documented Debian 14 (Trixie) 64-bit as the validated Raspberry Pi host OS while clarifying that the container image continues to ship on Debian Bookworm via the
python:3.12-slim-bookwormbase. - Documented the release governance workflow across the README, ABOUT page, Terms of Use, master roadmap, and site footer so version numbering, changelog discipline, and regression verification remain mandatory for every contribution.
- Suppressed automatic EAS generation for Special Weather Statements and Dense Fog Advisories to align with standard activation practices.
- Clarified in the README and dependency notes that PostgreSQL with PostGIS must run in a dedicated container separate from the application services.
- Documented a single-line command for cloning the Experimental branch and launching the Docker Compose stack so operators can bootstrap quickly.
- Clarified the update instructions to explicitly pull the Experimental branch when refreshing deployments.
- Documented the expectation that deployments supply their own PostgreSQL/PostGIS host and simplified Compose instructions to run only the application services.
- Reworked the EAS Output tab with an interactive Manual Broadcast Builder and refreshed the README/HELP documentation to cover the browser-based workflow.
- Enhanced the Manual Broadcast Builder with a hierarchical state→county SAME picker, a deduplicated PSSCCC list manager, a live
ZCZC-ORG-EEE-PSSCCC+TTTT-JJJHHMM-LLLLLLLL-preview with field-by-field guidance, and refreshed docs that align with commercial encoder terminology. - Added a one-touch Quick Weekly Test preset to the Manual Broadcast Builder so operators can load the configured SAME counties, test status, and sample script before generating audio.
- Updated the Quick Weekly Test preset to omit the attention signal by default and added a
- Bundled
ffmpeg,espeak, andlibespeak-ng1system packages in the Docker image so offline narration dependencies work out of the box during container builds.
Fixed
- Inserted the mandatory display-position byte in LED sign mode fields so M-Protocol
- Surface offline pyttsx3 narration failures in the Manual Broadcast Builder with
- Detect missing libespeak dependencies when pyttsx3 fails and surface
- Detect missing ffmpeg dependencies and empty audio output from pyttsx3 so the
- Surface actionable pyttsx3 dependency hints when audio decoding fails so
- Added an espeak CLI fallback when pyttsx3 fails to emit audio so offline
- Count manual EAS activations when calculating Audio Archive totals and show them
- Moved the Manual Broadcast Archive card to span the full EAS console width,
- Corrected the Quick Weekly Test preset so the sample Required Weekly Test script
- Standardised the manual and automated encoder timing so each SAME section includes a one-second
NNNN payload per 47 CFR §11.31.
- Replaced the free-form originator/call-sign fields with a guarded originator dropdown listing the four FCC originator codes (EAS, CIV, WXR, PEP) and a station identifier input, filtered the event selector to remove placeholder
??*codes, and enforced the 31-location SAME limit in the UI. - Simplified database configuration by deriving
DATABASEURLfrom thePOSTGRES*variables when it is not explicitly set, eliminating duplicate secrets in.env. - Restored the
.envtemplate workflow, updated quick-start documentation to copy
.env.example, and reiterated that operators must rotate the placeholder
secrets immediately after bootstrapping the stack.
- Streamlined
.env.exampleby removing unused settings and documenting optional location defaults leveraged by the admin UI. - Updated the GPIO relay control so it remains engaged for the full alert audio playback,
EASGPIOHOLD_SECONDS as the minimum release delay once audio finishes.
- Automatically generate and play an End-Of-Message (EOM) data burst sequence after each alert
- Refactored the monolithic
app.pyinto cohesiveapp_coremodules (alerts, boundaries,
- Manual CAP tooling now validates inputs against the registry, surfaces friendly area
- Manual CAP broadcasts enforce configurable SAME event allow-lists and display the
- Ensured automated and manual SAME headers include the sixteen 0xAB preamble bytes
- Restricted automatic EAS activations to CAP products whose SAME event codes match
Fixed
- Corrected SAME/RTTY generation to follow 47 CFR §11.31 framing (seven LSB-first ASCII bits, trailing null bit, and precise 520 5⁄6 baud timing) so the AFSK bursts decode at the proper pitch and speed.
- Fixed admin location settings so statewide SAME/FIPS codes remain saved when operators select entire states.
- Corrected the generated End Of Message burst to prepend the sixteen 0xAB preamble bytes so decoders reliably synchronise with the termination header.
- Trimmed the manual and UI event selector to the authorised 47 CFR §11.31(d–e) code tables and removed placeholder
??*entries. - Eliminated
service "app" depends on undefined service "alerts-db"errors by removing the optional compose overlay, deleting the unused service definition, and updating documentation to assume an external database. - Ensured the Manual Broadcast Builder always renders the SAME event code list so operators can
- Fixed the Manual Broadcast Builder narration preview so newline escaping no longer triggers a
- Restored the
.env.exampletemplate and documented the startup error shown when the
- Skip PostGIS-specific geometry checks when running against SQLite and store geometry
- Corrected manual CAP allow-all FIPS logic to use 6-digit SAME identifiers so alerts configured
- Resolved an SQLAlchemy metadata attribute conflict so the Flask app and polling services can
- Ensure the Flask application automatically enables the PostGIS extension before creating
- Rebuilt the LED sign M-Protocol frame generation to include the SOH/type/address header,
- Honored the Alpha M-Protocol handshake by draining stale responses, sending EOT after
- Fixed the Alpha text write command to send the single-byte "A" opcode followed by the
- Prevented the LED fallback initializer from raising a
NameErrorwhen the optional
[2.7.5] - 2025-11-15
Fixed
- Allow first-time deployments to create the initial administrator from a dedicated
[2.7.2] - 2025-11-15
Fixed
- Restore SDR audio monitor adapters on-demand for all audio ingest APIs, eliminating the recurring 503 responses and broken
[2.7.1] - 2025-11-15
Fixed
- Backfill SDR squelch columns automatically when legacy deployments haven't run the
[2.7.0] - 2025-11-14
Added
- Added an audio-monitor provisioning API and UI workflow that auto-starts SDR Icecast streams, surfaces RBDS programme data, and exposes squelch/carrier telemetry directly from the radio settings page for immediate listening checks.
Changed
- Enabled configurable squelch thresholds, timing, and carrier-loss alarms for SDR receivers with service-specific defaults tuned for Raspberry Pi deployments, reducing false positives while keeping CPU usage low.
[2.4.16] - 2025-11-10
Fixed
- Removed the
APPBUILDVERSIONenvironment override so persistent.envfiles can no longer pin stale release numbers; the UI now always reflects the repositoryVERSIONmanifest.
[2.4.15] - 2025-11-10
Fixed
- Ensured the version resolver invalidates its cache when
APPBUILDVERSIONor theVERSIONfile changes so dashboards display
- Disabled caching on the built-in documentation viewer routes to prevent browsers and reverse proxies from serving outdated
[2.4.14] - 2025-11-10
Fixed
- Added automatic cache-busting query parameters to all Flask-served static asset URLs so envoy/nginx layers fetch freshly deployed bundles instead of stale copies (Screenshot7-11-202575931_easstation.com.jpeg).
[2.4.11] - 2025-11-09
Fixed
- Corrected the documentation viewer's Mermaid block detection to support Windows-style line endings so diagrams render instead of showing raw code.
- Refreshed system version metadata on each request so the footer and monitoring endpoints display the latest release after version bumps.
[2.4.1] - 2025-11-09
Fixed
- Resolved production nginx image regressions - Ensured HTTPS container bundles required tooling and static assets
- Added
certbotto nginx Docker image so Let's Encrypt provisioning no longer fails withcertbot: not found - Copied repository
static/directory into the image to stop 404 errors for CSS, JS, and image assets - Updated nginx configuration to use the modern
http2 on;directive and silence deprecation warnings during startup
[2.3.12] - 2025-11-15
Fixed
- Hardened admin location validation so statewide SAME/FIPS codes are always accepted and labelled consistently when saving.
[2.3.11] - 2025-11-14
Fixed
- Fixed admin location settings so statewide SAME/FIPS codes remain saved when operators select entire states.
[2.3.10] - 2025-11-03
Changed
- Reformatted SAME plain-language summaries to omit appended FIPS and state code
[2.3.9] - 2025-11-03
Changed
- Display the per-location FIPS identifiers and state codes on the Audio Archive
[2.3.8] - 2025-11-02
Fixed
- Backfilled missing plain-language SAME header summaries when loading existing
[2.3.7] - 2025-11-02
Changed
- Linked the admin location reference summary and API responses to the bundled
assets/pd01005007curr.pdf) and NOAA Public
Forecast Zones catalog so operators see the authoritative data sources.[2.3.6] - 2025-11-02
Added
- Added an admin location reference API and dashboard card that surfaces the saved
[2.3.5] - 2025-11-01
Fixed
- Prevented the public forecast zone catalog synchronizer from inserting duplicate
[2.3.3] - 2025-11-13
Changed
- Rebased the container on the
python:3.12-slim-bookwormimage, added security upgrades during build, and refreshed pinned Python dependencies (including SciPy 1.14.1) to address Docker Hub vulnerability scans. - Documented Raspberry Pi 5 (4 GB RAM) as the reference platform across the README, policy documents, and in-app help/about pages while noting continued Raspberry Pi 4 compatibility.
[2.3.2] - 2025-11-02
Changed
- The web server now falls back to a guarded setup mode when critical
/setup so operators can repair the environment without editing
.env manually first.[2.3.1] - 2025-11-01
Added
- Added one-click backup and upgrade controls to the Admin System Operations panel, wrapping the existing CLI helpers in background tasks with status reporting.
[2.1.9] - 2025-10-31
Added
- Delivered a WYSIWYG LED message designer with content-editable line cards, live colour/effect previews,
Changed
- Refactored the LED controller to accept structured line payloads, allowing nested colours, display modes,
- Enhanced the LED send API to normalise structured payloads, summarise mixed-format messages for history
[2.1.8] - 2025-10-30
Fixed
- Inserted the mandatory display-position byte in LED sign mode fields so M-Protocol
[2.1.7] - 2025-10-29
Removed
- Purged IDE metadata, historical log outputs, unused static assets, and legacy diagnostic scripts
Changed
- Updated ignore rules and documentation so generated EAS artifacts and runtime logs remain outside
[2.1.6] - 2025-10-28
Changed
- Aligned build metadata across environment defaults, the diagnostics endpoints, and the
/health, /version, and the footer display the same system version.
- Refreshed the README to highlight core features, deployment steps, and configuration
[2.1.5] - 2025-10-27
Added
- Added database-backed administrator authentication with PBKDF2 hashed passwords,
- Expanded the admin console with a user management tab, dedicated login page, and APIs
- Introduced
.env.examplealongside README instructions covering environment setup and
- Implemented the EAS broadcaster pipeline that generates SAME headers, synthesizes WAV
- Published
/admin/eas_messagesfor browsing generated transmissions and downloading
Changed
- Switched administrator password handling to Werkzeug's PBKDF2 helpers while migrating
- Extended the database seed script to provision
adminusers,easmessages, and
location_settings tables together with supporting indexes.[2.1.4] - 2025-10-26
Added
- Persisted configurable location settings with admin APIs and UI controls for managing
- Delivered a manual NOAA alert import workflow with backend validation, a reusable CLI
- Enabled editing and deletion of stored alerts from the admin console, including audit
- Broadened boundary metadata with new hydrography groupings and preset labels for water
Changed
- Hardened manual import queries to enforce supported NOAA parameters and improved error
- Updated Docker Compose defaults and boundary ingestion utilities to better support
[2.1.0] - 2025-10-25
Added
- Established the NOAA CAP alert monitoring stack with Flask, PostGIS persistence,
- Delivered the interactive Bootstrap-powered dashboard with alert history, statistics,
- Integrated optional LED sign controls with configurable presets, message scheduling,
- Added containerized deployment assets (Dockerfile, docker-compose) and operational
[2.2.0] - 2025-10-29
Added
- Recorded the originating feed for each CAP alert and poll cycle, exposing the source in the
- Normalised IPAWS XML payloads with explicit source tagging and circle-to-polygon conversion
Changed
- Automatically migrate existing databases to include
cap_alerts.sourceand
pollhistory.datasource columns during application or poller start-up.
- Surfaced poll provenance in the statistics dashboard, including the observed feed sources
[2.3.4]
Added
- Documented the public forecast zone catalog synchronisation workflow and
[2.3.0] - 2025-10-30
Changed
- Normalized every database URL builder to require
POSTGRES_PASSWORD, apply safe
POSTGRES_* variables, and URL-encode credentials so
special characters work consistently across the web app, CLI, and poller.
- Trimmed duplicate database connection variables from the default
.envfile and
- Bumped the default
APPBUILDVERSIONto 2.3.0 across the application and sample
[2.4.9] - 2025-11-09
Fixed
- Switch certbot issuance to standalone HTTP-01 mode so the container itself binds to port 80 during startup,
- Log the standalone challenge server activation so operators can confirm ACME connectivity when debugging
[2.4.8] - 2025-11-09
Fixed
- Verify existing certificates against the system trust store and expiration before skipping issuance, so stale self-signed chains are purged and a new ACME request runs on startup.
- Log detailed reasons when certificate validation fails and remove the associated material, making it obvious when fallback artifacts block public issuance.
[2.4.7] - 2025-11-09
Fixed
- Detect existing certificates issued by anything other than Let's Encrypt (including legacy self-signed chains)
- Extend the certificate cleanup routine to treat unknown issuers as invalid, guaranteeing that deployments replace
[2.4.6] - 2025-11-09
Fixed
- Remove any lingering self-signed certificate directories (including suffixed variants) on
- Extend the certificate purge routine to clean historical self-signed material before certbot
[2.4.5] - 2025-11-09
Fixed
- Purge the domain's existing
/etc/letsencryptmaterial whenever a self-signed
- Force certbot to request a fresh certificate for self-signed domains by
[2.4.4] - 2025-11-09
Fixed
- Detect legacy self-signed fallback certificates by inspecting the existing fullchain.pem and
- Remove invalid certificate files prior to issuing new ones so nginx never launches with the
[2.4.3] - 2025-11-09
Fixed
- Detect previously generated self-signed certificates and automatically retry Let's Encrypt
- Tag self-signed fallbacks with a marker file and clear it after successful issuance to avoid
[2.4.2] - 2025-11-09
Fixed
- Provision certbot in the nginx container via Python's package manager so Let's Encrypt
certbot: not found.
- Replaced bash-specific
[[ ... ]]usage in the nginx initialization script with
This document is served from docs/reference/CHANGELOG.md in the EAS Station installation.