MeshCore Beacon

MeshCore Beacon · Releases

from GitHub · updated 2026-07-03

12 releases

  1. 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

  2. v1.5.3 # 1 month ago · 2026-06-20 17:41 UTC

    Features

    • Discovery request/response parsing — Beacon now parses DISCOVER_REQ/DISCOVER_RESP control payloads from the mesh, feeding directly into neighbor data.
    • Neighbor SNR tracking — a new optional snr column on node_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-go to v1.0.8.
    • SECURITY: Bumped github.com/go-chi/chi/v5 from v5.2.2 to v5.2.4 (dependabot).
    • Documented the remaining parsed ingest payload structs.
    • Added the new neighbor snr field to the swagger docs.

    Full Changelog: https://github.com/MeshCore-Beacon/beacon-server/compare/v1.5.2...v1.5.3

  3. 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.Querier interface in db.Store, enabling mock-based testing of the database layer without a real PostgreSQL connection
    • Added gomock-generated mock for sqlc.Querier at db/sqlc/mock
    • Converted stubReader in handlers tests to a configurable struct with function fields, eliminating the need for a separate funcReader type
    • 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 IATAs
    • internal/api/handlers — validation paths and happy paths across all handlers including messages, packets, observers, nodes, stats, routes, scopes, and traces
    • internal/cachegetOrSet cache hit/miss/error/corrupt-entry behaviour, TTL resolution fallback chain, node and observer invalidation
    • internal/config — YAML loading, config seeding, default resolution extracted into testable Resolve function
    • internal/hub — full runtime behaviour including broadcast, subscription lifecycle, lagged notification, OR-scope semantics
    • internal/ingest — pure function coverage for payload parsing, transport code derivation, capability detection, observer type normalisation
    • internal/keystore — key derivation, fingerprinting, store lookup, EntryExists (moved from main)
    • internal/scopestore — load, replace, copy-on-read semantics
    • internal/background — scheduler task execution and context cancellation
    • internal/ws — IP limiter acquire/release/cleanup logic

    Refactoring

    • config.Resolve() extracted from main.go to derive runtime defaults with fallback chain — now tested and used at startup
    • keystore.EntryExists() moved from main.go into the keystore package where it belongs

    Full Changelog: https://github.com/MeshCore-Beacon/beacon-server/compare/v1.4.1...v1.5.0

  4. v1.4.1 # 1 month ago · 2026-06-12 18:29 UTC
  5. 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/background package. Intervals are set per-task under the background: config key; all default to 1h.
    • Route and neighbor reconfirmation — a new background task periodically prunes known_routes and node_neighbors rows that have become stale or ambiguous: routes where any hop has departed node_short_ids or 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 seedingUpsertIATADetails is 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 mustEnvgetEnv, fixed view refresh comment, added note on node type helper.

    Contributors

    Welcome and thank you to @gadgethd — first contribution to Beacon!

  6. 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 /traces list 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 new type query parameter allows filtering traces by TRACE or PING.

    Routes

    Single-hop routes are no longer stored — direct links are already captured by neighbor relationships, making them redundant.

    Nodes

    knownNeighborCount added to node summaries, and publicKey added 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

  7. v1.2.1 # 1 month ago · 2026-06-10 20:49 UTC

    Just a silly bug in a query for radio preset stats.

  8. 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-types endpoint 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 accept iatas, iata, regionId, and region query 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, 24h intervals) 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

  9. 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) — a CachedReader wraps the database store and transparently caches responses using a generic getOrSet helper 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_ADDR to enable. Unset, Beacon behaves exactly as before.

    Configuration

    Add to .env:

    REDIS_ADDR=localhost:6379
    REDIS_PASSWORD=
    REDIS_DB=0
    

    Add to config.yaml (all optional, defaults to 1h):

    cache:
      ttl: "1h"
      ttls:
        stats: "1h"
        reference: "1h"
        nodes: "1h"
        observers: "1h"
    
  10. 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

  11. 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 subscribeScope struct that could cause unexpected subscription behaviour.
    • Fixed missing Swagger annotation for the traces rawPath field.

    Documentation

    • Updated schema migration notes.

    Full Changelog: https://github.com/MeshCore-Beacon/beacon-server/compare/v1.0.1...v1.0.2

  12. 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_FLOOD and TRANSPORT_DIRECT packets 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 lagged notifications 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 main and dev