diff --git a/src/PowerMeterHttpJson.cpp b/src/PowerMeterHttpJson.cpp index cc8b600a..b1b530d7 100644 --- a/src/PowerMeterHttpJson.cpp +++ b/src/PowerMeterHttpJson.cpp @@ -53,7 +53,6 @@ void PowerMeterHttpJson::loop() return; } - _powerValues = std::get(res); gotUpdate(); } @@ -62,6 +61,12 @@ PowerMeterHttpJson::poll_result_t PowerMeterHttpJson::poll() power_values_t cache; JsonDocument jsonResponse; + auto prefixedError = [](uint8_t idx, char const* err) -> String { + String res("Value "); + res.reserve(strlen(err) + 16); + return res + String(idx + 1) + ": " + err; + }; + for (uint8_t i = 0; i < POWERMETER_HTTP_JSON_MAX_VALUES; i++) { auto const& cfg = Configuration.get().PowerMeter.HttpJson[i]; @@ -75,24 +80,24 @@ PowerMeterHttpJson::poll_result_t PowerMeterHttpJson::poll() if (upGetter) { auto res = upGetter->performGetRequest(); if (!res) { - return upGetter->getErrorText(); + return prefixedError(i, upGetter->getErrorText()); } auto pStream = res.getStream(); if (!pStream) { - return String("Programmer error: HTTP request yields no stream"); + return prefixedError(i, "Programmer error: HTTP request yields no stream"); } const DeserializationError error = deserializeJson(jsonResponse, *pStream); if (error) { String msg("Unable to parse server response as JSON: "); - return msg + error.c_str(); + return prefixedError(i, String(msg + error.c_str()).c_str()); } } auto pathResolutionResult = Utils::getJsonValueByPath(jsonResponse, cfg.JsonPath); if (!pathResolutionResult.second.isEmpty()) { - return pathResolutionResult.second; + return prefixedError(i, pathResolutionResult.second.c_str()); } // this value is supposed to be in Watts and positive if energy is consumed @@ -112,6 +117,7 @@ PowerMeterHttpJson::poll_result_t PowerMeterHttpJson::poll() if (cfg.SignInverted) { cache[i] *= -1; } } + _powerValues = cache; return cache; } diff --git a/src/WebApi_powermeter.cpp b/src/WebApi_powermeter.cpp index 72db067e..0178eb90 100644 --- a/src/WebApi_powermeter.cpp +++ b/src/WebApi_powermeter.cpp @@ -192,26 +192,15 @@ void WebApiPowerMeterClass::onTestHttpJsonRequest(AsyncWebServerRequest* request auto& retMsg = asyncJsonResponse->getRoot(); - JsonObject requestConfig = root["http_request"]; - if (!requestConfig.containsKey("url") - || !requestConfig.containsKey("auth_type") - || !requestConfig.containsKey("username") - || !requestConfig.containsKey("password") - || !requestConfig.containsKey("header_key") - || !requestConfig.containsKey("header_value") - || !requestConfig.containsKey("timeout") - || !root.containsKey("json_path")) { - retMsg["message"] = "Missing fields!"; - asyncJsonResponse->setLength(); - request->send(asyncJsonResponse); - return; - } - - char response[256]; auto powerMeterConfig = std::make_unique(); - Configuration.deserializePowerMeterHttpJsonConfig(root.as(), powerMeterConfig->HttpJson[0]); + powerMeterConfig->HttpIndividualRequests = root["http_individual_requests"].as(); + JsonArray httpJson = root["http_json"]; + for (uint8_t i = 0; i < httpJson.size(); i++) { + Configuration.deserializePowerMeterHttpJsonConfig(httpJson[i].as(), + powerMeterConfig->HttpJson[i]); + } auto backup = std::make_unique(Configuration.get().PowerMeter); Configuration.get().PowerMeter = *powerMeterConfig; auto upMeter = std::make_unique(); @@ -222,9 +211,14 @@ void WebApiPowerMeterClass::onTestHttpJsonRequest(AsyncWebServerRequest* request if (std::holds_alternative(res)) { retMsg["type"] = "success"; auto vals = std::get(res); - snprintf_P(response, sizeof(response), "Result: %5.2fW", vals[0]); + auto pos = snprintf(response, sizeof(response), "Result: %5.2fW", vals[0]); + for (size_t i = 1; i < POWERMETER_HTTP_JSON_MAX_VALUES; ++i) { + if (!powerMeterConfig->HttpJson[i].Enabled) { continue; } + pos += snprintf(response + pos, sizeof(response) - pos, ", %5.2fW", vals[i]); + } + snprintf(response + pos, sizeof(response) - pos, ", Total: %5.2f", upMeter->getPowerTotal()); } else { - snprintf_P(response, sizeof(response), "%s", std::get(res).c_str()); + snprintf(response, sizeof(response), "%s", std::get(res).c_str()); } retMsg["message"] = response; diff --git a/webapp/src/locales/de.json b/webapp/src/locales/de.json index a982a563..e7e3317f 100644 --- a/webapp/src/locales/de.json +++ b/webapp/src/locales/de.json @@ -581,7 +581,8 @@ "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.", - "testHttpJsonRequest": "Konfiguration testen (HTTP(S)-Anfrage senden)", + "testHttpJsonHeader": "Konfiguration testen", + "testHttpJsonRequest": "HTTP(S)-Anfrage(n) senden und Antwort(en) verarbeiten", "testHttpSmlRequest": "Konfiguration testen (HTTP(S)-Anfrage senden)", "HTTP_SML": "HTTP(S) + SML - Konfiguration" }, diff --git a/webapp/src/locales/en.json b/webapp/src/locales/en.json index 30407c7d..218eef94 100644 --- a/webapp/src/locales/en.json +++ b/webapp/src/locales/en.json @@ -583,7 +583,8 @@ "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.", - "testHttpJsonRequest": "Test configuration (send HTTP(S) request)", + "testHttpJsonHeader": "Test Configuration", + "testHttpJsonRequest": "Send HTTP(S) request(s) and process response(s)", "testHttpSmlRequest": "Test configuration (send HTTP(S) request)", "HTTP_SML": "Configuration" }, diff --git a/webapp/src/views/PowerMeterAdminView.vue b/webapp/src/views/PowerMeterAdminView.vue index 46a78426..fd2934f8 100644 --- a/webapp/src/views/PowerMeterAdminView.vue +++ b/webapp/src/views/PowerMeterAdminView.vue @@ -154,18 +154,24 @@ v-model="httpJson.sign_inverted" :tooltip="$t('powermeteradmin.httpSignInvertedHint')" type="checkbox" /> - -
- -
- - - {{ testHttpJsonRequestAlert[index].message }} - + + + +
+ +
+ + + {{ testHttpJsonRequestAlert.message }} + +
@@ -203,7 +209,7 @@ import FormFooter from '@/components/FormFooter.vue'; import InputElement from '@/components/InputElement.vue'; import HttpRequestSettings from '@/components/HttpRequestSettings.vue'; import { handleResponse, authHeader } from '@/utils/authentication'; -import type { PowerMeterHttpJsonConfig, PowerMeterConfig } from "@/types/PowerMeterConfig"; +import type { PowerMeterConfig } from "@/types/PowerMeterConfig"; export default defineComponent({ components: { @@ -235,7 +241,7 @@ export default defineComponent({ alertMessage: "", alertType: "info", showAlert: false, - testHttpJsonRequestAlert: [{message: "", type: "", show: false}] as { message: string; type: string; show: boolean; }[], + testHttpJsonRequestAlert: {message: "", type: "", show: false} as { message: string; type: string; show: boolean; }, testHttpSmlRequestAlert: {message: "", type: "", show: false} as { message: string; type: string; show: boolean; } }; }, @@ -250,14 +256,6 @@ export default defineComponent({ .then((data) => { this.powerMeterConfigList = data; this.dataLoading = false; - - for (let i = 0; i < this.powerMeterConfigList.http_json.length; i++) { - this.testHttpJsonRequestAlert.push({ - message: "", - type: "", - show: false, - }); - } }); }, savePowerMeterConfig(e: Event) { @@ -281,25 +279,15 @@ export default defineComponent({ } ); }, - testHttpJsonRequest(index: number) { - let valueConfig:PowerMeterHttpJsonConfig; - - if (this.powerMeterConfigList.http_individual_requests) { - valueConfig = this.powerMeterConfigList.http_json[index]; - } else { - valueConfig = { ...this.powerMeterConfigList.http_json[0] }; - valueConfig.index = this.powerMeterConfigList.http_json[index].index; - valueConfig.json_path = this.powerMeterConfigList.http_json[index].json_path; - } - - this.testHttpJsonRequestAlert[index] = { + testHttpJsonRequest() { + this.testHttpJsonRequestAlert = { message: "Sending HTTP request...", type: "info", show: true, }; const formData = new FormData(); - formData.append("data", JSON.stringify(valueConfig)); + formData.append("data", JSON.stringify(this.powerMeterConfigList)); fetch("/api/powermeter/testhttpjsonrequest", { method: "POST", @@ -309,7 +297,7 @@ export default defineComponent({ .then((response) => handleResponse(response, this.$emitter, this.$router)) .then( (response) => { - this.testHttpJsonRequestAlert[index] = { + this.testHttpJsonRequestAlert = { message: response.message, type: response.type, show: true,