Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

908 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

  โ–ˆโ–ˆโ–ˆโ•—   โ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•—  โ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ•—   โ–ˆโ–ˆโ–ˆโ•—
  โ–ˆโ–ˆโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ•โ•โ•โ•โ•โ–ˆโ–ˆโ•”โ•โ•โ•โ•โ•โ–ˆโ–ˆโ•‘  โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ•โ•โ•โ•โ•โ–ˆโ–ˆโ•”โ•โ•โ•โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ–ˆโ•‘
  โ–ˆโ–ˆโ•”โ–ˆโ–ˆโ–ˆโ–ˆโ•”โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘     โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ–ˆโ–ˆโ–ˆโ–ˆโ•”โ–ˆโ–ˆโ•‘
  โ–ˆโ–ˆโ•‘โ•šโ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ•โ•โ•  โ•šโ•โ•โ•โ•โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘     โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘โ•šโ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ•‘
  โ–ˆโ–ˆโ•‘ โ•šโ•โ• โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘  โ–ˆโ–ˆโ•‘โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ•‘ โ•šโ•โ• โ–ˆโ–ˆโ•‘
  โ•šโ•โ•     โ•šโ•โ•โ•šโ•โ•โ•โ•โ•โ•โ•โ•šโ•โ•โ•โ•โ•โ•โ•โ•šโ•โ•  โ•šโ•โ• โ•šโ•โ•โ•โ•โ•โ• โ•šโ•โ•โ•โ•โ•โ• โ•šโ•โ•     โ•šโ•โ•
    โ–ˆโ–ˆโ•—    โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•—  โ–ˆโ–ˆโ•—
    โ–ˆโ–ˆโ•‘    โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ•โ•โ•โ•โ•โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•”โ•โ•โ•โ•โ•โ–ˆโ–ˆโ•”โ•โ•โ•โ•โ•โ–ˆโ–ˆโ•‘ โ–ˆโ–ˆโ•”โ•
    โ–ˆโ–ˆโ•‘ โ–ˆโ•— โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ•‘  โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•
    โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ•โ•โ•  โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•‘  โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ•โ•โ•  โ•šโ•โ•โ•โ•โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ•—
    โ•šโ–ˆโ–ˆโ–ˆโ•”โ–ˆโ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘  โ–ˆโ–ˆโ•—
     โ•šโ•โ•โ•โ•šโ•โ•โ• โ•šโ•โ•โ•โ•โ•โ•โ•โ•šโ•โ•โ•โ•โ•โ• โ•šโ•โ•โ•โ•โ•โ• โ•šโ•โ•โ•โ•โ•โ•โ•โ•šโ•โ•โ•โ•โ•โ•โ•โ•šโ•โ•  โ•šโ•โ•

MeshCom WebDesk

A Blazor Server web application for communicating with a MeshCom 4.0 node via UDP (EXTUDP JSON protocol).
Built with .NET 10 and Blazor Interactive Server.

MeshCom Firmware: Compatible with icssw-org/MeshCom-Firmware v4.35+
Hardware IDs 1โ€“57 supported (TLORA, T-BEAM, T-ECHO, T-DECK, T-DECK-PLUS, T-DECK-PRO, T-ETH-ELITE, HELTEC-V1โ€“V4, HELTEC-T114, HELTEC-WPAPER, RAK4631, EBYTE-E22, T5-EPAPER, T3-S3, T-CONNECT-PRO, โ€ฆ)

๐Ÿ’พ Ready-to-run binaries (Windows & Linux) โ€“ no build required:
๐Ÿ‘‰ Download latest release

๐Ÿงช Development branch (dev): Contains the latest features and fixes โ€“ may be unstable.
To try it: git clone -b dev https://github.com/DH1FR/MeshcomWebDesk.git


๐Ÿ†• What's New in v1.14.1

โœจ Features

  • Ping & ACK round-trip time โ€“ when a direct ping/--ping/>ping gets a Pong! reply from the same station within 5 minutes, the chat bubble now shows the round-trip time (โฑ ms/s) next to the reply text, alongside the ACK round-trip time.
  • UDP receive diagnostics โ€“ a โ“ button next to the UDP status badge (shown once it falls back to yellow after 15 minutes without a new packet) opens a popover with the node's local IP addresses and a troubleshooting checklist.
  • Battery level as a fill-proportional icon โ€“ the static ๐Ÿ”‹ emoji next to node battery readings is now a small icon whose fill bar reflects the charge percentage, colour-coded ok/warn/low. Used consistently in the chat status bar, node switcher, monitor list, MH table and callsign popup, and now shown for every configured node instead of only the primary one.

๐Ÿ”ง Bug Fixes

  • Service worker: no longer throws an invalid Response on a failed fetch, which could leave the browser tab hanging after the laptop resumes from sleep.
  • Chrome tab crash: switching chat tabs or sending a message could crash the page in Chrome (never Firefox), caused by Chrome's automatic page translation rewriting the DOM behind Blazor's back; the app now opts out of translation.

โ˜• Do you like my work? Then buy me a coffee! โ˜•

Donate via PayPal


๐Ÿ’ก Motivation

MeshCom always reminds me a little of the good old Packet Radio days โ€“ digital text communication over radio, simple and direct.

However, I could not find any suitable software that provides a web server interface for MeshCom accessible from any device (PC, tablet, smartphone) within the local network. That is why I created this MeshCom WebDesk.

The application runs on Windows or Linux and makes a full web client for MeshCom available via a simple URL โ€“ no installation required on the end device, everything runs directly in the browser.


Screenshots & Demo

MeshCom Web Client

MeshCom AI Search

MeshCom Live Map

Terminal Startup Banner

Console Command Helper mit Spektrum-Scan


Features

