Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 39 additions & 2 deletions src/Components/MQTT/MQTTManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ namespace MQTTManager
uint8_t gCurValueIndex = 0;
char TopicBuffer[128];
char PayloadBuffer[1024];
char AvailabilityTopic[128];
PrefixedString gMqttTopic(128);

constexpr uint16_t NumMqttPublishedValues = 10;
Expand Down Expand Up @@ -58,7 +59,19 @@ namespace MQTTManager
StringUtils::InsertString(topic, TopicBuffer, sizeof(TopicBuffer), '%', Settings::Instance()->DeviceName.c_str());
StringUtils::InsertString(payload, PayloadBuffer, sizeof(PayloadBuffer), '%', Settings::Instance()->DeviceName.c_str());

gMqttClient.publish(TopicBuffer, 1, true, PayloadBuffer);
// Publishing many discovery messages back-to-back can exceed the client's TCP
// send buffer, causing publish() to silently drop the message (it returns 0).
// Retry briefly instead of losing the config message.
for (uint8_t attempt = 0; attempt < Constants::MQTT::MaxPublishAttempts; attempt++)
{
if (gMqttClient.publish(TopicBuffer, 1, true, PayloadBuffer) != 0)
{
return;
}
delay(20);
}

Logger::Warning("MQTT: Failed to publish discovery topic %s", TopicBuffer);
}

