MeshCore Beacon · Releases
from GitHub · updated 2026-07-0312 releases
v1.5.4 # 26 days ago · 2026-06-24 15:11 UTC
Fixes
- Packet Observation Duplication - The packet observations were being constrained as unique on observer, packet hash and the heard at TS. The TS has been removed and a migration is in place to clean up bad data.
Full Changelog: https://github.com/MeshCore-Beacon/beacon-server/compare/v1.5.3...v1.5.4
v1.5.3 # 1 month ago · 2026-06-20 17:41 UTC
Features
- Discovery request/response parsing — Beacon now parses
DISCOVER_REQ/DISCOVER_RESPcontrol payloads from the mesh, feeding directly into neighbor data. - Neighbor SNR tracking — a new optional
snrcolumn onnode_neighbors, now populated from three independent sources:- discovery responses observed by Beacon
- zero-hop adverts seen directly by observers
- hop pairs derived from TRACE packets
- Observer online check uses last seen — ingest now factors in an observer's last-seen timestamp when determining online status, rather than relying solely on connection state.
Fixes
- Node summary neighbor counts — deduplicated neighbor counts in node summaries that were previously inflated by duplicate rows.
- Release image publishing — fixed the GitHub Actions release workflow so built images are pushed to the public registry correctly. (Thanks, @MrAlders0n!)
Maintenance
- Bumped
meshcore-goto v1.0.8. - SECURITY: Bumped
github.com/go-chi/chi/v5from v5.2.2 to v5.2.4 (dependabot). - Documented the remaining parsed ingest payload structs.
- Added the new neighbor
snrfield to the swagger docs.
Full Changelog: https://github.com/MeshCore-Beacon/beacon-server/compare/v1.5.2...v1.5.3
- Discovery request/response parsing — Beacon now parses
v1.5.0 # 1 month ago · 2026-06-15 22:28 UTC
Testing
This release is primarily a testing overhaul, bringing project coverage from minimal to ~46% with a solid foundation across all major layers.
Infrastructure
- Introduced
sqlc.Querierinterface indb.Store, enabling mock-based testing of the database layer without a real PostgreSQL connection - Added
gomock-generated mock forsqlc.Querieratdb/sqlc/mock - Converted
stubReaderin handlers tests to a configurable struct with function fields, eliminating the need for a separatefuncReadertype - CI coverage filtering now correctly excludes generated code (
db/sqlc,docs,iatadb/gen) for accurate badge reporting
Coverage by package
db— store mapping logic, pagination, nil pointer handling, conditional field mapping, type conversions across channels, observers, nodes, packets, traces, routes, scopes, stats, and IATAsinternal/api/handlers— validation paths and happy paths across all handlers including messages, packets, observers, nodes, stats, routes, scopes, and tracesinternal/cache—getOrSetcache hit/miss/error/corrupt-entry behaviour, TTL resolution fallback chain, node and observer invalidationinternal/config— YAML loading, config seeding, default resolution extracted into testableResolvefunctioninternal/hub— full runtime behaviour including broadcast, subscription lifecycle, lagged notification, OR-scope semanticsinternal/ingest— pure function coverage for payload parsing, transport code derivation, capability detection, observer type normalisationinternal/keystore— key derivation, fingerprinting, store lookup,EntryExists(moved frommain)internal/scopestore— load, replace, copy-on-read semanticsinternal/background— scheduler task execution and context cancellationinternal/ws— IP limiter acquire/release/cleanup logic
Refactoring
config.Resolve()extracted frommain.goto derive runtime defaults with fallback chain — now tested and used at startupkeystore.EntryExists()moved frommain.gointo the keystore package where it belongs
Full Changelog: https://github.com/MeshCore-Beacon/beacon-server/compare/v1.4.1...v1.5.0
- Introduced
v1.4.1 # 1 month ago · 2026-06-12 18:29 UTC
Most recent release with code changes was https://github.com/MeshCore-Beacon/beacon-server/releases/tag/v1.4.0
v1.4.0 # 1 month ago · 2026-06-12 18:00 UTC
Features
- Background task scheduler — periodic maintenance tasks now run on independent configurable intervals via a new
internal/backgroundpackage. Intervals are set per-task under thebackground:config key; all default to1h. - Route and neighbor reconfirmation — a new background task periodically prunes
known_routesandnode_neighborsrows that have become stale or ambiguous: routes where any hop has departednode_short_idsor whose prefix now resolves to multiple nodes, and neighbors under the same conditions.
Fixes
- Neighbor recording — neighbors are now only recorded when the resolved first-hop node is a repeater or room. Previously a prefix collision could cause a companion or other non-infrastructure node to be written as a neighbor. Thanks to @gadgethd for the contributing fix to IATA seeding that triggered this investigation.
- IATA seeding —
UpsertIATADetailsis now a true upsert, correctly updating existing records rather than silently doing nothing on conflict. Contributed by @gadgethd . - Graceful shutdown — added a timeout to the shutdown sequence to prevent possible hangs on exit.
Maintenance
- Switched to dedicated CodeQL action.
- Corrected route list handler cursor documentation.
- Fixed broken README API reference chart.
- Minor code cleanup: renamed
mustEnv→getEnv, fixed view refresh comment, added note on node type helper.
Contributors
Welcome and thank you to @gadgethd — first contribution to Beacon!
- Background task scheduler — periodic maintenance tasks now run on independent configurable intervals via a new
v1.3.1 # 1 month ago · 2026-06-11 23:00 UTC
Traces & Pings
Single-hop traces are now classified as pings and tagged accordingly. The
/traceslist response now includes the path and SNR values from the most complete observation of each trace, making it possible to assess signal quality and hop progression at a glance without opening the detail view. A newtypequery parameter allows filtering traces byTRACEorPING.Routes
Single-hop routes are no longer stored — direct links are already captured by neighbor relationships, making them redundant.
Nodes
knownNeighborCountadded to node summaries, andpublicKeyadded to node neighbor responses.Database Migrations
Migrations are now embedded in the binary and applied automatically on startup, removing the dependency on external tooling or container entrypoints. Existing deployments will bootstrap cleanly on first run.
Full Changelog: https://github.com/MeshCore-Beacon/beacon-server/compare/v1.3.0...v1.3.1
v1.2.1 # 1 month ago · 2026-06-10 20:49 UTC
Just a silly bug in a query for radio preset stats.
v1.2.0 # 1 month ago · 2026-06-10 20:23 UTC
New features
CORS support
- Configurable CORS headers for cross-origin frontend deployments
Node type breakdown
- New
GET /api/v1/stats/node-typesendpoint returning node counts by type (companion, repeater, room server, sensor) - Supports the same multi-IATA and region filtering as all other stats endpoints
Multi-IATA and region filtering on stats endpoints
- All
/stats/*endpoints now acceptiatas,iata,regionId, andregionquery params - Previously only a single exact-match IATA was supported
- Top nodes chart now returns data correctly in the default all-regions view
Bug fixes
Observer telemetry
- Timestamps were being returned in seconds instead of milliseconds — now consistent with the rest of the API
- Bucketed telemetry (
6h,24hintervals) was grouping by hour-of-day rather than by time window, causing incorrect bucket boundaries and near-zero deltas in the 30-day view - Running total fields (
airtime_tx_pct,airtime_rx_pct,receive_errors) were being averaged across buckets instead of computing the delta — now correctly returns increase per bucket
Maintenance
- Removed unused queries
- Updated dependencies (SHOULDERS.md)
- CodeQL security scanning via GitHub integration
Full Changelog: https://github.com/MeshCore-Beacon/beacon-server/compare/v1.1.0...v1.2.0
v1.1.0 # 1 month ago · 2026-06-09 21:15 UTC
v1.1.0 — Redis caching layer
This release adds an optional Redis-backed caching layer that reduces redundant PostgreSQL reads for read-heavy, slow-changing endpoints.
What's new
- Redis cache layer (
internal/cache) — aCachedReaderwraps the database store and transparently caches responses using a genericgetOrSethelper with graceful degradation. If Redis is unavailable, all reads fall through to PostgreSQL with no impact on availability. - Explicit cache invalidation — node and observer cache entries are invalidated immediately on upsert from the ingest path, keeping detail responses accurate despite caching.
- TTL-based expiry for stats and reference data, with a per-category override system and a global fallback. Defaults to 1h, aligned with the materialized view refresh cycle.
- Fully optional — set
REDIS_ADDRto enable. Unset, Beacon behaves exactly as before.
Configuration
Add to
.env:REDIS_ADDR=localhost:6379 REDIS_PASSWORD= REDIS_DB=0Add to
config.yaml(all optional, defaults to 1h):cache: ttl: "1h" ttls: stats: "1h" reference: "1h" nodes: "1h" observers: "1h"- Redis cache layer (
v1.0.4 # 1 month ago · 2026-06-09 16:23 UTC
[v1.0.4] — 2026-06-09
Security
Fix no bounds check on region IDs.
Full Changelog: https://github.com/MeshCore-Beacon/beacon-server/compare/v1.0.3...v1.0.4
v1.0.2 # 1 month ago · 2026-06-09 15:42 UTC
[v1.0.2] — 2026-06-09
Features
- Traces: raw path hashes included in responses — trace responses now include raw (unresolved) path hashes alongside the resolved node data, giving clients access to the full hop information even when nodes aren't known to the observer.
Bug Fixes
- Fixed typo in
subscribeScopestruct that could cause unexpected subscription behaviour. - Fixed missing Swagger annotation for the traces
rawPathfield.
Documentation
- Updated schema migration notes.
Full Changelog: https://github.com/MeshCore-Beacon/beacon-server/compare/v1.0.1...v1.0.2
v1.0.0 # 1 month ago · 2026-06-08 23:16 UTC
v1.0.0
This is the first public release of Beacon, a MeshCore network observation backend built by MeshCore Canada.
What is Beacon
Beacon connects to one or more MeshCore MQTT brokers, ingests LoRa packet traffic in real time, stores it in PostgreSQL, and serves it via a REST API and WebSocket stream. It is designed to be the data backbone for MeshCore network monitoring frontends and tools.
Features
Packet ingestion and storage
- Subscribes to multiple MeshCore MQTT brokers simultaneously
- Decodes all MeshCore packet types using meshcore-go
- Deduplicates observations across brokers — the same packet heard by multiple brokers produces one observation per observer
- Stores packets, observations, nodes, observers, traces, known routes, neighbors, and channel messages in PostgreSQL
- Configurable retention for packets and telemetry
Node and observer tracking
- Upserts nodes from advert payloads with name, type, location, and radio settings
- Tracks observers from /status messages including hardware model, firmware version, battery level, uptime, and radio configuration
- Detects multibyte path and trace firmware capability from path hash sizes
- Records node neighbors from forwarded adverts
- Builds and maintains known routes — fully resolved multi-hop paths where all nodes are identified with high confidence
- Observer telemetry snapshots with configurable resolution and bucketed query support (1h, 6h, 24h intervals)
Channel messages
- Decrypts group text messages for configured channel keys
- Supports hashtag-derived PSKs (
SHA256("#tag")[:16]) and explicit hex keys - Records channel hash observations even for unknown channels
Transport scopes
- Matches
TRANSPORT_FLOODandTRANSPORT_DIRECTpackets to configured scope keys - Tags nodes and observers with their default scope
- Scope-filtered queries across packets, nodes, observers, channels, and traces
Geographic filtering
- Optional ingest filter by country or continent using a compiled-in IATA → country/continent database sourced from OurAirports
- Regions group IATAs for display and filtering
REST API
- Full paginated REST API with cursor-based pagination across all resources
- Endpoints for packets, observations, nodes, observers, channels, messages, traces, routes, regions, IATAs, scopes, and stats
- Cross-IATA route search
- Observer telemetry with bucketed aggregation
- Swagger UI at
/swagger/index.html
WebSocket
- Real-time event stream with per-connection subscription filtering by IATA, region slug, region ID, payload type, channel hash, and event type
- Events:
packetObservation,observerStatus,nodeUpdate,channelMessage - Backpressure handling with
laggednotifications and REST backfill support - Per-IP connection limits
Path resolution
- Resolves path hash prefixes to node UUIDs using
node_short_ids - Confidence levels:
high(unambiguous),ambiguous(hash collision),none(unknown) - Resolved hop nodes included in packet observations, traces, and known routes
Project
- AGPL-3.0-or-later license
- Contributor Covenant code of conduct
- Full contributing guide including database change, API change, and testing requirements
- GitHub Actions CI with build, format, vet, test, and swagger doc checks
- Docker image published to GitHub Container Registry on every push to
mainanddev