Mesh-Plug for WordPress
Developer Reference and Integration Guide
Updated: January 2026 (v0.5.x)
Mesh-Plug bridges Meshtastic networks and MQTT data streams into WordPress, allowing developers to observe, store, enrich, and react to live mesh data using familiar WordPress tools.
This document is a technical appendix for developers who want to extend Mesh-Plug beyond the default UI; custom dashboards, automations, integrations, and data pipelines.
1) Architecture Overview
Mesh-Plug is structured as layered services rather than a single monolith. Each layer can be extended or intercepted independently.
MQTT Service Layer
Responsible for:
- Broker connection and authentication
- Topic subscription management
- MQTT-over-WebSocket handling (ws / wss)
- Payload ingestion and JSON decoding
Supported connection modes:
- Auto mode; broker resolved via site domain and proxy or tunnel
- Manual mode; explicit
ws://orwss://endpoint with credentials, TLS, and ACLs
This layer is intentionally isolated from rendering and storage.
Data Manager
Normalizes inbound messages and routes them to:
- Transient cache (always enabled)
- Optional database archive table
- Automation and event hooks
Archive table (optional):
{wp_prefix}meshtastic_archive
Messages are normalized once and reused across the system.
NodeDB Cache (Optional)
Lightweight, in-memory cache of node metadata:
- Node ID
- Node name
- Last seen timestamp
- Position (if available)
Used to enrich messages at render time. Stored as a WordPress option and rebuilt dynamically.
Shortcode and Rendering Layer
Responsible for:
- Rendering live or archived data
- Tables, logs, charts, maps, and node summaries
- Live Refresh and timed refresh modes
- Theme-aware output
Rendering never talks directly to MQTT.
Automation Layer
Rule-based engine that evaluates normalized messages and triggers actions such as:
- Email notifications
- Webhooks
- PHP callbacks
Rules are evaluated after normalization and before rendering.
REST API Layer
Exposes read and write access for:
- JavaScript dashboards
- External systems
- Headless or hybrid front ends
All REST responses are derived from the same normalized message pool.
2) MQTT Message Normalization
All inbound MQTT messages are converted into a common PHP array before use.
[
'topic' => 'msh/2/e/nodedata',
'timestamp' => 1730828392, // UNIX seconds (UTC)
'node_id' => '2',
'node_name' => 'FieldNode02', // via NodeDB or payload
'text' => 'Hello from Node 2',
'rssi' => -67,
'snr' => 9.5,
'battery' => 3.81,
'temperature' => 22.4,
'raw' => '{ ...original JSON... }'
]
Notes:
- Unknown or custom fields are preserved
- Telemetry, position, and vendor-specific fields pass through untouched
- Normalization happens exactly once per message
3) Shortcode Reference
Universal shortcode
[mesh_plug_display]
Attributes
| Attribute | Description | Example |
|---|---|---|
topic | Topic or wildcard | msh/# |
format | log, text, table, chart, map, nodes | format="table" |
limit | Max rows or messages | limit="20" |
order | asc or desc | order="desc" |
filter_field | Field name to filter on | filter_field="text" |
filter_value | Match value | filter_value="alert" |
refresh | Auto-refresh interval (seconds) | refresh="10" |
chart_type | line, bar, gauge, scatter | chart_type="line" |
value_field | Numeric field to chart | value_field="temperature" |
columns | Table column list | timestamp,node_name,rssi |
empty_text | Display when no data | Waiting for data… |
nodedb | Enrich with NodeDB | nodedb="on" |
dedupe | Collapse duplicates | dedupe="on" |
theme | light, dark, system | theme="system" |
Maps render automatically when latitude and longitude fields are present and map support is enabled.
Shortcode examples
[mesh_plug_display
topic="msh/2/e/telemetry"
format="chart"
chart_type="line"
value_field="temperature"
refresh="30"]
[mesh_plug_display
topic="msh/#"
format="table"
columns="timestamp,node_name,text,rssi"
filter_field="text"
filter_value="alert"
limit="20"
order="desc"
nodedb="on"]
4) PHP Hooks and Filters
4.1 mesh_plug_before_render
Filter the message array before rendering.
add_filter('mesh_plug_before_render', function (array $messages, array $atts) {
return array_filter($messages, fn($m) => isset($m['rssi']) && $m['rssi'] > -70);
}, 10, 2);
4.2 mesh_plug_format_message
Modify or enrich individual messages.
add_filter('mesh_plug_format_message', function (array $msg) {
if (isset($msg['rssi'])) {
$msg['signal_quality'] = $msg['rssi'] > -70 ? 'Good' : 'Weak';
}
return $msg;
});
4.3 mesh_plug_message
Triggered when a new MQTT message is received and normalized.
add_action('mesh_plug_message', function (array $msg) {
error_log("Node {$msg['node_id']} sent: " . ($msg['text'] ?? '[no text]'));
});
4.4 mesh_plug_automation_triggered
Runs after an automation rule executes.
add_action('mesh_plug_automation_triggered', function (array $rule, array $result) {
// Inspect success, HTTP status, or error data
});
5) REST API
Base path:
/wp-json/mesh-plug/v1/
Endpoints
| Endpoint | Method | Description |
|---|---|---|
/messages | GET | Recent messages |
/messages/latest | GET | Latest per topic |
/topics | GET | Active topics with counts |
/automations | GET | Automation rules (redacted) |
/publish | POST | Publish MQTT message (optional) |
Example request:
GET /wp-json/mesh-plug/v1/messages?topic=msh/2/e/telemetry&limit=10
Authentication
- Nonces required for POST requests
- Default capability:
manage_options(filterable)
6) Automation Rule Schema
Internally stored as structured arrays.
[
'id' => 7,
'name' => 'Battery Warning',
'topic' => 'msh/#',
'condition' => [
'field' => 'battery',
'operator' => '<',
'value' => 3.5
],
'actions' => [
[
'type' => 'email',
'to' => 'admin@domain.com',
'subject' => 'Low Battery {{node_id}}',
'body' => 'Battery: {{battery}}V'
]
]
];
Template tokens such as {{battery}} and {{node_name}} are rendered at runtime.
7) JavaScript Front-End API
Mesh-Plug exposes a minimal browser API for dynamic interfaces.
window.MeshPlug
Methods
subscribe(topic, callback)unsubscribe(topic)latest(topic)publish(topic, payload)(if enabled)
Example:
MeshPlug.subscribe('msh/#', data => {
console.log('New message:', data);
});
8) PHP Utility Functions
Fetch messages
$messages = mesh_plug_get_messages([
'topic' => 'msh/#',
'limit' => 10,
'order' => 'desc'
]);
Publish message
mesh_plug_publish('msh/local/toDevice', [
'text' => 'Hello from WordPress'
]);
Publishing requires broker and plugin write permissions.
9) Database Schema (Archive)
Table:
{wp_prefix}meshtastic_archive
| Column | Type | Description |
|---|---|---|
| id | BIGINT | Primary key |
| topic | VARCHAR(255) | MQTT topic |
| payload | LONGTEXT | Raw JSON |
| timestamp | DATETIME | Message time (UTC) |
| node_id | VARCHAR(64) | Node ID |
| node_name | VARCHAR(191) | Node name |
| rssi | FLOAT | Signal strength |
| battery | FLOAT | Battery voltage |
| hash | CHAR(40) | SHA1 for dedupe |
| created_at | DATETIME | Insert time |
Recommended indexes: topic, timestamp, node_id, hash.
10) Security and Best Practices
- Always use credentials on remote brokers
- Prefer TLS (
wss://) for public endpoints - Scope topics tightly in production
- Escape custom output using WordPress helpers
- Limit refresh intervals on high-traffic dashboards
11) Extending Mesh-Plug
class My_Custom_Extension {
public function __construct() {
add_action('mesh_plug_message', [$this, 'process']);
}
public function process(array $msg) {
if (!empty($msg['temperature']) && $msg['temperature'] > 30) {
wp_mail('alerts@domain.com', 'High Temperature', print_r($msg, true));
}
}
}
new My_Custom_Extension();
12) Debugging and Diagnostics
- Enable
WP_DEBUG_LOG - Optional constant:
define('MESH_PLUG_DEBUG', true);
- Diagnostics UI: Mesh-Plug → Diagnostics
If WP-CLI support is enabled:
wp mesh-plug status
wp mesh-plug subscribe msh/# --limit=5
wp mesh-plug publish msh/test '{"text":"Ping"}'
13) Compatibility
- PHP: 8.1+
- WordPress: 6.2+
- Charts: Chart.js 4.x
- Brokers: Mosquitto, EMQX, HiveMQ (WS/WSS)
Shortcode and REST contracts are stable across the 0.5.x series.
Final Notes
This reference is intentionally exhaustive. Mesh-Plug is designed to let developers stay inside WordPress while building real-time, mesh-aware systems.
MQTT handles transport; WordPress handles presentation and logic. Mesh-Plug connects the two cleanly.
