Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove redundant libraries (FirebaseJson and Crypto) #958

Merged
merged 2 commits into from
May 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/HttpPowerMeter.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class HttpPowerMeterClass {
String extractParam(String& authReq, const String& param, const char delimit);
String getcNonce(const int len);
String getDigestAuth(String& authReq, const String& username, const String& password, const String& method, const String& uri, unsigned int counter);
bool tryGetFloatValueForPhase(int phase, const char* jsonPath, Unit_t unit, bool signInverted);
bool tryGetFloatValueForPhase(int phase, String jsonPath, Unit_t unit, bool signInverted);
void prepareRequest(uint32_t timeout, const char* httpHeader, const char* httpValue);
String sha256(const String& data);
};
Expand Down
2 changes: 0 additions & 2 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,6 @@ lib_deps =
https://github.com/coryjfowler/MCP_CAN_lib
plerup/EspSoftwareSerial @ ^8.0.1
https://github.com/dok-net/ghostl @ ^1.0.1
mobizt/FirebaseJson @ ^3.0.6
rweather/Crypto@^0.4.0

extra_scripts =
pre:pio-scripts/auto_firmware_version.py
Expand Down
75 changes: 48 additions & 27 deletions src/HttpPowerMeter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@
#include "HttpPowerMeter.h"
#include "MessageOutput.h"
#include <WiFiClientSecure.h>
#include <FirebaseJson.h>
#include <Crypto.h>
#include <SHA256.h>
#include <ArduinoJson.h>
#include "mbedtls/sha256.h"
#include <base64.h>
#include <memory>
#include <ESPmDNS.h>
Expand Down Expand Up @@ -219,18 +218,43 @@ String HttpPowerMeterClass::getDigestAuth(String& authReq, const String& usernam
return authorization;
}

