System Views
Settings View
The Settings view maps directly to the System Config API. It reads the current config from /api/system/config on load and writes changes back via POST /api/system/config/update.
Connected Radios (Multi-Slot)
The top section shows all active radio slots. Each slot row displays the slot ID, label, connection status, and a disconnect/remove button. The ADD RADIO button opens a modal to create a new slot by specifying connection type, host/port/serial/BLE as needed. The primary slot (node_0) cannot be removed.
Switching which slot the dashboard is viewing is done by clicking a slot's radio button in the connected radios list — this calls window._sseSetSlot(slotId) to reconnect the SSE stream to that slot.
Primary Radio Connection
The Protocol dropdown sets MESHTASTIC_CONNECTION_TYPE. Selecting a type shows/hides the relevant input fields:
MESHTASTIC_SERIAL_PORT)Web Server & Auth
Edit bind host, port, session timeout, and the Auth Secret Key. Changing AUTH_SECRET_KEY invalidates all active sessions — all logged-in users will need to log in again.
Privacy & Location
Toggle controls for SEND_LOCAL_NODE_LOCATION, SEND_OTHER_NODES_LOCATION, and LOCATION_OFFSET_ENABLED. When location obfuscation is enabled, a max offset (metres) input appears.
Saving & Restarting
SAVE CONFIG calls POST /api/system/config/update. Some settings take effect immediately (log level, auth secret, packet memory size). Others require a restart. RESTART SERVICE calls POST /api/system/restart — the server process restarts via os.execv() and the browser reconnects via SSE auto-reconnect.
Node Config View
The Node Config view reads the connected radio's full protobuf configuration and renders it as editable fields, grouped by section. Changes are written directly to the radio's flash memory.
How It Works
On load, GET /api/node/config returns a snapshot of all localConfig, moduleConfig, and channels settings, flattened into field objects with path, name, type, and current value.
The view generates a tab for each top-level config section (lora, device, position, network, bluetooth, mqtt, etc.). Clicking a tab renders all fields for that section as appropriate input types:
| Field type | Rendered as |
|---|---|
bool | Toggle switch |
enum | Select dropdown with all enum value names |
int | Number input |
float | Number input with step |
string | Text input |
ip | Text input with IP format (stored as uint32) |
bytes | Text input (base64-encoded) |
repeated | Read-only display (repeated fields cannot be set via this UI) |
Identity Fields
A special "Identity" tab lets you change the node's long name and short name. These map to identity.long_name and identity.short_name paths, which the backend dispatches to localNode.setOwner().
Pending Changes & Save
Edited fields are tracked client-side. The N PENDING pill shows how many fields have been changed. RESET reverts all pending changes. SAVE CHANGES calls POST /api/node/config/save with the list of changed field paths and new values.
If REBOOT AFTER SAVE is checked (the default), the radio reboots 1.5 seconds after saving. The view shows a polling banner: NODE REBOOTING — AWAITING RECONNECT with a progress bar and elapsed time counter. Once the radio reconnects and /api/status reports is_system_ready: true, the view reloads the config automatically.
Plugins View
The Plugins view manages installed plugins and the plugin marketplace. See also the Plugin API and Plugin Development guides.
Summary Bar
Clickable filter pills at the top: ALL, RUNNING, STOPPED, CRASHED, HUNG, AVAILABLE (marketplace). Clicking a pill filters the card grid.
Plugin Cards
Each installed plugin has a card with a coloured left-stripe indicating status:
| Status | Stripe colour | Meaning |
|---|---|---|
running | Green | Plugin loaded and active. API routes accessible. |
stopped | Amber | Manually stopped. .disabled marker file present. Routes return 503. |
crashed | Red | Exception during load or init_plugin(). Error message shown in card. |
hung | Red | Background task stopped heartbeating (watchdog=true plugins only). Routes return 503. |
pending_restart | Purple | Start requested for a crashed/stopped plugin. Will be fully loaded on next service restart. |
invalid_manifest | Red | Manifest missing required watchdog field or invalid format. |
Plugin Start / Stop Lifecycle
The card footer shows context-appropriate action buttons:
STOP (running plugin):
- Calls
POST /api/system/plugins/{id}/toggle?action=stop - Backend creates
plugins/{id}/.disabledmarker file - Backend sets status to
stopped - SSE
plugin_updateevent fires → card stripe turns amber, STOP becomes START - Plugin API routes immediately return
503
START (stopped plugin):
- Calls
POST /api/system/plugins/{id}/toggle?action=start - Backend deletes the
.disabledmarker file - If the plugin was previously
runningand is still in memory: status →running, watchdog re-registered, routes immediately re-enabled - If the plugin was
crashed,stopped, orhung: the Python module cannot be re-imported without a restart. Status →pending_restart. The APPLY & RESTART button appears in the header
APPLY & RESTART button: Appears whenever any action returns requires_restart: true (install, uninstall, or start after crash). Calls POST /api/system/restart. After restart, newly installed plugins load fully and previously crashed plugins that were re-enabled will be in running state.
Logs Viewer
Every plugin card has a terminal icon button that opens the log viewer modal. It shows the last 250 log lines from that plugin's plugin.{id} Python logger, auto-refreshing every 3 seconds. Lines are colour-coded by level: DEBUG (grey), INFO (cyan), WARN (amber), ERROR (red bold). A CLEAR button wipes the in-memory buffer.
Installing Plugins
The INSTALL PLUGIN button opens a modal with two tabs:
.zip file. The file is uploaded to POST /api/system/plugins/install. Progress and success/error is shown in the log area below the drop zone..zip file. Calls POST /api/system/plugins/install-remote. The server downloads and installs server-side (SSRF-protected).Marketplace (AVAILABLE filter)
When the AVAILABLE filter is active, the grid shows plugins from GET /api/plugins/available (fetched from meshdash.co.uk/plugins.php). Each card shows an INSTALL button that calls the remote install endpoint with the plugin's download URL. After installation, the APPLY & RESTART button appears.
Search & Sort
The search box filters cards by plugin ID, name, or author. The sort dropdown orders by Name A–Z, Status, or Author.