mirror of
https://github.com/dalathegreat/Battery-Emulator.git
synced 2025-10-03 17:59:27 +02:00
Determine double battery usage in MQTT at run-time
This commit is contained in:
parent
8cb4884af7
commit
3789d72833
5 changed files with 68 additions and 60 deletions
|
@ -88,11 +88,6 @@ void setup() {
|
|||
&logging_loop_task, WIFI_CORE);
|
||||
#endif
|
||||
|
||||
#ifdef MQTT
|
||||
xTaskCreatePinnedToCore((TaskFunction_t)&mqtt_loop, "mqtt_loop", 4096, NULL, TASK_MQTT_PRIO, &mqtt_loop_task,
|
||||
WIFI_CORE);
|
||||
#endif
|
||||
|
||||
init_CAN();
|
||||
|
||||
init_contactors();
|
||||
|
@ -126,6 +121,12 @@ void setup() {
|
|||
};
|
||||
|
||||
// Start tasks
|
||||
|
||||
#ifdef MQTT
|
||||
xTaskCreatePinnedToCore((TaskFunction_t)&mqtt_loop, "mqtt_loop", 4096, NULL, TASK_MQTT_PRIO, &mqtt_loop_task,
|
||||
WIFI_CORE);
|
||||
#endif
|
||||
|
||||
xTaskCreatePinnedToCore((TaskFunction_t)&core_loop, "core_loop", 4096, NULL, TASK_CORE_PRIO, &main_loop_task,
|
||||
CORE_FUNCTION_CORE);
|
||||
#ifdef PERIODIC_BMS_RESET_AT
|
||||
|
|
|
@ -47,6 +47,9 @@ class Battery {
|
|||
// This allows for battery specific SOC plausibility calculations to be performed.
|
||||
virtual bool soc_plausible() { return true; }
|
||||
|
||||
// Battery reports total_charged_battery_Wh and total_discharged_battery_Wh
|
||||
virtual bool supports_charged_energy() { return false; }
|
||||
|
||||
virtual BatteryHtmlRenderer& get_status_renderer() { return defaultRenderer; }
|
||||
|
||||
private:
|
||||
|
|
|
@ -15,6 +15,7 @@ class MebBattery : public CanBattery {
|
|||
virtual void update_values();
|
||||
virtual void transmit_can(unsigned long currentMillis);
|
||||
bool supports_real_BMS_status() { return true; }
|
||||
bool supports_charged_energy() { return true; }
|
||||
|
||||
BatteryHtmlRenderer& get_status_renderer() { return renderer; }
|
||||
|
||||
|
|
|
@ -30,6 +30,8 @@ class TeslaBattery : public CanBattery {
|
|||
bool supports_reset_BMS() { return true; }
|
||||
void reset_BMS() { datalayer.battery.settings.user_requests_tesla_bms_reset = true; }
|
||||
|
||||
bool supports_charged_energy() { return true; }
|
||||
|
||||
BatteryHtmlRenderer& get_status_renderer() { return renderer; }
|
||||
|
||||
private:
|
||||
|
|
|
@ -89,11 +89,8 @@ SensorConfig sensorConfigTemplate[] = {
|
|||
{"bms_status", "BMS Status", "", "", ""},
|
||||
{"pause_status", "Pause Status", "", "", ""}};
|
||||
|
||||
#ifdef DOUBLE_BATTERY
|
||||
// Enough space for two batteries
|
||||
SensorConfig sensorConfigs[((sizeof(sensorConfigTemplate) / sizeof(sensorConfigTemplate[0])) * 2) - 2];
|
||||
#else
|
||||
SensorConfig sensorConfigs[sizeof(sensorConfigTemplate) / sizeof(sensorConfigTemplate[0])];
|
||||
#endif // DOUBLE_BATTERY
|
||||
|
||||
void create_sensor_configs() {
|
||||
int number_of_templates = sizeof(sensorConfigTemplate) / sizeof(sensorConfigTemplate[0]);
|
||||
|
@ -101,7 +98,8 @@ void create_sensor_configs() {
|
|||
SensorConfig config = sensorConfigTemplate[i];
|
||||
config.value_template = strdup(("{{ value_json." + std::string(config.object_id) + " }}").c_str());
|
||||
sensorConfigs[i] = config;
|
||||
#ifdef DOUBLE_BATTERY
|
||||
|
||||
if (battery2) {
|
||||
if (config.object_id == "pause_status" || config.object_id == "bms_status") {
|
||||
continue;
|
||||
}
|
||||
|
@ -110,7 +108,7 @@ void create_sensor_configs() {
|
|||
sensorConfigs[i + number_of_templates].object_id = strdup(String(config.object_id + String("_2")).c_str());
|
||||
sensorConfigs[i + number_of_templates].value_template =
|
||||
strdup(("{{ value_json." + std::string(config.object_id) + "_2 }}").c_str());
|
||||
#endif // DOUBLE_BATTERY
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -164,7 +162,8 @@ static String generateButtonTopic(const char* subtype) {
|
|||
return topic_name + "/command/" + String(subtype);
|
||||
}
|
||||
|
||||
void set_battery_attributes(JsonDocument& doc, const DATALAYER_BATTERY_TYPE& battery, const String& suffix) {
|
||||
void set_battery_attributes(JsonDocument& doc, const DATALAYER_BATTERY_TYPE& battery, const String& suffix,
|
||||
bool supports_charged) {
|
||||
doc["SOC" + suffix] = ((float)battery.status.reported_soc) / 100.0;
|
||||
doc["SOC_real" + suffix] = ((float)battery.status.real_soc) / 100.0;
|
||||
doc["state_of_health" + suffix] = ((float)battery.status.soh_pptt) / 100.0;
|
||||
|
@ -185,13 +184,14 @@ void set_battery_attributes(JsonDocument& doc, const DATALAYER_BATTERY_TYPE& bat
|
|||
doc["remaining_capacity" + suffix] = ((float)battery.status.reported_remaining_capacity_Wh);
|
||||
doc["max_discharge_power" + suffix] = ((float)battery.status.max_discharge_power_W);
|
||||
doc["max_charge_power" + suffix] = ((float)battery.status.max_charge_power_W);
|
||||
#if defined(MEB_BATTERY) || defined(TESLA_BATTERY)
|
||||
|
||||
if (supports_charged) {
|
||||
if (datalayer.battery.status.total_charged_battery_Wh != 0 &&
|
||||
datalayer.battery.status.total_discharged_battery_Wh != 0) {
|
||||
doc["charged_energy" + suffix] = ((float)datalayer.battery.status.total_charged_battery_Wh);
|
||||
doc["discharged_energy" + suffix] = ((float)datalayer.battery.status.total_discharged_battery_Wh);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static std::vector<EventData> order_events;
|
||||
|
@ -231,14 +231,15 @@ static bool publish_common_info(void) {
|
|||
|
||||
//only publish these values if BMS is active and we are comunication with the battery (can send CAN messages to the battery)
|
||||
if (datalayer.battery.status.CAN_battery_still_alive && allowed_to_send_CAN && millis() > BOOTUP_TIME) {
|
||||
set_battery_attributes(doc, datalayer.battery, "");
|
||||
set_battery_attributes(doc, datalayer.battery, "", battery->supports_charged_energy());
|
||||
}
|
||||
#ifdef DOUBLE_BATTERY
|
||||
|
||||
if (battery2) {
|
||||
//only publish these values if BMS is active and we are comunication with the battery (can send CAN messages to the battery)
|
||||
if (datalayer.battery2.status.CAN_battery_still_alive && allowed_to_send_CAN && millis() > BOOTUP_TIME) {
|
||||
set_battery_attributes(doc, datalayer.battery2, "_2");
|
||||
set_battery_attributes(doc, datalayer.battery2, "_2", battery2->supports_charged_energy());
|
||||
}
|
||||
}
|
||||
#endif // DOUBLE_BATTERY
|
||||
serializeJson(doc, mqtt_msg);
|
||||
if (mqtt_publish(state_topic.c_str(), mqtt_msg, false) == false) {
|
||||
#ifdef DEBUG_LOG
|
||||
|
@ -256,9 +257,7 @@ static bool publish_common_info(void) {
|
|||
static bool publish_cell_voltages(void) {
|
||||
static JsonDocument doc;
|
||||
static String state_topic = topic_name + "/spec_data";
|
||||
#ifdef DOUBLE_BATTERY
|
||||
static String state_topic_2 = topic_name + "/spec_data_2";
|
||||
#endif // DOUBLE_BATTERY
|
||||
|
||||
#ifdef HA_AUTODISCOVERY
|
||||
bool failed_to_publish = false;
|
||||
|
@ -280,7 +279,9 @@ static bool publish_cell_voltages(void) {
|
|||
}
|
||||
doc.clear(); // clear after sending autoconfig
|
||||
}
|
||||
#ifdef DOUBLE_BATTERY
|
||||
|
||||
if (battery2) {
|
||||
// TODO: Combine this identical block with the previous one.
|
||||
// If the cell voltage number isn't initialized...
|
||||
if (datalayer.battery2.info.number_of_cells != 0u) {
|
||||
|
||||
|
@ -297,7 +298,7 @@ static bool publish_cell_voltages(void) {
|
|||
}
|
||||
doc.clear(); // clear after sending autoconfig
|
||||
}
|
||||
#endif // DOUBLE_BATTERY
|
||||
}
|
||||
}
|
||||
if (failed_to_publish == false) {
|
||||
ha_cell_voltages_published = true;
|
||||
|
@ -324,7 +325,7 @@ static bool publish_cell_voltages(void) {
|
|||
doc.clear();
|
||||
}
|
||||
|
||||
#ifdef DOUBLE_BATTERY
|
||||
if (battery2) {
|
||||
// If cell voltages have been populated...
|
||||
if (datalayer.battery2.info.number_of_cells != 0u &&
|
||||
datalayer.battery2.status.cell_voltages_mV[datalayer.battery2.info.number_of_cells - 1] != 0u) {
|
||||
|
@ -344,7 +345,7 @@ static bool publish_cell_voltages(void) {
|
|||
}
|
||||
doc.clear();
|
||||
}
|
||||
#endif // DOUBLE_BATTERY
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue