@alteriom/painlessmesh 1.9.18 → 1.9.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +62 -0
- package/README.md +82 -63
- package/examples/alteriom/README.md +4 -4
- package/examples/alteriom/alteriom_custom_package_template.hpp +320 -0
- package/examples/alteriom/alteriom_sensor_package.hpp +1 -1
- package/examples/alteriom/mppt_example/alteriom_mppt_example.ino +208 -0
- package/examples/bridge_failover/bridge_failover.ino +17 -0
- package/examples/sendToInternet/CMakeLists.txt +54 -0
- package/examples/sendToInternet/PC_NODE_README.md +517 -0
- package/examples/sendToInternet/README.md +39 -1
- package/examples/sendToInternet/build.sh +153 -0
- package/examples/sendToInternet/mock_server_test.ino +361 -0
- package/examples/sendToInternet/pc_mesh_node.cpp +361 -0
- package/library.json +4 -1
- package/library.properties +1 -1
- package/package.json +3 -3
- package/src/AlteriomPainlessMesh.h +5 -13
- package/src/arduino/wifi.hpp +306 -100
- package/src/connection.cpp +10 -0
- package/src/painlessMesh.h +1 -14
- package/src/painlessmesh/connection.hpp +11 -16
- package/src/painlessmesh/gateway.hpp +0 -1061
- package/src/painlessmesh/mesh.hpp +58 -86
- package/src/painlessmesh/message_queue.hpp +1 -2
- package/src/painlessmesh/metrics.hpp +2 -262
- package/src/painlessmesh/validation.hpp +0 -143
- package/docs/README.md +0 -132
- package/docs/alteriom/overview.md +0 -531
- package/docs/api/core-api.md +0 -607
- package/docs/api/shared-gateway.md +0 -1207
- package/docs/architecture/mesh-architecture.md +0 -399
- package/docs/architecture/plugin-system.md +0 -517
- package/docs/getting-started/arduino-manual-install.md +0 -313
- package/docs/getting-started/first-mesh.md +0 -410
- package/docs/getting-started/installation.md +0 -275
- package/docs/getting-started/quickstart.md +0 -158
- package/docs/troubleshooting/common-issues.md +0 -679
- package/docs/troubleshooting/debugging.md +0 -455
- package/docs/troubleshooting/external-device-connection.md +0 -283
- package/docs/troubleshooting/faq.md +0 -574
- package/docs/tutorials/basic-examples.md +0 -718
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
//************************************************************
|
|
2
|
+
// AlteriomPainlessMesh – MPPT Charge Controller Example
|
|
3
|
+
//
|
|
4
|
+
// This sketch shows how to use a custom package (MpptPackage)
|
|
5
|
+
// to broadcast solar charge-controller telemetry over a
|
|
6
|
+
// painlessMesh network.
|
|
7
|
+
//
|
|
8
|
+
// Hardware assumptions:
|
|
9
|
+
// - An MPPT charge controller connected via Serial / RS-485
|
|
10
|
+
// (e.g. Renegy, Epever, Victron BlueSolar, etc.)
|
|
11
|
+
// - ESP8266 or ESP32 running this firmware
|
|
12
|
+
//
|
|
13
|
+
// How it works:
|
|
14
|
+
// 1. Every 10 seconds the node reads the charge controller
|
|
15
|
+
// and broadcasts an MpptPackage to all mesh nodes.
|
|
16
|
+
// 2. Any node that receives an MpptPackage prints the values
|
|
17
|
+
// to Serial (bridge nodes can forward them to MQTT/HTTP).
|
|
18
|
+
// 3. A CommandPackage handler is included so a bridge node can
|
|
19
|
+
// request an immediate reading (command code 10).
|
|
20
|
+
//
|
|
21
|
+
// See alteriom_custom_package_template.hpp for a step-by-step
|
|
22
|
+
// guide to creating your own custom packages.
|
|
23
|
+
//************************************************************
|
|
24
|
+
|
|
25
|
+
#include "AlteriomPainlessMesh.h"
|
|
26
|
+
#include "alteriom_custom_package_template.hpp"
|
|
27
|
+
#include "alteriom_sensor_package.hpp" // for CommandPackage
|
|
28
|
+
|
|
29
|
+
#define MESH_PREFIX "AlteriomMesh"
|
|
30
|
+
#define MESH_PASSWORD "somethingSneaky"
|
|
31
|
+
#define MESH_PORT 5555
|
|
32
|
+
|
|
33
|
+
// How often to broadcast MPPT data (milliseconds)
|
|
34
|
+
#define MPPT_SEND_INTERVAL 10000
|
|
35
|
+
|
|
36
|
+
Scheduler userScheduler;
|
|
37
|
+
painlessMesh mesh;
|
|
38
|
+
|
|
39
|
+
using namespace alteriom;
|
|
40
|
+
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
// Forward declarations
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
void sendMpptData();
|
|
45
|
+
void handleIncomingPackage(uint32_t from, String& msg);
|
|
46
|
+
void handleCommandPackage(CommandPackage& cmd);
|
|
47
|
+
void newConnectionCallback(uint32_t nodeId);
|
|
48
|
+
void changedConnectionCallback();
|
|
49
|
+
void nodeTimeAdjustedCallback(int32_t offset);
|
|
50
|
+
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
// Scheduled tasks
|
|
53
|
+
// ---------------------------------------------------------------------------
|
|
54
|
+
Task taskSendMppt(MPPT_SEND_INTERVAL, TASK_FOREVER, &sendMpptData);
|
|
55
|
+
|
|
56
|
+
// ---------------------------------------------------------------------------
|
|
57
|
+
// Stub: read data from your MPPT controller
|
|
58
|
+
//
|
|
59
|
+
// Replace this function body with real hardware reads, e.g.:
|
|
60
|
+
// - Modbus RTU over RS-485 (using ModbusMaster library)
|
|
61
|
+
// - Vendor protocol over SoftwareSerial / HardwareSerial
|
|
62
|
+
// - I²C registers for controllers that support it
|
|
63
|
+
// ---------------------------------------------------------------------------
|
|
64
|
+
MpptPackage readMpptController() {
|
|
65
|
+
MpptPackage data;
|
|
66
|
+
data.from = mesh.getNodeId();
|
|
67
|
+
data.deviceId = mesh.getNodeId();
|
|
68
|
+
data.timestamp = mesh.getNodeTime() / 1000; // convert µs → s
|
|
69
|
+
|
|
70
|
+
// --- Replace these lines with real hardware reads ---
|
|
71
|
+
data.solarVoltage = 18.5f; // V (example: 18.5 V PV panel)
|
|
72
|
+
data.solarCurrent = 5.2f; // A
|
|
73
|
+
data.solarPower = 96; // W (= solarVoltage * solarCurrent)
|
|
74
|
+
data.batteryVoltage = 12.6f; // V (12 V lead-acid, ~80 % SOC)
|
|
75
|
+
data.batterySOC = 80; // %
|
|
76
|
+
data.loadVoltage = 12.4f; // V
|
|
77
|
+
data.loadCurrent = 2.1f; // A
|
|
78
|
+
data.chargeState = CHARGE_MPPT;
|
|
79
|
+
data.controllerTemp = 32; // °C
|
|
80
|
+
// ----------------------------------------------------
|
|
81
|
+
|
|
82
|
+
return data;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// ---------------------------------------------------------------------------
|
|
86
|
+
// Setup
|
|
87
|
+
// ---------------------------------------------------------------------------
|
|
88
|
+
void setup() {
|
|
89
|
+
Serial.begin(115200);
|
|
90
|
+
|
|
91
|
+
mesh.setDebugMsgTypes(ERROR | STARTUP | CONNECTION);
|
|
92
|
+
mesh.init(MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT);
|
|
93
|
+
mesh.onReceive(&handleIncomingPackage);
|
|
94
|
+
mesh.onNewConnection(&newConnectionCallback);
|
|
95
|
+
mesh.onChangedConnections(&changedConnectionCallback);
|
|
96
|
+
mesh.onNodeTimeAdjusted(&nodeTimeAdjustedCallback);
|
|
97
|
+
|
|
98
|
+
userScheduler.addTask(taskSendMppt);
|
|
99
|
+
taskSendMppt.enable();
|
|
100
|
+
|
|
101
|
+
Serial.println("MPPT node initialised");
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// ---------------------------------------------------------------------------
|
|
105
|
+
// Loop
|
|
106
|
+
// ---------------------------------------------------------------------------
|
|
107
|
+
void loop() {
|
|
108
|
+
mesh.update();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// ---------------------------------------------------------------------------
|
|
112
|
+
// Broadcast MPPT telemetry
|
|
113
|
+
// ---------------------------------------------------------------------------
|
|
114
|
+
void sendMpptData() {
|
|
115
|
+
MpptPackage data = readMpptController();
|
|
116
|
+
|
|
117
|
+
// Serialise with ArduinoJson v7 API
|
|
118
|
+
JsonDocument doc;
|
|
119
|
+
JsonObject obj = doc.to<JsonObject>();
|
|
120
|
+
data.addTo(std::move(obj));
|
|
121
|
+
|
|
122
|
+
String msg;
|
|
123
|
+
serializeJson(doc, msg);
|
|
124
|
+
|
|
125
|
+
if (mesh.sendBroadcast(msg)) {
|
|
126
|
+
Serial.printf(
|
|
127
|
+
"MPPT sent: PV=%.1fV/%.1fA/%dW Bat=%.1fV/%d%% "
|
|
128
|
+
"Load=%.1fV/%.1fA State=%d Temp=%d°C\n",
|
|
129
|
+
data.solarVoltage, data.solarCurrent, data.solarPower,
|
|
130
|
+
data.batteryVoltage, data.batterySOC,
|
|
131
|
+
data.loadVoltage, data.loadCurrent,
|
|
132
|
+
data.chargeState, data.controllerTemp);
|
|
133
|
+
} else {
|
|
134
|
+
Serial.println("sendBroadcast failed – check mesh connectivity");
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// ---------------------------------------------------------------------------
|
|
139
|
+
// Receive handler
|
|
140
|
+
// ---------------------------------------------------------------------------
|
|
141
|
+
void handleIncomingPackage(uint32_t from, String& msg) {
|
|
142
|
+
JsonDocument doc;
|
|
143
|
+
if (deserializeJson(doc, msg) != DeserializationError::Ok) {
|
|
144
|
+
Serial.printf("JSON parse error from %u\n", from);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
JsonObject obj = doc.as<JsonObject>();
|
|
149
|
+
uint16_t msgType = obj["type"];
|
|
150
|
+
|
|
151
|
+
switch (msgType) {
|
|
152
|
+
case 203: { // MpptPackage
|
|
153
|
+
MpptPackage received(obj);
|
|
154
|
+
Serial.printf(
|
|
155
|
+
"MPPT from %u: PV=%.1fV/%.1fA/%dW Bat=%.1fV/%d%% "
|
|
156
|
+
"Load=%.1fV/%.1fA State=%d Temp=%d°C\n",
|
|
157
|
+
received.from,
|
|
158
|
+
received.solarVoltage, received.solarCurrent, received.solarPower,
|
|
159
|
+
received.batteryVoltage, received.batterySOC,
|
|
160
|
+
received.loadVoltage, received.loadCurrent,
|
|
161
|
+
received.chargeState, received.controllerTemp);
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
case 400: { // CommandPackage
|
|
166
|
+
CommandPackage cmd(obj);
|
|
167
|
+
if (cmd.dest == mesh.getNodeId()) {
|
|
168
|
+
handleCommandPackage(cmd);
|
|
169
|
+
}
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
default:
|
|
174
|
+
// Silently ignore unknown types
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// ---------------------------------------------------------------------------
|
|
180
|
+
// Command handler
|
|
181
|
+
// ---------------------------------------------------------------------------
|
|
182
|
+
void handleCommandPackage(CommandPackage& cmd) {
|
|
183
|
+
switch (cmd.command) {
|
|
184
|
+
case 10: // Immediate MPPT data request
|
|
185
|
+
Serial.printf("Immediate data request from command %u\n", cmd.commandId);
|
|
186
|
+
sendMpptData();
|
|
187
|
+
break;
|
|
188
|
+
|
|
189
|
+
default:
|
|
190
|
+
Serial.printf("Unknown command %d\n", cmd.command);
|
|
191
|
+
break;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// ---------------------------------------------------------------------------
|
|
196
|
+
// Mesh callbacks
|
|
197
|
+
// ---------------------------------------------------------------------------
|
|
198
|
+
void newConnectionCallback(uint32_t nodeId) {
|
|
199
|
+
Serial.printf("New connection: nodeId = %u\n", nodeId);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
void changedConnectionCallback() {
|
|
203
|
+
Serial.println("Connections changed");
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
void nodeTimeAdjustedCallback(int32_t offset) {
|
|
207
|
+
Serial.printf("Time adjusted: offset = %d µs\n", offset);
|
|
208
|
+
}
|
|
@@ -238,6 +238,23 @@ void setup() {
|
|
|
238
238
|
mesh.onBridgeStatusChanged(&bridgeStatusCallback);
|
|
239
239
|
mesh.onBridgeRoleChanged(&bridgeRoleCallback);
|
|
240
240
|
|
|
241
|
+
// Monitor bridge coordination (fires every ~30s per bridge)
|
|
242
|
+
mesh.onBridgeCoordination(
|
|
243
|
+
[](const plugin::BridgeCoordinationPackage& pkg, uint32_t fromNode) {
|
|
244
|
+
Serial.printf("Bridge %u: priority=%d, load=%d%%\n",
|
|
245
|
+
fromNode, pkg.priority, pkg.load);
|
|
246
|
+
}
|
|
247
|
+
);
|
|
248
|
+
|
|
249
|
+
// Get notified when bridge state changes (new/updated/lost)
|
|
250
|
+
mesh.onBridgeCoordinationChanged(
|
|
251
|
+
[](const plugin::BridgeCoordinationPackage& pkg, uint32_t fromNode,
|
|
252
|
+
TSTRING changeType) {
|
|
253
|
+
Serial.printf("Bridge %s: %u (role=%s)\n",
|
|
254
|
+
changeType.c_str(), fromNode, pkg.role.c_str());
|
|
255
|
+
}
|
|
256
|
+
);
|
|
257
|
+
|
|
241
258
|
// Configure logging
|
|
242
259
|
mesh.setDebugMsgTypes(ERROR | STARTUP | CONNECTION);
|
|
243
260
|
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
cmake_minimum_required(VERSION 3.10)
|
|
2
|
+
project(PCMeshNode)
|
|
3
|
+
|
|
4
|
+
set(CMAKE_CXX_STANDARD 14)
|
|
5
|
+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
6
|
+
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
|
7
|
+
|
|
8
|
+
# Find Boost (compatible with different CMake versions and platforms)
|
|
9
|
+
FIND_PACKAGE(Boost 1.66 COMPONENTS system)
|
|
10
|
+
|
|
11
|
+
IF(Boost_FOUND)
|
|
12
|
+
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
|
|
13
|
+
LINK_DIRECTORIES(${Boost_LIBRARY_DIRS})
|
|
14
|
+
message(STATUS "Boost found: ${Boost_VERSION}")
|
|
15
|
+
message(STATUS "Boost include dirs: ${Boost_INCLUDE_DIRS}")
|
|
16
|
+
ELSE()
|
|
17
|
+
message(FATAL_ERROR "Boost not found! Please install Boost development libraries:\n"
|
|
18
|
+
" Ubuntu/Debian: sudo apt-get install libboost-dev libboost-system-dev\n"
|
|
19
|
+
" macOS: brew install boost\n"
|
|
20
|
+
" Windows: See https://www.boost.org/")
|
|
21
|
+
ENDIF()
|
|
22
|
+
|
|
23
|
+
# Set compiler flags
|
|
24
|
+
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
|
|
25
|
+
|
|
26
|
+
# Add executable
|
|
27
|
+
add_executable(pc_mesh_node
|
|
28
|
+
pc_mesh_node.cpp
|
|
29
|
+
../../test/catch/fake_serial.cpp
|
|
30
|
+
../../src/scheduler.cpp
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
# Include directories
|
|
34
|
+
target_include_directories(pc_mesh_node PUBLIC
|
|
35
|
+
../../test/include/
|
|
36
|
+
../../test/boost/
|
|
37
|
+
../../test/ArduinoJson/src/
|
|
38
|
+
../../test/TaskScheduler/src/
|
|
39
|
+
../../src/
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
# Link libraries
|
|
43
|
+
TARGET_LINK_LIBRARIES(pc_mesh_node ${Boost_LIBRARIES})
|
|
44
|
+
|
|
45
|
+
# Print instructions
|
|
46
|
+
message(STATUS "")
|
|
47
|
+
message(STATUS "===========================================")
|
|
48
|
+
message(STATUS "PC Mesh Node - Build Configuration")
|
|
49
|
+
message(STATUS "===========================================")
|
|
50
|
+
message(STATUS "Build with: cmake . && make")
|
|
51
|
+
message(STATUS "Run with: ./pc_mesh_node <bridge_ip> <bridge_port>")
|
|
52
|
+
message(STATUS "Example: ./pc_mesh_node 192.168.1.100 5555")
|
|
53
|
+
message(STATUS "===========================================")
|
|
54
|
+
message(STATUS "")
|