@alteriom/painlessmesh 1.6.1

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 (80) hide show
  1. package/CHANGELOG.md +144 -0
  2. package/LICENSE +674 -0
  3. package/README.md +434 -0
  4. package/RELEASE_GUIDE.md +419 -0
  5. package/docs/DOCUMENTATION_MIGRATION_PLAN.md +176 -0
  6. package/docs/README.md +71 -0
  7. package/docs/alteriom/overview.md +508 -0
  8. package/docs/api/core-api.md +607 -0
  9. package/docs/architecture/mesh-architecture.md +379 -0
  10. package/docs/architecture/plugin-system.md +517 -0
  11. package/docs/getting-started/first-mesh.md +410 -0
  12. package/docs/getting-started/installation.md +275 -0
  13. package/docs/getting-started/quickstart.md +158 -0
  14. package/docs/improvements/README.md +69 -0
  15. package/docs/troubleshooting/common-issues.md +521 -0
  16. package/docs/troubleshooting/faq.md +473 -0
  17. package/docs/tutorials/basic-examples.md +718 -0
  18. package/docs/wiki/API-Reference.md +246 -0
  19. package/docs/wiki/Complete-Documentation.md +123 -0
  20. package/examples/alteriom/README.md +82 -0
  21. package/examples/alteriom/alteriom.ino +186 -0
  22. package/examples/alteriom/alteriom_sensor_node.ino +184 -0
  23. package/examples/alteriom/alteriom_sensor_package.hpp +128 -0
  24. package/examples/alteriom/improved_sensor_node.ino +246 -0
  25. package/examples/alteriom/platformio.ini +25 -0
  26. package/examples/basic/basic.ino +66 -0
  27. package/examples/basic/platformio.ini +25 -0
  28. package/examples/bridge/bridge.ino +51 -0
  29. package/examples/bridge/platformio.ini +25 -0
  30. package/examples/echoNode/echoNode.ino +33 -0
  31. package/examples/echoNode/platformio.ini +25 -0
  32. package/examples/logClient/logClient.ino +109 -0
  33. package/examples/logClient/platformio.ini +25 -0
  34. package/examples/logServer/logServer.ino +81 -0
  35. package/examples/logServer/platformio.ini +25 -0
  36. package/examples/mqttBridge/mqttBridge.ino +118 -0
  37. package/examples/mqttBridge/platformio.ini +26 -0
  38. package/examples/namedMesh/namedMesh.ino +97 -0
  39. package/examples/namedMesh/platformio.ini +25 -0
  40. package/examples/otaReceiver/otaReceiver.ino +79 -0
  41. package/examples/otaReceiver/platformio.ini +25 -0
  42. package/examples/otaSender/nodemcu32s_connections.JPG +0 -0
  43. package/examples/otaSender/otaSender.ino +151 -0
  44. package/examples/otaSender/platformio.ini +25 -0
  45. package/examples/startHere/platformio.ini +25 -0
  46. package/examples/startHere/startHere.ino +159 -0
  47. package/examples/webServer/platformio.ini +27 -0
  48. package/examples/webServer/webServer.ino +89 -0
  49. package/keywords.txt +49 -0
  50. package/library.json +34 -0
  51. package/library.properties +11 -0
  52. package/package.json +78 -0
  53. package/src/AlteriomPainlessMesh.h +98 -0
  54. package/src/arduino/wifi.hpp +365 -0
  55. package/src/boost/asynctcp.hpp +279 -0
  56. package/src/painlessMesh.h +70 -0
  57. package/src/painlessMeshSTA.cpp +236 -0
  58. package/src/painlessMeshSTA.h +58 -0
  59. package/src/painlessTaskOptions.h +4 -0
  60. package/src/painlessmesh/base64.hpp +111 -0
  61. package/src/painlessmesh/buffer.hpp +229 -0
  62. package/src/painlessmesh/callback.hpp +91 -0
  63. package/src/painlessmesh/configuration.hpp +77 -0
  64. package/src/painlessmesh/connection.hpp +192 -0
  65. package/src/painlessmesh/layout.hpp +188 -0
  66. package/src/painlessmesh/logger.hpp +158 -0
  67. package/src/painlessmesh/memory.hpp +120 -0
  68. package/src/painlessmesh/mesh.hpp +560 -0
  69. package/src/painlessmesh/metrics.hpp +323 -0
  70. package/src/painlessmesh/ntp.hpp +263 -0
  71. package/src/painlessmesh/ota.hpp +553 -0
  72. package/src/painlessmesh/plugin.hpp +188 -0
  73. package/src/painlessmesh/protocol.hpp +813 -0
  74. package/src/painlessmesh/router.hpp +322 -0
  75. package/src/painlessmesh/tcp.hpp +71 -0
  76. package/src/painlessmesh/validation.hpp +239 -0
  77. package/src/plugin/performance.hpp +214 -0
  78. package/src/plugin/remote.hpp +64 -0
  79. package/src/scheduler.cpp +10 -0
  80. package/src/wifi.cpp +2 -0
