@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.
Files changed (41) hide show
  1. package/CHANGELOG.md +62 -0
  2. package/README.md +82 -63
  3. package/examples/alteriom/README.md +4 -4
  4. package/examples/alteriom/alteriom_custom_package_template.hpp +320 -0
  5. package/examples/alteriom/alteriom_sensor_package.hpp +1 -1
  6. package/examples/alteriom/mppt_example/alteriom_mppt_example.ino +208 -0
  7. package/examples/bridge_failover/bridge_failover.ino +17 -0
  8. package/examples/sendToInternet/CMakeLists.txt +54 -0
  9. package/examples/sendToInternet/PC_NODE_README.md +517 -0
  10. package/examples/sendToInternet/README.md +39 -1
  11. package/examples/sendToInternet/build.sh +153 -0
  12. package/examples/sendToInternet/mock_server_test.ino +361 -0
  13. package/examples/sendToInternet/pc_mesh_node.cpp +361 -0
  14. package/library.json +4 -1
  15. package/library.properties +1 -1
  16. package/package.json +3 -3
  17. package/src/AlteriomPainlessMesh.h +5 -13
  18. package/src/arduino/wifi.hpp +306 -100
  19. package/src/connection.cpp +10 -0
  20. package/src/painlessMesh.h +1 -14
  21. package/src/painlessmesh/connection.hpp +11 -16
  22. package/src/painlessmesh/gateway.hpp +0 -1061
  23. package/src/painlessmesh/mesh.hpp +58 -86
  24. package/src/painlessmesh/message_queue.hpp +1 -2
  25. package/src/painlessmesh/metrics.hpp +2 -262
  26. package/src/painlessmesh/validation.hpp +0 -143
  27. package/docs/README.md +0 -132
  28. package/docs/alteriom/overview.md +0 -531
  29. package/docs/api/core-api.md +0 -607
  30. package/docs/api/shared-gateway.md +0 -1207
  31. package/docs/architecture/mesh-architecture.md +0 -399
  32. package/docs/architecture/plugin-system.md +0 -517
  33. package/docs/getting-started/arduino-manual-install.md +0 -313
  34. package/docs/getting-started/first-mesh.md +0 -410
  35. package/docs/getting-started/installation.md +0 -275
  36. package/docs/getting-started/quickstart.md +0 -158
  37. package/docs/troubleshooting/common-issues.md +0 -679
  38. package/docs/troubleshooting/debugging.md +0 -455
  39. package/docs/troubleshooting/external-device-connection.md +0 -283
  40. package/docs/troubleshooting/faq.md +0 -574
  41. 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 "")