Feature: add unit for MQTT battery voltage (#1143)

This commit is contained in:
vaterlangen 2024-07-31 14:51:26 +02:00 committed by Bernhard Kirchen
parent 1a19f881aa
commit cb5e7e59a5
9 changed files with 47 additions and 1 deletions

View File

@ -126,6 +126,8 @@ struct POWERMETER_HTTP_SML_CONFIG_T {
}; };
using PowerMeterHttpSmlConfig = struct POWERMETER_HTTP_SML_CONFIG_T; using PowerMeterHttpSmlConfig = struct POWERMETER_HTTP_SML_CONFIG_T;
enum BatteryVoltageUnit { Volts = 0, DeciVolts = 1, CentiVolts = 2, MilliVolts = 3 };
struct CONFIG_T { struct CONFIG_T {
struct { struct {
uint32_t Version; uint32_t Version;
@ -285,6 +287,7 @@ struct CONFIG_T {
char MqttSocJsonPath[BATTERY_JSON_MAX_PATH_STRLEN + 1]; char MqttSocJsonPath[BATTERY_JSON_MAX_PATH_STRLEN + 1];
char MqttVoltageTopic[MQTT_MAX_TOPIC_STRLEN + 1]; char MqttVoltageTopic[MQTT_MAX_TOPIC_STRLEN + 1];
char MqttVoltageJsonPath[BATTERY_JSON_MAX_PATH_STRLEN + 1]; char MqttVoltageJsonPath[BATTERY_JSON_MAX_PATH_STRLEN + 1];
BatteryVoltageUnit MqttVoltageUnit;
} Battery; } Battery;
struct { struct {

View File

@ -260,6 +260,7 @@ bool ConfigurationClass::write()
battery["mqtt_json_path"] = config.Battery.MqttSocJsonPath; battery["mqtt_json_path"] = config.Battery.MqttSocJsonPath;
battery["mqtt_voltage_topic"] = config.Battery.MqttVoltageTopic; battery["mqtt_voltage_topic"] = config.Battery.MqttVoltageTopic;
battery["mqtt_voltage_json_path"] = config.Battery.MqttVoltageJsonPath; battery["mqtt_voltage_json_path"] = config.Battery.MqttVoltageJsonPath;
battery["mqtt_voltage_unit"] = config.Battery.MqttVoltageUnit;
JsonObject huawei = doc["huawei"].to<JsonObject>(); JsonObject huawei = doc["huawei"].to<JsonObject>();
huawei["enabled"] = config.Huawei.Enabled; huawei["enabled"] = config.Huawei.Enabled;
@ -609,6 +610,7 @@ bool ConfigurationClass::read()
strlcpy(config.Battery.MqttSocJsonPath, battery["mqtt_json_path"] | "", sizeof(config.Battery.MqttSocJsonPath)); strlcpy(config.Battery.MqttSocJsonPath, battery["mqtt_json_path"] | "", sizeof(config.Battery.MqttSocJsonPath));
strlcpy(config.Battery.MqttVoltageTopic, battery["mqtt_voltage_topic"] | "", sizeof(config.Battery.MqttVoltageTopic)); strlcpy(config.Battery.MqttVoltageTopic, battery["mqtt_voltage_topic"] | "", sizeof(config.Battery.MqttVoltageTopic));
strlcpy(config.Battery.MqttVoltageJsonPath, battery["mqtt_voltage_json_path"] | "", sizeof(config.Battery.MqttVoltageJsonPath)); strlcpy(config.Battery.MqttVoltageJsonPath, battery["mqtt_voltage_json_path"] | "", sizeof(config.Battery.MqttVoltageJsonPath));
config.Battery.MqttVoltageUnit = battery["mqtt_voltage_unit"] | BatteryVoltageUnit::Volts;
JsonObject huawei = doc["huawei"]; JsonObject huawei = doc["huawei"];
config.Huawei.Enabled = huawei["enabled"] | HUAWEI_ENABLED; config.Huawei.Enabled = huawei["enabled"] | HUAWEI_ENABLED;

View File

@ -90,8 +90,25 @@ void MqttBattery::onMqttMessageVoltage(espMqttClientTypes::MessageProperties con
std::string(reinterpret_cast<const char*>(payload), len), topic, std::string(reinterpret_cast<const char*>(payload), len), topic,
jsonPath); jsonPath);
if (!voltage.has_value()) { return; } if (!voltage.has_value()) { return; }
auto const& config = Configuration.get();
using Unit_t = BatteryVoltageUnit;
switch (config.Battery.MqttVoltageUnit) {
case Unit_t::DeciVolts:
*voltage /= 10;
break;
case Unit_t::CentiVolts:
*voltage /= 100;
break;
case Unit_t::MilliVolts:
*voltage /= 1000;
break;
default:
break;
}
// since this project is revolving around Hoymiles microinverters, which can // since this project is revolving around Hoymiles microinverters, which can
// only handle up to 65V of input voltage at best, it is safe to assume that // only handle up to 65V of input voltage at best, it is safe to assume that
// an even higher voltage is implausible. // an even higher voltage is implausible.

View File

@ -44,6 +44,7 @@ void WebApiBatteryClass::onStatus(AsyncWebServerRequest* request)
root["mqtt_soc_json_path"] = config.Battery.MqttSocJsonPath; root["mqtt_soc_json_path"] = config.Battery.MqttSocJsonPath;
root["mqtt_voltage_topic"] = config.Battery.MqttVoltageTopic; root["mqtt_voltage_topic"] = config.Battery.MqttVoltageTopic;
root["mqtt_voltage_json_path"] = config.Battery.MqttVoltageJsonPath; root["mqtt_voltage_json_path"] = config.Battery.MqttVoltageJsonPath;
root["mqtt_voltage_unit"] = config.Battery.MqttVoltageUnit;
response->setLength(); response->setLength();
request->send(response); request->send(response);
@ -85,6 +86,7 @@ void WebApiBatteryClass::onAdminPost(AsyncWebServerRequest* request)
strlcpy(config.Battery.MqttSocJsonPath, root["mqtt_soc_json_path"].as<String>().c_str(), sizeof(config.Battery.MqttSocJsonPath)); strlcpy(config.Battery.MqttSocJsonPath, root["mqtt_soc_json_path"].as<String>().c_str(), sizeof(config.Battery.MqttSocJsonPath));
strlcpy(config.Battery.MqttVoltageTopic, root["mqtt_voltage_topic"].as<String>().c_str(), sizeof(config.Battery.MqttVoltageTopic)); strlcpy(config.Battery.MqttVoltageTopic, root["mqtt_voltage_topic"].as<String>().c_str(), sizeof(config.Battery.MqttVoltageTopic));
strlcpy(config.Battery.MqttVoltageJsonPath, root["mqtt_voltage_json_path"].as<String>().c_str(), sizeof(config.Battery.MqttVoltageJsonPath)); strlcpy(config.Battery.MqttVoltageJsonPath, root["mqtt_voltage_json_path"].as<String>().c_str(), sizeof(config.Battery.MqttVoltageJsonPath));
config.Battery.MqttVoltageUnit = static_cast<BatteryVoltageUnit>(root["mqtt_voltage_unit"].as<uint8_t>());
WebApi.writeConfig(retMsg); WebApi.writeConfig(retMsg);

View File

@ -676,6 +676,7 @@
"MqttVoltageConfiguration": "Einstellungen Spannung", "MqttVoltageConfiguration": "Einstellungen Spannung",
"MqttJsonPath": "Optional: JSON-Pfad", "MqttJsonPath": "Optional: JSON-Pfad",
"MqttJsonPathDescription": "Anwendungsspezifischer JSON-Pfad um den Wert in den JSON Nutzdatzen zu finden, z.B. 'electricLevel'. Leer lassen, falls die Nutzdaten des Topics einen numerischen Wert enthält.", "MqttJsonPathDescription": "Anwendungsspezifischer JSON-Pfad um den Wert in den JSON Nutzdatzen zu finden, z.B. 'electricLevel'. Leer lassen, falls die Nutzdaten des Topics einen numerischen Wert enthält.",
"MqttVoltageUnit": "Einheit",
"MqttSocTopic": "Topic für SoC", "MqttSocTopic": "Topic für SoC",
"MqttVoltageTopic": "Topic für Spannung", "MqttVoltageTopic": "Topic für Spannung",
"JkBmsConfiguration": "JK BMS Einstellungen", "JkBmsConfiguration": "JK BMS Einstellungen",

View File

@ -679,6 +679,7 @@
"MqttVoltageConfiguration": "Voltage Settings", "MqttVoltageConfiguration": "Voltage Settings",
"MqttJsonPath": "Optional: JSON Path", "MqttJsonPath": "Optional: JSON Path",
"MqttJsonPathDescription": "Application specific JSON path to find the value in the JSON payload, e.g., 'electricLevel'. Leave empty if the topic's payload contains a plain numeric value.", "MqttJsonPathDescription": "Application specific JSON path to find the value in the JSON payload, e.g., 'electricLevel'. Leave empty if the topic's payload contains a plain numeric value.",
"MqttVoltageUnit": "Unit",
"MqttSocTopic": "SoC Value Topic", "MqttSocTopic": "SoC Value Topic",
"MqttVoltageTopic": "Voltage Value Topic", "MqttVoltageTopic": "Voltage Value Topic",
"JkBmsConfiguration": "JK BMS Settings", "JkBmsConfiguration": "JK BMS Settings",

View File

@ -602,6 +602,7 @@
"MqttVoltageConfiguration": "Voltage Settings", "MqttVoltageConfiguration": "Voltage Settings",
"MqttJsonPath": "Optional: JSON Path", "MqttJsonPath": "Optional: JSON Path",
"MqttJsonPathDescription": "Application specific JSON path to find the value in the JSON payload, e.g., 'electricLevel'. Leave empty if the topic's payload contains a plain numeric value.", "MqttJsonPathDescription": "Application specific JSON path to find the value in the JSON payload, e.g., 'electricLevel'. Leave empty if the topic's payload contains a plain numeric value.",
"MqttVoltageUnit": "Unit",
"MqttSocTopic": "SoC Value Topic", "MqttSocTopic": "SoC Value Topic",
"MqttVoltageTopic": "Voltage Value Topic", "MqttVoltageTopic": "Voltage Value Topic",
"JkBmsConfiguration": "JK BMS Settings", "JkBmsConfiguration": "JK BMS Settings",

View File

@ -8,4 +8,5 @@ export interface BatteryConfig {
mqtt_soc_json_path: string; mqtt_soc_json_path: string;
mqtt_voltage_topic: string; mqtt_voltage_topic: string;
mqtt_voltage_json_path: string; mqtt_voltage_json_path: string;
mqtt_voltage_unit: number;
} }

View File

@ -78,6 +78,18 @@
maxlength="128" maxlength="128"
:tooltip="$t('batteryadmin.MqttJsonPathDescription')" /> :tooltip="$t('batteryadmin.MqttJsonPathDescription')" />
<div class="row mb-3">
<label for="mqtt_voltage_unit" class="col-sm-2 col-form-label">
{{ $t('batteryadmin.MqttVoltageUnit') }}
</label>
<div class="col-sm-10">
<select id="mqtt_voltage_unit" class="form-select" v-model="batteryConfigList.mqtt_voltage_unit">
<option v-for="u in voltageUnitTypeList" :key="u.key" :value="u.key">
{{ u.value }}
</option>
</select>
</div>
</div>
</CardElement> </CardElement>
</template> </template>
@ -122,6 +134,12 @@ export default defineComponent({
{ key: 0, value: 'Uart' }, { key: 0, value: 'Uart' },
{ key: 1, value: 'Transceiver' }, { key: 1, value: 'Transceiver' },
], ],
voltageUnitTypeList: [
{ key: 3, value: "mV" },
{ key: 2, value: "cV" },
{ key: 1, value: "dV" },
{ key: 0, value: "V" },
],
}; };
}, },
created() { created() {