// Publishes MQTT discovery messages for Home Assistant integration
Expand All @@ -71,6 +84,7 @@ namespace MQTTManager
"name":"Vehicle connected",
"device_class":"plug",
"state_topic":"%/is_vehicle_connected",
"availability_topic":"%/status",
"payload_on":"1",
"payload_off":"0",
"unique_id":"%_is_vehicle_connected",
Expand All @@ -83,6 +97,7 @@ namespace MQTTManager
"name":"Vehicle charging",
"device_class":"battery_charging",
"state_topic":"%/is_vehicle_charging",
"availability_topic":"%/status",
"payload_on":"1",
"payload_off":"0",
"unique_id":"%_is_vehicle_charging",
Expand All @@ -96,6 +111,7 @@ namespace MQTTManager
"device_class":"power",
"state_class":"measurement",
"state_topic":"%/charging_power",
"availability_topic":"%/status",
"unique_id":"%_charging_power",
"default_entity_id":"sensor.%_charging_power",
"unit_of_measurement":"W",
Expand All @@ -108,6 +124,7 @@ namespace MQTTManager
"device_class":"current",
"state_class":"measurement",
"state_topic":"%/charging_current/phase1",
"availability_topic":"%/status",
"unique_id":"%_charging_current_phase1",
"default_entity_id":"sensor.%_charging_current_phase1",
"unit_of_measurement":"A",
Expand All @@ -120,6 +137,7 @@ namespace MQTTManager
"device_class":"current",
"state_class":"measurement",
"state_topic":"%/charging_current/phase2",
"availability_topic":"%/status",
"unique_id":"%_charging_current_phase2",
"default_entity_id":"sensor.%_charging_current_phase2",
"unit_of_measurement":"A",
Expand All @@ -132,6 +150,7 @@ namespace MQTTManager
"device_class":"current",
"state_class":"measurement",
"state_topic":"%/charging_current/phase3",
"availability_topic":"%/status",
"unique_id":"%_charging_current_phase3",
"default_entity_id":"sensor.%_charging_current_phase3",
"unit_of_measurement":"A",
Expand All @@ -144,6 +163,7 @@ namespace MQTTManager
"device_class":"current",
"state_class":"measurement",
"state_topic":"%/charging_current_limit",
"availability_topic":"%/status",
"unique_id":"%_charging_current_limit",
"default_entity_id":"sensor.%_charging_current_limit",
"unit_of_measurement":"A",
Expand All @@ -155,6 +175,7 @@ namespace MQTTManager
"name":"Energy meter",
"device_class":"energy",
"state_topic":"%/energy_meter",
"availability_topic":"%/status",
"state_class":"total_increasing",
"unique_id":"%_energy_meter",
"default_entity_id":"sensor.%_energy_meter",
Expand All @@ -168,6 +189,7 @@ namespace MQTTManager
"device_class":"temperature",
"state_class":"measurement",
"state_topic":"%/temperature",
"availability_topic":"%/status",
"unique_id":"%_temperature",
"default_entity_id":"sensor.%_temperature",
"unit_of_measurement":"°C",
Expand All @@ -180,6 +202,7 @@ namespace MQTTManager
"device_class":"voltage",
"state_class":"measurement",
"state_topic":"%/charging_voltage/phase1",
"availability_topic":"%/status",
"unique_id":"%_charging_voltage_phase1",
"default_entity_id":"sensor.%_charging_voltage_phase1",
"unit_of_measurement":"V",
Expand All @@ -192,6 +215,7 @@ namespace MQTTManager
"device_class":"voltage",
"state_class":"measurement",
"state_topic":"%/charging_voltage/phase2",
"availability_topic":"%/status",
"unique_id":"%_charging_voltage_phase2",
"default_entity_id":"sensor.%_charging_voltage_phase2",
"unit_of_measurement":"V",
Expand All @@ -204,6 +228,7 @@ namespace MQTTManager
"device_class":"voltage",
"state_class":"measurement",
"state_topic":"%/charging_voltage/phase3",
"availability_topic":"%/status",
"unique_id":"%_charging_voltage_phase3",
"default_entity_id":"sensor.%_charging_voltage_phase3",
"unit_of_measurement":"V",
Expand All @@ -215,7 +240,8 @@ namespace MQTTManager
"name":"Enable Charging",
"state_topic":"%/enable_charging",
"command_topic":"%/control/enable_charging",
"unique_id":"%control_enable_charging",
"availability_topic":"%/status",
"unique_id":"%_control_enable_charging",
"default_entity_id":"switch.%_control_enable_charging",
"payload_on":"ON",
"payload_off":"OFF",
Expand All @@ -227,6 +253,7 @@ namespace MQTTManager
"name":"Standby Mode",
"state_topic":"%/standby_enabled",
"command_topic":"%/control/standby",
"availability_topic":"%/status",
"unique_id":"%_control_standby",
"default_entity_id":"switch.%_control_standby",
"payload_on":"ON",
Expand All @@ -239,6 +266,7 @@ namespace MQTTManager
"name":"Charging Current Limit",
"command_topic":"%/control/charging_current_limit",
"state_topic":"%/charging_current_limit",
"availability_topic":"%/status",
"min":6,
"max":16,
"step":1,
Expand Down Expand Up @@ -360,6 +388,9 @@ namespace MQTTManager
gMqttClient.publish(gMqttTopic.SetString("/build_date"), 0, true, __DATE__);
gMqttClient.publish(gMqttTopic.SetString("/ip_address"), 0, true, WiFi.localIP().toString().c_str());

// Birth message: signals the device is back online (counterpart to the LWT)
gMqttClient.publish(AvailabilityTopic, 1, true, "online");

// Publish discovery data
PublishHomeAssistantDiscovery();
}
Expand Down Expand Up @@ -413,6 +444,12 @@ namespace MQTTManager

gWallbox = wallbox;

// Last Will & Testament: lets Home Assistant mark the device (and its
// entities via availability_topic) unavailable if the connection drops
// unexpectedly, instead of showing stale last-known values forever.
snprintf(AvailabilityTopic, sizeof(AvailabilityTopic), "%s/status", Settings::Instance()->DeviceName.c_str());
gMqttClient.setWill(AvailabilityTopic, 1, true, "offline");

// Register event callbacks
gMqttClient.onConnect(OnMqttConnect);
gMqttClient.onDisconnect(OnMqttDisconnect);
Expand Down
1 change: 1 addition & 0 deletions src/Configuration/Constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,5 +98,6 @@ namespace Constants
namespace MQTT
{
constexpr uint16_t PublishIntervalMs = 500;
constexpr uint8_t MaxPublishAttempts = 5;
};
};
Loading