mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 15:59:52 +03:00
HA integration - add devices as HA devices - HomeAssistant Discovery #288
This commit is contained in:
@@ -85,8 +85,24 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const
|
|||||||
// create the config topics for Home Assistant MQTT Discovery
|
// create the config topics for Home Assistant MQTT Discovery
|
||||||
// for each of the main elements
|
// for each of the main elements
|
||||||
void Boiler::register_mqtt_ha_config() {
|
void Boiler::register_mqtt_ha_config() {
|
||||||
Mqtt::register_mqtt_ha_binary_sensor(F("Boiler DHW"), "tapwater_active");
|
// Create the Master device
|
||||||
Mqtt::register_mqtt_ha_binary_sensor(F("Boiler Heating"), "heating_active");
|
StaticJsonDocument<EMSESP_MAX_JSON_SIZE_MEDIUM> doc;
|
||||||
|
doc["name"] = F("EMS-ESP");
|
||||||
|
doc["uniq_id"] = F("boiler");
|
||||||
|
doc["ic"] = F("mdi:home-thermometer-outline");
|
||||||
|
doc["stat_t"] = F("ems-esp/boiler_data");
|
||||||
|
doc["val_tpl"] = F("{{value_json.serviceCode}}");
|
||||||
|
JsonObject dev = doc.createNestedObject("dev");
|
||||||
|
dev["name"] = F("EMS-ESP Boiler");
|
||||||
|
dev["sw"] = EMSESP_APP_VERSION;
|
||||||
|
dev["mf"] = this->brand_to_string();
|
||||||
|
dev["mdl"] = this->name();
|
||||||
|
JsonArray ids = dev.createNestedArray("ids");
|
||||||
|
ids.add("ems-esp-boiler");
|
||||||
|
Mqtt::publish_retain(F("homeassistant/sensor/ems-esp/boiler/config"), doc.as<JsonObject>(), true); // publish the config payload with retain flag
|
||||||
|
|
||||||
|
Mqtt::register_mqtt_ha_binary_sensor(F("Boiler DHW"), this->device_type(), "tapwater_active");
|
||||||
|
Mqtt::register_mqtt_ha_binary_sensor(F("Boiler Heating"), this->device_type(), "heating_active");
|
||||||
|
|
||||||
Mqtt::register_mqtt_ha_sensor(F("Service Code"), this->device_type(), "serviceCode", "", "");
|
Mqtt::register_mqtt_ha_sensor(F("Service Code"), this->device_type(), "serviceCode", "", "");
|
||||||
Mqtt::register_mqtt_ha_sensor(F("Service Code number"), this->device_type(), "serviceCodeNumber", "", "");
|
Mqtt::register_mqtt_ha_sensor(F("Service Code number"), this->device_type(), "serviceCodeNumber", "", "");
|
||||||
|
|||||||
@@ -139,6 +139,22 @@ void Mixing::publish_values() {
|
|||||||
|
|
||||||
// publish config topic for HA MQTT Discovery
|
// publish config topic for HA MQTT Discovery
|
||||||
void Mixing::register_mqtt_ha_config() {
|
void Mixing::register_mqtt_ha_config() {
|
||||||
|
// Create the Master device
|
||||||
|
StaticJsonDocument<EMSESP_MAX_JSON_SIZE_MEDIUM> doc;
|
||||||
|
doc["name"] = F("EMS-ESP");
|
||||||
|
doc["uniq_id"] = F("mixing");
|
||||||
|
doc["ic"] = F("mdi:home-thermometer-outline");
|
||||||
|
doc["stat_t"] = F("ems-esp/mixing_data");
|
||||||
|
doc["val_tpl"] = F("{{value_json.pumpStatus}}");
|
||||||
|
JsonObject dev = doc.createNestedObject("dev");
|
||||||
|
dev["name"] = F("EMS-ESP Mixing");
|
||||||
|
dev["sw"] = EMSESP_APP_VERSION;
|
||||||
|
dev["mf"] = this->brand_to_string();
|
||||||
|
dev["mdl"] = this->name();
|
||||||
|
JsonArray ids = dev.createNestedArray("ids");
|
||||||
|
ids.add("ems-esp-mixing");
|
||||||
|
Mqtt::publish_retain(F("homeassistant/sensor/ems-esp/mixing/config"), doc.as<JsonObject>(), true); // publish the config payload with retain flag
|
||||||
|
|
||||||
if (this->type() == Type::HC) {
|
if (this->type() == Type::HC) {
|
||||||
Mqtt::register_mqtt_ha_sensor(F("Current flow temperature"), this->device_type(), "flowTemp", "°C", "");
|
Mqtt::register_mqtt_ha_sensor(F("Current flow temperature"), this->device_type(), "flowTemp", "°C", "");
|
||||||
Mqtt::register_mqtt_ha_sensor(F("Setpoint flow temperature"), this->device_type(), "flowSetTemp", "°C", "");
|
Mqtt::register_mqtt_ha_sensor(F("Setpoint flow temperature"), this->device_type(), "flowSetTemp", "°C", "");
|
||||||
|
|||||||
@@ -127,6 +127,22 @@ void Solar::publish_values() {
|
|||||||
|
|
||||||
// publish config topic for HA MQTT Discovery
|
// publish config topic for HA MQTT Discovery
|
||||||
void Solar::register_mqtt_ha_config() {
|
void Solar::register_mqtt_ha_config() {
|
||||||
|
// Create the Master device
|
||||||
|
StaticJsonDocument<EMSESP_MAX_JSON_SIZE_MEDIUM> doc;
|
||||||
|
doc["name"] = F("EMS-ESP");
|
||||||
|
doc["uniq_id"] = F("solar");
|
||||||
|
doc["ic"] = F("mdi:home-thermometer-outline");
|
||||||
|
doc["stat_t"] = F("ems-esp/solar_data");
|
||||||
|
doc["val_tpl"] = F("{{value_json.solarPump}}");
|
||||||
|
JsonObject dev = doc.createNestedObject("dev");
|
||||||
|
dev["name"] = F("EMS-ESP Solar");
|
||||||
|
dev["sw"] = EMSESP_APP_VERSION;
|
||||||
|
dev["mf"] = this->brand_to_string();
|
||||||
|
dev["mdl"] = this->name();
|
||||||
|
JsonArray ids = dev.createNestedArray("ids");
|
||||||
|
ids.add("ems-esp-solar");
|
||||||
|
Mqtt::publish_retain(F("homeassistant/sensor/ems-esp/solar/config"), doc.as<JsonObject>(), true); // publish the config payload with retain flag
|
||||||
|
|
||||||
Mqtt::register_mqtt_ha_sensor(F("Collector temperature (TS1)"), this->device_type(), "collectorTemp", "°C", "");
|
Mqtt::register_mqtt_ha_sensor(F("Collector temperature (TS1)"), this->device_type(), "collectorTemp", "°C", "");
|
||||||
Mqtt::register_mqtt_ha_sensor(F("Bottom temperature (TS2)"), this->device_type(), "tankBottomTemp", "°C", "");
|
Mqtt::register_mqtt_ha_sensor(F("Bottom temperature (TS2)"), this->device_type(), "tankBottomTemp", "°C", "");
|
||||||
Mqtt::register_mqtt_ha_sensor(F("Bottom temperature (TS5)"), this->device_type(), "tankBottomTemp2", "°C", "");
|
Mqtt::register_mqtt_ha_sensor(F("Bottom temperature (TS5)"), this->device_type(), "tankBottomTemp2", "°C", "");
|
||||||
|
|||||||
@@ -599,10 +599,14 @@ void Thermostat::register_mqtt_ha_config(uint8_t hc_num) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
JsonObject dev = doc.createNestedObject(F("dev"));
|
JsonObject dev = doc.createNestedObject(F("dev"));
|
||||||
|
dev["name"] = F("EMS-ESP Thermostat");
|
||||||
|
dev["sw"] = EMSESP_APP_VERSION;
|
||||||
|
dev["mf"] = this->brand_to_string();
|
||||||
|
dev["mdl"] = this->name();
|
||||||
JsonArray ids = dev.createNestedArray(F("ids"));
|
JsonArray ids = dev.createNestedArray(F("ids"));
|
||||||
ids.add(F("ems-esp"));
|
ids.add(F("ems-esp-thermostat"));
|
||||||
|
|
||||||
std::string topic(100, '\0'); // e.g homeassistant/climate/hc1/thermostat/config
|
std::string topic(100, '\0');
|
||||||
snprintf_P(&topic[0], topic.capacity() + 1, PSTR("homeassistant/climate/ems-esp/thermostat_hc%d/config"), hc_num);
|
snprintf_P(&topic[0], topic.capacity() + 1, PSTR("homeassistant/climate/ems-esp/thermostat_hc%d/config"), hc_num);
|
||||||
// Mqtt::publish(topic); // empty payload, this remove any previous config sent to HA
|
// Mqtt::publish(topic); // empty payload, this remove any previous config sent to HA
|
||||||
Mqtt::publish_retain(topic, doc.as<JsonObject>(), true); // publish the config payload with retain flag
|
Mqtt::publish_retain(topic, doc.as<JsonObject>(), true); // publish the config payload with retain flag
|
||||||
|
|||||||
14
src/mqtt.cpp
14
src/mqtt.cpp
@@ -474,7 +474,7 @@ void Mqtt::on_connect() {
|
|||||||
LOG_INFO(F("MQTT connected"));
|
LOG_INFO(F("MQTT connected"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Home Assistant Discovery
|
// Home Assistant Discovery - the main master Device
|
||||||
// homeassistant/sensor/ems-esp/status/config
|
// homeassistant/sensor/ems-esp/status/config
|
||||||
void Mqtt::ha_status() {
|
void Mqtt::ha_status() {
|
||||||
StaticJsonDocument<EMSESP_MAX_JSON_SIZE_MEDIUM> doc;
|
StaticJsonDocument<EMSESP_MAX_JSON_SIZE_MEDIUM> doc;
|
||||||
@@ -681,7 +681,7 @@ void Mqtt::process_queue() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// HA config for a binary_sensor
|
// HA config for a binary_sensor
|
||||||
void Mqtt::register_mqtt_ha_binary_sensor(const __FlashStringHelper * name, const char * entity) {
|
void Mqtt::register_mqtt_ha_binary_sensor(const __FlashStringHelper * name, const uint8_t device_type, const char * entity) {
|
||||||
if (mqtt_format() != Format::HA) {
|
if (mqtt_format() != Format::HA) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -710,7 +710,9 @@ void Mqtt::register_mqtt_ha_binary_sensor(const __FlashStringHelper * name, cons
|
|||||||
|
|
||||||
JsonObject dev = doc.createNestedObject(F("dev"));
|
JsonObject dev = doc.createNestedObject(F("dev"));
|
||||||
JsonArray ids = dev.createNestedArray(F("ids"));
|
JsonArray ids = dev.createNestedArray(F("ids"));
|
||||||
ids.add(F("ems-esp"));
|
std::string ha_device(40, '\0');
|
||||||
|
snprintf_P(&ha_device[0], ha_device.capacity() + 1, PSTR("ems-esp-%s"), EMSdevice::device_type_2_device_name(device_type).c_str());
|
||||||
|
ids.add(ha_device);
|
||||||
|
|
||||||
std::string topic(100, '\0');
|
std::string topic(100, '\0');
|
||||||
snprintf_P(&topic[0], topic.capacity() + 1, PSTR("homeassistant/binary_sensor/ems-esp/%s/config"), entity);
|
snprintf_P(&topic[0], topic.capacity() + 1, PSTR("homeassistant/binary_sensor/ems-esp/%s/config"), entity);
|
||||||
@@ -718,7 +720,7 @@ void Mqtt::register_mqtt_ha_binary_sensor(const __FlashStringHelper * name, cons
|
|||||||
Mqtt::publish_retain(topic, doc.as<JsonObject>(), true); // publish the config payload with retain flag
|
Mqtt::publish_retain(topic, doc.as<JsonObject>(), true); // publish the config payload with retain flag
|
||||||
}
|
}
|
||||||
|
|
||||||
// HA config for a normal sensor
|
// HA config for a normal 'sensor' type
|
||||||
void Mqtt::register_mqtt_ha_sensor(const __FlashStringHelper * name, const uint8_t device_type, const char * entity, const char * uom, const char * icon) {
|
void Mqtt::register_mqtt_ha_sensor(const __FlashStringHelper * name, const uint8_t device_type, const char * entity, const char * uom, const char * icon) {
|
||||||
if (mqtt_format() != Format::HA) {
|
if (mqtt_format() != Format::HA) {
|
||||||
return;
|
return;
|
||||||
@@ -748,7 +750,9 @@ void Mqtt::register_mqtt_ha_sensor(const __FlashStringHelper * name, const uint8
|
|||||||
|
|
||||||
JsonObject dev = doc.createNestedObject(F("dev"));
|
JsonObject dev = doc.createNestedObject(F("dev"));
|
||||||
JsonArray ids = dev.createNestedArray(F("ids"));
|
JsonArray ids = dev.createNestedArray(F("ids"));
|
||||||
ids.add(F("ems-esp"));
|
std::string ha_device(40, '\0');
|
||||||
|
snprintf_P(&ha_device[0], ha_device.capacity() + 1, PSTR("ems-esp-%s"), EMSdevice::device_type_2_device_name(device_type).c_str());
|
||||||
|
ids.add(ha_device);
|
||||||
|
|
||||||
std::string topic(100, '\0');
|
std::string topic(100, '\0');
|
||||||
snprintf_P(&topic[0], topic.capacity() + 1, PSTR("homeassistant/sensor/ems-esp/%s/config"), entity);
|
snprintf_P(&topic[0], topic.capacity() + 1, PSTR("homeassistant/sensor/ems-esp/%s/config"), entity);
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ class Mqtt {
|
|||||||
static void publish_retain(const __FlashStringHelper * topic, const std::string & payload, bool retain);
|
static void publish_retain(const __FlashStringHelper * topic, const std::string & payload, bool retain);
|
||||||
static void publish_retain(const __FlashStringHelper * topic, const JsonObject & payload, bool retain);
|
static void publish_retain(const __FlashStringHelper * topic, const JsonObject & payload, bool retain);
|
||||||
|
|
||||||
static void register_mqtt_ha_binary_sensor(const __FlashStringHelper * name, const char * entity);
|
static void register_mqtt_ha_binary_sensor(const __FlashStringHelper * name, const uint8_t device_type, const char * entity);
|
||||||
static void register_mqtt_ha_sensor(const __FlashStringHelper * name, const uint8_t device_type, const char * entity, const char * uom, const char * icon);
|
static void register_mqtt_ha_sensor(const __FlashStringHelper * name, const uint8_t device_type, const char * entity, const char * uom, const char * icon);
|
||||||
|
|
||||||
static void show_topic_handlers(uuid::console::Shell & shell, const uint8_t device_type);
|
static void show_topic_handlers(uuid::console::Shell & shell, const uint8_t device_type);
|
||||||
@@ -162,7 +162,7 @@ class Mqtt {
|
|||||||
static size_t maximum_mqtt_messages_;
|
static size_t maximum_mqtt_messages_;
|
||||||
static uint16_t mqtt_message_id_;
|
static uint16_t mqtt_message_id_;
|
||||||
|
|
||||||
static constexpr size_t MAX_MQTT_MESSAGES = 30; // size of queue
|
static constexpr size_t MAX_MQTT_MESSAGES = 70; // size of queue
|
||||||
static constexpr uint32_t MQTT_PUBLISH_WAIT = 200; // delay between sending publishes, to account for large payloads
|
static constexpr uint32_t MQTT_PUBLISH_WAIT = 200; // delay between sending publishes, to account for large payloads
|
||||||
static constexpr uint8_t MQTT_PUBLISH_MAX_RETRY = 3; // max retries for giving up on publishing
|
static constexpr uint8_t MQTT_PUBLISH_MAX_RETRY = 3; // max retries for giving up on publishing
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ void Shower::start() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (Mqtt::mqtt_format() == Mqtt::Format::HA) {
|
if (Mqtt::mqtt_format() == Mqtt::Format::HA) {
|
||||||
Mqtt::register_mqtt_ha_binary_sensor(F("Shower Active"), "shower_active");
|
Mqtt::register_mqtt_ha_binary_sensor(F("Shower Active"), EMSdevice::DeviceType::BOILER, "shower_active");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user