Feature: support JSON payload in MQTT power meter
the MQTT power meter can now process the messages published at the respective topics as JSON and extract a power value using a JSON path (same as in HTTP+JSON power meter). additionally, selecting a unit for the power value as well as an option to invert the value's sign was added as well, similar to the HTTPS+JSON power meter.
This commit is contained in:
parent
347dd67684
commit
15b6a32b92
@ -79,6 +79,12 @@ using HttpRequestConfig = struct HTTP_REQUEST_CONFIG_T;
|
|||||||
|
|
||||||
struct POWERMETER_MQTT_VALUE_T {
|
struct POWERMETER_MQTT_VALUE_T {
|
||||||
char Topic[MQTT_MAX_TOPIC_STRLEN + 1];
|
char Topic[MQTT_MAX_TOPIC_STRLEN + 1];
|
||||||
|
char JsonPath[POWERMETER_HTTP_JSON_MAX_PATH_STRLEN + 1];
|
||||||
|
|
||||||
|
enum Unit { Watts = 0, MilliWatts = 1, KiloWatts = 2 };
|
||||||
|
Unit PowerUnit;
|
||||||
|
|
||||||
|
bool SignInverted;
|
||||||
};
|
};
|
||||||
using PowerMeterMqttValue = struct POWERMETER_MQTT_VALUE_T;
|
using PowerMeterMqttValue = struct POWERMETER_MQTT_VALUE_T;
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
#include <espMqttClient.h>
|
#include <espMqttClient.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
class PowerMeterMqtt : public PowerMeterProvider {
|
class PowerMeterMqtt : public PowerMeterProvider {
|
||||||
public:
|
public:
|
||||||
@ -23,13 +24,12 @@ private:
|
|||||||
using MsgProperties = espMqttClientTypes::MessageProperties;
|
using MsgProperties = espMqttClientTypes::MessageProperties;
|
||||||
void onMessage(MsgProperties const& properties, char const* topic,
|
void onMessage(MsgProperties const& properties, char const* topic,
|
||||||
uint8_t const* payload, size_t len, size_t index,
|
uint8_t const* payload, size_t len, size_t index,
|
||||||
size_t total, float* targetVariable);
|
size_t total, float* targetVariable, PowerMeterMqttValue const* cfg);
|
||||||
|
|
||||||
PowerMeterMqttConfig const _cfg;
|
PowerMeterMqttConfig const _cfg;
|
||||||
|
|
||||||
float _powerValueOne = 0;
|
using power_values_t = std::array<float, POWERMETER_MQTT_MAX_VALUES>;
|
||||||
float _powerValueTwo = 0;
|
power_values_t _powerValues;
|
||||||
float _powerValueThree = 0;
|
|
||||||
|
|
||||||
std::vector<String> _mqttSubscriptions;
|
std::vector<String> _mqttSubscriptions;
|
||||||
|
|
||||||
|
|||||||
@ -36,6 +36,9 @@ void ConfigurationClass::serializePowerMeterMqttConfig(PowerMeterMqttConfig cons
|
|||||||
PowerMeterMqttValue const& s = source.Values[i];
|
PowerMeterMqttValue const& s = source.Values[i];
|
||||||
|
|
||||||
t["topic"] = s.Topic;
|
t["topic"] = s.Topic;
|
||||||
|
t["json_path"] = s.JsonPath;
|
||||||
|
t["unit"] = s.PowerUnit;
|
||||||
|
t["sign_inverted"] = s.SignInverted;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -301,10 +304,14 @@ void ConfigurationClass::deserializeHttpRequestConfig(JsonObject const& source,
|
|||||||
|
|
||||||
void ConfigurationClass::deserializePowerMeterMqttConfig(JsonObject const& source, PowerMeterMqttConfig& target)
|
void ConfigurationClass::deserializePowerMeterMqttConfig(JsonObject const& source, PowerMeterMqttConfig& target)
|
||||||
{
|
{
|
||||||
JsonArray s = source["values"].as<JsonArray>();
|
|
||||||
for (size_t i = 0; i < POWERMETER_MQTT_MAX_VALUES; ++i) {
|
for (size_t i = 0; i < POWERMETER_MQTT_MAX_VALUES; ++i) {
|
||||||
PowerMeterMqttValue& t = target.Values[i];
|
PowerMeterMqttValue& t = target.Values[i];
|
||||||
strlcpy(t.Topic, s[i]["topic"] | "", sizeof(t.Topic));
|
JsonObject s = source["values"][i];
|
||||||
|
|
||||||
|
strlcpy(t.Topic, s["topic"] | "", sizeof(t.Topic));
|
||||||
|
strlcpy(t.JsonPath, s["json_path"] | "", sizeof(t.JsonPath));
|
||||||
|
t.PowerUnit = s["unit"] | PowerMeterMqttValue::Unit::Watts;
|
||||||
|
t.SignInverted = s["sign_inverted"] | false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,24 +2,27 @@
|
|||||||
#include "PowerMeterMqtt.h"
|
#include "PowerMeterMqtt.h"
|
||||||
#include "MqttSettings.h"
|
#include "MqttSettings.h"
|
||||||
#include "MessageOutput.h"
|
#include "MessageOutput.h"
|
||||||
|
#include "ArduinoJson.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
|
||||||
bool PowerMeterMqtt::init()
|
bool PowerMeterMqtt::init()
|
||||||
{
|
{
|
||||||
auto subscribe = [this](char const* topic, float* targetVariable) {
|
auto subscribe = [this](PowerMeterMqttValue const& val, float* targetVariable) {
|
||||||
|
char const* topic = val.Topic;
|
||||||
if (strlen(topic) == 0) { return; }
|
if (strlen(topic) == 0) { return; }
|
||||||
MqttSettings.subscribe(topic, 0,
|
MqttSettings.subscribe(topic, 0,
|
||||||
std::bind(&PowerMeterMqtt::onMessage,
|
std::bind(&PowerMeterMqtt::onMessage,
|
||||||
this, std::placeholders::_1, std::placeholders::_2,
|
this, std::placeholders::_1, std::placeholders::_2,
|
||||||
std::placeholders::_3, std::placeholders::_4,
|
std::placeholders::_3, std::placeholders::_4,
|
||||||
std::placeholders::_5, std::placeholders::_6,
|
std::placeholders::_5, std::placeholders::_6,
|
||||||
targetVariable)
|
targetVariable, &val)
|
||||||
);
|
);
|
||||||
_mqttSubscriptions.push_back(topic);
|
_mqttSubscriptions.push_back(topic);
|
||||||
};
|
};
|
||||||
|
|
||||||
subscribe(_cfg.Values[0].Topic, &_powerValueOne);
|
for (size_t i = 0; i < _powerValues.size(); ++i) {
|
||||||
subscribe(_cfg.Values[1].Topic, &_powerValueTwo);
|
subscribe(_cfg.Values[i], &_powerValues[i]);
|
||||||
subscribe(_cfg.Values[2].Topic, &_powerValueThree);
|
}
|
||||||
|
|
||||||
return _mqttSubscriptions.size() > 0;
|
return _mqttSubscriptions.size() > 0;
|
||||||
}
|
}
|
||||||
@ -32,22 +35,63 @@ PowerMeterMqtt::~PowerMeterMqtt()
|
|||||||
|
|
||||||
void PowerMeterMqtt::onMessage(PowerMeterMqtt::MsgProperties const& properties,
|
void PowerMeterMqtt::onMessage(PowerMeterMqtt::MsgProperties const& properties,
|
||||||
char const* topic, uint8_t const* payload, size_t len, size_t index,
|
char const* topic, uint8_t const* payload, size_t len, size_t index,
|
||||||
size_t total, float* targetVariable)
|
size_t total, float* targetVariable, PowerMeterMqttValue const* cfg)
|
||||||
{
|
{
|
||||||
std::string value(reinterpret_cast<char const*>(payload), len);
|
std::string value(reinterpret_cast<char const*>(payload), len);
|
||||||
|
std::string logValue = value.substr(0, 32);
|
||||||
|
if (value.length() > logValue.length()) { logValue += "..."; }
|
||||||
|
|
||||||
|
auto log= [topic](char const* format, auto&&... args) -> void {
|
||||||
|
MessageOutput.printf("[PowerMeterMqtt] Topic '%s': ", topic);
|
||||||
|
MessageOutput.printf(format, args...);
|
||||||
|
MessageOutput.println();
|
||||||
|
};
|
||||||
|
|
||||||
|
if (strlen(cfg->JsonPath) == 0) {
|
||||||
try {
|
try {
|
||||||
std::lock_guard<std::mutex> l(_mutex);
|
std::lock_guard<std::mutex> l(_mutex);
|
||||||
*targetVariable = std::stof(value);
|
*targetVariable = std::stof(value);
|
||||||
}
|
}
|
||||||
catch (std::invalid_argument const& e) {
|
catch (std::invalid_argument const& e) {
|
||||||
MessageOutput.printf("[PowerMeterMqtt] cannot parse payload of topic "
|
return log("cannot parse payload '%s' as float", logValue.c_str());
|
||||||
"'%s' as float: %s\r\n", topic, value.c_str());
|
}
|
||||||
return;
|
}
|
||||||
|
else {
|
||||||
|
JsonDocument json;
|
||||||
|
|
||||||
|
const DeserializationError error = deserializeJson(json, value);
|
||||||
|
if (error) {
|
||||||
|
return log("cannot parse payload '%s' as JSON", logValue.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (json.overflowed()) {
|
||||||
|
return log("payload too large to process as JSON");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto pathResolutionResult = Utils::getJsonValueByPath<float>(json, cfg->JsonPath);
|
||||||
|
if (!pathResolutionResult.second.isEmpty()) {
|
||||||
|
return log("%s", pathResolutionResult.second.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
*targetVariable = pathResolutionResult.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
using Unit_t = PowerMeterMqttValue::Unit;
|
||||||
|
switch (cfg->PowerUnit) {
|
||||||
|
case Unit_t::MilliWatts:
|
||||||
|
*targetVariable /= 1000;
|
||||||
|
break;
|
||||||
|
case Unit_t::KiloWatts:
|
||||||
|
*targetVariable *= 1000;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cfg->SignInverted) { *targetVariable *= -1; }
|
||||||
|
|
||||||
if (_verboseLogging) {
|
if (_verboseLogging) {
|
||||||
MessageOutput.printf("[PowerMeterMqtt] Updated from '%s', TotalPower: %5.2f\r\n",
|
log("new value: %5.2f, total: %5.2f", *targetVariable, getPowerTotal());
|
||||||
topic, getPowerTotal());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gotUpdate();
|
gotUpdate();
|
||||||
@ -55,14 +99,16 @@ void PowerMeterMqtt::onMessage(PowerMeterMqtt::MsgProperties const& properties,
|
|||||||
|
|
||||||
float PowerMeterMqtt::getPowerTotal() const
|
float PowerMeterMqtt::getPowerTotal() const
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> l(_mutex);
|
float sum = 0.0;
|
||||||
return _powerValueOne + _powerValueTwo + _powerValueThree;
|
std::unique_lock<std::mutex> lock(_mutex);
|
||||||
|
for (auto v: _powerValues) { sum += v; }
|
||||||
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PowerMeterMqtt::doMqttPublish() const
|
void PowerMeterMqtt::doMqttPublish() const
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> l(_mutex);
|
std::lock_guard<std::mutex> l(_mutex);
|
||||||
mqttPublish("power1", _powerValueOne);
|
mqttPublish("power1", _powerValues[0]);
|
||||||
mqttPublish("power2", _powerValueTwo);
|
mqttPublish("power2", _powerValues[1]);
|
||||||
mqttPublish("power3", _powerValueThree);
|
mqttPublish("power3", _powerValues[2]);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -566,6 +566,7 @@
|
|||||||
"typeHTTP_SML": "HTTP(S) + SML (z.B. Tibber Pulse via Tibber Bridge)",
|
"typeHTTP_SML": "HTTP(S) + SML (z.B. Tibber Pulse via Tibber Bridge)",
|
||||||
"MqttValue": "Konfiguration Wert {valueNumber}",
|
"MqttValue": "Konfiguration Wert {valueNumber}",
|
||||||
"MqttTopic": "MQTT Topic",
|
"MqttTopic": "MQTT Topic",
|
||||||
|
"mqttJsonPath": "Optional: JSON-Pfad",
|
||||||
"SDM": "SDM-Stromzähler Konfiguration",
|
"SDM": "SDM-Stromzähler Konfiguration",
|
||||||
"sdmaddress": "Modbus Adresse",
|
"sdmaddress": "Modbus Adresse",
|
||||||
"HTTP_JSON": "HTTP(S) + JSON - Allgemeine Konfiguration",
|
"HTTP_JSON": "HTTP(S) + JSON - Allgemeine Konfiguration",
|
||||||
@ -575,11 +576,11 @@
|
|||||||
"jsonPathExamplesExplanation": "Die folgenden Pfade finden jeweils den Wert '123.4' im jeweiligen Beispiel-JSON.",
|
"jsonPathExamplesExplanation": "Die folgenden Pfade finden jeweils den Wert '123.4' im jeweiligen Beispiel-JSON.",
|
||||||
"httpValue": "Konfiguration Wert {valueNumber}",
|
"httpValue": "Konfiguration Wert {valueNumber}",
|
||||||
"httpEnabled": "Wert aktiviert",
|
"httpEnabled": "Wert aktiviert",
|
||||||
"httpJsonPath": "JSON-Pfad",
|
"valueJsonPath": "JSON-Pfad",
|
||||||
"httpJsonPathDescription": "Anwendungsspezifischer JSON-Pfad um den Leistungswert in the HTTP(S) Antwort zu finden, z.B. 'power/total/watts' oder nur 'total'.",
|
"valueJsonPathDescription": "Anwendungsspezifischer JSON-Pfad um den Leistungswert in den JSON Nutzdatzen zu finden, z.B. 'power/total/watts' oder nur 'total'.",
|
||||||
"httpUnit": "Einheit",
|
"valueUnit": "Einheit",
|
||||||
"httpSignInverted": "Vorzeichen umkehren",
|
"valueSignInverted": "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.",
|
"valueSignInvertedHint": "Positive Werte werden als Leistungsabnahme aus dem Netz interpretiert. Diese Option muss aktiviert werden, wenn das Vorzeichen des Wertes die gegenteilige Bedeutung hat.",
|
||||||
"testHttpJsonHeader": "Konfiguration testen",
|
"testHttpJsonHeader": "Konfiguration testen",
|
||||||
"testHttpJsonRequest": "HTTP(S)-Anfrage(n) senden und Antwort(en) verarbeiten",
|
"testHttpJsonRequest": "HTTP(S)-Anfrage(n) senden und Antwort(en) verarbeiten",
|
||||||
"testHttpSmlHeader": "Konfiguration testen",
|
"testHttpSmlHeader": "Konfiguration testen",
|
||||||
|
|||||||
@ -567,6 +567,7 @@
|
|||||||
"typeSMAHM2": "SMA Homemanager 2.0",
|
"typeSMAHM2": "SMA Homemanager 2.0",
|
||||||
"typeHTTP_SML": "HTTP(S) + SML (e.g. Tibber Pulse via Tibber Bridge)",
|
"typeHTTP_SML": "HTTP(S) + SML (e.g. Tibber Pulse via Tibber Bridge)",
|
||||||
"MqttValue": "Value {valueNumber} Configuration",
|
"MqttValue": "Value {valueNumber} Configuration",
|
||||||
|
"mqttJsonPath": "Optional: JSON Path",
|
||||||
"MqttTopic": "MQTT Topic",
|
"MqttTopic": "MQTT Topic",
|
||||||
"SDM": "SDM-Power Meter Parameter",
|
"SDM": "SDM-Power Meter Parameter",
|
||||||
"sdmaddress": "Modbus Address",
|
"sdmaddress": "Modbus Address",
|
||||||
@ -577,11 +578,11 @@
|
|||||||
"jsonPathExamplesExplanation": "The following paths each find the value '123.4' in the respective example JSON.",
|
"jsonPathExamplesExplanation": "The following paths each find the value '123.4' in the respective example JSON.",
|
||||||
"httpValue": "Value {valueNumber} Configuration",
|
"httpValue": "Value {valueNumber} Configuration",
|
||||||
"httpEnabled": "Value Enabled",
|
"httpEnabled": "Value Enabled",
|
||||||
"httpJsonPath": "JSON Path",
|
"valueJsonPath": "JSON Path",
|
||||||
"httpJsonPathDescription": "Application specific JSON path to find the power value in the HTTP(S) response, e.g., 'power/total/watts' or simply 'total'.",
|
"valueJsonPathDescription": "Application specific JSON path to find the power value in the JSON payload, e.g., 'power/total/watts' or simply 'total'.",
|
||||||
"httpUnit": "Unit",
|
"valueUnit": "Unit",
|
||||||
"httpSignInverted": "Change Sign",
|
"valueSignInverted": "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.",
|
"valueSignInvertedHint": "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.",
|
||||||
"testHttpJsonHeader": "Test Configuration",
|
"testHttpJsonHeader": "Test Configuration",
|
||||||
"testHttpJsonRequest": "Send HTTP(S) request(s) and process response(s)",
|
"testHttpJsonRequest": "Send HTTP(S) request(s) and process response(s)",
|
||||||
"testHttpSmlHeader": "Test Configuration",
|
"testHttpSmlHeader": "Test Configuration",
|
||||||
|
|||||||
@ -2,6 +2,9 @@ import type { HttpRequestConfig } from '@/types/HttpRequestConfig';
|
|||||||
|
|
||||||
export interface PowerMeterMqttValue {
|
export interface PowerMeterMqttValue {
|
||||||
topic: string;
|
topic: string;
|
||||||
|
json_path: string;
|
||||||
|
unit: number;
|
||||||
|
sign_inverted: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PowerMeterMqttConfig {
|
export interface PowerMeterMqttConfig {
|
||||||
|
|||||||
@ -30,6 +30,18 @@
|
|||||||
</CardElement>
|
</CardElement>
|
||||||
|
|
||||||
<div v-if="powerMeterConfigList.enabled">
|
<div v-if="powerMeterConfigList.enabled">
|
||||||
|
<div v-if="powerMeterConfigList.source === 0 || powerMeterConfigList.source === 3">
|
||||||
|
<div class="alert alert-secondary mt-5" role="alert">
|
||||||
|
<h2>{{ $t('powermeteradmin.jsonPathExamplesHeading') }}:</h2>
|
||||||
|
{{ $t('powermeteradmin.jsonPathExamplesExplanation') }}
|
||||||
|
<ul>
|
||||||
|
<li><code>power/total/watts</code> — <code>{ "power": { "phase1": { "factor": 0.98, "watts": 42 }, "total": { "watts": 123.4 } } }</code></li>
|
||||||
|
<li><code>data/[1]/power</code> — <code>{ "data": [ { "factor": 0.98, "power": 42 }, { "factor": 1.0, "power": 123.4 } ] } }</code></li>
|
||||||
|
<li><code>total</code> — <code>{ "othervalue": 66, "total": 123.4 }</code></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<CardElement v-if="powerMeterConfigList.source === 0"
|
<CardElement v-if="powerMeterConfigList.source === 0"
|
||||||
v-for="(mqtt, index) in powerMeterConfigList.mqtt.values"
|
v-for="(mqtt, index) in powerMeterConfigList.mqtt.values"
|
||||||
:text="$t('powermeteradmin.MqttValue', { valueNumber: index + 1})"
|
:text="$t('powermeteradmin.MqttValue', { valueNumber: index + 1})"
|
||||||
@ -41,6 +53,33 @@
|
|||||||
type="text"
|
type="text"
|
||||||
maxlength="256"
|
maxlength="256"
|
||||||
wide />
|
wide />
|
||||||
|
|
||||||
|
<InputElement :label="$t('powermeteradmin.mqttJsonPath')"
|
||||||
|
v-model="mqtt.json_path"
|
||||||
|
type="text"
|
||||||
|
maxlength="256"
|
||||||
|
:tooltip="$t('powermeteradmin.valueJsonPathDescription')"
|
||||||
|
wide />
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<label for="mqtt_power_unit" class="col-sm-4 col-form-label">
|
||||||
|
{{ $t('powermeteradmin.valueUnit') }}
|
||||||
|
</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<select id="mqtt_power_unit" class="form-select" v-model="mqtt.unit">
|
||||||
|
<option v-for="u in unitTypeList" :key="u.key" :value="u.key">
|
||||||
|
{{ u.value }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<InputElement
|
||||||
|
:label="$t('powermeteradmin.valueSignInverted')"
|
||||||
|
v-model="mqtt.sign_inverted"
|
||||||
|
:tooltip="$t('powermeteradmin.valueSignInvertedHint')"
|
||||||
|
type="checkbox"
|
||||||
|
wide />
|
||||||
</CardElement>
|
</CardElement>
|
||||||
|
|
||||||
<CardElement v-if="(powerMeterConfigList.source === 1 || powerMeterConfigList.source === 2)"
|
<CardElement v-if="(powerMeterConfigList.source === 1 || powerMeterConfigList.source === 2)"
|
||||||
@ -63,6 +102,16 @@
|
|||||||
</CardElement>
|
</CardElement>
|
||||||
|
|
||||||
<div v-if="powerMeterConfigList.source === 3">
|
<div v-if="powerMeterConfigList.source === 3">
|
||||||
|
<div class="alert alert-secondary mt-5" role="alert">
|
||||||
|
<h2>{{ $t('powermeteradmin.urlExamplesHeading') }}:</h2>
|
||||||
|
<ul>
|
||||||
|
<li>http://shelly3em.home/status</li>
|
||||||
|
<li>https://shelly3em.home/status</li>
|
||||||
|
<li>http://tasmota-123.home/cm?cmnd=status%208</li>
|
||||||
|
<li>http://12.34.56.78:8080/emeter/0</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
<CardElement :text="$t('powermeteradmin.HTTP')"
|
<CardElement :text="$t('powermeteradmin.HTTP')"
|
||||||
textVariant="text-bg-primary"
|
textVariant="text-bg-primary"
|
||||||
add-space>
|
add-space>
|
||||||
@ -80,24 +129,6 @@
|
|||||||
wide />
|
wide />
|
||||||
</CardElement>
|
</CardElement>
|
||||||
|
|
||||||
<div class="alert alert-secondary mt-5" role="alert">
|
|
||||||
<h2>{{ $t('powermeteradmin.urlExamplesHeading') }}:</h2>
|
|
||||||
<ul>
|
|
||||||
<li>http://shelly3em.home/status</li>
|
|
||||||
<li>https://shelly3em.home/status</li>
|
|
||||||
<li>http://tasmota-123.home/cm?cmnd=status%208</li>
|
|
||||||
<li>http://12.34.56.78:8080/emeter/0</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h2>{{ $t('powermeteradmin.jsonPathExamplesHeading') }}:</h2>
|
|
||||||
{{ $t('powermeteradmin.jsonPathExamplesExplanation') }}
|
|
||||||
<ul>
|
|
||||||
<li><code>power/total/watts</code> — <code>{ "power": { "phase1": { "factor": 0.98, "watts": 42 }, "total": { "watts": 123.4 } } }</code></li>
|
|
||||||
<li><code>data/[1]/power</code> — <code>{ "data": [ { "factor": 0.98, "power": 42 }, { "factor": 1.0, "power": 123.4 } ] } }</code></li>
|
|
||||||
<li><code>total</code> — <code>{ "othervalue": 66, "total": 123.4 }</code></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<CardElement
|
<CardElement
|
||||||
v-for="(httpJson, index) in powerMeterConfigList.http_json.values"
|
v-for="(httpJson, index) in powerMeterConfigList.http_json.values"
|
||||||
:key="index"
|
:key="index"
|
||||||
@ -114,17 +145,17 @@
|
|||||||
|
|
||||||
<HttpRequestSettings :cfg="httpJson.http_request" v-if="index == 0 || powerMeterConfigList.http_json.individual_requests"/>
|
<HttpRequestSettings :cfg="httpJson.http_request" v-if="index == 0 || powerMeterConfigList.http_json.individual_requests"/>
|
||||||
|
|
||||||
<InputElement :label="$t('powermeteradmin.httpJsonPath')"
|
<InputElement :label="$t('powermeteradmin.valueJsonPath')"
|
||||||
v-model="httpJson.json_path"
|
v-model="httpJson.json_path"
|
||||||
type="text"
|
type="text"
|
||||||
maxlength="256"
|
maxlength="256"
|
||||||
placeholder="total_power"
|
placeholder="total_power"
|
||||||
:tooltip="$t('powermeteradmin.httpJsonPathDescription')"
|
:tooltip="$t('powermeteradmin.valueJsonPathDescription')"
|
||||||
wide />
|
wide />
|
||||||
|
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<label for="power_unit" class="col-sm-4 col-form-label">
|
<label for="power_unit" class="col-sm-4 col-form-label">
|
||||||
{{ $t('powermeteradmin.httpUnit') }}
|
{{ $t('powermeteradmin.valueUnit') }}
|
||||||
</label>
|
</label>
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<select id="power_unit" class="form-select" v-model="httpJson.unit">
|
<select id="power_unit" class="form-select" v-model="httpJson.unit">
|
||||||
@ -136,9 +167,9 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<InputElement
|
<InputElement
|
||||||
:label="$t('powermeteradmin.httpSignInverted')"
|
:label="$t('powermeteradmin.valueSignInverted')"
|
||||||
v-model="httpJson.sign_inverted"
|
v-model="httpJson.sign_inverted"
|
||||||
:tooltip="$t('powermeteradmin.httpSignInvertedHint')"
|
:tooltip="$t('powermeteradmin.valueSignInvertedHint')"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
wide />
|
wide />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user