Skip to content

Commit

Permalink
Feature: add unit for MQTT battery voltage (#1143)
Browse files Browse the repository at this point in the history
  • Loading branch information
vaterlangen authored and schlimmchen committed Jul 31, 2024
1 parent 1a19f88 commit cb5e7e5
Show file tree
Hide file tree
Showing 9 changed files with 47 additions and 1 deletion.
3 changes: 3 additions & 0 deletions include/Configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ 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 {
uint32_t Version;
Expand Down Expand Up @@ -285,6 +287,7 @@ struct CONFIG_T {
char MqttSocJsonPath[BATTERY_JSON_MAX_PATH_STRLEN + 1];
char MqttVoltageTopic[MQTT_MAX_TOPIC_STRLEN + 1];
char MqttVoltageJsonPath[BATTERY_JSON_MAX_PATH_STRLEN + 1];
BatteryVoltageUnit MqttVoltageUnit;
} Battery;

struct {
Expand Down
2 changes: 2 additions & 0 deletions src/Configuration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ bool ConfigurationClass::write()
battery["mqtt_json_path"] = config.Battery.MqttSocJsonPath;
battery["mqtt_voltage_topic"] = config.Battery.MqttVoltageTopic;
battery["mqtt_voltage_json_path"] = config.Battery.MqttVoltageJsonPath;
battery["mqtt_voltage_unit"] = config.Battery.MqttVoltageUnit;

JsonObject huawei = doc["huawei"].to<JsonObject>();
huawei["enabled"] = config.Huawei.Enabled;
Expand Down Expand Up @@ -609,6 +610,7 @@ bool ConfigurationClass::read()
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.MqttVoltageJsonPath, battery["mqtt_voltage_json_path"] | "", sizeof(config.Battery.MqttVoltageJsonPath));
config.Battery.MqttVoltageUnit = battery["mqtt_voltage_unit"] | BatteryVoltageUnit::Volts;

JsonObject huawei = doc["huawei"];
config.Huawei.Enabled = huawei["enabled"] | HUAWEI_ENABLED;
Expand Down
17 changes: 17 additions & 0 deletions src/MqttBattery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,25 @@ void MqttBattery::onMqttMessageVoltage(espMqttClientTypes::MessageProperties con
std::string(reinterpret_cast<const char*>(payload), len), topic,
jsonPath);


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
// only handle up to 65V of input voltage at best, it is safe to assume that
// an even higher voltage is implausible.
Expand Down
4 changes: 3 additions & 1 deletion src/WebApi_battery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ void WebApiBatteryClass::onStatus(AsyncWebServerRequest* request)
if (!WebApi.checkCredentialsReadonly(request)) {
return;
}

AsyncJsonResponse* response = new AsyncJsonResponse();
auto& root = response->getRoot();
const CONFIG_T& config = Configuration.get();
Expand All @@ -44,6 +44,7 @@ void WebApiBatteryClass::onStatus(AsyncWebServerRequest* request)
root["mqtt_soc_json_path"] = config.Battery.MqttSocJsonPath;
root["mqtt_voltage_topic"] = config.Battery.MqttVoltageTopic;
root["mqtt_voltage_json_path"] = config.Battery.MqttVoltageJsonPath;
root["mqtt_voltage_unit"] = config.Battery.MqttVoltageUnit;

response->setLength();
request->send(response);
Expand Down Expand Up @@ -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.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));
config.Battery.MqttVoltageUnit = static_cast<BatteryVoltageUnit>(root["mqtt_voltage_unit"].as<uint8_t>());

WebApi.writeConfig(retMsg);

Expand Down
1 change: 1 addition & 0 deletions webapp/src/locales/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,7 @@
"MqttVoltageConfiguration": "Einstellungen Spannung",
"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.",
"MqttVoltageUnit": "Einheit",
"MqttSocTopic": "Topic für SoC",
"MqttVoltageTopic": "Topic für Spannung",
"JkBmsConfiguration": "JK BMS Einstellungen",
Expand Down
1 change: 1 addition & 0 deletions webapp/src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -679,6 +679,7 @@
"MqttVoltageConfiguration": "Voltage Settings",
"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.",
"MqttVoltageUnit": "Unit",
"MqttSocTopic": "SoC Value Topic",
"MqttVoltageTopic": "Voltage Value Topic",
"JkBmsConfiguration": "JK BMS Settings",
Expand Down
1 change: 1 addition & 0 deletions webapp/src/locales/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,7 @@
"MqttVoltageConfiguration": "Voltage Settings",
"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.",
"MqttVoltageUnit": "Unit",
"MqttSocTopic": "SoC Value Topic",
"MqttVoltageTopic": "Voltage Value Topic",
"JkBmsConfiguration": "JK BMS Settings",
Expand Down
1 change: 1 addition & 0 deletions webapp/src/types/BatteryConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ export interface BatteryConfig {
mqtt_soc_json_path: string;
mqtt_voltage_topic: string;
mqtt_voltage_json_path: string;
mqtt_voltage_unit: number;
}
18 changes: 18 additions & 0 deletions webapp/src/views/BatteryAdminView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,18 @@
maxlength="128"
: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>
</template>

Expand Down Expand Up @@ -122,6 +134,12 @@ export default defineComponent({
{ key: 0, value: 'Uart' },
{ key: 1, value: 'Transceiver' },
],
voltageUnitTypeList: [
{ key: 3, value: "mV" },
{ key: 2, value: "cV" },
{ key: 1, value: "dV" },
{ key: 0, value: "V" },
],
};
},
created() {
Expand Down

0 comments on commit cb5e7e5

Please sign in to comment.