Repository navigation
Beacon Web - v2.0.0
Beacon Web 2.0.0
A huge thank you to n30nex for helping get Beacon to this point. Many of the dashboards and features in 2.0.0, from the observer dashboard and the new analytics tabs to channel scopes and the French translation, are there because of his help.
This release pairs with Beacon Server 2.0.0 and needs it: the analytics tabs, observer dashboard and region-filtered scope lists all read endpoints that only exist on 2.0.0.
Breaking change: the server needs a fresh database
Server 2.0.0 starts from a new schema baseline and will not run against a 1.x database. 1.x history does not carry over. There is nothing to migrate on the web side, but read the upgrade guide before you pull either image. The deployment template now requires an explicit BEACON_WEB_IMAGE.
Built for big instances
MeshMapper's instance at analyzer.meshmapper.net handles around 400,000 packets every 15 minutes on 2.0.0 and barely sweats. On the web side, analytics now read the server's hourly rollups instead of live scans, the packet-path canvas loads on demand, lists wait for the selected region before requesting, and the client backs off cleanly when the server rate limits it.
MeshMapper integration
MeshMapper has expanded its API and Beacon Server now ingests it: scoped traffic is tagged from MeshMapper's scope catalogues, regions and geo borders can be set up automatically from its zones, and regional public channels are imported. In the web app that shows up as region-filtered scope lists, scope chips on packets and channel messages, imported region borders on the map, and the Possibly foreign label on repeaters.
Versioning from here on
Starting with 2.0.0, Beacon Web and Beacon Server share the same major and minor version. Only the patch number moves on its own, so web 2.0.1 runs with server 2.0.3. Keep both on the same 2.X. The latest image tag is now reserved for stable releases from main; pin :2.0 on both images if you want to choose when to move to the next minor.
Everything since v1.3.0
Observers
- The Observers tab is now a dashboard. The list sits beside it on desktop with status, type, broker, scope and name filters, Activity or Name sort, hearing counts and activity bars, and live status over the websocket.
- The dashboard leads with packets heard per hour and day, packet-type mix, received signal, airtime TX and RX, and device telemetry (battery, uptime, noise floor, queue length, receive errors, channel busy) over 24h, 7d or 30d.
- Airtime is charted as a percent of elapsed time, and four heard-activity charts (channel busy, packets heard, SNR heard, payload type) come from the new per-observer activity endpoint.
- Observer header shows labelled device, public key, brokers and first seen rows, with Copy link and Compare with actions.
- Compare with compares two observers on aligned windows, with packet overlap at 24h and 7d.
- Adverts heard is a collapsible section inside the dashboard.
- Inspect observer from a packet observation opens the dashboard directly and keeps the packet in the side drawer on desktop. On mobile it opens as an overlay, and Close steps back to the packet it came from.
- The Analytics Observer section is gone. Old
?statsTab=observerlinks land on the Observers tab.
Analytics
- Analytics is served from the server's hourly rollups. Sparklines break at missing or partial hours instead of joining across them, and hours before the first rollup draw as gaps instead of zero.
- Hourly sparklines on every stat card backed by hourly data (Mesh, Traffic, Signal, Paths), plus Most path entries, the Scoped packets and Active scopes cards, and the Observers and Default-scope nodes cards on Scopes.
- New RF / Signal tab: SNR and RSSI distributions, hourly means, sample availability and exact tables.
- New Paths and Hashes tab: hash-width share, received entry counts, hourly trends, coverage categories and exact tables.
- New Traffic tab: hourly reception trends by IATA, a UTC heatmap, reception share and exact counts.
- New Scopes tab: scope charts, search and exact counts. The Mesh scope card follows the selected region.
- New Compare observers tab: pick two observers and a time window to see distinct flood packets heard only by A, only by B or both. The URL carries the selection.
- KPI cards say Last 24h, and a region with no IATAs shows empty data instead of the whole network.
- Refresh buttons and repeated page titles are gone (data reloads every minute). Explanations moved into info tooltips beside the section chooser.
- Talkers rows open the node, and Talkers and Mesh overview no longer show stale rows or previous-region data while a refresh is pending.
- Clock Drift shows compact cards on phones. Charts are drawn in UTC consistently.
Packets and analyzer
- One Observations list in the analyzer. Reception evidence and the Observations dropdown are merged into a single section grouped by path, each report a selectable signal card with Inspect observer and Map report links. It starts collapsed with counts visible and opens when a specific report was picked.
- Observation card edges are coloured by SNR level, and expanded rows show observation cards below the md breakpoint.
- Packet Structure breaks out the transport codes (bytes, value, matched scope). The raw hex view on TRANSPORT packets was off by the 4 transport-code bytes and is fixed.
- Payload summaries appear in packet rows without opening the packet: adverts show one node chip and trace and ACK summaries replace n/a.
- Latest path search: enter whole hop hashes to filter loaded packets by consecutive hops.
- A
?hashselection outside the loaded results shows a notice with an Open analyzer action. - Load older packets button when filters leave too few rows to scroll.
- Endpoint chips show every ambiguous candidate without picking a winner.
- Route evidence is folded into Route Detail: clicking a route opens summary, hops, first and last seen, and a Recent packets list bounded by retention.
- The packet drawer and stacked windows stay open across tabs on desktop.
- Rate limiting is handled: a 429 shows a RATE LIMITED badge in the header, queries stop retrying 4xx, and websocket reconnects back off exponentially and jump to the longest wait on close codes 1008 and 1013.
- PING packets render with the TRACE payload renderer.
- The packet-path canvas loads on demand. The initial gzip payload dropped from 448 KB to 172 KB.
Channels
- Channels loads every channel Beacon has a key for first and hides the rest behind Load other channels.
- Channel messages show the packet scope, with a server-side Scope filter in the channel header. Unresolved scopes get a muted chip.
- Scope filter dropdowns on packets, nodes, observers and channels list only the selected region's scopes. A selected out-of-region scope stays so shared links keep filtering.
- Load more channels pages the directory without losing the open channel.
- Channel live messages recover after an overflow that settles under a 429.
Nodes and map
- Repeaters the server flags as
possiblyForeignshow a Possibly foreign label in rows, cards and the detail panel. - View on map in node panels opens the Map tab framed at zoom 14 and keeps the panel open on desktop.
- A node's position is cleared when the server sends an explicit null in
nodeUpdate. Explicit 0/0 resets and invalid coordinates are omitted from markers, neighbour lines, path maps and live flow. - Turning the IATA borders toggle off clears the drawn borders, and missing boundaries are retried.
- Map cluster clicks work again after a dataset reset.
- maplibre-gl 6.
Languages
- Language picker in the header with English and French. The choice is saved in the browser.
- Translated: navigation and shared controls, every analytics tab, Clock Drift, relative timestamps, observer monitoring, channel scopes, packet investigation, nodes, channels, map, packets (list, table, analyzer, observations), routes, traces, MapLibre control tooltips, chart series names and node type labels, with French plural forms.
- Kept in English on purpose: protocol and enum names, SNR, RSSI and dB units, theme names and raw node-type values.
Layout and mobile
- The header collapses to one row on phones with language, theme and GitHub in a menu. The region picker is left-anchored on phones and right-anchored on desktop.
- Region filter input is 16px on phones to avoid iOS focus zoom.
- Routes search stacks into from/to and IATA/Search rows on mobile. Observer list is edge-to-edge with row dividers on mobile, like Nodes.
- Stat card sublabels wrap under the title on narrow screens.
- Plain wording across panels: observations, Heard by N observers, Packets heard, area instead of IATA, sentence-case analytics tabs, Map path and Map all paths.
- Lists, map, neighbour graph and observer comparison wait for a named region's IATAs before requesting, so there is no brief whole-network fetch.
- Desktop tab order puts Observers after Nodes.
Configuration
- New
VITE_BANNER: an optional notice above the header on every page, for example on a test instance.[label](url)and bare URLs become links. - Runtime config is injected through
/config.jswritten at container start instead of rewriting the bundle. - The image workflow no longer publishes
latestfromdev. The deployment template requires an explicitBEACON_WEB_IMAGE. - Deployment docs moved to beacon-docs.
Fixes
- Compare tab no longer shows a spurious invalid link alert after a tab change.
- Observer Copy link keeps only region params.
- Route table no longer navigates on region change with no route open, and routes paging is tie-safe.
- Live overview deltas no longer flip a failed overview query back to success.
- All observers button restored on desktop, and observer, route and compare windows restored to 24h, 7d and 30d.
- History paging and region gating for stats fixed in the release review.
- Websocket liveness check no longer loops on reconnect.