Feature: HTTP power meter: support mW/kW as units
This commit is contained in:
parent
247cfe712e
commit
ede1abb5e6
@ -64,6 +64,7 @@ struct INVERTER_CONFIG_T {
|
||||
|
||||
struct POWERMETER_HTTP_PHASE_CONFIG_T {
|
||||
enum Auth { None, Basic, Digest };
|
||||
enum Unit { Watts = 0, MilliWatts = 1, KiloWatts = 2 };
|
||||
bool Enabled;
|
||||
char Url[POWERMETER_MAX_HTTP_URL_STRLEN + 1];
|
||||
Auth AuthType;
|
||||
@ -73,6 +74,7 @@ struct POWERMETER_HTTP_PHASE_CONFIG_T {
|
||||
char HeaderValue[POWERMETER_MAX_HTTP_HEADER_VALUE_STRLEN + 1];
|
||||
uint16_t Timeout;
|
||||
char JsonPath[POWERMETER_MAX_HTTP_JSON_PATH_STRLEN + 1];
|
||||
Unit PowerUnit;
|
||||
};
|
||||
using PowerMeterHttpConfig = struct POWERMETER_HTTP_PHASE_CONFIG_T;
|
||||
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
#include "Configuration.h"
|
||||
|
||||
using Auth_t = PowerMeterHttpConfig::Auth;
|
||||
using Unit_t = PowerMeterHttpConfig::Unit;
|
||||
|
||||
class HttpPowerMeterClass {
|
||||
public:
|
||||
@ -25,7 +26,7 @@ private:
|
||||
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);
|
||||
bool tryGetFloatValueForPhase(int phase, const char* jsonPath, Unit_t unit);
|
||||
void prepareRequest(uint32_t timeout, const char* httpHeader, const char* httpValue);
|
||||
String sha256(const String& data);
|
||||
};
|
||||
|
||||
@ -175,6 +175,7 @@ bool ConfigurationClass::write()
|
||||
powermeter_phase["header_value"] = config.PowerMeter.Http_Phase[i].HeaderValue;
|
||||
powermeter_phase["timeout"] = config.PowerMeter.Http_Phase[i].Timeout;
|
||||
powermeter_phase["json_path"] = config.PowerMeter.Http_Phase[i].JsonPath;
|
||||
powermeter_phase["unit"] = config.PowerMeter.Http_Phase[i].PowerUnit;
|
||||
}
|
||||
|
||||
JsonObject powerlimiter = doc.createNestedObject("powerlimiter");
|
||||
@ -427,6 +428,7 @@ bool ConfigurationClass::read()
|
||||
strlcpy(config.PowerMeter.Http_Phase[i].HeaderValue, powermeter_phase["header_value"] | "", sizeof(config.PowerMeter.Http_Phase[i].HeaderValue));
|
||||
config.PowerMeter.Http_Phase[i].Timeout = powermeter_phase["timeout"] | POWERMETER_HTTP_TIMEOUT;
|
||||
strlcpy(config.PowerMeter.Http_Phase[i].JsonPath, powermeter_phase["json_path"] | "", sizeof(config.PowerMeter.Http_Phase[i].JsonPath));
|
||||
config.PowerMeter.Http_Phase[i].PowerUnit = powermeter_phase["unit"] | PowerMeterHttpConfig::Unit::Watts;
|
||||
}
|
||||
|
||||
JsonObject powerlimiter = doc["powerlimiter"];
|
||||
|
||||
@ -42,7 +42,7 @@ bool HttpPowerMeterClass::updateValues()
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!tryGetFloatValueForPhase(i, phaseConfig.JsonPath)) {
|
||||
if(!tryGetFloatValueForPhase(i, phaseConfig.JsonPath, phaseConfig.PowerUnit)) {
|
||||
MessageOutput.printf("[HttpPowerMeter] Getting the power of phase %d (from JSON fetched with Phase 1 config) failed.\r\n", i + 1);
|
||||
MessageOutput.printf("%s\r\n", httpPowerMeterError);
|
||||
return false;
|
||||
@ -159,7 +159,9 @@ bool HttpPowerMeterClass::httpRequest(int phase, WiFiClient &wifiClient, const S
|
||||
httpResponse = httpClient.getString(); // very unfortunate that we cannot parse WifiClient stream directly
|
||||
httpClient.end();
|
||||
|
||||
return tryGetFloatValueForPhase(phase, jsonPath);
|
||||
// TODO(schlimmchen): postpone calling tryGetFloatValueForPhase, as it
|
||||
// will be called twice for each phase when doing separate requests.
|
||||
return tryGetFloatValueForPhase(phase, config.JsonPath, config.PowerUnit);
|
||||
}
|
||||
|
||||
String HttpPowerMeterClass::extractParam(String& authReq, const String& param, const char delimit) {
|
||||
@ -217,7 +219,7 @@ String HttpPowerMeterClass::getDigestAuth(String& authReq, const String& usernam
|
||||
return authorization;
|
||||
}
|
||||
|
||||
bool HttpPowerMeterClass::tryGetFloatValueForPhase(int phase, const char* jsonPath)
|
||||
bool HttpPowerMeterClass::tryGetFloatValueForPhase(int phase, const char* jsonPath, Unit_t unit)
|
||||
{
|
||||
FirebaseJson json;
|
||||
json.setJsonData(httpResponse);
|
||||
@ -227,7 +229,17 @@ bool HttpPowerMeterClass::tryGetFloatValueForPhase(int phase, const char* jsonPa
|
||||
return false;
|
||||
}
|
||||
|
||||
power[phase] = value.to<float>();
|
||||
power[phase] = value.to<float>(); // this is supposed to be in Watts
|
||||
switch (unit) {
|
||||
case Unit_t::MilliWatts:
|
||||
power[phase] /= 1000;
|
||||
break;
|
||||
case Unit_t::KiloWatts:
|
||||
power[phase] *= 1000;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -39,6 +39,7 @@ void WebApiPowerMeterClass::decodeJsonPhaseConfig(JsonObject const& json, PowerM
|
||||
strlcpy(config.HeaderValue, json["header_value"].as<String>().c_str(), sizeof(config.HeaderValue));
|
||||
config.Timeout = json["timeout"].as<uint16_t>();
|
||||
strlcpy(config.JsonPath, json["json_path"].as<String>().c_str(), sizeof(config.JsonPath));
|
||||
config.PowerUnit = json["unit"].as<PowerMeterHttpConfig::Unit>();
|
||||
}
|
||||
|
||||
void WebApiPowerMeterClass::onStatus(AsyncWebServerRequest* request)
|
||||
@ -71,8 +72,9 @@ void WebApiPowerMeterClass::onStatus(AsyncWebServerRequest* request)
|
||||
phaseObject["password"] = String(config.PowerMeter.Http_Phase[i].Password);
|
||||
phaseObject["header_key"] = String(config.PowerMeter.Http_Phase[i].HeaderKey);
|
||||
phaseObject["header_value"] = String(config.PowerMeter.Http_Phase[i].HeaderValue);
|
||||
phaseObject["json_path"] = String(config.PowerMeter.Http_Phase[i].JsonPath);
|
||||
phaseObject["timeout"] = config.PowerMeter.Http_Phase[i].Timeout;
|
||||
phaseObject["json_path"] = String(config.PowerMeter.Http_Phase[i].JsonPath);
|
||||
phaseObject["unit"] = config.PowerMeter.Http_Phase[i].PowerUnit;
|
||||
}
|
||||
|
||||
response->setLength();
|
||||
|
||||
@ -574,7 +574,8 @@
|
||||
"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 unten.",
|
||||
"httpJsonPathDescription": "JSON Pfad um den Leistungswert zu finden. Es verwendet die Selektions-Syntax von mobizt/FirebaseJson. Beispiele gibt es oben.",
|
||||
"httpUnit": "Einheit",
|
||||
"httpTimeout": "Timeout",
|
||||
"testHttpRequest": "Testen"
|
||||
},
|
||||
|
||||
@ -578,8 +578,9 @@
|
||||
"httpHeaderKey": "Optional: HTTP request header - Key",
|
||||
"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 below for some examples.",
|
||||
"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.",
|
||||
"httpUnit": "Unit",
|
||||
"httpTimeout": "Timeout",
|
||||
"testHttpRequest": "Run test",
|
||||
"milliSeconds": "ms"
|
||||
|
||||
@ -9,6 +9,7 @@ export interface PowerMeterHttpPhaseConfig {
|
||||
header_value: string;
|
||||
json_path: string;
|
||||
timeout: number;
|
||||
unit: number;
|
||||
}
|
||||
|
||||
export interface PowerMeterConfig {
|
||||
|
||||
@ -189,6 +189,19 @@
|
||||
placeholder="total_power"
|
||||
:tooltip="$t('powermeteradmin.httpJsonPathDescription')" />
|
||||
|
||||
<div class="row mb-3">
|
||||
<label for="power_unit" class="col-sm-2 col-form-label">
|
||||
{{ $t('powermeteradmin.httpUnit') }}
|
||||
</label>
|
||||
<div class="col-sm-10">
|
||||
<select id="power_unit" class="form-select" v-model="http_phase.unit">
|
||||
<option value="1">mW</option>
|
||||
<option value="0">W</option>
|
||||
<option value="2">kW</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-center mb-3">
|
||||
<button type="button" class="btn btn-danger" @click="testHttpRequest(index)">
|
||||
{{ $t('powermeteradmin.testHttpRequest') }}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user