@@ -0,0 +1,214 @@
1
+ #ifndef _PAINLESS_MESH_PLUGIN_PERFORMANCE_HPP_
2
+ #define _PAINLESS_MESH_PLUGIN_PERFORMANCE_HPP_
3
+
4
+ #include "painlessmesh/configuration.hpp"
5
+
6
+ #include "painlessmesh/logger.hpp"
7
+ #include "painlessmesh/plugin.hpp"
8
+
9
+ namespace painlessmesh {
10
+ namespace plugin {
11
+ /** Add performance tracking to the mesh
12
+ *
13
+ * Nodes will send out special packages to each other, allowing each node to
14
+ * keep track of different performance measures
15
+ */
16
+ namespace performance {
17
+
18
+ /** Track mean and variance of the given value
19
+ *
20
+ * Older values are discounted, so that you keep a rolling average
21
+ */
22
+ class Stats {
23
+ public:
24
+ void update(double v, double alpha = 0.1) {
25
+ if (!init) {
26
+ mu = v;
27
+ init = true;
28
+ return;
29
+ }
30
+ auto d = v - mu;
31
+ mu = mu + alpha * d;
32
+ var = (1 - alpha) * (var + alpha * pow(d, 2));
33
+ }
34
+
35
+ // Returns the mean and 95% interval based on 1.96*sd? or 2.96*sd
36
+ TSTRING toString() const {
37
+ #ifdef PAINLESSMESH_ENABLE_STD_STRING
38
+ std::stringstream ss;
39
+ ss << mu << "[" << mu - 1.96 * sqrt(var) << "," << mu + 1.96 * sqrt(var)
40
+ << "]";
41
+ return ss.str();
42
+ #else
43
+ return TSTRING(mu) + TSTRING("[") + TSTRING(mu - 1.96 * sqrt(var)) +
44
+ TSTRING(",") + TSTRING(mu + 1.96 * sqrt(var)) + TSTRING("]");
45
+ #endif
46
+ }
47
+
48
+ protected:
49
+ double mu = 0;
50
+ double var = 0;
51
+ bool init = false;
52
+ };
53
+
54
+ class PerformancePackage : public plugin::BroadcastPackage {
55
+ public:
56
+ int id = 0; // Can see if we missed values
57
+ int time; // Get an idea of the delay, by comparing it with nodetime
58
+ int stability; // stability of the sending node
59
+ int freeMemory; // memory of the sending node
60
+ #ifdef ESP32
61
+ TSTRING hardware = "ESP32";
62
+ #else
63
+ TSTRING hardware = "ESP8266";
64
+ #endif
65
+ PerformancePackage() : plugin::BroadcastPackage(13) {}
66
+
67
+ PerformancePackage(JsonObject jsonObj) : plugin::BroadcastPackage(jsonObj) {
68
+ id = jsonObj["id"];
69
+ time = jsonObj["time"];
70
+ stability = jsonObj["stability"];
71
+ freeMemory = jsonObj["freeMemory"];
72
+ hardware = jsonObj["hardware"].as<TSTRING>();
73
+ }
74
+
75
+ JsonObject addTo(JsonObject&& jsonObj) const {
76
+ jsonObj = BroadcastPackage::addTo(std::move(jsonObj));
77
+ jsonObj["type"] = type;
78
+ jsonObj["id"] = id;
79
+ jsonObj["time"] = time;
80
+ jsonObj["stability"] = stability;
81
+ jsonObj["freeMemory"] = freeMemory;
82
+ jsonObj["hardware"] = hardware;
83
+ return jsonObj;
84
+ }
85
+
86
+ #if ARDUINOJSON_VERSION_MAJOR < 7
87
+ size_t jsonObjectSize() const {
88
+ return JSON_OBJECT_SIZE(4 + 5) + round(2 * (hardware.length()));
89
+ }
90
+ #endif
91
+ };
92
+
93
+ /// Numbers to track for each node we receive PerformancePackages from
94
+ class Track {
95
+ public:
96
+ uint32_t nodeId;
97
+ TSTRING hardware;
98
+ uint32_t hits = 0;
99
+ uint32_t misses = 0;
100
+ int lastId = 0;
101
+ Stats delay;
102
+ Stats stability;
103
+ Stats freeMemory;
104
+ uint32_t present = 0; // Every so often check if each node is absent or
105
+ // present in the layout
106
+ uint32_t absent = 0;
107
+ Track() {}
108
+
109
+ void addTo(JsonObject& jsonObj) const {
110
+ jsonObj["nodeId"] = nodeId;
111
+ jsonObj["hardware"] = hardware;
112
+ jsonObj["hits"] = hits;
113
+ jsonObj["misses"] = misses;
114
+ jsonObj["delay"] = delay.toString();
115
+ jsonObj["stability"] = stability.toString();
116
+ jsonObj["freeMemory"] = freeMemory.toString();
117
+ jsonObj["present"] = present;
118
+ jsonObj["absent"] = absent;
119
+ }
120
+ };
121
+
122
+ /// Holds resulst from all the nodes
123
+ class TrackMap : public protocol::PackageInterface,
124
+ public std::map<uint32_t, Track> {
125
+ public:
126
+ JsonObject addTo(JsonObject&& jsonObj) const {
127
+ jsonObj["event"] = "performance";
128
+ // Start array
129
+ #if ARDUINOJSON_VERSION_MAJOR == 7
130
+ auto jsonArr = jsonObj["nodes"].to<JsonArray>();
131
+ #else
132
+ auto jsonArr = jsonObj.createNestedArray("nodes");
133
+ #endif
134
+ // for each in map do
135
+ for (auto&& pair : (*this)) {
136
+ #if ARDUINOJSON_VERSION_MAJOR == 7
137
+ JsonObject obj = jsonArr.add<JsonObject>();
138
+ #else
139
+ auto obj = jsonArr.createNestedObject();
140
+ #endif
141
+ pair.second.addTo(obj);
142
+ }
143
+ return jsonObj;
144
+ } // namespace performance
145
+
146
+ #if ARDUINOJSON_VERSION_MAJOR < 7
147
+ size_t jsonObjectSize() const {
148
+ return JSON_OBJECT_SIZE(2 + 15) + JSON_ARRAY_SIZE(this->size()) +
149
+ this->size() * (JSON_OBJECT_SIZE(9) + 4 * 100);
150
+ }
151
+ #endif
152
+ }; // namespace plugin
153
+
154
+ template <class T>
155
+ void begin(T& mesh, double frequency = 2) {
156
+ auto tracker = std::make_shared<TrackMap>();
157
+ auto sendPkg = std::make_shared<PerformancePackage>();
158
+
159
+ mesh.onPackage(sendPkg->type, [&mesh, tracker](protocol::Variant& var) {
160
+ auto pkg = var.to<PerformancePackage>();
161
+ // if not in tracker, add it
162
+ if (!tracker->count(pkg.from)) {
163
+ tracker->operator[](pkg.from) = Track();
164
+ if (pkg.id > 0) tracker->operator[](pkg.from).lastId = pkg.id - 1;
165
+ }
166
+ // update all the values in the trackmap
167
+ tracker->operator[](pkg.from).nodeId = pkg.from;
168
+ tracker->operator[](pkg.from).hardware = pkg.hardware;
169
+ ++tracker->operator[](pkg.from).hits;
170
+ if (pkg.id < tracker->operator[](pkg.from).lastId) // Node was reset?
171
+ tracker->operator[](pkg.from).lastId = pkg.id;
172
+ else {
173
+ tracker->operator[](pkg.from).misses +=
174
+ (pkg.id - tracker->operator[](pkg.from).lastId) - 1;
175
+ }
176
+ tracker->operator[](pkg.from).lastId = pkg.id;
177
+ tracker->operator[](pkg.from).delay.update(
178
+ ((int)mesh.getNodeTime() - pkg.time) / 1000);
179
+ tracker->operator[](pkg.from).stability.update(pkg.stability);
180
+ tracker->operator[](pkg.from).freeMemory.update(pkg.freeMemory);
181
+ return false;
182
+ });
183
+
184
+ sendPkg->from = mesh.getNodeId();
185
+ mesh.addTask(frequency * TASK_SECOND, TASK_FOREVER, [sendPkg, &mesh]() {
186
+ ++sendPkg->id;
187
+ sendPkg->time = mesh.getNodeTime();
188
+ sendPkg->stability = mesh.stability;
189
+ sendPkg->freeMemory = ESP.getFreeHeap();
190
+ mesh.sendPackage(sendPkg.get());
191
+ });
192
+
193
+ mesh.addTask(TASK_MINUTE, TASK_FOREVER, [tracker, &mesh]() {
194
+ for (auto&& pair : (*tracker)) {
195
+ if (mesh.isConnected(pair.first))
196
+ ++pair.second.present;
197
+ else
198
+ ++pair.second.absent;
199
+ }
200
+ protocol::Variant var(tracker.get());
201
+ TSTRING str;
202
+ var.printTo(str);
203
+ #ifdef PAINLESSMESH_ENABLE_STD_STRING
204
+ std::cout << str << std::endl;
205
+ #else
206
+ Serial.println(str);
207
+ #endif
208
+ });
209
+ }
210
+
211
+ } // namespace performance
212
+ } // namespace plugin
213
+ } // namespace painlessmesh
214
+ #endif
@@ -0,0 +1,64 @@
1
+ #pragma once
2
+
3
+ #include "painlessmesh/configuration.hpp"
4
+
5
+ #include "painlessmesh/logger.hpp"
6
+ #include "painlessmesh/plugin.hpp"
7
+
8
+ extern painlessmesh::logger::LogClass Log;
9
+
10
+ namespace painlessmesh {
11
+ namespace plugin {
12
+ /** Add remote logger to the mesh
13
+ *
14
+ * Call remote::begin(nodeId, millis) to start it
15
+ */
16
+ namespace remote {
17
+ class RemotePackage : public plugin::SinglePackage {
18
+ public:
19
+ std::list<std::pair<uint, TSTRING>> log;
20
+ RemotePackage() : plugin::SinglePackage(14) {}
21
+ RemotePackage(JsonObject jsonObj) : plugin::SinglePackage(jsonObj) {
22
+ for (JsonObject doc : jsonObj["log"].as<JsonArray>()) {
23
+ std::pair<uint, TSTRING> pr(doc["first"], doc["second"]);
24
+ log.push_back(pr);
25
+ }
26
+ }
27
+
28
+ JsonObject addTo(JsonObject&& jsonObj) const {
29
+ jsonObj = SinglePackage::addTo(std::move(jsonObj));
30
+ JsonArray arr = jsonObj["log"].to<JsonArray>();
31
+ for (auto&& pr : log) {
32
+ JsonDocument obj;
33
+ obj["first"] = pr.first;
34
+ obj["second"] = pr.second;
35
+ arr.add(obj);
36
+ }
37
+ return jsonObj;
38
+ }
39
+ };
40
+
41
+ template <class T>
42
+ void begin(T& mesh, uint32_t destination, double frequency = 120,
43
+ std::function<bool(protocol::Variant&)> callback = nullptr) {
44
+ auto sendPkg = std::make_shared<RemotePackage>();
45
+ sendPkg->from = mesh.getNodeId();
46
+ sendPkg->dest = destination;
47
+ mesh.addTask(frequency * TASK_SECOND, TASK_FOREVER, [sendPkg, &mesh]() {
48
+ Log.remote("Memory %u and stability %u\n", ESP.getFreeHeap(),
49
+ mesh.stability);
50
+ // Note that we could clear the queue afterwards, but we
51
+ // actually want to keep resending it in case something just
52
+ // went wrong and we lost connection
53
+ sendPkg->log = Log.get_remote_queue();
54
+ if (!sendPkg->log.empty()) mesh.sendPackage(sendPkg.get());
55
+ });
56
+
57
+ if (callback) {
58
+ mesh.onPackage(sendPkg->type, callback);
59
+ }
60
+ }
61
+
62
+ } // namespace remote
63
+ } // namespace plugin
64
+ } // namespace painlessmesh
@@ -0,0 +1,10 @@
1
+ /*
2
+ * https://github.com/arkhipenko/TaskScheduler/tree/master/examples/Scheduler_example16_Multitab
3
+ */
4
+
5
+ #include "painlessTaskOptions.h"
6
+
7
+ #pragma GCC diagnostic push
8
+ #pragma GCC diagnostic ignored "-Wunused-function"
9
+ #include <TaskScheduler.h>
10
+ #pragma GCC diagnostic pop
package/src/wifi.cpp ADDED
@@ -0,0 +1,2 @@
1
+ #include "arduino/wifi.hpp"
2
+ painlessmesh::logger::LogClass Log;