-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathparser.cpp
More file actions
77 lines (73 loc) · 3.26 KB
/
parser.cpp
File metadata and controls
77 lines (73 loc) · 3.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include "parser.h"
// Attempt to parse minimized jq filtered JSON first; fallback to broader legacy layout.
bool ParseEvccState(const String& body, Metrics& out) {
StaticJsonDocument<1024> doc; // sized for minimized payload
DeserializationError err = deserializeJson(doc, body);
if (err) {
return false; // caller may log details
}
// Primary (minimized) structure: {gridPower, pvPower, loadpoints:[{chargePower, soc/vehicleSoc, charging, plugged}, ...]}
bool usedMin = true;
JsonArray lps = doc["loadpoints"].as<JsonArray>();
if (doc.containsKey("gridPower")) {
out.gridPower = doc["gridPower"].as<long>();
} else {
usedMin = false;
}
if (doc.containsKey("pvPower")) {
out.pvPower = doc["pvPower"].as<long>();
} else {
usedMin = false;
}
if (usedMin && !lps.isNull() && lps.size() > 0) {
out.totalChargePower = 0;
out.lpCount = 0;
uint8_t limit = lps.size() < 2 ? lps.size() : 2;
for (uint8_t i=0; i<limit; i++) {
JsonVariant lpi = lps[i];
MetricsLoadpoint &mlp = out.lps[i];
mlp.chargePower = lpi["chargePower"].as<long>();
if (lpi["soc"].is<int>()) mlp.soc = lpi["soc"].as<int>();
else if (lpi["soc"].is<float>()) mlp.soc = (int)(lpi["soc"].as<float>() + 0.5f);
else if (lpi["vehicleSoc"].is<int>()) mlp.soc = lpi["vehicleSoc"].as<int>();
else if (lpi["vehicleSoc"].is<float>()) mlp.soc = (int)(lpi["vehicleSoc"].as<float>() + 0.5f);
mlp.charging = lpi["charging"].as<bool>();
mlp.plugged = lpi["plugged"].as<bool>() || lpi["connected"].as<bool>();
out.totalChargePower += mlp.chargePower;
out.lpCount++;
}
return true;
}
// Fallback: try legacy / full state keys
// grid.power, pvPower, loadpoints array objects with chargePower & vehicleSoc or soc
JsonVariant grid = doc["grid"];
if (grid.is<JsonObject>() && grid["power"].is<long>()) {
out.gridPower = grid["power"].as<long>();
}
if (doc["pvPower"].is<long>()) {
out.pvPower = doc["pvPower"].as<long>();
}
if (doc["loadpoints"].is<JsonArray>()) {
lps = doc["loadpoints"].as<JsonArray>();
out.totalChargePower = 0;
out.lpCount = 0;
if (!lps.isNull()) {
uint8_t limit = lps.size() < 2 ? lps.size() : 2;
for (uint8_t i=0; i<limit; i++) {
JsonVariant lpv = lps[i];
MetricsLoadpoint &mlp = out.lps[i];
mlp.chargePower = lpv["chargePower"].as<long>();
if (lpv["vehicleSoc"].is<int>()) mlp.soc = lpv["vehicleSoc"].as<int>();
else if (lpv["vehicleSoc"].is<float>()) mlp.soc = (int)(lpv["vehicleSoc"].as<float>() + 0.5f);
else if (lpv["soc"].is<int>()) mlp.soc = lpv["soc"].as<int>();
else if (lpv["soc"].is<float>()) mlp.soc = (int)(lpv["soc"].as<float>() + 0.5f);
mlp.charging = lpv["charging"].as<bool>();
mlp.plugged = lpv["connected"].as<bool>() || lpv["plugged"].as<bool>();
out.totalChargePower += mlp.chargePower;
out.lpCount++;
}
}
return true;
}
return false; // nothing usable
}