Feature: HTTP power meter: support changing sign
This commit is contained in:
parent
ede1abb5e6
commit
abe01ae36f
@ -75,6 +75,7 @@ struct POWERMETER_HTTP_PHASE_CONFIG_T {
|
|||||||
uint16_t Timeout;
|
uint16_t Timeout;
|
||||||
char JsonPath[POWERMETER_MAX_HTTP_JSON_PATH_STRLEN + 1];
|
char JsonPath[POWERMETER_MAX_HTTP_JSON_PATH_STRLEN + 1];
|
||||||
Unit PowerUnit;
|
Unit PowerUnit;
|
||||||
|
bool SignInverted;
|
||||||
};
|
};
|
||||||
using PowerMeterHttpConfig = struct POWERMETER_HTTP_PHASE_CONFIG_T;
|
using PowerMeterHttpConfig = struct POWERMETER_HTTP_PHASE_CONFIG_T;
|
||||||
|
|
||||||
|
|||||||
@ -26,7 +26,7 @@ private:
|
|||||||
String extractParam(String& authReq, const String& param, const char delimit);
|
String extractParam(String& authReq, const String& param, const char delimit);
|
||||||
String getcNonce(const int len);
|
String getcNonce(const int len);
|
||||||
String getDigestAuth(String& authReq, const String& username, const String& password, const String& method, const String& uri, unsigned int counter);
|
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 tryGetFloatValueForPhase(int phase, const char* jsonPath, Unit_t unit, bool signInverted);
|
||||||
void prepareRequest(uint32_t timeout, const char* httpHeader, const char* httpValue);
|
void prepareRequest(uint32_t timeout, const char* httpHeader, const char* httpValue);
|
||||||
String sha256(const String& data);
|
String sha256(const String& data);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -176,6 +176,7 @@ bool ConfigurationClass::write()
|
|||||||
powermeter_phase["timeout"] = config.PowerMeter.Http_Phase[i].Timeout;
|
powermeter_phase["timeout"] = config.PowerMeter.Http_Phase[i].Timeout;
|
||||||
powermeter_phase["json_path"] = config.PowerMeter.Http_Phase[i].JsonPath;
|
powermeter_phase["json_path"] = config.PowerMeter.Http_Phase[i].JsonPath;
|
||||||
powermeter_phase["unit"] = config.PowerMeter.Http_Phase[i].PowerUnit;
|
powermeter_phase["unit"] = config.PowerMeter.Http_Phase[i].PowerUnit;
|
||||||
|
powermeter_phase["sign_inverted"] = config.PowerMeter.Http_Phase[i].SignInverted;
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonObject powerlimiter = doc.createNestedObject("powerlimiter");
|
JsonObject powerlimiter = doc.createNestedObject("powerlimiter");
|
||||||
@ -429,6 +430,7 @@ bool ConfigurationClass::read()
|
|||||||
config.PowerMeter.Http_Phase[i].Timeout = powermeter_phase["timeout"] | POWERMETER_HTTP_TIMEOUT;
|
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));
|
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;
|
config.PowerMeter.Http_Phase[i].PowerUnit = powermeter_phase["unit"] | PowerMeterHttpConfig::Unit::Watts;
|
||||||
|
config.PowerMeter.Http_Phase[i].SignInverted = powermeter_phase["sign_inverted"] | false;
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonObject powerlimiter = doc["powerlimiter"];
|
JsonObject powerlimiter = doc["powerlimiter"];
|
||||||
|
|||||||
@ -42,7 +42,7 @@ bool HttpPowerMeterClass::updateValues()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!tryGetFloatValueForPhase(i, phaseConfig.JsonPath, phaseConfig.PowerUnit)) {
|
if(!tryGetFloatValueForPhase(i, phaseConfig.JsonPath, phaseConfig.PowerUnit, phaseConfig.SignInverted)) {
|
||||||
MessageOutput.printf("[HttpPowerMeter] Getting the power of phase %d (from JSON fetched with Phase 1 config) failed.\r\n", i + 1);
|
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);
|
MessageOutput.printf("%s\r\n", httpPowerMeterError);
|
||||||
return false;
|
return false;
|
||||||
@ -161,7 +161,7 @@ bool HttpPowerMeterClass::httpRequest(int phase, WiFiClient &wifiClient, const S
|
|||||||
|
|
||||||
// TODO(schlimmchen): postpone calling tryGetFloatValueForPhase, as it
|
// TODO(schlimmchen): postpone calling tryGetFloatValueForPhase, as it
|
||||||
// will be called twice for each phase when doing separate requests.
|
// will be called twice for each phase when doing separate requests.
|
||||||
return tryGetFloatValueForPhase(phase, config.JsonPath, config.PowerUnit);
|
return tryGetFloatValueForPhase(phase, config.JsonPath, config.PowerUnit, config.SignInverted);
|
||||||
}
|
}
|
||||||
|
|
||||||
String HttpPowerMeterClass::extractParam(String& authReq, const String& param, const char delimit) {
|
String HttpPowerMeterClass::extractParam(String& authReq, const String& param, const char delimit) {
|
||||||
@ -219,7 +219,7 @@ String HttpPowerMeterClass::getDigestAuth(String& authReq, const String& usernam
|
|||||||
return authorization;
|
return authorization;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HttpPowerMeterClass::tryGetFloatValueForPhase(int phase, const char* jsonPath, Unit_t unit)
|
bool HttpPowerMeterClass::tryGetFloatValueForPhase(int phase, const char* jsonPath, Unit_t unit, bool signInverted)
|
||||||
{
|
{
|
||||||
FirebaseJson json;
|
FirebaseJson json;
|
||||||
json.setJsonData(httpResponse);
|
json.setJsonData(httpResponse);
|
||||||
@ -229,7 +229,9 @@ bool HttpPowerMeterClass::tryGetFloatValueForPhase(int phase, const char* jsonPa
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
power[phase] = value.to<float>(); // this is supposed to be in Watts
|
// this value is supposed to be in Watts and positive if energy is consumed.
|
||||||
|
power[phase] = value.to<float>();
|
||||||
|
|
||||||
switch (unit) {
|
switch (unit) {
|
||||||
case Unit_t::MilliWatts:
|
case Unit_t::MilliWatts:
|
||||||
power[phase] /= 1000;
|
power[phase] /= 1000;
|
||||||
@ -240,6 +242,9 @@ bool HttpPowerMeterClass::tryGetFloatValueForPhase(int phase, const char* jsonPa
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (signInverted) { power[phase] *= -1; }
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -40,6 +40,7 @@ void WebApiPowerMeterClass::decodeJsonPhaseConfig(JsonObject const& json, PowerM
|
|||||||
config.Timeout = json["timeout"].as<uint16_t>();
|
config.Timeout = json["timeout"].as<uint16_t>();
|
||||||
strlcpy(config.JsonPath, json["json_path"].as<String>().c_str(), sizeof(config.JsonPath));
|
strlcpy(config.JsonPath, json["json_path"].as<String>().c_str(), sizeof(config.JsonPath));
|
||||||
config.PowerUnit = json["unit"].as<PowerMeterHttpConfig::Unit>();
|
config.PowerUnit = json["unit"].as<PowerMeterHttpConfig::Unit>();
|
||||||
|
config.SignInverted = json["sign_inverted"].as<bool>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiPowerMeterClass::onStatus(AsyncWebServerRequest* request)
|
void WebApiPowerMeterClass::onStatus(AsyncWebServerRequest* request)
|
||||||
@ -75,6 +76,7 @@ void WebApiPowerMeterClass::onStatus(AsyncWebServerRequest* request)
|
|||||||
phaseObject["timeout"] = config.PowerMeter.Http_Phase[i].Timeout;
|
phaseObject["timeout"] = config.PowerMeter.Http_Phase[i].Timeout;
|
||||||
phaseObject["json_path"] = String(config.PowerMeter.Http_Phase[i].JsonPath);
|
phaseObject["json_path"] = String(config.PowerMeter.Http_Phase[i].JsonPath);
|
||||||
phaseObject["unit"] = config.PowerMeter.Http_Phase[i].PowerUnit;
|
phaseObject["unit"] = config.PowerMeter.Http_Phase[i].PowerUnit;
|
||||||
|
phaseObject["sign_inverted"] = config.PowerMeter.Http_Phase[i].SignInverted;
|
||||||
}
|
}
|
||||||
|
|
||||||
response->setLength();
|
response->setLength();
|
||||||
|
|||||||
@ -576,6 +576,8 @@
|
|||||||
"httpJsonPath": "JSON Pfad",
|
"httpJsonPath": "JSON Pfad",
|
||||||
"httpJsonPathDescription": "JSON Pfad um den Leistungswert zu finden. Es verwendet die Selektions-Syntax von mobizt/FirebaseJson. Beispiele gibt es oben.",
|
"httpJsonPathDescription": "JSON Pfad um den Leistungswert zu finden. Es verwendet die Selektions-Syntax von mobizt/FirebaseJson. Beispiele gibt es oben.",
|
||||||
"httpUnit": "Einheit",
|
"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.",
|
||||||
"httpTimeout": "Timeout",
|
"httpTimeout": "Timeout",
|
||||||
"testHttpRequest": "Testen"
|
"testHttpRequest": "Testen"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -581,6 +581,8 @@
|
|||||||
"httpJsonPath": "JSON path",
|
"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": "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",
|
"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.",
|
||||||
"httpTimeout": "Timeout",
|
"httpTimeout": "Timeout",
|
||||||
"testHttpRequest": "Run test",
|
"testHttpRequest": "Run test",
|
||||||
"milliSeconds": "ms"
|
"milliSeconds": "ms"
|
||||||
|
|||||||
@ -10,6 +10,7 @@ export interface PowerMeterHttpPhaseConfig {
|
|||||||
json_path: string;
|
json_path: string;
|
||||||
timeout: number;
|
timeout: number;
|
||||||
unit: number;
|
unit: number;
|
||||||
|
sign_inverted: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PowerMeterConfig {
|
export interface PowerMeterConfig {
|
||||||
|
|||||||
@ -202,6 +202,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<InputElement
|
||||||
|
:label="$t('powermeteradmin.httpSignInverted')"
|
||||||
|
v-model="http_phase.sign_inverted"
|
||||||
|
:tooltip="$t('powermeteradmin.httpSignInvertedHint')"
|
||||||
|
type="checkbox" />
|
||||||
|
|
||||||
<div class="text-center mb-3">
|
<div class="text-center mb-3">
|
||||||
<button type="button" class="btn btn-danger" @click="testHttpRequest(index)">
|
<button type="button" class="btn btn-danger" @click="testHttpRequest(index)">
|
||||||
{{ $t('powermeteradmin.testHttpRequest') }}
|
{{ $t('powermeteradmin.testHttpRequest') }}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user