Centralizations and mods for it

This commit is contained in:
Cabooman 2024-02-03 22:27:25 +01:00
parent 838c2f0dcb
commit 13bfdcc33b
6 changed files with 107 additions and 73 deletions

View file

@ -3,6 +3,7 @@
#include <WiFi.h>
#include <freertos/FreeRTOS.h>
#include "../../../USER_SETTINGS.h"
#include "../../battery/BATTERIES.h"
#include "../../lib/knolleary-pubsubclient/PubSubClient.h"
#include "../utils/timer.h"
@ -16,9 +17,17 @@ int value = 0;
static unsigned long previousMillisUpdateVal;
MyTimer publish_global_timer(5000);
static void publish_common_info(void);
static void publish_cell_voltages(void);
/** Publish global values and call callbacks for specific modules */
static void publish_values(void) {
publish_common_info();
publish_cell_voltages();
publish_battery_specifics();
}
static void publish_common_info(void) {
snprintf(mqtt_msg, sizeof(mqtt_msg),
"{\n"
" \"SOC\": %.3f,\n"
@ -31,7 +40,83 @@ static void publish_values(void) {
((float)SOC) / 100.0, ((float)StateOfHealth) / 100.0, ((float)((int16_t)temperature_min)) / 10.0,
((float)((int16_t)temperature_max)) / 10.0, cell_max_voltage, cell_min_voltage);
bool result = client.publish("battery/info", mqtt_msg, true);
Serial.println(mqtt_msg); // Uncomment to print the payload on serial
//Serial.println(mqtt_msg); // Uncomment to print the payload on serial
}
static void publish_cell_voltages(void) {
static bool mqtt_first_transmission = true;
// If the cell voltage number isn't initialized...
if (nof_cellvoltages == 0u) {
return;
}
// At startup, re-post the discovery message for home assistant
if (mqtt_first_transmission == true) {
mqtt_first_transmission = false;
// Base topic for any cell voltage "sensor"
String topic = "homeassistant/sensor/battery-emulator/cell_voltage";
for (int i = 0; i < nof_cellvoltages; i++) {
// Build JSON message with device configuration for each cell voltage
// Probably shouldn't be BatteryEmulator here, instead "LeafBattery"
// or similar but hey, it works.
// mqtt_msg is a global buffer, should be fine since we run too much
// in a single thread :)
snprintf(mqtt_msg, sizeof(mqtt_msg),
"{"
"\"device\": {"
"\"identifiers\": ["
"\"battery-emulator\""
"],"
"\"manufacturer\": \"DalaTech\","
"\"model\": \"BatteryEmulator\","
"\"name\": \"BatteryEmulator\""
"},"
"\"device_class\": \"voltage\","
"\"enabled_by_default\": true,"
"\"object_id\": \"sensor_battery_voltage_cell%d\","
"\"origin\": {"
"\"name\": \"BatteryEmulator\","
"\"sw\": \"4.4.0-mqtt\","
"\"url\": \"https://github.com/dalathegreat/Battery-Emulator\""
"},"
"\"state_class\": \"measurement\","
"\"name\": \"Battery Cell Voltage %d\","
"\"state_topic\": \"battery/spec_data\","
"\"unique_id\": \"battery-emulator_battery_voltage_cell%d\","
"\"unit_of_measurement\": \"V\","
"\"value_template\": \"{{ value_json.cell_voltages[%d] }}\""
"}",
i + 1, i + 1, i + 1, i);
// End each discovery topic with cell number and '/config'
String cell_topic = topic + String(i + 1) + "/config";
mqtt_publish_retain(cell_topic.c_str());
}
}
else {
// Every 5-ish seconds, build the JSON payload for the state topic. This requires
// some annoying formatting due to C++ not having nice Python-like string formatting.
// msg_length is a cumulative variable to track start position (param 1) and for
// modifying the maxiumum amount of characters to write (param 2). The third parameter
// is the string content
// If cell voltages haven't been populated...
if (cellvoltages[0] == 0u) {
return;
}
size_t msg_length = snprintf(mqtt_msg, sizeof(mqtt_msg), "{\n\"cell_voltages\":[");
for (size_t i = 0; i < nof_cellvoltages; ++i) {
msg_length +=
snprintf(mqtt_msg + msg_length, sizeof(mqtt_msg) - msg_length, "%s%d", (i == 0) ? "" : ", ", cellvoltages[i]);
}
snprintf(mqtt_msg + msg_length, sizeof(mqtt_msg) - msg_length, "]\n}\n");
// Publish and print error if not OK
if (mqtt_publish_retain("battery/spec_data") == false) {
Serial.println("Cell voltage MQTT msg could not be sent");
}
}
}
/* This is called whenever a subscribed topic changes (hopefully) */