AlteriomPainlessMesh v2.1.1
Easy ESP32/ESP8266 mesh networking with Alteriom IoT extensions
Loading...
Searching...
No Matches
performance.hpp
Go to the documentation of this file.
1#ifndef _PAINLESS_MESH_PLUGIN_PERFORMANCE_HPP_
2#define _PAINLESS_MESH_PLUGIN_PERFORMANCE_HPP_
3
5
8
9namespace painlessmesh {
10namespace plugin {
16namespace performance {
17
22class 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
55 public:
56 int id = 0; // Can see if we missed values
57 int time = 0; // Get an idea of the delay, by comparing it with nodetime
58 int stability = 0; // stability of the sending node
59 int freeMemory = 0; // memory of the sending node
60#ifdef ESP32
61 TSTRING hardware = "ESP32";
62#else
63 TSTRING hardware = "ESP8266";
64#endif
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
94class Track {
95 public:
96 uint32_t nodeId = 0;
98 uint32_t hits = 0;
99 uint32_t misses = 0;
100 int lastId = 0;
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
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
154template <class T>
155void 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
JsonObject addTo(JsonObject &&jsonObj) const
Definition plugin.hpp:84
int type
Definition plugin.hpp:73
PerformancePackage(JsonObject jsonObj)
Definition performance.hpp:67
JsonObject addTo(JsonObject &&jsonObj) const
Definition performance.hpp:75
PerformancePackage()
Definition performance.hpp:65
size_t jsonObjectSize() const
Definition performance.hpp:87
TSTRING hardware
Definition performance.hpp:63
Definition performance.hpp:22
TSTRING toString() const
Definition performance.hpp:36
void update(double v, double alpha=0.1)
Definition performance.hpp:24
double var
Definition performance.hpp:50
bool init
Definition performance.hpp:51
double mu
Definition performance.hpp:49
Holds resulst from all the nodes.
Definition performance.hpp:124
JsonObject addTo(JsonObject &&jsonObj) const
Definition performance.hpp:126
size_t jsonObjectSize() const
Definition performance.hpp:147
Numbers to track for each node we receive PerformancePackages from.
Definition performance.hpp:94
uint32_t misses
Definition performance.hpp:99
uint32_t present
Definition performance.hpp:104
Stats stability
Definition performance.hpp:102
uint32_t absent
Definition performance.hpp:106
Stats delay
Definition performance.hpp:101
void addTo(JsonObject &jsonObj) const
Definition performance.hpp:109
Stats freeMemory
Definition performance.hpp:103
int lastId
Definition performance.hpp:100
TSTRING hardware
Definition performance.hpp:97
Track()
Definition performance.hpp:107
uint32_t nodeId
Definition performance.hpp:96
uint32_t hits
Definition performance.hpp:98
Definition protocol.hpp:481
String TSTRING
Definition configuration.hpp:132
void begin(T &mesh, double frequency=2)
Definition performance.hpp:155
Definition wifi.hpp:34