bool HttpPowerMeterClass::tryGetFloatValueForPhase(int phase, const char* jsonPath, Unit_t unit, bool signInverted)
bool HttpPowerMeterClass::tryGetFloatValueForPhase(int phase, String jsonPath, Unit_t unit, bool signInverted)
{
FirebaseJson json;
json.setJsonData(httpResponse);
FirebaseJsonData value;
if (!json.get(value, jsonPath)) {
snprintf_P(httpPowerMeterError, sizeof(httpPowerMeterError), PSTR("[HttpPowerMeter] Couldn't find a value for phase %i with Json query \"%s\""), phase, jsonPath);
JsonDocument root;
const DeserializationError error = deserializeJson(root, httpResponse);
if (error) {
snprintf_P(httpPowerMeterError, sizeof(httpPowerMeterError),
PSTR("[HttpPowerMeter] Unable to parse server response as JSON"));
return false;
}

constexpr char delimiter = '/';
int start = 0;
int end = jsonPath.indexOf(delimiter);
auto value = root.as<JsonVariantConst>();

// NOTE: "Because ArduinoJson implements the Null Object Pattern, it is
// always safe to read the object: if the key doesn't exist, it returns an
// empty value."
while (end != -1) {
String key = jsonPath.substring(start, end);
value = value[key];
start = end + 1;
end = jsonPath.indexOf(delimiter, start);
}

String lastKey = jsonPath.substring(start);
value = value[lastKey];

if (value.isNull()) {
snprintf_P(httpPowerMeterError, sizeof(httpPowerMeterError),
PSTR("[HttpPowerMeter] Unable to find a value for phase %i with JSON path \"%s\""),
phase+1, jsonPath.c_str());
return false;
}

// this value is supposed to be in Watts and positive if energy is consumed.
power[phase] = value.to<float>();
power[phase] = value.as<float>();

switch (unit) {
case Unit_t::MilliWatts:
Expand Down Expand Up @@ -299,27 +323,24 @@ bool HttpPowerMeterClass::extractUrlComponents(String url, String& _protocol, St
return true;
}

#define HASH_SIZE 32

String HttpPowerMeterClass::sha256(const String& data) {
SHA256 sha256;
uint8_t hash[HASH_SIZE];

sha256.reset();
sha256.update(data.c_str(), data.length());
sha256.finalize(hash, HASH_SIZE);

String hashStr = "";
for (int i = 0; i < HASH_SIZE; i++) {
String hex = String(hash[i], HEX);
if (hex.length() == 1) {
hashStr += "0";
}
hashStr += hex;
uint8_t hash[32];

mbedtls_sha256_context ctx;
mbedtls_sha256_init(&ctx);
mbedtls_sha256_starts(&ctx, 0); // select SHA256
mbedtls_sha256_update(&ctx, reinterpret_cast<const unsigned char*>(data.c_str()), data.length());
mbedtls_sha256_finish(&ctx, hash);
mbedtls_sha256_free(&ctx);

char res[sizeof(hash) * 2 + 1];
for (int i = 0; i < sizeof(hash); i++) {
snprintf(res + (i*2), sizeof(res) - (i*2), "%02x", hash[i]);
}

return hashStr;
return res;
}

void HttpPowerMeterClass::prepareRequest(uint32_t timeout, const char* httpHeader, const char* httpValue) {
httpClient.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
httpClient.setUserAgent("OpenDTU-OnBattery");
Expand Down
2 changes: 1 addition & 1 deletion webapp/src/locales/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,7 @@
"httpHeaderKeyDescription": "Ein individueller HTTP request header kann hier definiert werden. Das kann z.B. verwendet werden um einen eigenen Authorization header mitzugeben.",
"httpHeaderValue": "Optional: HTTP request header - Wert",
"httpJsonPath": "JSON Pfad",
"httpJsonPathDescription": "JSON Pfad um den Leistungswert zu finden. Es verwendet die Selektions-Syntax von mobizt/FirebaseJson. Beispiele gibt es oben.",
"httpJsonPathDescription": "Anwendungsspezifischer JSON-Pfad um den Leistungswert in the HTTP(S) Antwort zu finden, z.B. 'power/total/watts' oder nur 'total'.",
"httpUnit": "Einheit",
"httpSignInverted": "Vorzeichen umkehren",
"httpSignInvertedHint": "Positive Werte werden als Leistungsabnahme aus dem Netz interpretiert. Diese Option muss aktiviert werden, wenn das Vorzeichen des Wertes die gegenteilige Bedeutung hat.",
Expand Down
2 changes: 1 addition & 1 deletion webapp/src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,7 @@
"httpHeaderKeyDescription": "A custom HTTP request header can be defined. Might be useful if you have to send something like a custom Authorization header.",
"httpHeaderValue": "Optional: HTTP request header - Value",
"httpJsonPath": "JSON path",
"httpJsonPathDescription": "JSON path to find the power value in the response. This uses the JSON path query syntax from mobizt/FirebaseJson. See above for examples.",
"httpJsonPathDescription": "Application specific JSON path to find the power value in the HTTP(S) response, e.g., 'power/total/watts' or simply 'total'.",
"httpUnit": "Unit",
"httpSignInverted": "Change Sign",
"httpSignInvertedHint": "Is is expected that positive values denote power usage from the grid. Check this option if the sign of this value has the opposite meaning.",
Expand Down
6 changes: 2 additions & 4 deletions webapp/src/views/PowerMeterAdminView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,9 @@

<h2>JSON path examples:</h2>
<ul>
<li>total_power - { "othervalue": "blah", "total_power": 123.4 }</li>
<li>testarray/[2]/myvalue - { "testarray": [ {}, { "power": 123.4 } ] }</li>
<li><code>power/total/watts</code> - Finds 123.4 in <code>{ "power": { "phase1": { "factor": 0.98, "watts": 42 }, "total": { "watts": 123.4 } } }</code></li>
<li><code>total</code> - Finds 123.4 in <code>{ "othervalue": 66, "total": 123.4 }</code></li>
</ul>

More info: <a href="https://github.com/mobizt/FirebaseJson">https://github.com/mobizt/FirebaseJson</a>
</div>

<CardElement
Expand Down
Loading