|
3 | 3 | #include "HttpPowerMeter.h"
|
4 | 4 | #include "MessageOutput.h"
|
5 | 5 | #include <WiFiClientSecure.h>
|
6 |
| -#include <FirebaseJson.h> |
7 |
| -#include <Crypto.h> |
8 |
| -#include <SHA256.h> |
| 6 | +#include <ArduinoJson.h> |
| 7 | +#include "mbedtls/sha256.h" |
9 | 8 | #include <base64.h>
|
10 | 9 | #include <memory>
|
11 | 10 | #include <ESPmDNS.h>
|
@@ -219,18 +218,43 @@ String HttpPowerMeterClass::getDigestAuth(String& authReq, const String& usernam
|
219 | 218 | return authorization;
|
220 | 219 | }
|
221 | 220 |
|
222 |
| -bool HttpPowerMeterClass::tryGetFloatValueForPhase(int phase, const char* jsonPath, Unit_t unit, bool signInverted) |
| 221 | +bool HttpPowerMeterClass::tryGetFloatValueForPhase(int phase, String jsonPath, Unit_t unit, bool signInverted) |
223 | 222 | {
|
224 |
| - FirebaseJson json; |
225 |
| - json.setJsonData(httpResponse); |
226 |
| - FirebaseJsonData value; |
227 |
| - if (!json.get(value, jsonPath)) { |
228 |
| - snprintf_P(httpPowerMeterError, sizeof(httpPowerMeterError), PSTR("[HttpPowerMeter] Couldn't find a value for phase %i with Json query \"%s\""), phase, jsonPath); |
| 223 | + JsonDocument root; |
| 224 | + const DeserializationError error = deserializeJson(root, httpResponse); |
| 225 | + if (error) { |
| 226 | + snprintf_P(httpPowerMeterError, sizeof(httpPowerMeterError), |
| 227 | + PSTR("[HttpPowerMeter] Unable to parse server response as JSON")); |
| 228 | + return false; |
| 229 | + } |
| 230 | + |
| 231 | + constexpr char delimiter = '/'; |
| 232 | + int start = 0; |
| 233 | + int end = jsonPath.indexOf(delimiter); |
| 234 | + auto value = root.as<JsonVariantConst>(); |
| 235 | + |
| 236 | + // NOTE: "Because ArduinoJson implements the Null Object Pattern, it is |
| 237 | + // always safe to read the object: if the key doesn't exist, it returns an |
| 238 | + // empty value." |
| 239 | + while (end != -1) { |
| 240 | + String key = jsonPath.substring(start, end); |
| 241 | + value = value[key]; |
| 242 | + start = end + 1; |
| 243 | + end = jsonPath.indexOf(delimiter, start); |
| 244 | + } |
| 245 | + |
| 246 | + String lastKey = jsonPath.substring(start); |
| 247 | + value = value[lastKey]; |
| 248 | + |
| 249 | + if (value.isNull()) { |
| 250 | + snprintf_P(httpPowerMeterError, sizeof(httpPowerMeterError), |
| 251 | + PSTR("[HttpPowerMeter] Unable to find a value for phase %i with JSON path \"%s\""), |
| 252 | + phase+1, jsonPath.c_str()); |
229 | 253 | return false;
|
230 | 254 | }
|
231 | 255 |
|
232 | 256 | // this value is supposed to be in Watts and positive if energy is consumed.
|
233 |
| - power[phase] = value.to<float>(); |
| 257 | + power[phase] = value.as<float>(); |
234 | 258 |
|
235 | 259 | switch (unit) {
|
236 | 260 | case Unit_t::MilliWatts:
|
@@ -299,27 +323,24 @@ bool HttpPowerMeterClass::extractUrlComponents(String url, String& _protocol, St
|
299 | 323 | return true;
|
300 | 324 | }
|
301 | 325 |
|
302 |
| -#define HASH_SIZE 32 |
303 |
| - |
304 | 326 | String HttpPowerMeterClass::sha256(const String& data) {
|
305 |
| - SHA256 sha256; |
306 |
| - uint8_t hash[HASH_SIZE]; |
307 |
| - |
308 |
| - sha256.reset(); |
309 |
| - sha256.update(data.c_str(), data.length()); |
310 |
| - sha256.finalize(hash, HASH_SIZE); |
311 |
| - |
312 |
| - String hashStr = ""; |
313 |
| - for (int i = 0; i < HASH_SIZE; i++) { |
314 |
| - String hex = String(hash[i], HEX); |
315 |
| - if (hex.length() == 1) { |
316 |
| - hashStr += "0"; |
317 |
| - } |
318 |
| - hashStr += hex; |
| 327 | + uint8_t hash[32]; |
| 328 | + |
| 329 | + mbedtls_sha256_context ctx; |
| 330 | + mbedtls_sha256_init(&ctx); |
| 331 | + mbedtls_sha256_starts(&ctx, 0); // select SHA256 |
| 332 | + mbedtls_sha256_update(&ctx, reinterpret_cast<const unsigned char*>(data.c_str()), data.length()); |
| 333 | + mbedtls_sha256_finish(&ctx, hash); |
| 334 | + mbedtls_sha256_free(&ctx); |
| 335 | + |
| 336 | + char res[sizeof(hash) * 2 + 1]; |
| 337 | + for (int i = 0; i < sizeof(hash); i++) { |
| 338 | + snprintf(res + (i*2), sizeof(res) - (i*2), "%02x", hash[i]); |
319 | 339 | }
|
320 | 340 |
|
321 |
| - return hashStr; |
| 341 | + return res; |
322 | 342 | }
|
| 343 | + |
323 | 344 | void HttpPowerMeterClass::prepareRequest(uint32_t timeout, const char* httpHeader, const char* httpValue) {
|
324 | 345 | httpClient.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
|
325 | 346 | httpClient.setUserAgent("OpenDTU-OnBattery");
|
|
0 commit comments