๐Ÿ’ฌ Chat

  • Multi-tab conversations โ€“ each partner (callsign, group, broadcast) gets its own tab
  • Broadcast tab "All" for * / CQCQCQ messages
  • Direct messages โ€“ each callsign gets its own tab automatically
  • Group messages โ€“ group destinations appear as #<group> tabs with optional whitelist filter
  • Group Labels โ€“ configurable display names for group numbers (e.g. #262 โ†’ DL); short label in the tab, full name as tooltip; pre-filled with the official MeshCom GRC group list
  • Smart routing: broadcast replies from a known callsign appear in their direct tab
  • Auto-scroll to the latest message when a tab is opened or a new message arrives
  • Unread badge โ€“ inactive tabs show a yellow counter badge for new messages
  • New-message divider โ€“ a horizontal โ€žNeue Nachrichten / New messages" line separates already-read messages from newly arrived ones after returning to a tab
  • ACK delivery indicator on every outgoing message:
    • โณ grey โ€“ waiting for node echo (message queued)
    • โœ“ blue โ€“ node has transmitted over LoRa (sequence number assigned)
    • โœ“โœ“ green โ€“ recipient confirmed delivery (LoRa ACK received)
    • โ˜๏ธ โ€“ sent to group or broadcast (no ACK expected)
    • โ˜๏ธโœ“ โ€“ delivered via gateway (Gateway ACK received)
  • Clickable callsigns in the monitor โ€“ click any sender or recipient to open a chat tab instantly; hover over a callsign to reveal a small @ button โ€“ clicking it inserts @CALLSIGN at the current cursor position in the message input field (useful for addressing someone in a group or broadcast message without switching tabs)
  • @-Mention in chat messages โ€“ the same @ button appears next to every incoming callsign in the group/broadcast message list; clicking it inserts @CALLSIGN at the cursor position in the send bar
  • QRZ.com tooltips โ€“ when enabled, hovering over any callsign (tab buttons, chat messages, monitor From/To) shows the operator's first name and home QTH (e.g. Chat mit DH1FR-2 รถffnen ยท Max, Berlin); concurrent lookups for the same callsign share a single HTTP request (in-flight deduplication)
  • Audio notification ๐Ÿ”” when a new direct message to your own callsign arrives (Web Audio API, no audio file required); mute toggle in the status bar
  • ๐Ÿ”Š Voice announcements โ€“ incoming direct messages are read aloud using the browser's built-in Web Speech API (no plugin or audio file required); toggle with the ๐Ÿ”Š/๐Ÿ”‡ button in the status bar; state is saved in localStorage and restored on reload; language passed to the speech synthesiser matches the current UI language
  • โšก Quick Texts โ€“ configurable one-click text buttons in the send bar; clicking a button loads the predefined text into the input field for review before sending; supports all {variable} placeholders ({mycall}, {mylocator}, {callsign}, {locator}, {rssi}, {time}, {date}, {telemetry}, โ€ฆ); buttons can be reordered by drag & drop in the flyout; new order is saved immediately; configured in Settings โ†’ โšก Quick Texts
  • Variable expansion in the send bar โ€“ type any {variable} directly in the message input field (e.g. {telemetry}, {mycall}, {date}); press Tab to expand as a live preview; variables are always expanded automatically on send
  • Browser spell-check โ€“ the message input field has spellcheck="true"; the browser's built-in spell checker underlines misspelled words when spell-checking is enabled in the browser settings
  • Draggable tabs โ€“ chat tabs can be reordered by drag & drop; order is saved in localStorage and restored on every visit
  • Timestamps โ€“ time is always shown as HH:mm:ss; for messages not from today a compact date (dd.MM.yy) is shown below the time without increasing row height
  • ๐Ÿ”Ž QSO dialog โ€“ every direct-chat tab shows a ๐Ÿ”Ž button once the MySQL database is active; opens a four-tab modal with KI-Zusammenfassung (AI summary), Verlauf (history), Suche (text search) and KI-Suche (AI search); History and Search work without an AI API key โ€“ MySQL only required; KI-Suche supports an optional โ€žSearch all direct QSOs" mode to search across all 1:1 conversations at once
  • ๐Ÿ“‹ Recent QSO partners โ€“ a ๐Ÿ“‹ button next to the + tab button opens a flyout listing the most recently contacted callsigns (sorted by last contact time); clicking a row opens the chat tab directly; populated from the MySQL database
  • ๐Ÿ“ค Export / ๐Ÿ“ฅ Import of Quick Texts โ€“ export the quick-text list as MeshComWebDesk-quick-texts.json; import to replace the list; filename editable before export; share presets with other operators
  • ๐Ÿ“‹ Copy message to clipboard โ€“ hovering over a message in a direct chat tab reveals a ๐Ÿ“‹ button; clicking it copies the message text to the clipboard (JS Clipboard API)
  • {last-qso} variable โ€“ expands to the date and time of the previous direct QSO with the current callsign (the contact that triggered the expansion is excluded); kein QSO / no QSO if no prior QSO exists; database-first with in-memory fallback; available in Auto-Reply, Bot commands, Beacon and Quick Texts

๐Ÿ–ง Multi-Node Support

MeshCom WebDesk can connect to multiple MeshCom nodes simultaneously. Each node has its own UDP connection, callsign, chat tabs, monitor feed and console credentials.

Node profiles (Settings โ†’ Further Nodes)

Each node profile contains:

Field Description
Enabled Checkbox to take a node out of active use (registration, sending, chat switcher, telnet console) temporarily without deleting its configuration. The primary node cannot be disabled.
Name Display name shown in the node switcher (e.g. Balkon, Auto)
Callsign Own callsign used for outgoing messages on this node (e.g. OE1ABC-2). For the primary node this is read-only and mirrors Settings โ†’ Connection (see below).
Device IP IP address of the MeshCom node. For the primary node this is read-only and mirrors Settings โ†’ Connection.
Device Port UDP port on the node (default 1799)
Listen IP Local bind address (0.0.0.0 = all interfaces). For the primary node this is read-only and mirrors Settings โ†’ Connection.
Listen Port Local UDP port to receive packets from this node (default 1799)
Primary Exactly one node must be marked primary โ€“ only the primary node drives MH list, Live Map, beacons, telemetry, bot and OTA/reboot
TLS Certificate Fingerprint SHA-256 fingerprint of this node's self-signed TLS certificate; filled automatically via Trust & Save on first connect
TLS Password Console password for this node (encrypted at rest with DPAPI)

๐Ÿ’ก When multiple nodes share the same UDP port (1799), incoming packets are routed to the correct node by the sender's IP address โ€“ no port forwarding required.

๐Ÿ’ก The primary node's connection data (callsign, device/listen IP + port) lives in Settings โ†’ Connection, not in its Additional Nodes card, so it's never entered twice. Promoting a different node to primary (Set Primary) moves that node's connection data up into the Connection section instead, and the previous primary becomes a regular, editable secondary node.

Node behaviour

  • Chat tabs and monitor are scoped per node โ€“ each node has its own independent set of tabs and monitor messages
  • Incoming messages are routed to the correct node by source IP address
  • Outgoing messages are sent via the node that owns the active chat tab
  • Auto-replies and bot replies are sent back through the same node that received the triggering message
  • MH list, Live Map, beacon, bot, telemetry, OTA and reboot only operate on the primary node
  • A node switcher dropdown appears in the Chat header whenever more than one node is configured; switching changes the visible chat tabs and monitor without reconnecting UDP
  • Disabled nodes are excluded from UDP registration/sending, the chat node switcher and the telnet console selector, but keep their saved configuration for later re-enabling

State persistence

  • All node states (tabs, monitor messages) are saved and restored independently per node on restart
  • The primary node's MH list is saved separately

๐Ÿ“ป MH โ€“ Most Recently Heard

  • GPS position parsed from EXTUDP position packets (lat_dir / long_dir APRS format)
  • QTH Locator โ€“ Maidenhead locator (e.g. JN48qn) calculated from GPS coordinates; shown below the GPS position in the MH table and in the station card popup; also available as {locator} placeholder in Auto-Reply, Bot commands and Quick Texts
  • Station card popup โ€“ hovering (desktop) or tapping (mobile) a callsign shows a rich card with QRZ name/QTH, RSSI/SNR, battery, distance, QTH locator, GPS coordinates (as OSM link) and firmware; buttons: ๐Ÿ’ฌ Open Chat and ๐Ÿ”— aprs.fi
  • Distance calculation (Haversine) from own position to each heard station
  • Battery level ๐Ÿ”‹ column parsed from batt field in position/telemetry packets, colour-coded (๐ŸŸข >60% / ๐ŸŸก >30% / ๐Ÿ”ด โ‰ค30%)
  • Search / filter ๐Ÿ” โ€“ search field in the header; type callsign, message text or QRZ name; results debounced (250 ms); Enter applies immediately; clearing the field resets instantly
  • Firmware tooltip โ€“ hover the callsign to see firmware version, hardware ID and first-heard time
  • QRZ.com callsign data โ€“ when the QRZ.com integration is enabled, a dedicated Name / Location column shows each operator's first name and home QTH; the same data also appears as a hover tooltip on every callsign
  • RSSI / SNR signal quality with colour coding (green / yellow / red)
  • Altitude correctly converted from APRS feet to metres
  • ๐Ÿ—บ๏ธ OpenStreetMap link per station
  • Own position extracted automatically from the node's type:"pos" UDP beacon
  • Browser GPS button to use device geolocation as own position
  • Click ๐Ÿ’ฌ to open a chat tab with any station

๐Ÿ“ก Monitor (lower pane)

  • Structured display with type badge (MSG / POS / TEL / ACK / SYS), direction (RX / TX), routing and signal
  • Full relay path shown inline for relayed messages: OE1XAR-62 โŸถ DL0VBK-12 โŸถ DB0KH-11 โ†’ all
  • Telemetry rows (type:"tele") display temperature ๐ŸŒก๏ธ, humidity ๐Ÿ’ง, pressure ๐Ÿงญ and battery ๐Ÿ”‹
  • Colour-coded rows: green for TX, cyan for position beacons, purple for telemetry, gold for ACKs
  • UDP registration packet ({"type":"info",...}) sent on startup is shown as a SYS TX entry
  • Newest entry always at the top; configurable history limit (MonitorMaxMessages)
  • Resizable: drag the divider bar between chat and monitor to adjust the split โ€“ last position is saved in localStorage and restored on the next visit
  • Collapsible on mobile (toggle button)
  • Live filter ๐Ÿ” in the monitor title bar โ€“ type any callsign or text fragment to instantly show only matching rows; press Enter to apply immediately; the entry counter switches to X / Y Entries while a filter is active; clear with the ร— button or delete all text; filter results are cached and only recomputed on change (debounced 250 ms)

๐Ÿ“Š Status bar

  • Three-state UDP indicator: ๐Ÿ”ด No socket (bind failed) ยท ๐ŸŸก Waiting for signal (socket open, no packet yet) ยท ๐ŸŸข Receiving (at least one packet received) โ€“ semantically correct for connectionless UDP
  • Last RX timestamp, sender callsign, RSSI / SNR with colour coding
  • TX counter, own callsign, device IP:Port
  • Own GPS position with source label (Node / Browser GPS)
  • ๐Ÿ”” / ๐Ÿ”• Sound notification toggle

๐Ÿ”„ Deduplication

  • Incoming messages are deduplicated using the msg_id field (unique hex ID from the node)
  • Fallback chain: msg_id โ†’ {NNN} sequence number โ†’ message text
  • Duplicate suppression window: 10 minutes (rolling cache, auto-pruned)

๐Ÿ’พ State Persistence

  • Chat tabs, MH list, monitor history and own GPS position are saved to disk on shutdown
  • State is restored automatically on startup โ€“ no waiting for the first position beacon
  • Auto-save every 5 minutes; data stored in DataPath (configurable)

๐Ÿš€ Startup

  • ASCII banner with version number printed to the console/terminal on every start
  • Browser auto-open: when launched directly as an executable the default browser opens automatically at http://localhost:5162
  • Skipped when running in Docker, as a Windows service, or under systemd
  • Portable data paths: all data (data/), logs (logs/) and keys (data/keys/) are stored next to the executable by default โ€“ no hard-coded C:\Temp paths

โ„น๏ธ About page

  • Displays assembly version (e.g. v1.4.1), build timestamp and links
  • Version is also shown in the navigation bar next to the app title
  • Author contact: dh1fr@darc.de

โš™๏ธ Settings page

  • Web-based configuration editor at /settings โ€“ edit all settings directly in the browser
  • Changes are written to appsettings.override.json in DataPath (Docker-safe read-only mount supported)
  • Most settings apply immediately without restart
  • Settings that still require a restart: Listen-IP / Listen-Port (socket binding) and Log-Path / Log-Retention (Serilog)
  • Collapsible sections โ€“ all 14 setting sections can be individually expanded/collapsed; all start collapsed so the page is compact by default; state is saved in localStorage and restored on every visit
  • Encrypted sensitive fields โ€“ MySqlConnectionString, InfluxToken, Qrz.Password and TelemetryApiKey are encrypted with the ASP.NET Core Data Protection API before being written to appsettings.override.json (prefix dp:); existing plain-text values continue to work and are encrypted on the next save

๐ŸŽจ Appearance & Themes

  • Settings โ†’ ๐ŸŽจ Appearance โ€“ choose between four built-in themes or create your own:
    • MeshCom Dark (default) โ€“ the classic look
    • Midnight (OLED) โ€“ near-black backgrounds for OLED displays
    • Light
    • High Contrast
  • Live preview โ€“ selecting a theme applies it immediately; it only becomes permanent after Save
  • Custom themes โ€“ edited in a grouped colour editor (backgrounds, accents, buttons, text, links, status colours, messages, monitor), starting from any existing theme's colours, and saved under a name
  • Export / Import โ€“ custom themes can be exported as .mctheme.json files and imported again, so users can share their theme with others
  • The entire UI stylesheet uses semantic CSS custom properties; the default theme renders identical to pre-1.14.0 releases

๐ŸŒ UI Language

  • Full multilingual interface: Deutsch ๐Ÿ‡ฉ๐Ÿ‡ช, English ๐Ÿ‡ฌ๐Ÿ‡ง, Franรงais ๐Ÿ‡ซ๐Ÿ‡ท, Italiano ๐Ÿ‡ฎ๐Ÿ‡น, Espaรฑol ๐Ÿ‡ช๐Ÿ‡ธ
  • Language is selected in Settings โ†’ Language and persisted in appsettings.override.json
  • Switching applies instantly across all pages without any page reload or restart

๐Ÿ–ฅ๏ธ Console (TLS & Serial)

โš ๏ธ Firmware requirement: The TLS Console feature requires MeshCom firmware v4.35p.05.13 or later. Serial Console (USB) works with all firmware versions.

The Console page (/telnet) provides direct command-line access to the MeshCom node. Two connection modes are supported, selectable in Settings โ†’ ๐Ÿ–ฅ๏ธ Console:

TLS Console

The TLS Console transmits the same input/output that is available on the node's serial interface โ€“ but over the network, encrypted via TLS. This is particularly useful when the node is not physically accessible via USB (e.g. mounted outdoors or inside an enclosure).

Node setup (one-time, via the node's serial console or web interface):

  1. Enable TLS Console on the node:
    • Via serial command: --tlsconsole on
    • Or via the node's web interface: Settings โ†’ IP Network Settings โ†’ TLS Console
  2. Set a password on the node (strongly recommended):
    • Via serial command: --passwd <your-password>

WebDesk setup (Settings โ†’ ๐Ÿ–ฅ๏ธ Console):

  • Enable TLS Console
  • Enter the Device IP (same IP as configured for UDP)
  • Enter the password set on the node โ€“ it is stored encrypted (DPAPI) in appsettings.override.json
  • On first connect, the node's self-signed TLS certificate is shown โ€“ click Trust & Save to accept and store the fingerprint

โš ๏ธ Firmware requirement: TLS Console requires MeshCom firmware v4.35p.05.13 or later.

Features:

  • Pause โ€“ freeze the visible output; new lines continue to buffer
  • Clear โ€“ clear the visible output
  • OTA Update โ€“ sends --ota-update; a 5-second countdown dialog appears; the OTA page opens automatically in a new browser tab
  • Reboot โ€“ sends --reboot with a confirmation dialog
  • Firmware link โ€“ direct link to the MeshCom Firmware releases in the console header

Serial Console (USB)

  • Direct connection to a MeshCom node via USB/serial (CP210x or similar)
  • Select the COM port and baud rate in Settings โ†’ ๐Ÿ–ฅ๏ธ Console โ†’ Serial Console
  • On Windows: plain COMx names are used โ€“ do not add \\.\ prefix
  • On Linux/Docker: pass the device through (/dev/ttyUSB0) and add the container user to the dialout group (see Docker section)
  • DTR/RTS are explicitly held low after opening the port so the ESP32 reset pin is not asserted and the node does not reboot on connect
  • The serial console does not use certificates; the TLS certificate banner is suppressed in serial mode

๐ŸŽ›๏ธ Console Command Helper

The Console Command Helper (/console-commands) provides a graphical interface for reading and setting MeshCom node parameters โ€“ without having to remember or type raw console commands.

  • Live status display โ€“ reads current parameter values from the connected node on demand via the ๐Ÿ”„ Refresh button
  • Grouped cards โ€“ commands are organised by category (e.g. Network, LoRa, System) with collapsible group panels and an item counter
  • Command types supported:
    • Toggle โ€“ on/off switch (e.g. --lora-tx-enable); card colour reflects the current state
    • Value โ€“ numeric input or dropdown for commands with a fixed option list; includes unit hint
    • Text โ€“ free-text input; IP-address fields offer a ๐Ÿ“ picker to select a detected local interface address
    • Action โ€“ sends a command immediately; critical commands (e.g. reboot, OTA) require a confirmation dialog
  • Spectrum chart โ€“ when the node returns a spectrum scan, the result is displayed as an inline chart (SpectrumChart)
  • Mini console popup โ€“ a lightweight console overlay is accessible directly from the helper page for quick manual commands
  • Connection state badge โ€“ a clear โš  indicator when the node is not connected; all send buttons are disabled automatically
  • Toast notifications โ€“ brief on-screen feedback after each command is sent or an error occurs
  • Requires an active TLS or Serial console connection (configure in Settings โ†’ ๐Ÿ–ฅ๏ธ Console)

๐Ÿ“ก Beacon (Bake)

  • Periodic beacon โ€“ sends a configurable text to a configurable group at a fixed interval
  • Interval is configurable in whole hours (minimum 8 h); existing values below 8 h are automatically corrected on load; first transmission after one full interval (no send on every restart)
  • Enabled / disabled via BeaconEnabled flag โ€“ applies live without restart
  • Supported placeholders in BeaconText: {version}, {mycall}, {mylocator}, {date}, {time}, {telemetry} โ€“ shown as inline hint in Settings
  • Status indicator in the status bar: pulsing โ— dot with next scheduled send time; turns yellow when < 10 min away
  • Beacon appears in the monitor feed and in the corresponding group chat tab
  • "Send Beacon Now" test button in Settings โ€“ sends the beacon immediately without waiting for the interval

๐Ÿ“… Calendar Beacon (Scheduled Event Announcements)

Automatically announces recurring events (e.g. club meetings) to a configured group โ€“ ahead of time and/or at the exact event time.

  • Multiple entries โ€“ any number of event beacons can be defined; each can be enabled/disabled individually

  • Recurrence types:

    • Once โ€“ single event on a specific date
    • Weekly โ€“ every week on a selected weekday
    • Bi-weekly โ€“ every two weeks, anchored to a reference date
    • Monthly โ€“ fixed day of month (e.g. every 15th)
    • Nth weekday โ€“ e.g. 2nd Tuesday of the month
    • Last weekday โ€“ e.g. last Friday of the month
  • Announcement timing โ€“ any number of lead times per event as a comma-separated list, e.g. 3d, 24h, 2h (units: d = days, h = hours, m = minutes; no unit = hours); optionally also at the exact event time

  • Message placeholders: {title}, {event_date}, {event_time}, {days_until}, {hours_until}
    Example: ๐Ÿ“… {title} on {event_date} at {event_time} โ€“ in {days_until} days!

  • Next occurrence preview โ€“ Settings shows a live preview of the next calculated send date

  • External process announcements โš™๏ธ โ€“ tick the โš™๏ธ External checkbox on an entry to have the beacon text generated by an external script instead of a static message:

    • The script receives a JSON payload on stdin and writes the announcement text to stdout
    • Same directory and supported file types as bot commands (BotExternalCommandsPath, .py, .ps1, .bat, .exe)
    • Empty stdout โ†’ announcement is silently skipped for this slot
    • Configurable timeout per entry (default 10 s)

    JSON payload written to stdin:

    {
      "event": {
        "title":      "OV-Abend K01",
        "date":       "2026-06-20",
        "time":       "19:00",
        "dateTime":   "2026-06-20T19:00:00",
        "daysUntil":  3,
        "hoursUntil": 72,
        "group":      "#262",
        "recurrence": "Weekly"
      },
      "station": {
        "myCall": "OE5ABC-1", "version": "1.13.0",
        "txPowerDbm": 20, "frequencyMhz": 433.175,
        "antennaGainDbi": 2.15, "antennaType": "Dipol", "antennaHeightM": 5.0
      }
    }

    daysUntil / hoursUntil are null when announcing at the exact event time.

  • Configured in Settings โ†’ ๐Ÿ“… Termin-Bake / Calendar Beacon

โ†ฉ๏ธ Auto-Reply

  • Sends a configurable reply text automatically when a brand-new direct chat tab is opened by an incoming message (first contact from a callsign)
  • Enabled / disabled via AutoReplyEnabled โ€“ applies live without restart
  • Supported placeholders in AutoReplyText: {mycall}, {mylocator}, {callsign}, {locator}, {dest-name}, {dest-loc}, {rssi}, {snr}, {hw}, {route}, {hops}, {srctype}, {srctype-label}, {date}, {time}, {version}, {telemetry}, {last-qso}, {my-tx-power}, {my-eirp}, {my-antenna}, {my-antenna-type}, {my-antenna-height}, {my-freq}
    Example: MeshCom WebDesk V{version} โ€“ QTH: {mylocator} โ†’ MeshCom WebDesk V1.8.0 โ€“ QTH: JN48qn
  • Test button in Settings โ€“ send the auto-reply text immediately to any callsign without waiting for an incoming message

๐Ÿค– Bot โ€“ Remote commands via direct message

  • Command-based auto-responses for incoming direct messages

  • Trigger: any direct message starting with -- (two hyphens) or โ€” (em dash, as typed by many MeshCom clients and mobile keyboards) immediately followed by a letter โ€“ decoration strings like ---=== are intentionally ignored

  • Built-in commands:

    Command Response
    --help List of all registered commands
    --version MeshcomWebDesk vX.Y.Z
    --time Current date and time
    --mh Count and callsigns of recently heard stations
    --ping Pong! ๐Ÿ‘‹ <callsign> | RSSI: -87 dBm, SNR: 6.5 dB | Route (2 hops): OE1XAR-62,DB0TAW-13 | Received: 14:32:07
    --echo <text> Echoes <text> back to the sender
  • Bare ping keyword: a direct message containing only ping (case-insensitive, with optional surrounding whitespace) is treated identically to --ping

  • User-defined commands fully configurable in Settings โ†’ ๐Ÿค– Bot โ€“ no code changes required:

    • Name โ€“ command name without -- (e.g. info)
    • Response โ€“ reply text; supports all {variable} placeholders ({mycall}, {mylocator}, {callsign}, {locator}, {version}, {rssi}, {snr}, {hw}, {route}, {hops}, {srctype}, {srctype-label}, {date}, {time}, {telemetry}, {last-qso}, {my-tx-power}, {my-eirp}, {my-antenna}, {my-antenna-type}, {my-antenna-height}, {my-freq})
    • Description โ€“ optional short text shown in --help output
  • External process commands โš™๏ธ โ€“ tick the โš™๏ธ External checkbox in the command table to run an arbitrary executable or script instead of returning a static response:

    • The script receives a JSON payload on stdin (UTF-8) and writes the reply to stdout
    • Empty stdout โ†’ no reply is sent (useful for conditional responses)
    • Exit code โ‰  0 โ†’ error is logged, no reply is sent
    • All scripts must reside in the External Commands Directory (BotExternalCommandsPath); path traversal is blocked
    • Supported file types: .exe, .ps1 (PowerShell), .bat / .cmd, .py (Python)
    • The reply may still contain {variable} placeholders โ€“ they are expanded by the WebDesk after the script exits
    • Configurable timeout per command (default 10 s)

    JSON payload written to stdin:

    {
      "command": "digi",
      "args":    ["arg1", "arg2"],
      "sender":  "OE5XYZ-7",
      "message": {
        "rssi": -87, "snr": 4.2,
        "route": "OE1XAR-62,DB0TAW-13", "hops": 2,
        "srcType": "lora", "timestamp": "2026-06-16T14:32:00",
        "lat": 48.2, "lon": 16.3, "alt": 220
      },
      "station": {
        "myCall": "OE5ABC-1", "version": "1.13.0",
        "txPowerDbm": 20, "frequencyMhz": 433.175,
        "antennaGainDbi": 2.15, "antennaType": "Dipol", "antennaHeightM": 5.0
      }
    }

    Example Python script (ships as bot-scripts/bot-command-example.py next to the executable; Docker: inside the ./bot-scripts volume):

    import json, sys
    
    payload = json.loads(sys.stdin.read())
    sender  = payload["sender"]
    args    = payload.get("args", [])
    rssi    = (payload.get("message") or {}).get("rssi")
    
    reply = f"Hallo {sender}! RSSI: {rssi} dBm. Args: {args}"
    print(reply, end="")

    Settings example:

    Field Value
    Name digi
    โš™๏ธ External โœ“
    Filename bot-command-example.py
    Timeout (s) 10
    Description Digipeater info
  • Test button in Settings โ€“ enter any command (e.g. --ping) and an optional sender callsign; the bot executes the command locally (dry-run, no UDP send) and shows the exact reply including all expanded {variable} placeholders

  • ๐Ÿ“ค Export / ๐Ÿ“ฅ Import โ€“ export all user-defined bot commands as MeshComWebDesk-bot-commands.json (browser download); import a previously exported or hand-edited file to replace the current list; filename editable before export

  • Developer extension: implement IBotCommand and register via services.AddSingleton<IBotCommand, MyCommand>() in Program.cs

  • Auto-split: replies longer than 149 characters are automatically split into consecutive packets (2 s pause between parts) โ€“ same strategy as multi-bucket telemetry

  • Enabled / disabled via BotEnabled โ€“ applies live without restart

๐Ÿ“ป Watchlist โ€“ Callsign alert

  • Configurable callsign list โ€“ specify any number of callsigns to watch
  • Flexible matching: entry without SSID (e.g. DH1FR) matches all SSIDs (DH1FR, DH1FR-1, DH1FR-11, โ€ฆ); entry with SSID (e.g. DH1FR-1) matches only that exact callsign
  • Alert tone ๐Ÿ”” (ascending three-tone beep, distinct from the normal message beep) when a watched callsign is heard
  • Toast notification in the top-right corner showing the callsign, packet type badge (MSG / POS / TEL / ACK) and relative age; configurable auto-dismiss (default 5 min, adjustable in Settings); multiple hits are stacked in the same toast; manual close button โœ•
  • Per-type filter โ€“ independently enable/disable alerts for: chat messages (MSG), position beacons (POS), telemetry (TEL, default off to avoid noise from periodic data), and ACKs (ACK, default off)
  • Respects the global ๐Ÿ”• mute toggle in the status bar โ€“ no sound when muted
  • Configured in Settings โ†’ ๐Ÿ“ป Watchlist; changes apply live without restart

๐Ÿ“ข CQ Detection

  • Incoming group messages are scanned for CQ calls (case-insensitive regex; no false positives on words like "FREQUENCY")
  • Own callsign is suppressed; only groups matching the active group filter are evaluated
  • Toast notification (yellow, top-right) showing callsign, group and relative age; auto-dismissed after 60 seconds; manual close โœ•
  • CQ Beep โ€“ Morse pattern CQ CQ in CW style (700 Hz, 80 ms unit, correct dit/dah timing with inter-element and inter-character pauses, word pause between the two CQ sequences); only when sound is enabled
  • Voice announcement โ€“ e.g. โ€œC Q C Q from Delta Hotel One Foxtrot Romeo in group 2 6 2โ€œ โ€“ only when TTS is active; follows the app language (DE/EN)
  • Watchlist and CQ toasts are stacked vertically in a shared container so both are visible simultaneously

๐Ÿ“ก Station / HF Parameters

  • Configurable in Settings โ†’ ๐Ÿ“ก Station / HF (new section)

  • TX power (dBm), cable type (15 preset 50-ฮฉ types in three attenuation groups), cable length, antenna gain (dBi), antenna type (free text, e.g. Dipol, Yagi 3-El.), antenna height, operating frequency and system margin (dB)

  • Manual attenuation input โ€“ selecting "Manuell eingeben โ€ฆ" reveals an extra input field for custom cable loss in dB/10 m

  • Live display of calculated EIRP (P_TX โˆ’ cable loss + antenna gain) and theoretical free-space range (using configured system margin, default 30 dB)

  • All parameters are included in the settings backup and are backwards compatible

  • FSPL coverage circle on the map โ€“ when the coverage overlay is active a yellow circle shows the theoretical free-space range derived from EIRP, frequency and system margin; legend distinguishes "Gemessen (Convex Hull)" and "FSPL-Reichweite (theor.)"

  • Station template variables โ€“ available in Auto-Reply, Bot commands, Beacon and Quick Texts:

    Variable Example
    {my-tx-power} 22 dBm
    {my-eirp} 23.50 dBm
    {my-antenna} 2.5 dBi
    {my-antenna-type} Dipol
    {my-antenna-height} 10 m
    {my-freq} 433.175 MHz

๐Ÿ“Š Telemetry (Telemetrie-Sender)

  • Two independent delivery paths, both read from the same mapping table and the same source (file or HTTP POST):
    • Chat-text telemetry โ€“ sent on the configured schedule (TelemetryScheduleHours), as a readable TM: message to a group/callsign
    • Native extudp telemetry โ€“ sent directly to the node as a "type":"tele" UDP telegram (see below), on value change rather than on a schedule
  • Source-agnostic: any system can write the JSON file โ€“ Home Assistant, Node-RED, MQTT bridge, shell script, etc.
  • HTTP POST endpoint POST /api/telemetry โ€“ external sources (e.g. Home Assistant) can push JSON directly; no shared filesystem needed; protected by optional X-Api-Key header
  • Flexible mapping โ€“ unlimited key โ†’ label / unit / decimal-places pairs, fully configurable in the Settings UI without touching source code
  • Role column โ€“ each mapping row can additionally be assigned one of 7 fixed roles (temp/humidity/pressure/temp2/qnh/gasres/co2); roles drive both the map popup and the native extudp telegram fields (only one row per role is used)
  • Auto-split (chat-text path): if all values exceed 150 chars, messages are automatically split into TM1: / TM2: / โ€ฆ with a 2-second pause between packets
  • Destination โ€“ group (e.g. #262), broadcast (*) or direct callsign (e.g. OE1KBC-1)
  • Status indicator in the status bar analogue to the beacon
  • Live preview in Settings: shows current file values, formatted output per entry, and exact LoRa message(s)
  • Instant send button in Settings for immediate test send without waiting for the interval
  • Example messages: TM: ๐ŸŒก=10.7C ๐Ÿงญ=1022hPa ๐Ÿ’ง=86% ๐ŸŒฌ=0.0m/s or split into TM1: / TM2: when needed
  • ๐Ÿ“– Home Assistant integration guide โ€“ complete example with weather station sensors, rest_command and automation

๐Ÿ“ก Native extudp telemetry

  • "Extudp enabled" toggle โ€“ sends role-assigned values directly to the node as a "type":"tele" UDP telegram instead of (or alongside) the chat-text message; the node writes them straight into its own sensor variables, so they appear in its next position beacon exactly like real sensor hardware
  • Send-on-change โ€“ a send only happens when at least one role-assigned value differs from the last successfully sent set, throttled by a configurable minimum interval (the node applies no rate limiting of its own)
  • Firmware-capability check โ€“ after each send, WebDesk watches for the node's own next telemetry echo and compares it against the values just sent; if no matching echo arrives within 20 s, extudp telemetry is disabled automatically and persisted (the confirmation status โœ…/โš ๏ธ/โ„น๏ธ is shown live next to the toggle)
  • Requires firmware with handleExternTelemetry() support and a node with no real onboard sensor hardware (real sensors take priority and the external values are ignored)
  • ๐Ÿ“– Practical setup guide and protocol reference

๐ŸŒค๏ธ Weather API (Wetter-API)

  • Automatic weather data: fetch live measurements from external weather platforms and feed them directly into the telemetry JSON file
  • Supported providers:
    • AWEKAS โ€“ Austrian weather network; uses https://api.awekas.at/current.php?key=<API-KEY>
    • Weather Underground (PWS) โ€“ uses https://api.weather.com/v2/pws/observations/current
    • Simulation โ€“ generates realistic test data without any API key or network access (always available)
  • Configurable fields: temperature (in/out), humidity (in/out), pressure (rel/abs), wind speed/gust/direction, rain rate/daily total, UV index, solar radiation, dew point
  • Telemetry integration: field names (temp_out, humidity_out, pressure_rel, โ€ฆ) can be used directly as JSON-Key in the Telemetry Mapping
  • Bot command --weather: reports provider, last received values and timestamp
  • Poll interval: configurable 5โ€“60 minutes
  • Upload format for AWEKAS virtual station: http://ws.awekas.at/weatherstation/updateweatherstation.php?ID=<id>&PASSWORD=<pw>&dateutc=now&tempf=<F>&humidity=<pct>&baromin=<inHg>&windspeedmph=<mph>&windgustmph=<mph>&winddir=<deg>&rainin=0.0&dailyrainin=0.0&softwaretype=custom&action=updateraw

๐Ÿ“ Logging (Serilog)

  • Rolling daily log files with configurable retention
  • Optional UDP traffic log (LogUdpTraffic) for offline analysis

๐Ÿ—„๏ธ Database integration

  • Optional persistent storage of all monitor data to an external database
  • MySQL / MariaDB: writes each monitor entry as a row via parametrised INSERT (uses MySqlConnector)
  • InfluxDB 2: writes each monitor entry as a point via HTTP Line Protocol (/api/v2/write)
  • Provider selection in Settings โ†’ ๐Ÿ—„๏ธ Datenbank:
  • "Test connection" button: detects missing database, table or bucket and offers automatic creation with a single click
  • Optional insert logging โ€“ every successful write is logged at Information level; privacy notice shown in Settings
  • Provider and connection settings change live without restart

๐Ÿ’ฌ Message length validation

  • MeshCom LoRa packets are limited to 149 characters of message text
  • Character counter X/149 next to the input field: grey โ†’ yellow (โ‰ฅ 130) โ†’ red bold (โ‰ฅ 145)
  • maxlength="149" prevents over-long input in the browser
  • Server-side guard in SendMessageAsync: logs a warning and aborts send if text exceeds 149 characters
  • Bot replies and beacon texts that exceed 149 characters are automatically split into multiple packets (2 s pause between parts) rather than being dropped

๐Ÿ—บ๏ธ Live Map

  • Interactive map at /map powered by Leaflet.js + OpenStreetMap
  • APRS-style markers: filled circle colour-coded by RSSI (๐ŸŸข > โˆ’90 / ๐ŸŸก > โˆ’105 / ๐Ÿ”ด โ‰ค โˆ’105 dBm) + callsign label below
  • Own position shown as gold diamond โ—† (APRS convention)
  • Popup on click: callsign, QRZ operator name / QTH (when enabled), last message, RSSI, battery, altitude, QTH locator, GPS coordinates (as clickable OSM link) and a direct ๐Ÿ”— aprs.fi link (opens station info page in new tab)
  • Callsign search ๐Ÿ” โ€“ search field in the control bar; press Enter or click the button to jump directly to the station and open its popup; multiple matches show a dropdown; shows โ€žNot found" if no match
  • First open: map automatically zooms to a 50 km radius around own position (once own GPS is known)
  • View persistence: last map position and zoom level are saved in localStorage and restored on every subsequent visit
  • Compact info bar at the bottom: ๐Ÿ“ก N Station(en) ยท ๐Ÿ“ MyCallsign โ€“ clean one-liner regardless of station count
  • ๐Ÿค– KI-Stationsbeschreibung (AI popup) โ€“ every station marker popup has a ๐Ÿค– button; clicking it sends the station's data (callsign, RSSI, SNR, battery, firmware, relay path, QRZ data) as context to the configured AI and shows a concise German-language station description directly inside the popup; requires AI integration to be configured and enabled
  • Updates in real-time as new position beacons arrive
  • Nav link ๐Ÿ—บ๏ธ added to the navigation bar

๐Ÿ“ก Reichweite (Coverage)

  • Coverage overlay on the map โ€“ toggled with the ๐Ÿ“ถ button in the map control bar
  • Measured convex hull (blue polygon) โ€“ shows the actual coverage area based on all directly heard stations (HopCount = 0); calculated as the convex hull of the GPS positions of all direct-receive stations plus own position (Haversine / gift-wrapping algorithm, implemented in JavaScript)
  • Fill opacity 35 %, solid border (weight 3, opacity 95 %) for good contrast against the map tiles
  • Tooltip: ๐Ÿ“ก Gemessene Reichweite
  • Coverage is recalculated every time the button is toggled; no background polling
  • FSPL radius (yellow circle) โ€“ shown alongside the convex hull when station/HF parameters are configured; represents the theoretical free-space range based on EIRP, frequency and system margin; legend shows both layers

๐Ÿค– KI / AI โ€“ QSO Summary, History & Search

Requires MySQL database to be configured for all features in this section.

๐Ÿ”Ž QSO Dialog

A ๐Ÿ”Ž icon appears on every direct-chat tab as soon as the MySQL database is active.
Clicking it opens a modal dialog with four tabs:

Tab Requires AI Description
๐Ÿ“‹ KI-Zusammenfassung โœ… Yes AI-generated summary of recent QSO messages
๐Ÿ“œ Verlauf โŒ No Paginated message history with date & text filter
๐Ÿ”Ž Suche โŒ No Full-text search across all messages in the conversation
๐Ÿ”Ž KI-Suche โœ… Yes Ask a natural-language question; AI cites exact timestamps
  • Without AI configured: tabs ๐Ÿ“‹ and ๐Ÿ”Ž KI-Suche are disabled (greyed out); History and Search work with MySQL only
  • With AI configured: all four tabs available; the dialog opens on the Summary tab by default

๐Ÿ“‹ KI-Zusammenfassung (AI Summary)

  • Automatic QSO summaries generated by an external AI API (OpenAI, Grok or Azure OpenAI)

  • A ๐Ÿ”Ž icon appears on the chat tab of every direct conversation once the last contact is older than the configurable threshold (ThresholdDays, default 7 days) โ€“ or immediately when a summary already exists

  • Generate / Regenerate button โ€“ sends the last N messages (configurable MaxMessages, default 50) to the AI and stores the result in the qso_summaries table

  • Supported AI providers:

    Provider Provider value Available models
    OpenAI (default) openai auto (recommended) ยท gpt-4o-mini ยท gpt-4.1-nano ยท gpt-4.1-mini ยท gpt-4.1 ยท gpt-4o ยท gpt-3.5-turbo
    Grok (xAI) grok grok-3-mini ยท grok-3
    Azure OpenAI azure deployment name

    Model auto (Automatic): selects the best model based on prompt size - gpt-4o-mini for small prompts, gpt-4.1-mini for medium and gpt-4.1 for large context windows. Recommended for AI Search.- Token usage statistics โ€“ current session prompt / completion / total tokens and request count shown in Settings โ†’ ๐Ÿค– KI

  • OpenAI balance check โ€“ queries the OpenAI billing API and shows remaining credit / monthly usage in Settings; falls back to a dashboard link when the billing endpoint is restricted (project keys)

  • Azure OpenAI: configurable resource endpoint and API version

๐Ÿ“œ Verlauf (History)

  • Paginated chronological message history for the current conversation (oldest first)
  • Date range filter (from / to) and free-text filter โ€“ all combinable
  • Page size: 50 messages; previous/next pagination with total count
  • Works with MySQL only โ€“ no AI API key required

๐Ÿ”Ž Suche (Text Search)

  • Full-text search across all stored messages in the direct conversation
  • Date range filter (from / to) combinable with the search term
  • Results shown in a table with matching text highlighted
  • Works with MySQL only โ€“ no AI API key required

๐Ÿ”Ž KI-Suche (AI Search)

  • Ask any natural-language question about the conversation (e.g. "What did Jรผrgen recommend?")
  • The AI receives all relevant messages and responds with a precise answer citing exact timestamps
  • Date range pre-filled - when opening the global AI search the date range is automatically set to the last 90 days up to the end of the current day (23:59:59); can be adjusted manually
  • "Alle Direkt-QSOs durchsuchen" / "Search all direct QSOs" - optional checkbox to search across all direct 1:1 QSOs, own group messages and group @-mentions; raw JSON status packets and ACKs are filtered out automatically
  • Echo deduplication - LoRa-echo duplicates (same message stored twice from outgoing + incoming echo) are removed before the prompt is built, reducing token usage
  • Automatic model selection - model option ๏ฟฝuto (Automatic (recommended)) picks gpt-4o-mini, gpt-4.1-mini or gpt-4.1 automatically based on prompt size
  • Requires AI to be enabled and an API key to be configured#### โš™๏ธ Setting up AI features (step by step)
  1. Set up MySQL โ€“ configure Database.Provider = "mysql" and a valid MySqlConnectionString in Settings; use the โ€žAnlegen" button to create the schema automatically
  2. Choose a provider โ€“ openai (default), grok or azure
  3. Enter your API key:
    • OpenAI: create a key at platform.openai.com/api-keys (project key is sufficient for summaries)
    • Grok / xAI: create a key at console.x.ai
    • Azure OpenAI: enter resource endpoint + deployment name + API version
  4. Choose a model - select Automatic (recommended) (auto) to let the app pick the best model based on prompt size, or choose a specific model (e.g. gpt-4.1-mini for large searches, gpt-4o-mini for cost efficiency)
  5. Enable AI - tick "Aktiviert" and click ๐Ÿ’พ Save; takes effect immediately without restart
  6. Test - enter a callsign in the test field and click "DB + API testen"; the test checks DB connectivity and makes a live API call
  7. The ๐Ÿ”Ž icon appears on chat tabs once messages are stored in MySQL

Tip: Enable "KI-Anfragen protokollieren" (Log AI requests) in Settings to see detailed diagnostics - SQL used, prompt size, token estimate and answer preview - in the application log. API keys are stored encrypted in appsettings.override.json (ASP.NET Core Data Protection, dp: prefix).

๐Ÿ”— Webhook

  • HTTP POST to a configurable URL on incoming events
  • Configurable triggers: chat messages / position beacons / telemetry (each individually)
  • JSON payload: event, timestamp, from, to, text, rssi, snr, latitude, longitude, altitude, battery, firmware, relay_path, src_type; telemetry events additionally include temp1, temp2, humidity, pressure; null fields are omitted
  • Fire-and-forget (10 s timeout); errors logged and swallowed โ€“ never blocks reception
  • Configured in Settings โ†’ ๐Ÿ”— Webhook; changes apply live without restart
  • Compatible with Home Assistant webhooks, Node-RED, n8n, IFTTT, custom endpoints

๐Ÿ“ก MQTT

  • Optional connection to an external MQTT broker (e.g. Mosquitto, Home Assistant Mosquitto add-on, EMQX)

  • Publisher โ€“ forwards incoming MeshCom events to typed MQTT topics:

    Event Topic
    Broadcast chat {prefix}/broadcast
    Group chat {prefix}/group/{group} e.g. meshcom/group/262
    Direct message {prefix}/dm/{callsign} e.g. meshcom/dm/DH1FR-1
    Position beacon {prefix}/position/{callsign}
    Telemetry {prefix}/telemetry/{callsign}
  • Subscriber (optional) โ€“ subscribes to send-topics and forwards them as outgoing UDP messages to the MeshCom node:

    Topic Action
    {prefix}/send/broadcast Send broadcast message
    {prefix}/send/group/{group} Send group message
    {prefix}/send/dm/{callsign} Send direct message

    Payload: JSON { "text": "message text" } โ€“ all {variable} placeholders ({mycall}, {callsign}, {date}, {time}, โ€ฆ) are expanded before sending.

  • MQTT payload is identical to the Webhook JSON payload for consistency

  • Supports authentication (username / password stored encrypted), TLS and a configurable topic prefix

  • Auto-reconnect on connection loss

  • Configurable per-event publish flags (messages / positions / telemetry separately)

  • Configured in Settings โ†’ ๐Ÿ“ก MQTT; password is stored encrypted

๐Ÿท๏ธ Group Labels

  • User-defined display names for MeshCom group numbers shown in the chat tab below the group number
  • The short label (e.g. DL, DACH, OE1) appears inside the tab; the full name (e.g. DL โ€“ Deutschland) appears as a tooltip on hover
  • Pre-filled with the official MeshCom GRC group list from icssw.org/meshcom-grc-gruppen covering all European and international groups (EU, DACH, country codes, Italian regions, German regional groups, โ€ฆ)
  • Fully editable in Settings โ†’ ๐Ÿท๏ธ Group Labels โ€“ add, remove or rename entries
  • Restore Defaults button resets the list to the official MeshCom group table
  • ๐Ÿ“ค Export / ๐Ÿ“ฅ Import โ€“ export labels as MeshComWebDesk-group-labels.json; share with other users or import a community list; filename editable before export
  • Labels are saved in appsettings.override.json and apply without restart

๐Ÿ” Backup & Restore (Settings)

  • Full encrypted backup of all settings including passwords and API keys โ€“ exported as MeshComWebDesk-settings.enc (binary, browser download)

  • AES-256-CBC encryption with a user-supplied password; key derived via PBKDF2 / SHA-256 / 100,000 iterations

  • File format: [MCWD magic 4B][Salt 16B][IV 16B][AES ciphertext] โ€“ portable across machines and operating systems

  • Password is never stored โ€“ if lost, the file cannot be recovered

  • Import / Restore: select the .enc file and enter the password; settings are decrypted, validated and saved; the page reloads automatically with a success confirmation

  • Error handling: wrong password, corrupted file, invalid JSON and missing fields all produce clear error messages

  • Filename editable before export (default: MeshComWebDesk-settings.enc)

  • Found in Settings โ†’ ๐Ÿ” Datensicherung at the bottom of the settings page

  • Complete coverage โ€“ the following settings are included in the backup:

    Category What is backed up
    Appearance Active theme and all custom themes (name + full colour set)
    Multi-Node profiles All node profiles (Name, Callsign, Device IP/Port, Listen IP/Port, Primary flag, Enabled flag, TLS fingerprint, TLS password)
    Connection Primary ListenIp, ListenPort, DeviceIp, DevicePort, MyCallsign
    Console TelnetEnabled, ConsoleMode, TelnetPort, TelnetPassword, TelnetCertThumbprint, SerialPortName, SerialBaudRate
    Chat & Groups Groups, WatchCallsigns, watch options, GroupLabels, OwnMessagesAlignLeft, TxCooldownSeconds, GatewayHighlightEnabled
    Auto-Reply AutoReplyEnabled, AutoReplyText
    Bot BotEnabled, BotExternalCommandsPath, all user-defined bot commands (incl. external process fields)
    Quick Texts All quick-text entries
    Beacon BeaconEnabled, BeaconGroup, BeaconText, BeaconIntervalHours
    Calendar Beacon All event entries incl. AnnounceLeadTimes, IsExternal, ExternalFileName, TimeoutSeconds
    Telemetry TelemetryEnabled, TelemetryFilePath, TelemetryGroup, TelemetryScheduleHours, TelemetryMapping (incl. per-row Role), TelemetryApiEnabled, TelemetryApiKey, TelemetryExtUdpEnabled, TelemetryExtUdpMinIntervalMinutes
    Station / RF TxPowerDbm, CableType, CableLengthM, AntennaGainDbi, AntennaType, AntennaHeightM, FrequencyMhz, SystemMarginDb
    Database Provider, MySQL connection string, InfluxDB URL/token/org/bucket, table name, log inserts flag
    QRZ.com Enabled, Username, Password, cache settings
    AI Enabled, provider, API key, model, Azure endpoint/version, threshold/summary days, max messages
    Webhook Enabled, URL, event flags
    MQTT All broker and topic settings including username/password
    UI Language, MonitorMaxMessages, MhMaxAgeHours, TimeOffsetHours
    Logging LogPath, LogRetainDays, LogUdpTraffic

๐Ÿ“ฑ PWA โ€“ Progressive Web App

  • Installable on any device via the browser's "Add to Home Screen" / "Install" prompt
  • manifest.webmanifest with name, icon, display: standalone, shortcuts (Chat + Map)
  • Minimal service worker โ€“ enables install prompt; full offline not possible (Blazor Server requires live connection)
  • Apple meta tags for iOS Safari Add-to-Home-Screen
  • Custom antenna SVG icon in the app colour scheme

๐Ÿ” QRZ.com Callsign Lookup

  • Optional integration with the QRZ.com XML API for operator name and home location
  • Requires a free QRZ.com account (username + password โ€“ no separate API key)
  • Login flow: the app fetches a session key automatically on first lookup and refreshes it transparently on expiry
  • Free account returns first name + city/QTH โ€“ sufficient for all MeshCom WebDesk displays
  • XML subscription (~$30/year) unlocks full profile data
  • SSID stripping: DH1FR-2 is looked up as DH1FR automatically
  • Results are cached in memory per app session โ€“ each callsign is only queried once regardless of how many pages display it
  • Shown everywhere a callsign appears:
    • ๐Ÿ“ป MH list โ€“ dedicated Name / Location column + hover tooltip on the callsign cell
    • ๐Ÿ’ฌ Chat โ€“ hover tooltip on tab buttons (direct chats) and on every callsign in messages and monitor rows
    • ๐Ÿ—บ๏ธ Map โ€“ callsign popup shows name and QTH below the bold callsign
  • Configured in Settings โ†’ ๐Ÿ” QRZ.com; can be enabled/disabled live without restart
  • Test button in Settings: performs a live lookup of your own callsign and shows the result immediately
  • Cache-clear button in Settings: forces fresh lookups after account upgrade or data change
  • All errors (wrong credentials, network failure, unknown callsign) are logged as Warning in the Serilog log file

๐Ÿ”’ HTTPS for LAN (required for PWA on mobile)

  • scripts/create-lan-cert.ps1 โ€“ one-click self-signed certificate generator for Windows PowerShell
    • Auto-detects LAN IP; can also be set manually with -LanIp
    • Creates cert with IP SAN (Subject Alternative Name) so browsers accept it without warnings
    • Exports certs/meshcom-lan.pfx for Kestrel + certs/meshcom-lan.crt for mobile device trust
    • Trusts the cert in Windows CurrentUser\Root automatically
  • New launch profile lan-https โ€“ binds HTTP :5162 and HTTPS :5163 simultaneously
  • appsettings.LanHttps.json โ€“ Kestrel HTTPS endpoint configuration (loaded via ASPNETCORE_ENVIRONMENT=LanHttps)
  • HTTP on port 5162 stays active โ€“ existing bookmarks and Docker deployments are unaffected
  • HTTPS is only needed for PWA installation on Android / iPad / iPhone over LAN

โšก Optimisations & Bugfixes (selected)

  • QRZ race condition โ€“ in-flight deduplication (ConcurrentDictionary) prevents parallel duplicate lookups for the same callsign
  • Direct tab visibility โ€“ newly created direct-message tabs appear immediately in the UI even when voice announcements are disabled
  • Bot false-positive โ€“ decoration strings like ---=== are no longer misidentified as bot commands; IsCommand() checks that -- or โ€” is immediately followed by a letter
  • {last-qso} accuracy โ€“ the variable returns the previous QSO (the triggering message is excluded); no previous QSO โ†’ kein QSO / no QSO
  • Telemetry double-send โ€“ the telemetry scheduler now initialises lastSentSlot to the current hour on startup, preventing a duplicate send within the first hour after a restart
  • TLS password transmission โ€“ the encrypted dp: prefix string is now decrypted before being sent to the node; plain-text password is transmitted correctly
  • TelnetEnabled persistence โ€“ the setting is now correctly written to and read from appsettings.override.json; no longer lost after restart or backup restore
  • Multi-node first-connect cert โ€“ certThumbprintOverride is passed as string.Empty (not null) for nodes without a stored fingerprint, preventing Node-1's fingerprint from being applied to Node-2
  • Serial connect โ€“ no ESP32 reboot โ€“ DTR and RTS are explicitly held low after SerialPort.Open() to prevent the hardware reset that Windows triggers via the DTR pin
  • Speaker icon persists โ€“ the speaker toggle in the status bar remains visible immediately after chat page reloads (state stored like the bell icon)
  • PBKDF2 on thread-pool โ€“ CPU-intensive key derivation for backup encryption runs on Task.Run() to keep the SignalR heartbeat alive
  • Backup import via Blazor InputFile โ€“ replaces the JS-interop int[] file-read that exceeded the 32 KB SignalR message limit

Architecture

MeshcomWebDesk/              โ† Blazor Server (ASP.NET Core host)
โ”‚  Program.cs                  โ† DI setup, Serilog, hosted services
โ”‚  appsettings.json            โ† All configuration
โ”‚  appsettings.LanHttps.json   โ† Kestrel HTTPS endpoint on :5163 (for PWA on mobile)
โ”‚
โ”œโ”€ Components/
โ”‚  โ”œโ”€ App.razor                โ† HTML shell + JS helpers + Leaflet CDN + SW registration
โ”‚  โ”œโ”€ Layout/
โ”‚  โ”‚    MainLayout.razor       โ† Top navigation bar
โ”‚  โ””โ”€ Pages/
โ”‚       Chat.razor             โ† Chat tabs + monitor pane + status bar
โ”‚       Mh.razor               โ† Most Recently Heard table + own position
โ”‚       Map.razor              โ† Live Leaflet map with APRS-style markers
โ”‚       Settings.razor         โ† Web-based configuration editor
โ”‚       About.razor            โ† Version / copyright / build info + PayPal donation link
โ”‚       Clear.razor            โ† Data reset page
โ”‚
โ”œโ”€ Helpers/
โ”‚     GeoHelper.cs             โ† Haversine, coordinate formatting, OSM links
โ”‚     MeshcomLookup.cs         โ† hw_id โ†’ hardware name table, firmware formatter
โ”‚
โ”œโ”€ Models/
โ”‚     MeshcomMessage.cs        โ† Message model (from/to/text/GPS/RSSI/ACK/relay/telemetry)
โ”‚     MeshcomSettings.cs       โ† Strongly-typed config (IOptions)
โ”‚     AiSettings.cs            โ† AI provider + API key + model + summary parameters
โ”‚     TelemetryMappingEntry.cs โ† Telemetry mapping entry (JSON key โ†’ label + unit + decimals)
โ”‚     QuickTextEntry.cs        โ† Quick-text button entry (label + text, supports {variables})
โ”‚     DatabaseSettings.cs      โ† DB provider + connection settings + LogInserts
โ”‚     WebhookSettings.cs       โ† Webhook URL + trigger flags
โ”‚     QrzSettings.cs           โ† QRZ.com credentials + enabled flag
โ”‚     ChatTab.cs               โ† Tab model with UnreadCount
โ”‚     HeardStation.cs          โ† MH list entry (GPS, signal, battery, hardware, firmware)
โ”‚     ConnectionStatus.cs      โ† Live UDP status + own GPS position
โ”‚     PersistenceSnapshot.cs   โ† Serialisable state snapshot (tabs, MH, monitor, own GPS)
โ”‚
โ”œโ”€ wwwroot/
โ”‚     map.js                   โ† Leaflet JS helpers (init, updateMarkers, APRS icons)
โ”‚     manifest.webmanifest     โ† PWA manifest (name, icon, display:standalone, shortcuts)
โ”‚     service-worker.js        โ† Minimal SW โ€“ enables install prompt
โ”‚     icons/icon.svg           โ† Antenna icon in app colour scheme
โ”‚     certs/                   โ† LAN certificate directory (not in repo โ€“ .gitignore)
โ”‚
โ”œโ”€ scripts/
โ”‚     create-lan-cert.ps1      โ† PowerShell: generates self-signed cert for HTTPS LAN access (Windows)
โ”‚     create-lan-cert.sh       โ† Bash: generates self-signed cert for HTTPS LAN access (Linux / Docker)
โ”‚     start-https.sh           โ† Bash: starts Docker Compose with HTTPS overlay (checks cert first)
โ”‚
โ”œโ”€ docker-compose.yml         โ† Standard deployment: HTTP only (always works)
โ”œโ”€ docker-compose.https.yml   โ† HTTPS overlay: adds port 5163 + cert volume (requires cert)
โ”‚
โ””โ”€ Services/
      MeshcomUdpService.cs     โ† BackgroundService: UDP RX/TX, JSON parsing, ACK matching, beacon timer, bot reply sender
      ChatService.cs           โ† Singleton: routing, tabs, MH list, monitor, deduplication, webhook trigger, OnBotCommand event
      DataPersistenceService.csโ† BackgroundService: load/save state to JSON on disk
      SettingsService.cs       โ† Writes appsettings.override.json in DataPath (Docker-safe); changes applied live via IOptionsMonitor
      LanguageService.cs       โ† Singleton: UI language switching (de/en); T(de,en) helper; OnChange event for instant re-render
      WebhookService.cs        โ† HTTP POST fire-and-forget on message / position / telemetry events
      QrzService.cs             โ† QRZ.com XML API: session login, callsign lookup, in-memory cache
      QsoSummaryService.cs      โ† AI-based QSO summary: reads messages from MySQL, calls AI API, stores result in qso_summaries table; token usage tracking; balance check
      ExternalProcessRunner.cs  โ† Singleton: launches external scripts from a caller-supplied directory; JSON on stdin โ†’ reply from stdout; path-traversal guard, timeout, .exe/.ps1/.bat/.cmd/.py support; shared by bot commands and calendar beacon
      Bot/
        IBotCommand.cs          โ† Interface for all bot commands (Name, Description, ExecuteAsync)
        BotCommandService.cs    โ† Dispatcher: parses --name [args], builds --help, hot-reloads user commands from config; normalises bare "ping" keyword
        VersionCommand.cs       โ† --version: returns app version
        TimeCommand.cs          โ† --time: returns current date/time
        MhCommand.cs            โ† --mh: returns MH list count + callsigns
        PingCommand.cs          โ† --ping / bare "ping": pong with RSSI, SNR, relay route and receive timestamp
        EchoCommand.cs          โ† --echo <text>: echoes arguments back to the sender
        ConfiguredBotCommand.cs โ† Wrapper for static BotCommands entries from appsettings.json
        ExternalProcessCommand.csโ† IBotCommand implementation that delegates to ExternalProcessRunner
      Database/
        IMonitorDataSink.cs    โ† Interface: WriteAsync(MeshcomMessage)
        MySqlMonitorSink.cs    โ† MySQL / MariaDB write sink (MySqlConnector)
        InfluxDbMonitorSink.cs โ† InfluxDB 2 write sink (HTTP Line Protocol)
        MonitorSinkService.cs  โ† Routes each write to the active provider; IOptionsMonitor-aware
        DatabaseSetupService.csโ† Connection test + automatic schema creation (DB, table, bucket)

Configuration

All settings in MeshcomWebDesk/appsettings.json:

"Meshcom": {
  "ListenIp":           "0.0.0.0",       // bind address (0.0.0.0 = all interfaces)
  "ListenPort":         1799,            // local UDP port
  "DeviceIp":           "192.168.1.60",  // MeshCom node IP
  "DevicePort":         1799,            // MeshCom node UDP port
  "MyCallsign":         "NOCALL-1",       // own callsign
  "LogPath":            "C:\\Temp\\Logs",// log file directory
  "LogRetainDays":      30,              // log file retention in days
  "LogUdpTraffic":      false,           // log every UDP packet to file
  "MonitorMaxMessages": 1000,            // max monitor history (oldest dropped)
  "GroupFilterEnabled": true,            // only show whitelisted group tabs
  "Groups":             ["#20","#262"],  // whitelisted groups (GroupFilterEnabled=true)
  "WatchCallsigns":     ["DH1FR","OE1KBC-1"], // watched callsigns (without SSID = match all SSIDs)
  "WatchOnMessage":     true,            // alert on chat messages from watched callsigns
  "WatchOnPosition":    true,            // alert on position beacons
  "WatchOnTelemetry":   false,           // alert on telemetry packets (periodic โ€“ off by default)
  "WatchOnAck":         false,           // alert on ACK packets
  "WatchAlertMinutes":  5,              // watchlist toast auto-dismiss in minutes (min 1)
  "DataPath":           "C:\\Temp\\MeshcomData", // persistent state directory
  "AutoReplyEnabled":   false,           // send auto-reply on first contact
  "AutoReplyText":      "...",           // auto-reply text; {version} โ†’ app version
  "BotEnabled":               false,     // enable remote command bot (-- prefix)
  "BotExternalCommandsPath":  "scripts", // directory for external bot command scripts (relative or absolute)
  "BotCommands": [                       // user-defined bot commands (built-in: --help/--version/--time/--mh)
    { "Name": "info",  "Response": "QTH: Wien, HW: {hw}, 73 de {mycall}!", "Description": "Stationsinfo" },
    // External process example (IsExternal=true โ†’ ExternalFileName used instead of Response):
    { "Name": "digi",  "IsExternal": true, "ExternalFileName": "bot-command-example.py", "TimeoutSeconds": 10, "Description": "Digipeater info" }
  ],
  "BeaconEnabled":      false,           // send periodic beacon (Bake)
  "BeaconGroup":        "#262",          // target group for beacon
  "BeaconText":         "...",           // beacon text; {version} โ†’ app version
  "BeaconIntervalHours": 8,              // beacon interval in hours (minimum 8)
  "TelemetryEnabled":      false,        // send periodic telemetry message
  "TelemetryFilePath":     "/data/telemetry.json", // source JSON file (written by HA, script etc.)
  "TelemetryGroup":        "#262",       // destination: group (#262), broadcast (*), or callsign
  "TelemetryScheduleHours":   "11,15",      // send at 11:00 and 15:00 (comma-separated hours 0โ€“23)
  "TelemetryApiEnabled":   false,        // enable POST /api/telemetry HTTP endpoint
  "TelemetryApiKey":       "",           // optional X-Api-Key for the endpoint (empty = no auth)
  "Language":              "de",         // UI language: "de", "en", "fr", "it", "es"
  "Database": {                          // optional database sink
    "Provider":              "none",     // "none" | "mysql" | "influxdb2"
    "MySqlConnectionString": "",         // e.g. "Server=localhost;Database=meshcom;User=mc;Password=secret;"
    "MySqlTableName":        "meshcom_monitor", // created automatically via Settings โ†’ Anlegen
    "InfluxUrl":             "http://localhost:8086",
    "InfluxToken":           "",
    "InfluxOrg":             "meshcom",
    "InfluxBucket":          "meshcom",
    "LogInserts":            false       // log every successful write at Information level
  },
  "Webhook": {
    "Enabled":     false,              // send HTTP POST on events
    "Url":         "",                 // target URL (HTTP POST, JSON body)
    "OnMessage":   true,               // fire on incoming chat messages
    "OnPosition":  false,              // fire on incoming position beacons
    "OnTelemetry": false               // fire on incoming telemetry
  },
  "Mqtt": {                            // optional MQTT broker integration
    "Enabled":          false,         // enable MQTT connection
    "Host":             "localhost",   // MQTT broker hostname or IP
    "Port":             1883,          // MQTT broker port (default 1883, TLS usually 8883)
    "ClientId":         "meshcom-webdesk",
    "Username":         "",            // optional MQTT username
    "Password":         "",            // optional MQTT password (stored encrypted after first UI save)
    "UseTls":           false,         // enable TLS/SSL
    "TopicPrefix":      "meshcom",     // prefix for all topics
    "PublishMessage":   true,          // publish incoming chat messages
    "PublishPosition":  false,         // publish incoming position beacons
    "PublishTelemetry": false,         // publish incoming telemetry packets
    "SubscribeEnabled": false          // subscribe to send-topics and forward to mesh
  },
  "Qrz": {
    "Enabled":  false,                 // enable QRZ.com XML API callsign lookups
    "Username": "",                    // QRZ.com login username (usually your callsign)
    "Password": ""                     // QRZ.com login password (stored encrypted after first UI save)
  },
  "Ai": {
    "Enabled":        false,           // enable AI-based QSO summary feature
    "Provider":       "openai",        // "openai" | "grok" | "azure"
    "ApiKey":         "",              // API key (stored encrypted after first UI save)
    "Model":          "gpt-4o-mini",   // OpenAI: "gpt-4o-mini"/"gpt-4o"; Grok: "grok-3-mini"/"grok-3"; Azure: deployment name
    "AzureEndpoint":  "",              // Azure OpenAI resource endpoint (only for Provider="azure")
    "AzureApiVersion":"2024-08-01-preview", // Azure OpenAI API version (only for Provider="azure")
    "ThresholdDays":  7,               // days since last QSO before the ๐Ÿค– icon appears (0 = always)
    "SummaryDays":    365,             // how many days back to look for messages
    "MaxMessages":    50,              // max messages sent to AI per request (limits token usage)
    "LogRequests":    false            // log every AI API request at Information level
  },
  "TelemetryMapping": [                  // any number of entries; configure in Settings UI
    { "JsonKey": "aussentemp",  "Label": "๐ŸŒก",  "Unit": "C",   "Decimals": 1 },
    { "JsonKey": "luftdruck",   "Label": "๐Ÿงญ",  "Unit": "hPa", "Decimals": 1 },
    { "JsonKey": "pv_leistung", "Label": "โ˜€",  "Unit": "kW",  "Decimals": 2 }
  ]
}

LAN access (iPad / mobile)

The lan launch profile binds to all network interfaces:

# In Visual Studio: select profile "lan" next to the Run button
# Then open in browser on any device in the same network:
http://192.168.x.x:5162

UDP traffic logging

Set "LogUdpTraffic": true to write every packet to the log file:

[INF] [UDP-RX] 192.168.1.60:1799 {"src_type":"lora","type":"msg","src":"DH1FR-1",...}
[INF] [UDP-TX] 192.168.1.60:1799 {"type":"msg","dst":"DH1FR-1","msg":"Hello"}

Filter the log file:

Select-String "\[UDP-RX\]" C:\Temp\Logs\MeshcomWebDesk-*.log
Select-String "\[UDP-TX\]" C:\Temp\Logs\MeshcomWebDesk-*.log

EXTUDP Protocol

This client communicates with the MeshCom node using the EXTUDP JSON protocol defined in the MeshCom firmware.

Packet types

type Description Handled as
msg Chat message (direct, broadcast, group, ACK) Chat tab + monitor
pos Position beacon with GPS coordinates MH list + monitor
tele Telemetry (temperature, humidity, pressure, battery) MH list + monitor

๐Ÿ’ก WebDesk can also send a "type":"tele" telegram to the node to inject external sensor values (temp, humidity, pressure, temp 2, QNH, gas resistance, CO2) into its own position beacon, on firmware that supports it โ€“ see docs/ext_udp_telemetry_guide.md. WebDesk verifies via the node's own telemetry echo that the values were actually applied and disables the feature automatically if not (shown live in Settings โ†’ Telemetry).

Example packets

Direction Example
Registration {"type":"info","src":"NOCALL-2"}
Chat RX (direct) {"src_type":"lora","type":"msg","src":"NOCALL-1","dst":"NOCALL-2","msg":"Hello{034","msg_id":"5DFC7187","rssi":-95,"snr":12,"firmware":35,"fw_sub":"p"}
Chat RX (relayed) {"src_type":"lora","type":"msg","src":"OE1XAR-62,DL0VBK-12,DB0KH-11","dst":"*","msg":"...","rssi":-109,"snr":5}
Position RX {"src_type":"lora","type":"pos","src":"DB0MGN-1,...","lat":50.57,"lat_dir":"N","long":10.42,"long_dir":"E","alt":1243,"batt":100,"hw_id":42,"firmware":35,"fw_sub":"p","rssi":-108,"snr":5}
Telemetry RX {"src_type":"lora","type":"tele","src":"DB0MGN-1,...","batt":100,"temp1":20.6,"hum":0,"qnh":1031.4}
Chat TX {"type":"msg","dst":"NOCALL-1","msg":"Hello"}
ACK RX {"src_type":"udp","type":"msg","src":"NOCALL-1","dst":"NOCALL-2","msg":"NOCALL-2 :ack034","msg_id":"A177E139"}

ACK delivery tracking

  1. Outgoing message sent โ†’ โณ pending (waiting for node echo)
  2. Node echo arrives with sequence marker {034} โ†’ indicator changes to โœ“ (transmitted over LoRa)
  3. Recipient sends ACK :ack034 โ†’ message marked as delivered โœ“โœ“ (LoRa ACK)
  4. Group / broadcast messages: no ACK expected โ†’ โ˜๏ธ after node echo
  5. Gateway ACK received (src_type udp) โ†’ โ˜๏ธโœ“
  6. Both LoRa ACK and Gateway ACK received โ†’ โœ“โœ“ โ˜๏ธโœ“ (direct LoRa + Gateway confirmed)
  7. Node echo missing after 5 seconds โ†’ โš ๏ธ (UDP packet possibly not received by node)
Icon Meaning
โณ Sent โ€“ waiting for node echo
โœ“ Node echo received (on air)
โœ“โœ“ Delivered โ€“ LoRa ACK from recipient
โ˜๏ธ Sent via group/broadcast โ€“ no ACK expected
โ˜๏ธโœ“ Delivered โ€“ Gateway ACK only
โœ“โœ“ โ˜๏ธโœ“ Delivered โ€“ LoRa ACK and Gateway ACK
โš ๏ธ Node echo missing โ€“ UDP packet possibly not received by node

Hardware IDs (hw_id)

ID Short name Hardware
1โ€“3 TLORA-V1/V2 TTGO LoRa32
4โ€“6, 12 T-BEAM TTGO T-Beam
7 T-ECHO LilyGO T-Echo
8 T-DECK LilyGO T-Deck
9 RAK4631 Wisblock RAK4631
10โ€“11, 43 HELTEC-V1/V2/V3 Heltec WiFi LoRa 32
39 EBYTE-E22 Ebyte LoRa E22 (ESP32)
41 HELTEC-TRACK Heltec Wireless Tracker
42 HELTEC-STICK Heltec Wireless Stick v3
44 HELTEC-E290 Heltec E-Ink E290
45 T-BEAM-1262 TTGO T-Beam 1.2 SX1262
46 T-DECK-PLUS LilyGO T-Deck Plus
47 TBEAM-SUP TTGO T-Beam Supreme
48 EBYTE-E22-S3 Ebyte LoRa E22 (ESP32-S3)
49 T-LORA-PAGER LilyGO T-Lora Pager
50 T-DECK-PRO LilyGO T-Deck Pro
51 T-BEAM-1W LilyGO T-Beam 1W
52 HELTEC-V4 Heltec WiFi LoRa 32 v4
40 T5-EPAPER LilyGO T5 E-Paper
53 T-ETH-ELITE LilyGO T-ETH Elite S3
54 HELTEC-T114 Heltec T114
55 T3-S3-V1.3 LilyGO T3-S3 v1.3
56 T-CONNECT-PRO LilyGO T-Connect Pro
57 HELTEC-WPAPER Heltec Wireless Paper

Note: Altitude in position packets follows APRS convention (feet). The client converts to metres automatically.


Requirements

๐Ÿ’ก No build required: Ready-to-run binaries for Windows and Linux are available under Releases.

  • .NET 10 Runtime (ASP.NET Core Runtime, required to run the Windows binary)
  • .NET 10 SDK (only required for build from source)
  • A reachable MeshCom node running firmware v4.35+ with EXTUDP enabled
  • UDP port 1799 open (Windows Firewall / router)

โš ๏ธ Windows SmartScreen warning

When running the .exe for the first time, Windows may show "Windows protected your PC".
This happens because the binary is not code-signed.

To run it anyway:

  1. Click "More info" in the SmartScreen dialog
  2. Click "Run anyway"

Alternative: Right-click the .exe โ†’ Properties โ†’ check "Unblock" โ†’ OK


Build & Run

cd MeshcomWebDesk
dotnet run --launch-profile lan         # HTTP only, accessible from all LAN devices
# or
dotnet run --launch-profile lan-https   # HTTP :5162 + HTTPS :5163 (required for PWA on mobile)
# or
dotnet run                              # localhost only

Then open http://localhost:5162 (or http://<your-ip>:5162 for LAN access).

HTTPS for LAN (PWA on mobile)

# Step 1 โ€“ Generate self-signed certificate (once, run as admin)
cd C:\SRC\RA\MeshcomWebDesk
.\scripts\create-lan-cert.ps1          # auto-detects LAN IP
# or: .\scripts\create-lan-cert.ps1 -LanIp 192.168.1.100

# Step 2 โ€“ Start app with HTTPS
cd MeshcomWebDesk
dotnet run --launch-profile lan-https

Mobile trust: Copy certs/meshcom-lan.crt to your phone and install it as a trusted root CA. Then open https://<your-ip>:5163 in the browser and install the PWA.


๐Ÿ”’ HTTPS & Zertifikat โ€“ Schritt-fรผr-Schritt / Step by Step

๐Ÿ‡ฉ๐Ÿ‡ช Deutsch

Das selbstsignierte Zertifikat ermรถglicht verschlรผsselten HTTPS-Zugriff im Heimnetz. Ohne HTTPS lรคsst sich die App nicht als PWA auf Mobilgerรคten installieren.

1. Zertifikat erstellen (einmalig, Windows)

# PowerShell als Administrator รถffnen
cd C:\SRC\RA\MeshcomWebDesk

# IP automatisch erkennen:
.\scripts\create-lan-cert.ps1

# oder IP manuell angeben:
.\scripts\create-lan-cert.ps1 -LanIp 192.168.1.100

Das Skript erstellt:

  • certs/meshcom-lan.pfx โ€“ fรผr Kestrel (wird von der App verwendet)
  • certs/meshcom-lan.crt โ€“ fรผr Mobilgerรคte (dort installieren)
  • Trรคgt das Zertifikat in Windows CurrentUser\Root ein โ†’ kein Browser-Warning mehr auf dem PC

1b. Zertifikat erstellen (Linux / Docker-Server)

Voraussetzung: openssl installiert (sudo apt-get install -y openssl).

# Skript ausfรผhrbar machen (einmalig)
chmod +x scripts/create-lan-cert.sh

# IP automatisch erkennen:
./scripts/create-lan-cert.sh

# oder IP manuell angeben:
./scripts/create-lan-cert.sh 192.168.1.100

Das Skript erstellt:

  • MeshcomWebDesk/certs/meshcom-lan.pfx โ€“ fรผr Kestrel im Container
  • MeshcomWebDesk/certs/meshcom-lan.crt โ€“ fรผr Mobilgerรคte

2. App mit HTTPS starten

Windows (dotnet run):

cd MeshcomWebDesk
dotnet run --launch-profile lan-https

Linux / Docker Compose:

Zwei separate Compose-Dateien โ€“ HTTP lรคuft immer, HTTPS nur wenn Zertifikat vorhanden:

# HTTP only (Standard โ€“ immer funktionsfรคhig):
docker compose up -d --build

# HTTP + HTTPS (mit Zertifikat-Prรผfung):
./scripts/start-https.sh            # prรผft ob certs/meshcom-lan.pfx existiert

# oder manuell:
docker compose -f docker-compose.yml -f docker-compose.https.yml up -d --build

docker-compose.https.yml setzt ASPNETCORE_ENVIRONMENT=LanHttps und mountet ./certs:/app/certs:ro โ€“ wenn das Verzeichnis leer ist, startet der Container nicht. Das Skript scripts/start-https.sh prรผft das vorab und gibt eine klare Fehlermeldung.

Beide Ports laufen gleichzeitig:

HTTP  โ†’ http://192.168.x.x:5162   โ† wie bisher, bleibt aktiv
HTTPS โ†’ https://192.168.x.x:5163   โ† neu, fรผr PWA

3. Zertifikat auf Mobilgerรคten installieren

Die Datei certs/meshcom-lan.crt auf das Gerรคt รผbertragen (z.ย B. per E-Mail oder USB).

Gerรคt Pfad
iPad / iPhone (iOS) Einstellungen โ†’ Allgemein โ†’ VPN & Gerรคteverwaltung โ†’ Profil installieren โ†’ danach: Einstellungen โ†’ Allgemein โ†’ Info โ†’ Zertifikatsvertrauenseinstellungen โ†’ Zertifikat aktivieren
Android Einstellungen โ†’ Sicherheit โ†’ Verschlรผsselung & Anmeldedaten โ†’ Zertifikat installieren โ†’ CA-Zertifikat

4. Zertifikat auf Windows-PC installieren

Noetig wenn der Container auf einem Linux-Server laeuft und du von Windows darauf zugreifst.

Vorbereitung: meshcom-lan.crt vom Linux-Server kopieren (SCP / WinSCP / USB-Stick):

scp user@192.168.1.x:/opt/meshcom/certs/meshcom-lan.crt C:\Temp\meshcom-lan.crt

Variante A - Doppelklick (empfohlen):

  1. meshcom-lan.crt per Doppelklick oeffnen
  2. Klick auf Zertifikat installieren
  3. Speicherort: Lokaler Computer -> Weiter (Adminrechte erforderlich)
  4. Alle Zertifikate in folgendem Speicher speichern -> Durchsuchen
  5. Vertrauenswuerdige Stammzertifizierungsstellen -> OK -> Weiter -> Fertig stellen
  6. Sicherheitswarnung: Ja

Variante B - PowerShell als Administrator:

$cert  = New-Object Security.Cryptography.X509Certificates.X509Certificate2("C:\Temp\meshcom-lan.crt")
$store = New-Object Security.Cryptography.X509Certificates.X509Store("Root","LocalMachine")
$store.Open("ReadWrite"); $store.Add($cert); $store.Close()
Write-Host "Installiert: $($cert.Thumbprint)"

Danach Browser neu starten (Strg+Shift+Del empfohlen).

Firefox nutzt einen eigenen Zertifikatspeicher. Empfehlung: about:config -> security.enterprise_roots.enabled auf true setzen -> neu starten.

Ergebnis: https://192.168.x.x:5163 zeigt das Schloss-Symbol ohne Warnung.


๐Ÿ“ฑ PWA โ€“ Progressive Web App

Was ist eine PWA?

Eine Progressive Web App ist eine normale Webseite, die sich wie eine native App verhรคlt. Der Browser bietet an, sie auf dem Gerรคt zu installieren โ€“ ohne App Store, ohne Download.

Nach der Installation:

  • Eigenes Icon auf dem Home-Screen / Desktop
  • ร–ffnet sich ohne Adressleiste (wie eine native App)
  • Shortcut-Kacheln fรผr Chat und Karte im Startmenรผ (Windows/Android)

โš ๏ธ Offline-Betrieb ist nicht mรถglich โ€“ MeshCom WebDesk ist Blazor Server und benรถtigt immer eine Verbindung zum Server.

PWA installieren

๐Ÿ“ฑ iPhone / iPad (iOS Safari)

  1. https://192.168.x.x:5163 im Safari รถffnen
  2. Zertifikat muss vorab installiert sein (siehe oben)
  3. Teilen-Symbol โคต antippen โ†’ "Zum Home-Bildschirm"
  4. Namen bestรคtigen โ†’ Hinzufรผgen

๐Ÿค– Android (Chrome)

  1. https://192.168.x.x:5163 in Chrome รถffnen
  2. Zertifikat muss vorab installiert sein
  3. โ‹ฎ Menรผ โ†’ "App installieren" oder automatischer Banner am unteren Rand

๐Ÿ’ป Windows / Mac (Chrome oder Edge)

  1. https://192.168.x.x:5163 รถffnen (Zertifikat wird automatisch vertraut)
  2. In der Adressleiste rechts: โŠ• Installieren
  3. Oder: โ‹ฎ Menรผ โ†’ "MeshCom WebDesk installieren"

Die App bekommt ein eigenes Fenster ohne Browser-UI und erscheint im Startmenรผ / Taskbar.


๐Ÿณ Docker โ€“ Deployment on Linux

Official multi-architecture Docker images are published automatically on every release to the GitHub Container Registry:

Tag Description
ghcr.io/dh1fr/meshcomwebdesk:latest Latest stable release
ghcr.io/dh1fr/meshcomwebdesk:v1.12.2 Specific version

Supported platforms: linux/amd64 and linux/arm64 (Raspberry Pi 4 / 5).

All published images are listed at ghcr.io/dh1fr/meshcomwebdesk.


Prerequisites

# Install Docker + Docker Compose plugin (Debian / Ubuntu / Raspberry Pi OS)
sudo apt-get update
sudo apt-get install -y docker.io docker-compose-plugin

# Add current user to the docker group (no sudo needed)
sudo usermod -aG docker $USER
newgrp docker

Initial setup & start

Two options โ€“ choose one:

Option A โ€“ Pre-built image from GHCR (recommended, no build step)

# Clone repository (for docker-compose.yml and config)
git clone https://github.com/DH1FR/MeshcomWebDesk.git
cd MeshcomWebDesk

# Pull latest image
docker pull ghcr.io/dh1fr/meshcomwebdesk:latest

# Create optional config file (overrides embedded defaults)
cp deploy/appsettings.linux.json appsettings.json
nano appsettings.json          # set DeviceIp, MyCallsign, Groups etc.

# Start container
docker compose up -d

Option B โ€“ Build image locally from source

git clone https://github.com/DH1FR/MeshcomWebDesk.git
cd MeshcomWebDesk

cp deploy/appsettings.linux.json appsettings.json
nano appsettings.json

docker compose up -d --build

The container runs in the background and restarts automatically (restart: unless-stopped).
Web interface: http://<Linux-IP>:5162

Note: network_mode: host is required so the container can receive UDP packets from the MeshCom device.

Changing the configuration

Either edit appsettings.json (next to docker-compose.yml) or use environment variables in docker-compose.yml:

environment:
  - Meshcom__DeviceIp=192.168.1.60
  - Meshcom__MyCallsign=NOCALL-1
  - Meshcom__GroupFilterEnabled=true
  - Meshcom__Groups__0=#OE
  - Meshcom__Groups__1=#Test

Settings saved via the UI are written to DataPath/appsettings.override.json (inside the ./data volume).
The appsettings.json mount stays read-only (:ro) โ€“ no container rebuild needed after UI changes.

External bot command scripts are placed in ./bot-scripts/ on the host (mapped to /app/bot-scripts in the container).
The example script bot-command-example.py is included in the image under /app/bot-scripts/ and is available at startup.
To persist your own scripts across container rebuilds, copy them to the host ./bot-scripts/ directory before running docker compose up -d.

After any change to docker-compose.yml or appsettings.json:

docker compose up -d

๐Ÿ”„ Updating to a new version

Option A โ€“ Pre-built image from GHCR (recommended)

cd MeshcomWebDesk

# Pull new image and replace container (brief downtime)
docker compose pull
docker compose up -d

# Remove unused old image (optional)
docker image prune -f

Option B โ€“ Build from source

cd MeshcomWebDesk

# Fetch latest changes
git pull origin master

# Rebuild image and replace container (brief downtime)
docker compose up -d --build

# Remove unused old image (optional)
docker image prune -f

Useful Docker commands

# Check container status
docker compose ps

# Follow live logs (Ctrl+C to exit)
docker compose logs -f

# Stop container
docker compose stop

# Stop and remove container (config & logs are preserved)
docker compose down

# Stop, remove container and delete image (full reset)
docker compose down --rmi local

๐Ÿ’ป Direct installation (without Docker)

Docker is the recommended deployment method. If you prefer not to use Docker, download the binary directly โ€“ it is framework-dependent, meaning the .NET 10 Runtime must be installed on the target machine (no SDK needed).

๐Ÿ“ฆ Download: GitHub Releases


Windows

Prerequisites:

# Unzip to e.g. C:\meshcom
Expand-Archive MeshcomWebDesk-vX.Y.Z-win-x64.zip -DestinationPath C:\meshcom

# Edit configuration
notepad C:\meshcom\appsettings.json   # set DeviceIp, MyCallsign

# Start
cd C:\meshcom
.\MeshcomWebDesk.exe

Open browser: http://localhost:5162

To run automatically at Windows startup, register as a Windows service:

sc.exe create MeshcomWebDesk binPath="C:\meshcom\MeshcomWebDesk.exe" start=auto
sc.exe start MeshcomWebDesk

Linux (systemd)

Prerequisites:

# Install .NET 10 Runtime (Debian / Ubuntu / Raspberry Pi OS)
sudo apt-get update && sudo apt-get install -y aspnetcore-runtime-10.0

# Extract archive (creates a MeshcomWebDesk/ folder)
tar -xzf MeshcomWebDesk-vX.Y.Z-linux-x64.tar.gz
cd MeshcomWebDesk

# Edit configuration (MyCallsign, DeviceIp etc.)
nano appsettings.json

# Install as systemd service (starts automatically at boot)
sudo bash install.sh

Web interface: http://<Linux-IP>:5162

Useful commands after installation:

journalctl -u meshcom-webdesk -f     # live log
systemctl status meshcom-webdesk     # status
systemctl restart meshcom-webdesk    # restart after config change

macOS (Intel & Apple Silicon)

Prerequisites:

# Extract the archive (choose the right binary for your CPU;
# creates a MeshcomWebDesk/ folder)
# Apple Silicon (M1/M2/M3):
tar -xzf MeshcomWebDesk-vX.Y.Z-osx-arm64.tar.gz -C ~

# Intel Mac:
tar -xzf MeshcomWebDesk-vX.Y.Z-osx-x64.tar.gz -C ~

cd ~/MeshcomWebDesk

# Edit configuration
nano appsettings.json      # set DeviceIp, MyCallsign

# Allow execution (macOS Gatekeeper)
xattr -d com.apple.quarantine MeshcomWebDesk

# Start
./MeshcomWebDesk

Open browser: http://localhost:5162

macOS Gatekeeper: If you see "cannot be opened because it is from an unidentified developer",
run xattr -d com.apple.quarantine ./MeshcomWebDesk once before starting.


Linux (systemd)

The shipped appsettings.json contains placeholder values โ€“ the following must be set before first start:

Key Description Example
MyCallsign Your own callsign NOCALL-1
DeviceIp IP address of the MeshCom node 192.168.1.60
LogPath Directory for log files ./logs / /var/log/meshcom
DataPath Directory for persistent state ./data / /opt/meshcom/data

โš–๏ธ Legal

Copyright

ยฉ 2025โ€“2026 Ralf Altenbrand (DH1FR) ยท All rights reserved.

Usage

This software is made available for licensed radio amateurs for private, non-commercial use.
Commercial use is not permitted without explicit written consent from the author.

Disclaimer

Use at your own risk.
The author accepts no liability for damages of any kind โ€“ including but not limited to damage to hardware, network infrastructure, radio equipment or data loss โ€“ caused by the use of this software.
The software is provided without any warranty.

License

See LICENSE


๐Ÿ”’ Privacy / Datenschutz

๐Ÿ‡ฉ๐Ÿ‡ช Deutsch | ๐Ÿ‡ฌ๐Ÿ‡ง English below

๐Ÿ‡ฉ๐Ÿ‡ช Datenschutzhinweis

MeshCom WebDesk verarbeitet Funkamateure-Daten โ€“ Rufzeichen und Nachrichtentexte, die รผber das MeshCom-Netz รผbertragen werden.
Diese Daten sind per se รถffentlich (LoRa-Funk ist fรผr jeden empfangbar), kรถnnen aber personenbezogen im Sinne der DSGVO sein.

Was gespeichert werden kann

Funktion Gespeicherte Daten Wo
Log-Datei (LogUdpTraffic: true) Rufzeichen, Nachrichtentexte, GPS-Koordinaten, RSSI/SNR โ€“ als Rohdaten jedes UDP-Pakets LogPath auf dem Server
Datenbank (Database.Provider != "none") Alle Monitor-Eintrรคge: Rufzeichen, Nachrichtentexte, Zeitstempel, GPS, RSSI, Batterie, Firmware Externer Datenbankserver
DB-Insert-Log (LogInserts: true) Vollstรคndige SQL-INSERT-Anweisungen mit allen Feldinhalten LogPath auf dem Server
Persistenz (DataPath) Chat-Verlauf, MH-Liste, Monitor-History, eigene GPS-Position DataPath auf dem Server

Empfehlungen

  • UDP-Traffic-Log (LogUdpTraffic) nur aktivieren, wenn zur Fehlersuche nรถtig; danach wieder deaktivieren.
  • DB-Insert-Log (LogInserts) nur kurzfristig zur Fehlersuche aktivieren; enthรคlt vollstรคndige Nachrichtentexte und Rufzeichen.
  • Die Datenbankanbindung ist fรผr den Betrieb im eigenen, abgesicherten Netz vorgesehen. Externe Datenbankserver sollten verschlรผsselte Verbindungen verwenden (SslMode=Required im Connection String).
  • Log-Aufbewahrung (LogRetainDays) auf den minimal notwendigen Zeitraum setzen.
  • Der Betrieb dieser Software unterliegt den fรผr Funkamateure geltenden datenschutzrechtlichen Regelungen (DSGVO, BDSG, ggf. nationale Amateurfunkgesetze). Der Betreiber ist selbst verantwortlich fรผr die rechtskonforme Nutzung.

๐Ÿ‡ฌ๐Ÿ‡ง Privacy Notice

MeshCom WebDesk processes amateur radio data โ€“ callsigns and message texts transmitted over the MeshCom mesh network.
This data is inherently public (LoRa radio is receivable by anyone), but may constitute personal data under GDPR.

What can be stored

Feature Data stored Location
Log file (LogUdpTraffic: true) Callsigns, message texts, GPS coordinates, RSSI/SNR โ€“ raw content of every UDP packet LogPath on the server
Database (Database.Provider != "none") All monitor entries: callsigns, message texts, timestamps, GPS, RSSI, battery, firmware External database server
DB insert log (LogInserts: true) Full SQL INSERT statements with all field values LogPath on the server
Persistence (DataPath) Chat history, MH list, monitor history, own GPS position DataPath on the server

Recommendations

  • Enable UDP traffic logging (LogUdpTraffic) only for troubleshooting; disable it afterwards.
  • Enable DB insert logging (LogInserts) only briefly for debugging; it contains full message texts and callsigns.
  • The database sink is intended for use within your own secured network. External database servers should use encrypted connections (SslMode=Required in the connection string).
  • Set log retention (LogRetainDays) to the minimum period necessary.
  • Operation of this software is subject to the data protection regulations applicable to amateur radio operators (GDPR, national regulations). The operator is solely responsible for lawful use.

ยฉ by Ralf Altenbrand (DH1FR) 2025โ€“2026


๐Ÿ“‹ Changelog

v1.13.0 (2026-06-26)

  • feat: ๐Ÿค– External bot commands โ€“ delegate bot command execution to external processes (.exe, .ps1, .bat, .cmd, .py); JSON payload on stdin, reply text on stdout; configurable timeout; license required
  • feat: ๐Ÿ“… External calendar beacon processes โ€“ calendar beacons can generate text via external process; full event context passed as JSON; license required
  • feat: ๐Ÿ—ฃ๏ธ Multilingual voice announcements โ€“ French, Italian, Spanish added alongside German and English
  • feat: ๐Ÿ“‹ MH list persistent column sorting โ€“ sort state remembered across reloads and sessions
  • fix: ๐Ÿ”„ Linux settings reload โ€“ IConfiguration force-reloaded after save to fix race condition
  • fix: ๐Ÿ“ก MQTT group destination โ€“ leading # stripped to prevent malformed topic paths

v1.12.4 (2026-06-14)

  • feat: โš™๏ธ Settings: path writability check โ€“ DataPath and LogPath probed on page load and after save; amber warnings shown above Save button on failure
  • feat: โš™๏ธ Settings: inline path syntax validation โ€“ invalid paths flagged in red below the input; Save button disabled until corrected; resolved absolute path shown below each field
  • feat: ๐Ÿ–ฅ๏ธ Console Command Helper: --setcont toggle โ€“ added to Debug group
  • feat: ๐ŸŒ --gateway: srv OE / srv DL โ€“ OE and DL gateway server options added
  • fix: ๐ŸŒค๏ธ --weather with Weather API disabled โ€“ full telemetry string returned correctly
  • fix: ๐Ÿ–ฅ๏ธ MH / Help popup โ€“ data visible when telnet line ring-buffer is at 500-cap or wraps around
  • fix: ๐Ÿ”„ Message deduplication โ€“ 30-minute window, cross-format detection, dedup keys global across all configured nodes
  • fix: ๐Ÿค– Bot commands โ€“ --ping and --version available without BotEnabled (v1.12.3 behaviour restored); --help available with bot disabled
  • fix: ๐Ÿ–ฅ๏ธ Console Command Helper โ€“ state reset correctly on node disconnect
  • fix: ๐Ÿ’ฌ CallsignPopup โ€“ name fields reset when callsign changes

v1.12.3 (2026-06-07)

  • feat: ๐Ÿ” AI Search: smarter token management โ€“ messages trimmed by token estimate to avoid rate-limit errors; warning shown when older messages are excluded; "Search in previous period" button to continue the search further back
  • feat: ๐Ÿ” AI Search: noise filter โ€“ bot commands and JSON system messages excluded from AI search and summary context
  • feat: ๐Ÿ“… DatePicker component โ€“ reusable date picker used in AI search date fields
  • feat: ๐Ÿ–ฅ๏ธ Console Command Helper: MH list & help popup โ€“ quick access to MH list and help directly from the console view
  • feat: ๐Ÿ”ง New hardware IDs 54โ€“57 โ€“ HELTEC-T114, T3-S3-V1.3, T-CONNECT-PRO, HELTEC-WPAPER
  • fix: ๐Ÿ”Œ NET Console โ€“ renamed from TLS Console; TLS option removed from settings
  • fix: โšก Echo-timeout warning โ€“ cleared correctly when relay echo arrives from sibling node
  • fix: ๐Ÿ–ฅ๏ธ Telnet line buffer wrap โ€“ console lines processed correctly when the line buffer wraps around

v1.12.2

  • feat: ๐Ÿ” QRZ first name always visible โ€“ displayed directly next to the callsign without hover
  • feat: ๐Ÿค– Bot --ping / --version when bot disabled โ€“ commands accepted even when the bot is turned off
  • feat: ๐Ÿ” Console Command Helper: password fields masked โ€“ --passwd and --setpwd rendered as type=password; values hidden in badges and toasts
  • feat: ๐Ÿ”‹ Console Command Helper: battery voltage & capacity โ€“ parsing of V and % with a visual progress bar
  • feat: ๐Ÿ“… Telemetry send times โ€“ limit raised to 24, * wildcard for all hours, duplicate/validation hints
  • fix: ๐Ÿค– Bot / auto-reply: min. 500 ms delay โ€“ prevents node UDP crash on fast replies
  • fix: ๐Ÿ’ฌ Send button disabled at packet limit โ€“ locked when message exceeds firmware JSON packet size
  • fix: ๐Ÿ’ฌ Emoji packet size โ€“ multi-byte emojis correctly counted in size calculation
  • fix: ๐Ÿ”ง Multi-node: new nodes register without restart โ€“ newly configured nodes become active immediately
  • fix: ๐Ÿ”ง Device / listen port fields read-only โ€“ with explanatory hint in Connection and Additional Nodes settings
  • fix: ๐Ÿ’ฌ Enter key sends message โ€“ line breaks require Shift+Enter
  • fix: ๐Ÿค– AI search all-contacts mode: 4ร— message limit โ€“ older results no longer cut off
  • fix: ๐Ÿ–ฅ๏ธ VersionCommand: LI prefix removed โ€“ formatting artefact stripped from version string output
  • fix: ๐Ÿ“ฑ Mobile: licence badge and map search field โ€“ improved layout on small screens

v1.12.1

  • feat: ๐Ÿ”„ Automatic update check every 24 hours โ€“ update banner appears as soon as a new version is published on GitHub
  • feat: ๐Ÿณ Docker image on GitHub Container Registry โ€“ official multi-arch images (linux/amd64, linux/arm64) published on every release
  • feat: ๐Ÿ”– --version shows licence status โ€“ licence callsign appended to version output
  • fix: ๐Ÿ” Licence badge race condition โ€“ OnLicenseChanged event triggers re-render at the correct moment
  • fix: ๐Ÿค– AI: auto sent as model name โ€“ literal auto no longer forwarded to the OpenAI API

v1.12.0

  • feat: ๐Ÿ“… Calendar Beacon โ€“ scheduled event announcements sent automatically to a configured group before and/or at the event time
  • feat: ๐Ÿ–ฅ๏ธ Console Command Helper โ€“ graphical assistant for reading and setting MeshCom node parameters without typing raw console commands
  • fix: ๐Ÿ”ง Optimisations & Bug Fixes โ€“ various improvements to stability and performance

v1.11.0

  • feat: ๐ŸŒค๏ธ Weather API โ€“ Live weather data from external providers usable as telemetry fields
    • AWEKAS (https://api.awekas.at/current.php?key=...) and Weather Underground supported
    • Simulation provider: offline test mode without API key (file-based or random values)
    • Bot command --weather: shows provider, latest measurement and timestamp
    • Settings: dedicated section with provider selection, API key/station ID and poll interval
  • feat: ๐Ÿ’ฌ New messages divider โ€“ visible divider line "New messages" in the chat tab when new messages arrive since last read (DE/EN)
  • feat: โ˜• Buy Me a Coffee โ€“ added as donation option alongside PayPal in About and welcome dialog
  • feat: ๐Ÿ–ฅ๏ธ Serial Console โ€“ console page supports TLS connection or direct USB serial access (115200 baud); switchable in settings
  • feat: โ™ป๏ธ OTA update via console โ€“ command --ota-update with 5-second countdown dialog
  • feat: ๐Ÿ”„ Reboot via console โ€“ command --reboot with confirmation dialog
  • fix: ๐ŸŒค๏ธ AWEKAS API key URL encoding โ€“ AWEKAS displays the key URL-encoded in the portal; now automatically decoded before the API call
  • fix: ๐ŸŒค๏ธ Weather API โ€“ settings persistence โ€“ WeatherApi block was missing from serialization; settings were not saved
  • fix: ๐ŸŒค๏ธ Weather API โ€“ API key decryption โ€“ key was encrypted on save but not decrypted on load; DecryptMeshcomSettingsPostConfigure corrected
  • fix: ๐Ÿ” Double encryption prevented โ€“ aes:/dp: prefix is detected; already encrypted values are not encrypted again
  • fix: ๐Ÿ” API key field empty on load โ€“ password/key fields are never pre-filled; saving with an empty field preserves the existing encrypted value
  • fix: ๐Ÿ”ง Build no longer overwrites runtime data โ€“ data/** is no longer copied to bin/Debug during build
  • fix: ๐Ÿ”Š Speaker icon โ€“ state preserved after chat page reload

v1.10.3

  • fix: ๐Ÿ› Chat crash on tab click โ€“ ArgumentNullException when opening the Chat page fixed; caused by a tab with Key = null created from an incoming UDP packet without a From field; from v1.10.2 onwards this tab was permanently persisted via server-side tab persistence
  • fix: ๐Ÿ› Null-Key tab prevented โ€“ message.From and message.To are now validated in AddIncomingMessage; malformed packets are routed harmlessly to the * (All) tab instead of creating an invalid tab
  • fix: ๐Ÿ› Snapshot restore skips invalid tabs โ€“ tabs with an empty or null key are skipped when restoring saved tab state; prevents a once-persisted broken tab from triggering the crash on every app start
  • fix: ๐Ÿ› ArgumentNullException in _lastNotificationTime โ€“ Dictionary<Guid?, DateTime> does not accept a null key; when _activeNodeId is still null on first load (no node connected) the lookup crashed; dictionary changed to Dictionary<Guid, DateTime>, null is replaced by Guid.Empty

v1.10.2 (released)

  • feat: ๐Ÿ”” Ping confirmation dialog โ€“ a browser confirmation is shown when sending ping or --ping to a group or broadcast tab, preventing accidental transmissions
  • feat: โœ“โœ“ Combined ACK display โ€“ the ACK indicator now shows LoRa and Gateway delivery combined (โœ“โœ“ โ˜๏ธโœ“); users can see whether their message arrived via LoRa, the gateway, or both
  • feat: ๐Ÿ–ฅ๏ธ NET Console (renamed from HMAC Console) โ€“ new HMAC-TCP console mode; renamed consistently throughout the UI and settings
  • feat: ๐Ÿ“ Per-node console log โ€“ console output can optionally be saved to a daily rolling log file per node; old files are deleted automatically after the configured retention period
  • feat: ๐Ÿค– Configurable bot/auto-reply delay โ€“ reply delay configurable from 0 to 30 seconds (default: 3 s)
  • feat: ๐Ÿ“ก Beacon interval restriction removed โ€“ the 8-hour minimum has been removed; freely configurable from 1 hour; hint text reminds users to choose intervals responsibly
  • feat: ๐Ÿ’ฌ Server-side tab order persistence โ€“ chat tab order is stored server-side and survives page reloads
  • feat: โš ๏ธ Node-Echo Timeout Monitoring โ€“ detects whether an outgoing UDP message was actually received by the node; outgoing messages show โš ๏ธ with tooltip when the node echo is missing after 5 seconds; not shown for group/broadcast messages (no echo expected)
  • feat: ๐Ÿ’ฌ Tab message limit (TabMaxMessages)
  • feat: ๐ŸŒ French TTS support โ€“ French (fr-FR) added to the browser TTS locale map
  • feat: ๐ŸŒ Full i18n coverage โ€“ all new UI texts fully translated into DE / EN / IT / ES / FR
  • fix: โœ“ ACK not shown in tab โ€“ ACK packets were incorrectly blocked by the src_type=node relay filter; now correctly exempt
  • fix: โœ“ Cross-node ACK matching โ€“ ACK checkmark now searches all node states so multi-node setups mark messages as delivered correctly
  • fix: ๐Ÿ’ฌ Relay echo deduplication โ€“ relay echoes from foreign callsigns are skipped to prevent deduplication collisions
  • fix: ๐Ÿ”Š Notification sound on node switch โ€“ sound and TTS are now scoped per node; no tone plays on node switch without new messages
  • fix: ๐Ÿค– Bot/auto-reply node routing โ€“ bot and auto-reply messages always use the own primary hardware node
  • fix: ๐Ÿ’ฌ Outgoing message callsign (multi-node) โ€“ outgoing messages show the correct msg.From per node
  • fix: ๐Ÿ–ฅ๏ธ Console connected IP โ€“ console header now shows the actually connected IP (ConnectedHost)
  • fix: โš™๏ธ Gateway Source not saved โ€“ GatewayServer setting was reset to default on every restart; now correctly persisted
  • fix: ๐Ÿณ Docker build failure โ€“ broken dictionary entries in IT/ES/FR translation files fixed

v1.10.1

  • feat: ๐Ÿค– AI Search: Default date range โ€“ date range pre-filled to the last 90 days when opening the global AI search
  • feat: ๐Ÿค– AI Search: Echo deduplication โ€“ group messages deduplicated before prompt construction; reduces token usage and improves answer quality
  • feat: ๐Ÿค– AI Search: Automatic model selection โ€“ new auto option picks between gpt-4o-mini, gpt-4.1-mini and gpt-4.1 depending on prompt size
  • feat: ๐Ÿค– AI Search: Expanded message scope โ€“ global search now includes all direct messages, own group messages and @-mentions; raw JSON status packets and ACKs are filtered out
  • fix: ๐Ÿค– AI Search: Timestamp fix โ€“ timestamps from MySQL now correctly treated as local time (DateTimeKind.Local); no more UTC shift in AI answers and QSO history
  • fix: ๐Ÿ“Š Telemetry mapping limit โ€“ the entry limit of 3 was incorrectly applied to the measurement mapping instead of the send-time schedule; mapping entries are now unlimited (send times: max. 6)
  • fix: ๐Ÿท๏ธ Group Labels growing โ€“ the group labels list was duplicated on every app start; now starts empty with buttons to restore defaults, add missing entries or clear the list

v1.10.0

  • feat: ๐ŸŒ Multi-language UI โ€“ interface now available in Franรงais ๐Ÿ‡ซ๐Ÿ‡ท, Italiano ๐Ÿ‡ฎ๐Ÿ‡น and Espaรฑol ๐Ÿ‡ช๐Ÿ‡ธ in addition to Deutsch and English; language is switched in Settings โ†’ Language and takes effect instantly without a page reload
  • feat: ๐Ÿ–ง Multi-Node support โ€“ configure multiple MeshCom nodes simultaneously; each node has its own UDP connection, callsign, chat tabs, monitor feed, and console credentials; node profiles are managed under Settings โ†’ Further Nodes
  • feat: ๐Ÿ–ฅ๏ธ TLS Console / Serial Console โ€“ console page now supports direct USB serial access (CP210x); COM port and baud rate configurable in Settings โ†’ ๐Ÿ–ฅ๏ธ Console โ†’ Serial Console; console mode switchable between TLS and Serial without restart; TLS Console requires MeshCom firmware v4.35p.05.13 or later
  • feat: ๐Ÿ”„ OTA-Update via console โ€“ button sends --ota-update to the node; 5-second countdown dialog; OTA page opens automatically in a new tab
  • feat: ๐Ÿ” Reboot via console โ€“ --reboot command shows a confirmation dialog; connection is closed after a short delay
  • feat: ๐Ÿ“ก Beacon interval minimum 8 h โ€“ the beacon interval can no longer be set below 8 hours; existing values < 8 h are automatically corrected to 8 h on load
  • feat: ๐Ÿ“Š Telemetry mapping limit โ€“ maximum of 3 telemetry mapping entries; the add button is disabled when the limit is reached
  • fix: ๐Ÿ”Š Speaker icon persists โ€“ the speaker icon in the status bar now persists across chat page reloads

v1.9.5

  • feat: ๐Ÿ’ฌ MsgId im Monitor โ€“ eingehende Nachrichten zeigen die Nachrichten-ID (msg_id) im Monitor an; erleichtert Diagnose und ACK-Zuordnung
  • feat: ๐ŸŸก Toast-Bezeichnung โ€“ Toast-Anzeige fรผr Watchlist- und CQ-Treffer zeigt jetzt โ€žempfangen" statt โ€žgehรถrt"
  • feat: โ†”๏ธ Eigene Nachrichten linksbรผndig โ€“ neue Option OwnMessagesAlignLeft in den Einstellungen; eigene gesendete Nachrichten kรถnnen optional linksbรผndig dargestellt werden (Standard: rechtsbรผndig)
  • feat: ๐Ÿ”Š Watchlist-TTS Drosselung โ€“ Sprachansagen fรผr Watchlist-Treffer werden pro Rufzeichen maximal einmal alle 5 Minuten ausgelรถst
  • fix: ๐Ÿ•” {last-qso} zeigt vorheriges QSO โ€“ Variable liefert jetzt den Zeitpunkt des vorherigen direkten QSOs (aktuelles Paket wird ausgeschlossen); kein vorheriges QSO โ†’ โ€žkein QSO"
  • fix: ๐Ÿค– Bot: ---=== nicht mehr als Befehl erkannt โ€“ Dekorations-Strings wie ---=== (WebDesk-Ident-Auto-Reply) werden nicht mehr als Bot-Befehl interpretiert
  • fix: ๐Ÿ’ฌ Direkt-Tab ohne Voice sofort sichtbar โ€“ neu angelegte Direkt-Tabs erscheinen jetzt auch dann sofort in der UI wenn Sprachansagen deaktiviert sind
  • fix: ๐Ÿ” QRZ Race Condition โ€“ In-Flight-Deduplizierung fรผr QRZ-Abfragen verhindert parallele Mehrfach-Requests fรผr dasselbe Rufzeichen

v1.9.4

  • feat: ๐Ÿ“ป Station / HF-Parameter โ€“ neue Einstellungssektion mit TX-Leistung (dBm), Kabeltyp (15 vordefinierte 50-ฮฉ-Typen), Kabeldรคmpfung (manuell eingebbar), Antennengewinn (dBi), Antennentyp (Freitext), Antennengehรถhe (m) und Frequenz (MHz); EIRP und theoretische Freiraumreichweite werden live berechnet und angezeigt
  • feat: ๐Ÿ—บ๏ธ FSPL-Reichweiten-Kreis auf der Karte โ€“ beim Aktivieren der Reichweitenanzeige wird neben der Convex-Hull-Wolke ein gelber Kreis mit der theoretischen Freiraumreichweite (EIRP + Frequenz + Systemreserve) eingeblendet; Legende unterscheidet โ€žGemessen (Convex Hull)โ€œ und โ€žFSPL-Reichweite (theor.)โ€œ
  • feat: ๐Ÿ“ก Stationsvariablen โ€“ {my-tx-power}, {my-eirp}, {my-antenna}, {my-antenna-type}, {my-antenna-height}, {my-freq} stehen in Auto-Reply, Bot-Befehlen, Bake-Text und Quick Texts als Platzhalter zur Verfรผgung
  • feat: ๐Ÿ•” Neue Variable {last-qso} โ€“ Zeitstempel des letzten direkten QSOs mit dem aktuellen Rufzeichen (Format dd.MM.yyyy HH:mm); DB-first + In-Memory-Fallback; verfรผgbar in Auto-Reply, Bot-Befehlen, Beacon und Quick Texts
  • feat: ๐Ÿ“‹ Nachricht in Zwischenablage kopieren โ€“ beim Hovern รผber eine Nachricht im Direkt-Tab erscheint ein ๐Ÿ“‹-Button zum Kopieren des Nachrichtentexts (JS Clipboard API)
  • feat: ๐Ÿ“ข CQ-Erkennung โ€“ eingehende Gruppen-Nachrichten werden automatisch auf CQ-Rufe geprรผft (case-insensitiver Regex, kein False-Positive bei Wรถrtern wie โ€žFREQUENCYโ€œ); eigenes Rufzeichen wird unterdrรผckt; nur Gruppen aus dem aktiven Gruppenfilter
  • feat: ๐Ÿ“ข CQ-Toast โ€“ Toast-Anzeige (gelb) mit Rufzeichen, Gruppe und Alter; automatisches Verschwinden nach 60 Sekunden; Watchlist- und CQ-Toast werden vertikal gestapelt, sodass beide gleichzeitig sichtbar sind
  • feat: ๐Ÿ“ข CQ-Beep โ€“ Morse-Muster CQ CQ in CW-Stil (700 Hz, 80 ms Einheit, korrektes dit/dah/Wortpausen-Timing); nur wenn Ton aktiv
  • feat: ๐Ÿ“ข CQ-TTS-Ansage โ€“ z.โ€ฏB. โ€žC Q C Q von Delta Hotel Eins Foxtrot Romeo in Gruppe 2 6 2โ€œ; nur wenn Sprachansagen aktiv; folgt der App-Sprache (DE/EN)
  • fix: ๐Ÿค– OpenAI Guthaben-Link โ€“ migriert von veralteten Dashboard-Endpunkten auf /v1/organization/costs; zusรคtzlicher Link zu https://platform.openai.com/usage ergรคnzt
  • fix: ๐Ÿ“ข CQ-Beep Timing โ€“ korrektes Morse-Timing (Inter-Element 1u, Inter-Zeichen 3u, Wortpause 7u) ohne doppelte Lรผcken

v1.9.3

  • feat: ๐Ÿ”ง Variable {telemetry} โ€“ Telemetrie-String aus der JSON-Datei steht รผberall als {telemetry}-Platzhalter zur Verfรผgung (Auto-Reply, Bot, Bake-Text, Quick Texts, Nachrichteneingabe); JSON wird bei jedem Abruf neu eingelesen; dokumentiert in der Variablen-Referenztabelle in den Einstellungen und im README
  • feat: ๐Ÿ—บ๏ธ Locator-Format korrigiert โ€“ Maidenhead-Locator wird jetzt รผberall korrekt dargestellt (letzte zwei Buchstaben kleingeschrieben, z. B. JO40nu statt JO40NU); zentral in GeoHelper.ToMaidenhead() geรคndert
  • feat: @-Mention-Button โ€“ neben jedem fremden Rufzeichen in der Nachrichtenliste (Gruppen/Alle) und im Monitor erscheint beim Hover ein kleiner @-Button; Klick fรผgt @RUFZEICHEN an der aktuellen Cursorposition im Nachrichteneingabefeld ein, ohne den bestehenden Chat-Tab-Klick zu beeinflussen
  • feat: ๐Ÿ” Globaler Such-Button in der Tab-Leiste โ€“ neuer ๐Ÿ”-Button neben ๐Ÿ“‹ รถffnet den QSO-Dialog im globalen Modus: Text-Suche und KI-Suche durchsuchen alle Direkt-QSOs gleichzeitig; Checkbox โ€žAlle Direkt-QSOs durchsuchen" ist automatisch aktiviert und gesperrt; Tabs KI-Zusammenfassung und Verlauf sind im globalen Modus ausgeblendet
  • feat: ๐Ÿ” KI-Suche รผber alle Direkt-QSOs โ€“ in der KI-Suche des QSO-Dialogs ist optional das Durchsuchen aller 1:1-QSOs mรถglich (Checkbox โ€žAlle Direkt-QSOs durchsuchen"); Gruppen- und Broadcast-Nachrichten werden dabei ausgeschlossen
  • feat: โš™๏ธ Node-Firmware & Hardware in Statusleiste โ€“ Firmware-Version und Hardware-Name des eigenen Nodes werden automatisch aus eingehenden src_type:"node"-Paketen gelesen und in der Statusleiste angezeigt (โš™๏ธ 4.35 ยท T-BEAM); Wert erscheint sobald das erste Node-Paket empfangen wird
  • feat: ๐Ÿ”ง Neue Variablen {node-firmware} und {node-hw} โ€“ Firmware-Version und Hardware-Name des eigenen Nodes stehen in Auto-Reply, Bot-Befehlen, Bake-Text und Quick Texts als Platzhalter zur Verfรผgung; ergรคnzt in der Variablen-Referenztabelle in den Einstellungen
  • feat: ๐Ÿ’ฌ Sequenznummer im Monitor โ€“ sobald der Node die Sequenznummer per Echo zurรผckmeldet, wird sie nachtrรคglich neben der gesendeten Nachricht im Monitor angezeigt ({411}); erleichtert die Zuordnung von ACK zu TX
  • fix: ๐Ÿ’ฌ ACK-Zuordnung โ€“ Fallback auf 10 Minuten begrenzt โ€“ der Fallback-Match (รคlteste unbestรคtigte Nachricht an Sender) wurde auf Nachrichten der letzten 10 Minuten beschrรคnkt; verhindert dass beim Neustart geladene alte Nachrichten fรคlschlicherweise neue ACKs konsumieren
  • fix: ๐Ÿ’ฌ AssignOutgoingSequence โ€“ SequenceNumber == "TX" wird berรผcksichtigt โ€“ beim Senden wird sofort "TX" als Sequenznummer gesetzt; die Suche nach dem passenden Echo-Paket schlug dadurch fehl (suchte nur null); beide Werte werden jetzt abgeglichen
  • fix: ๐Ÿ“ฑ iPad โ€“ Statusleiste nutzt volle Breite โ€“ width:100%; box-sizing:border-box verhindert dass Safari/iPad die Statusleiste schmaler als den Container rendert; 8px Toleranzpuffer im JS-Overflow-Check verhindert vorzeitiges Ausblenden von Elementen
  • fix: ๐Ÿ”Š iOS/iPad โ€“ Beep-Tรถne โ€“ AudioContext-Entsperrung auf touchstart (statt nur click) umgestellt; Kontext wird beim ersten Touch sofort erzeugt und entsperrt
  • fix: ๐Ÿ”Š iOS/iPad โ€“ Sprachausgabe โ€“ speechSynthesis aus Hintergrund-Callbacks ist auf iOS durch Apple blockiert; TTS wird auf iOS/iPadOS รผbersprungen; Beep-Tรถne werden als Benachrichtigung verwendet

v1.9.2

  • feat: ๐Ÿ—บ๏ธ MH-Liste โ€“ Automatisches Lรถschen alter Eintrรคge โ€“ neue Einstellung โ€žMH-Liste: Max. Alter (Stunden)โ€œ; Eintrรคge รคlter als die konfigurierte Anzahl Stunden werden automatisch gelรถscht; bestehende Werte (Tage) werden in Stunden migriert
  • perf: โš™๏ธ Einstellungen โ€“ Lazy Rendering โ€“ Section-Inhalte werden erst beim ร–ffnen gerendert; deutlich schnelleres Laden der Einstellungsseite
  • perf: ๐Ÿ“ป MH-Liste & Karte โ€“ neues OnMhChange-Event; nur noch MH-relevante Updates; Karte 400 ms Debounce; QRZ-Abfragen nur fรผr neue Rufzeichen
  • feat: ๐Ÿ“Š Statusleiste responsive โ€“ passt sich dynamisch der verfรผgbaren Breite an; Elemente werden stufenweise ausgeblendet wenn der Platz nicht ausreicht (ResizeObserver + MutationObserver)
  • fix: โš™๏ธ MH Max. Alter โ€“ Persistenz โ€“ MhMaxAgeHours wurde nach Seitenwechsel auf 0 zurรผckgesetzt; Fehler in SettingsService behoben
  • fix: ๐Ÿ—บ๏ธ Karte โ€“ Reichweiten-Wolke โ€“ Convex Hull wurde nach MH-Update oder MH-Purge nicht neu berechnet; UpdateMarkersAsync() ruft jetzt setCoverage automatisch neu auf wenn die Anzeige aktiv ist

v1.9.1

  • feat: Bug fixes and optimizations.

v1.9.0

  • feat: ๐Ÿ”Ž QSO dialog โ€“ History & Search without AI โ€“ the ๐Ÿ”Ž icon on direct-chat tabs is now always shown when MySQL is active (not only when an AI summary exists); the modal opens a four-tab dialog: KI-Zusammenfassung, Verlauf, Suche, KI-Suche; History and Text Search work with MySQL only (no AI API key required); AI tabs are disabled and greyed out when AI is not configured
  • feat: ๐Ÿค– KI-Zusammenfassung / KI-Suche locked when AI inactive โ€“ Summary and AI Search tabs are disabled with tooltip hint when Ai.Enabled = false or no API key is set; guard added in SwitchModalTab and template to prevent bypassing; reopens on the History tab when AI is off
  • feat: ๐Ÿ“‹ Recent QSO partners โ€“ ๐Ÿ“‹ button next to the + tab button opens a flyout with the most recently contacted callsigns; populated from MySQL; clicking a row opens the chat tab directly
  • feat: โœ๏ธ Browser spell-check โ€“ message input field has spellcheck="true"; browser underlines misspelled words when spell-check is enabled in browser settings
  • feat: ๐Ÿ“ค Import / Export โ€“ Bot Commands, Group Labels, Quick Texts โ€“ each section in Settings has ๐Ÿ“ค Export (browser download as .json) and ๐Ÿ“ฅ Import (replaces existing entries, with full error handling); filenames are editable before export; files can be shared between users
  • feat: ๐Ÿ” Backup & Restore โ€“ full encrypted backup of all settings (including passwords and API keys) as MeshComWebDesk-settings.enc; AES-256-CBC + PBKDF2/SHA-256/100k iterations; wrong password and corrupted files produce clear error messages; page reloads automatically after successful restore; filename editable before export
  • fix: โš™๏ธ Settings โ€“ โ€žEinstellungen gespeichert" moved โ€“ success message now appears directly above the Save button instead of at the top of the page; full width display corrected
  • fix: ๐Ÿค– IsAiActive reads live settings โ€“ IOptions<MeshcomSettings> replaced with IOptionsMonitor in Chat.razor; IsAiActive always reads CurrentValue so re-enabling AI in Settings is reflected immediately without page reload
  • fix: ๐Ÿ’พ QsoSummaryService โ€“ History/Search without AI โ€“ GetHistoryAsync and TextSearchAsync now use a new IsDbOnlyAvailable() check (MySQL configured, no ai.Enabled requirement) so Verlauf and Suche work even when KI is disabled
  • fix: ๐Ÿ” Backup โ€“ PBKDF2 on thread-pool โ€“ CPU-intensive key derivation moved to Task.Run() to prevent blocking the SignalR heartbeat and disconnecting the browser
  • fix: ๐Ÿ” Backup Import โ€“ Blazor InputFile โ€“ replaced JS-interop int[] file read (which exceeded the SignalR 32 KB message limit) with Blazor's InputFile component; connection no longer drops on file selection
  • docs: ๐Ÿ“– README โ€“ QSO dialog section fully rewritten; Import/Export and Backup & Restore documented; History, Text Search, AI Search and AI Summary documented as separate tabs; step-by-step AI setup guide added

v1.8.2

  • feat: ๐Ÿ“ก Reichweite (Coverage) โ€“ Kontrast der gemessenen Reichweiten-Flรคche erhรถht (fillOpacity 0.12 โ†’ 0.35, Randlinie weight 2 โ†’ 3, opacity 0.65 โ†’ 0.95); Topo-Prognose (ungenau) vollstรคndig entfernt
  • docs: ๐Ÿ“– README โ€“ Abschnitte fรผr ๐Ÿค– KI / QSO-Zusammenfassung, ๐Ÿ“ก Reichweiteberechnung (Convex Hull), ๐Ÿ—บ๏ธ KI-Stationsbeschreibung im Karten-Popup und Callsign-Suche ergรคnzt; Ai-Konfigurationsblock und Architektur aktualisiert

v1.8.1

  • feat: ๐ŸŸข MQTT/DB Verbindungsstatus in der Statusleiste โ€“ MQTT- und Datenbankverbindung werden als farbige Status-Badges in der Statusleiste angezeigt; MQTT-Verbindung kann direkt in den Einstellungen รผber einen โ€žVerbindung testen"-Button รผberprรผft werden
  • feat: ๐Ÿ”” Statusleiste โ€“ einheitliche Badge-Darstellung โ€“ alle Statusleisten-Elemente (UDP, Ton, MQTT, DB) werden einheitlich als farbige Badges dargestellt; Glocke-/Ton-aus-Button ebenfalls als Badge; UDP-Badge zeigt nur Icon+Label, vollstรคndiger Text als Tooltip
  • feat: โ˜๏ธ Gateway-ACK mit Wolken-Symbol โ€“ ACK-Nachrichten vom Gateway werden mit einem Wolken-Symbol (โ˜๏ธ) dargestellt; ACK-Matching korrigiert (FirstOrDefault)

v1.8.0

  • feat: ๐Ÿ“ก MQTT integration (Beta) โ€“ optionale Verbindung zu einem externen MQTT-Broker; publiziert eingehende Chat-Nachrichten, Positions-Baken und Telemetrie auf typisierten Topics ({prefix}/broadcast, {prefix}/group/{group}, {prefix}/dm/{callsign}, {prefix}/position/{callsign}, {prefix}/telemetry/{callsign}); optionaler Subscriber leitet {prefix}/send/#-Topics als ausgehende UDP-Nachrichten weiter; unterstรผtzt Authentifizierung, TLS und Auto-Reconnect; alle {variable}-Platzhalter werden in Subscriber-Payloads expandiert
  • feat: ๐Ÿ“ MQTT Logging โ€“ aktivierbares/deaktivierbares MQTT-Diagnose-Logging in den Einstellungen
  • feat: ๐Ÿท๏ธ Group Labels โ€“ konfigurierbare Kurz- und Vollnamen fรผr MeshCom-Gruppennummern; Kurzname wird im Monitor-Tab neben der Gruppe angezeigt; Gruppen einheitlich mit # dargestellt; vorbelegt mit der offiziellen MeshCom-GRC-Gruppenliste (icssw.org); in den Einstellungen editierbar mit Zurรผcksetzen-Button
  • feat: ๐Ÿš€ Automatische Update-Prรผfung โ€“ beim Start wird die GitHub-Releases-API abgefragt; bei verfรผgbarer neuer Version erscheint ein wegklickbares Banner
  • fix: ๐Ÿ’ฌ QRZ-Vorabladen fรผr Auto-Reply โ€“ QRZ-Daten werden vor dem Senden der Auto-Reply vorgeladen, damit {dest-name} bei neuen Kontakten korrekt befรผllt ist
  • fix: ๐Ÿ“ก Broadcast-Routing โ€“ ausgehende Broadcast-Nachrichten und Baken werden korrekt im *-Tab angezeigt (nicht mehr in #alle)
  • fix: ๐Ÿ”ค Tab-Key Normalisierung โ€“ ResolveTabKey normalisiert Callsigns einheitlich, damit Baken-Nachrichten im richtigen Tab erscheinen
  • fix: ๐ŸŒ Browser-Tab-Titel korrigiert auf โ€žMeshCom WebDesk"
  • fix: ๐Ÿ”ง MQTT ClientId โ€“ zufรคlliger Suffix verhindert Instanz-Konflikte beim Broker; Stack-Trace bei Connect-Fehler unterdrรผckt

v1.7.7

  • feat: ๐Ÿ“ก MQTT integration โ€“ optional connection to an external MQTT broker;
  • feat: ๐Ÿท๏ธ Group Labels โ€“ configurable short and full names for MeshCom group numbers; shown in chat tab (short label below group number, full name as tooltip); pre-filled with official MeshCom GRC group list (icssw.org); editable in Settings with restore-defaults button
  • feat: ๐Ÿš€ Automatic update check โ€“ on startup the app queries the GitHub Releases API and shows a dismissible banner when a newer version is available
  • fix: ๐ŸŒ Browser tab title corrected to "MeshCom WebDesk"

v1.7.6

  • feat: โšก Quick Texts โ€“ drag & drop reorder โ€“ buttons in the flyout can be reordered by drag & drop; new order saved immediately to appsettings.override.json
  • feat: ๐Ÿ”ง {mylocator} variable โ€“ own QTH Maidenhead locator (from Node GPS) available in all template texts: Auto-Reply, Bot commands, Quick Texts and Beacon
  • feat: ๐Ÿ’ฌ Variable expansion in send bar โ€“ {variables} can be typed directly in the message input; Tab expands inline as preview; Send always expands automatically
  • perf: ๐Ÿ“ป MH search debounce โ€“ same optimisation as monitor filter: 250 ms debounce, Enter applies immediately, clearing resets instantly
  • fix: ๐Ÿ“ก Broadcast TX uses dst * โ€“ outgoing messages in the ALL channel now use * as destination (not CQCQCQ) matching the MeshCom protocol spec
  • fix: โš ๏ธ Remove ::deep from global CSS โ€“ ::deep is only valid in scoped .razor.css files; removed from app.css

v1.7.5

  • feat: ๐Ÿ’ฌ Draggable chat tabs โ€“ tabs can be reordered by drag & drop; order persisted in localStorage
  • feat: ๐Ÿ“ป MH โ€“ QTH Locator โ€“ Maidenhead locator (JN48qn) shown below GPS coordinates in the MH table; also in the station card popup (with clickable OSM link for GPS coordinates)
  • feat: ๐Ÿ—บ๏ธ Map popup โ€“ GPS & QTH Locator โ€“ station popup now shows QTH locator and GPS coordinates as a clickable OSM link
  • feat: ๐Ÿ”ง {locator} variable โ€“ QTH locator of the chat partner available in Auto-Reply, Bot commands and Quick Texts
  • feat: โš™๏ธ Beacon variables hint โ€“ all supported placeholders ({version}, {mycall}, {date}, {time}) shown inline below the beacon text field
  • feat: ๐Ÿ’ฌ Timestamps โ€“ date (dd.MM.yy) shown below time for messages not from today; row height unchanged
  • perf: ๐Ÿ“ก Monitor filter debounce โ€“ filter input debounced (250 ms); Enter applies immediately; clearing the field resets instantly; results cached
  • fix: ๐ŸŒ InvariantCulture for coordinates and InfluxDB โ€“ OsmUrl, FormatCoord and all InfluxDB Line Protocol float fields now use . as decimal separator regardless of system locale

v1.7.4

  • feat: โšก Quick Texts โ€“ configurable one-click text buttons in the send bar; a โšก icon opens a flyout panel above the input; clicking a button loads the predefined text into the input field for review before sending; supports all {variable} placeholders ({mycall}, {callsign}, {rssi}, {snr}, {hw}, {route}, {hops}, {date}, {time}, โ€ฆ); variable reference table with live examples in Settings โ†’ โšก Quick Texts; fully multilingual (DE / EN / IT / ES)
  • feat: ๐Ÿ“ป MH โ€“ Station Card popup โ€“ hovering (desktop) or tapping (mobile) a callsign in the MH list shows a rich popup card with QRZ name/QTH, RSSI/SNR, battery, distance, firmware, last message preview, a ๐Ÿ’ฌ Open Chat button and a ๐Ÿ”— aprs.fi link
  • feat: ๐Ÿ”ง MeshcomLookup โ€“ new hardware IDs โ€“ added hw_id 40 (T5-EPAPER / LilyGo T5 E-Paper) and 53 (T-ETH-ELITE / LilyGo T-ETH-Elite S3 + SX1262 Ethernet) from MeshCom-Firmware v4.35p
  • fix: ๐Ÿ“ฑ Send bar overflow on iOS Safari โ€“ added width:100%, max-width:100%, min-width:0 through the full flex chain (app-body โ†’ meshcom-container โ†’ upper-pane โ†’ tab-content); tab-bar overflow-x container no longer breaks parent overflow:hidden on iOS
  • fix: ๐Ÿ“ป MH Station Card hover gap โ€“ removed 6 px gap between callsign and card (replaced with ::before bridge element); elevated z-index so card appears above subsequent table rows

v1.7.3

  • feat: ๐Ÿค– Bot โ€“ {srctype} and {srctype-label} variables โ€“ connection type (LoRa / UDP/Gateway / Node) available in all template texts
  • feat: ๐Ÿค– Bot โ€“ --ping command โ€“ replies with RSSI, SNR, relay route and receive timestamp; bare ping keyword also accepted (case-insensitive)
  • feat: ๐Ÿค– Bot โ€“ --echo command โ€“ echoes back any text after the command
  • feat: โš™๏ธ Settings โ€“ Bot command test โ€“ dry-run preview of any command with optional sender callsign; all {variable} placeholders expanded live
  • fix: ๐Ÿค– Bot โ€“ {srctype} partial substitution โ€“ {srctype-label} now replaced before {srctype} to avoid partial match
  • fix: ๐Ÿค– Bot โ€“ LastSrcType null from older persisted snapshots โ€“ graceful fallback to "lora" for stations loaded before the field was introduced

v1.7.2

  • feat: ๐Ÿ“ป MH โ€“ per-row delete button โ€“ individual stations can be removed from the MH list with a โœ• button without clearing the whole list
  • feat: ๐Ÿ“ป MH โ€“ navigate to chat on tab open โ€“ clicking ๐Ÿ’ฌ in the MH list now automatically navigates to the Chat page and activates the newly opened tab

v1.7.1

  • feat: ๐Ÿ” Encrypted sensitive settings โ€“ MySqlConnectionString, InfluxToken, Qrz.Password and TelemetryApiKey are now encrypted in appsettings.override.json using the ASP.NET Core Data Protection API (dp: prefix); IPostConfigureOptions<MeshcomSettings> decrypts them transparently on load; plain-text values in existing files pass through unchanged (backward compatible); keys stored in DataPath/keys
  • feat: ๐Ÿ“ป Watchlist โ€“ callsign alert system โ€“ configurable list of callsigns to watch; matching supports base-callsign wildcards (DH1FR matches all SSIDs) or exact SSID matching (DH1FR-1); triggers an ascending three-tone alert beep and a self-dismissing toast notification; per-type filters (MSG / POS / TEL / ACK); telemetry alerts off by default; respects the global mute toggle
  • feat: ๐Ÿ“ป Watchlist โ€“ configurable toast duration โ€“ new WatchAlertMinutes setting (default 5, min 1) configurable in Settings โ†’ ๐Ÿ“ป Watchlist
  • feat: โš™๏ธ Settings โ€“ collapsible sections โ€“ all 13 sections individually collapsible; all start collapsed by default; expanded/collapsed state saved to localStorage and restored on every visit
  • feat: ๐Ÿ”— Webhook โ€“ telemetry fields in payload โ€“ temp1, temp2, humidity, pressure added to eventType="telemetry" payload
  • fix: โš™๏ธ Settings โ€“ Watchlist persistence โ€“ WatchCallsigns and WatchOn* flags were missing from SettingsService

v1.7.0

  • feat: ๐Ÿค– Bot command system โ€“ incoming direct messages starting with -- (or โ€” em dash) are interpreted as bot commands; built-in: --help, --version, --time, --mh; fully configurable user-defined commands with {variable} placeholder support in Settings โ†’ ๐Ÿค– Bot; IBotCommand interface for developer extensions
  • feat: โ†ฉ๏ธ Auto-Reply โ€“ {route} and {hops} template variables โ€“ relay path and hop count from the sender's last message are now available in AutoReplyText
  • feat: โš™๏ธ Auto-Reply โ€“ collapsible variable reference table in Settings; all supported {variable} placeholders with live example values shown inline
  • fix: โ†ฉ๏ธ Auto-Reply ordering โ€“ auto-reply is now sent after the incoming message is stored in the tab so the reply always appears below the trigger message in the conversation
  • fix: โ†ฉ๏ธ Auto-Reply first-contact data โ€“ UpdateMhList is called before GetOrCreateTab so RSSI, relay path and hardware data from the first message are immediately available to ExpandVariables
  • fix: ๐Ÿค– Bot โ€“ em dash support โ€“ MeshCom clients and mobile keyboards often convert -- to โ€” (U+2014); both variants now accepted as command prefix
  • fix: ๐Ÿค– Bot โ€“ silent exception handling โ€“ HandleBotCommandAsync wrapped in try/catch so errors are always logged and never swallowed silently
  • fix: ๐Ÿค– Bot / ๐Ÿ“ก Beacon โ€“ auto-split โ€“ replies and beacon texts longer than 149 characters are automatically split into multiple packets (2 s pause between parts); previously they were silently dropped
  • fix: ๐Ÿ’พ Settings โ€“ TimeOffsetHours persistence โ€“ this field was missing from SettingsService.SaveMeshcomSettingsAsync and was reset to 0 on every UI save
  • fix: โš™๏ธ Settings โ€“ WeatherRole persistence โ€“ WeatherRole was not written to the override file when saving telemetry mapping via the UI
  • fix: ๐Ÿ—บ๏ธ Map โ€“ direct-link lines โ€“ corrected detection logic so direct (0-hop) connections are drawn reliably; broadcast replies and ACKs also count as confirmed direct links
  • perf: ๐Ÿ’ฌ Chat โ€“ SendBar extracted โ€“ input bar moved to its own component (SendBar.razor) to isolate re-renders and prevent the entire chat from re-rendering on every keystroke

v1.6.20

  • feat: ๐Ÿ—บ๏ธ Map โ€“ relay path lines โ€“ lines between relaying stations drawn from incoming relay paths and ACK return paths; colour-coded by hop count
  • feat: ๐Ÿ—บ๏ธ Map โ€“ own station popup โ€“ own position marker now shows callsign, own GPS source, and own telemetry values (temperature, humidity, pressure) when available
  • feat: ๐Ÿ—บ๏ธ Map โ€“ thermometer icon on own station marker when telemetry has been sent recently
  • feat: ๐Ÿ“Š Explicit WeatherRole per telemetry mapping entry โ€“ each entry can declare "temp", "humidity" or "pressure" role explicitly; unit-based auto-detection is the fallback for older configs
  • fix: ๐Ÿ’ฌ Chat โ€“ monitor visibility persisted across navigation โ€“ monitor collapsed/expanded state is now preserved when navigating away and back
  • fix: ๐Ÿ’ฌ Chat โ€“ splitscreen jump on navigation return eliminated
  • fix: ๐Ÿ’ฌ Chat โ€“ batch OnAfterRenderAsync re-renders; snapshot tabs filtered by group whitelist on load
  • fix: โš™๏ธ Settings โ€“ privacy warning labels cleaned up; DB-insert notice kept only in the database section
  • perf: ๐Ÿ“ป MH โ€“ QRZ data loaded from cache synchronously on first render โ€“ no more delayed flicker when returning to the MH page
  • feat: ๐Ÿ”— Clickable URLs in chat & monitor โ€“ http:// and https:// URLs in incoming messages are automatically rendered as clickable links; clicking shows a confirmation dialog before opening the external page in a new tab (works correctly in Blazor Server via capture-phase JS handler)
  • fix: ๐Ÿ—บ๏ธ Map โ€“ Leaflet self-hosted โ€“ Leaflet 1.9.4 is now served from wwwroot/lib/leaflet/ instead of the unpkg.com CDN; eliminates map init errors when the server has no internet access or the CDN is slow to respond (e.g. Docker / LAN-only setups)
  • fix: ๐Ÿณ Docker โ€“ browser auto-open warning suppressed โ€“ ENV DOTNET_RUNNING_IN_CONTAINER=true added to Dockerfile; [WRN] Could not open browser no longer appears in Docker logs
  • perf: โšก QRZ cache โ€“ no redundant async calls on navigation โ€“ new QrzService.TryGetCached() distinguishes "never queried" from "queried, not found"; components skip the async LookupAsync path for all already-known callsigns on every re-mount
  • docs: ๐Ÿ“– Multilingual node-connection guides โ€“ new docs/node-connection-{de,en,it,es}.md with step-by-step EXTUDP setup; in-app help banner added to the Connection section in Settings

v1.6.16

  • feat: ๐Ÿ“ฑ QRZ-Name im Tab-Button โ€“ der Vorname des Operators erscheint als kleiner Untertitel direkt im Chat-Tab-Button (immer sichtbar, kein Hover nรถtig)
  • feat: ๐ŸŽŸ๏ธ Touch-Display-Support โ€“ QRZ-Vorname wird als festes ยท Name-Badge inline bei jedem Rufzeichen angezeigt (Chat-Nachrichten und Monitor-Zeilen), ohne Hover-Interaktion
  • perf: โšก Nicht-blockierendes QRZ-Laden โ€“ Seiten rendern sofort; QRZ-Daten werden im Hintergrund nach dem ersten Render nachgeladen (OnAfterRenderAsync statt OnInitializedAsync)
  • perf: โšก Doppelter Re-Render entfernt โ€“ zweites StateHasChanged in OnChatChanged nur noch wenn tatsรคchlich neue QRZ-Daten hinzukamen
  • perf: โšก Karte synchron โ€“ UpdateMarkersAsync verwendet neuen synchronen QrzService.GetCached() statt sequentieller await-Kette
  • feat: ๐Ÿ’พ QRZ-Cache persistent โ€“ Lookups werden in qrz-cache.json im DataPath gespeichert und beim nรคchsten App-Start automatisch geladen; jedes Rufzeichen wird nur noch einmal abgefragt (auch รผber Neustarts hinweg)

v1.6.15

  • feat: ๐Ÿ” QRZ.com callsign lookup โ€“ optional integration with the QRZ.com XML API; free account returns operator first name + home QTH; session key fetched and refreshed automatically; results cached in memory per session
    • ๐Ÿ“ป MH list โ€“ dedicated Name / Location column + hover tooltip on every callsign
    • ๐Ÿ’ฌ Chat โ€“ QRZ data shown as hover tooltip on tab buttons, chat-message callsigns and monitor From/To callsigns
    • ๐Ÿ—บ๏ธ Map โ€“ callsign popup shows operator name and QTH below the bold callsign
    • Configured in Settings โ†’ ๐Ÿ” QRZ.com; test button + cache-clear button included; on/off live without restart
  • fix: ๐Ÿณ Docker โ€“ HTTPS outbound connections โ€“ added ca-certificates to debian:bookworm-slim runtime image; fixes "The SSL connection could not be established" for all outgoing HTTPS calls (QRZ.com, Webhook, InfluxDB Cloud etc.)

v1.6.13

  • feat: ๐Ÿ“ก Resizable monitor pane โ€“ drag handle between chat and monitor lets the user resize the split freely (mouse + touch); last position persisted in localStorage
  • fix: DH1FR greeting is now only sent when the tab is opened by an incoming message (not when opened manually with +)
  • fix: ๐Ÿ”’ HTTPโ†’HTTPS redirect disabled in non-LanHttps environments โ€“ POST /api/telemetry no longer redirects Home Assistant to HTTPS
  • feat: ๐Ÿš€ Browser auto-opens at http://localhost:5162 when launched directly as an executable (skipped in Docker / Windows service / systemd)
  • feat: ๐ŸŽจ ASCII startup banner now shows MESHCOM + WebDesk both in block-letter style
  • feat: ๐Ÿ“ Portable default paths โ€“ data/, logs/ and data/keys/ stored next to the executable; no hard-coded C:\Temp paths
  • docs: Screenshot_shell.png added; ๐Ÿš€ Startup section added to README

v1.6.9

  • fix: ๐Ÿ“ฑ iOS PWA โ€“ Leeraum unten (nur in PWA standalone, nicht im Browser) โ€“ Ursache war height: -webkit-fill-available in app.css, das im PWA-Modus eine kleinere Hรถhe als 100dvh liefert; ersetzt durch position: fixed; inset: 0 (von Apple empfohlene Methode fรผr PWA Full-Screen-Layouts)
  • fix: ๐Ÿ“ฑ Doppelte .app-layout-Definition aus app.css entfernt โ€“ nur noch in MainLayout.razor.css definiert

v1.6.8

  • fix: ๐Ÿ“ฑ iOS PWA โ€“ Leeraum unten (iPhone + iPad) โ€“ padding-bottom: env(safe-area-inset-bottom) auf .app-layout mit box-sizing: border-box verschoben; wirkt jetzt zuverlรคssig auf allen iOS-Gerรคten
  • fix: ๐Ÿ“ฑ iOS PWA โ€“ Titel zu groรŸ โ€“ Breakpoint von 390px auf 480px erhรถht (trifft jetzt alle iPhones inkl. 14 Pro / 15 Plus); SchriftgrรถรŸe auf 11px reduziert

v1.6.7

  • fix: ๐Ÿ“ฑ iOS PWA โ€“ Safe Area Insets โ€“ App startete zu weit oben (Inhalt unter Statusleiste) und lieรŸ unten Platz frei; env(safe-area-inset-top/bottom) korrekt in Header-Hรถhe und Body eingebunden
  • fix: ๐Ÿ“ฑ iOS PWA โ€“ Titel zu groรŸ โ€“ Auf kleinen iPhones (SE, mini) war โ€žMeshCom WebDesk" zu groรŸ; neue Media Query fรผr โ‰ค390px reduziert SchriftgrรถรŸe und blendet Versionsnummer aus

v1.6.6

  • feat: ๐Ÿณ docker-compose.https.yml โ€“ HTTPS overlay fรผr Docker Compose; HTTP bleibt in docker-compose.yml unverรคndert; beide Dateien werden mit -f kombiniert
  • feat: scripts/start-https.sh โ€“ Wrapper-Skript prรผft ob certs/meshcom-lan.pfx existiert und gibt klare Fehlermeldung wenn nicht; startet dann docker compose -f ... -f ...
  • fix: docker-compose.yml Encoding-Probleme in Kommentaren behoben

v1.6.5

  • feat: ๐Ÿ”’ scripts/create-lan-cert.sh โ€“ Linux/Docker equivalent of the Windows PowerShell cert script; uses openssl, auto-detects LAN IP, exports PFX + CRT
  • docs: ๐Ÿ”’ HTTPS Docker โ€“ vollstรคndige Anleitung fรผr Zertifikatserstellung auf Linux und Einbindung via Docker Compose volume mount
  • docs: Architecture updated with create-lan-cert.sh

v1.6.4

  • fix: ๐Ÿ—บ๏ธ Map โ€“ 50km Button โ€“ "An unhandled error has occurred" behoben; L.circle.getBounds() ersetzt durch manuelle Haversine-Bounding-Box (funktioniert ohne map context)
  • docs: ๐Ÿ”’ HTTPS & Zertifikat โ€“ vollstรคndige Schritt-fรผr-Schritt-Anleitung (Windows, iOS, Android) in der README
  • docs: ๐Ÿ“ฑ PWA โ€“ erklรคrt was PWA ist, wie man es auf iPhone/iPad/Android/Windows installiert

v1.6.3

  • feat: ๐Ÿ”’ HTTPS for LAN โ€“ scripts/create-lan-cert.ps1 generates a self-signed cert with IP SAN; new lan-https launch profile binds HTTP :5162 + HTTPS :5163 simultaneously; required for PWA installation on Android / iPad / iPhone
  • feat: appsettings.LanHttps.json โ€“ dedicated Kestrel HTTPS endpoint config; HTTP stays unaffected

v1.6.2

  • feat: ๐Ÿ—บ๏ธ Map โ€“ Zoom-Buttons โ€“ neue Button-Leiste รผber der Karte: ๐Ÿ“ก Alle (alle Stationen), ๐ŸŒ Europa, ๐Ÿ“ 50 km (Radius um eigene Position)
  • fix: ๐Ÿ—บ๏ธ Map โ€“ Auto-Zoom entfernt โ€“ Karte zoomt nur noch einmalig beim ersten Laden mit Daten; danach bleibt der Ausschnitt beim Eingang neuer Positionen stabil
  • fix: ๐Ÿ—บ๏ธ Map โ€“ Rufzeichen-Kontrast verbessert โ€“ dunkles halbtransparentes Pill-Label statt Text-Shadow, jetzt auf hellen und dunklen Kartenbereichen lesbar

v1.6.1

  • fix: ๐Ÿ—บ๏ธ Map โ€“ "Noch keine GPS-Position" wurde angezeigt obwohl bereits Stationen auf der Karte eingetragen waren โ€“ StateHasChanged() wird jetzt nach UpdateMarkersAsync() aufgerufen
  • fix: ๐Ÿ—บ๏ธ Map โ€“ Station-Strip ersetzt durch kompakte einzeilige Info-Leiste (๐Ÿ“ก N Station(en) ยท ๐Ÿ“ Rufzeichen) โ€“ bei vielen Stationen keine unleserliche Liste mehr

v1.6.0

  • feat: ๐Ÿ—บ๏ธ Live Map โ€“ interactive Leaflet.js + OpenStreetMap map at /map; APRS-style circle markers colour-coded by RSSI; own position as gold diamond; auto-fit bounds; real-time updates
  • feat: ๐Ÿ”— Webhook โ€“ HTTP POST fire-and-forget on incoming messages, position beacons and/or telemetry; configurable URL and triggers in Settings โ†’ ๐Ÿ”— Webhook
  • feat: ๐Ÿ“ฑ PWA โ€“ installable as Progressive Web App ("Add to Home Screen"); manifest.webmanifest, minimal service worker, Apple meta tags, custom antenna SVG icon
  • feat: โ˜• Donation link โ€“ PayPal link on the About page (paypal.me/DH1FR)
  • docs: Architecture, Configuration and Changelog updated

v1.5.0

  • feat: ๐Ÿ—„๏ธ Database integration โ€“ optional MySQL/MariaDB or InfluxDB 2 sink writes every monitor entry to an external database
  • feat: Settings โ†’ Datenbank โ€“ provider dropdown, connection fields, "Test connection" button with automatic DB/table/bucket creation
  • feat: Optional insert logging (LogInserts) โ€“ logs the full SQL INSERT at Information level; privacy notice shown in Settings UI
  • feat: Message length guard โ€“ character counter X/149 in the chat input, maxlength="149" enforced in the browser and server-side warning log when limit is exceeded
  • docs: ๐Ÿ”’ Privacy / Datenschutz section added to README โ€“ covers log files, database storage, DB insert log and persistence; includes recommendations for GDPR-compliant operation

v1.4.3

  • feat: TimeOffsetHours setting โ€“ configurable UTC offset for timestamp display (supports half-hour offsets, e.g. 5.5 for IST)
  • fix: Docker container now runs with TZ=Europe/Berlin by default (tzdata installed) โ€“ DateTime.Now correctly reflects MEZ/MESZ including automatic DST switching; TimeOffsetHours = 0 stays correct in Docker

v1.4.2

  • feat: {version} placeholder supported in AutoReplyText and BeaconText โ€“ replaced with the running application version at send time
  • feat: Test button for Auto-Reply in Settings โ€“ send to any callsign immediately without waiting for an incoming message
  • feat: Application version shown in the navigation bar next to the app title
  • feat: UDP registration packet ({"type":"info",...}) sent on startup now appears in the monitor feed as a SYS TX entry
  • feat: Automatic greeting sent to DH1FR-2 whenever a new chat tab for that callsign is opened (incoming or manual)

v1.4.1

  • feat: {version} placeholder supported in AutoReplyText and BeaconText โ€“ replaced with the running application version at send time
  • feat: Test button for Auto-Reply in Settings โ€“ send to any callsign immediately without waiting for an incoming message
  • feat: Application version shown in the navigation bar next to the app title
  • feat: UDP registration packet ({"type":"info",...}) sent on startup now appears in the monitor feed as a SYS TX entry
  • feat: Automatic greeting sent to DH1FR-2 whenever a new chat tab for that callsign is opened (incoming or manual)

v1.4.0

  • fix: UDP registration packet no longer sends dst or msg fields โ€“ prevents broadcasting "info" text over the mesh and gateway on startup
  • feat: Author e-mail address dh1fr@darc.de added to About page

v1.3.0

  • Telemetry sender with HTTP POST endpoint (POST /api/telemetry)
  • Live telemetry preview and instant-send button in Settings
  • Home Assistant integration guide
  • Auto-split of long telemetry messages (TM1: / TM2:)
  • Configurable telemetry schedule hours

v1.2.0

  • Periodic beacon (Bake) with status indicator
  • State persistence (chat tabs, MH list, monitor, own GPS)
  • Browser GPS button for own position
  • Audio notification for incoming direct messages
  • Full relay path display in monitor

v1.1.0

  • ACK delivery tracking (โณ / โœ“ / โœ“โœ“ / โ˜๏ธ / โ˜๏ธโœ“ / โœ“โœ“ โ˜๏ธโœ“ / โš ๏ธ)
  • MH list with GPS distance, battery level and hardware badge
  • Web-based Settings editor
  • Multi-language UI (de / en / it / es)

v1.0.0

  • Initial release

About

Blazor Server Web Desk for MeshCom EXTUDP (.NET 10)

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages