diff --git a/AquaMQTT/include/Version.h b/AquaMQTT/include/Version.h index 0ccdcf3..8d45be9 100644 --- a/AquaMQTT/include/Version.h +++ b/AquaMQTT/include/Version.h @@ -1,4 +1,4 @@ namespace aquamqtt { -constexpr char VERSION[] = "v2.0.0"; +constexpr char VERSION[] = "v1.5.0"; } \ No newline at end of file diff --git a/AquaMQTT/include/mqtt/MQTTDiscovery.h b/AquaMQTT/include/mqtt/MQTTDiscovery.h index 3e2ae8b..5ab6dcb 100644 --- a/AquaMQTT/include/mqtt/MQTTDiscovery.h +++ b/AquaMQTT/include/mqtt/MQTTDiscovery.h @@ -5,6 +5,7 @@ #include "MQTTDefinitions.h" #include "Version.h" +#include "message/MessageConstants.h" namespace aquamqtt { @@ -159,7 +160,11 @@ static const char* make_unique(char* buffer, uint16_t identifier, const char* st return buffer; } -static bool buildConfiguration(uint8_t* buffer, uint16_t identifier, MQTT_ITEM_SENSOR item) +static bool buildConfiguration( + uint8_t* buffer, + aquamqtt::message::ProtocolVersion protocolVersion, + uint16_t identifier, + MQTT_ITEM_SENSOR item) { JsonDocument doc = createFromDefault(identifier); char temp[100]; @@ -198,7 +203,10 @@ static bool buildConfiguration(uint8_t* buffer, uint16_t identifier, MQTT_ITEM_S doc["uniq_id"] = make_unique(temp, identifier, "main_evoAirTempLower"); break; case MQTT_ITEM_SENSOR::MAIN_COMPRESSOR_OUTLET_TEMP: - // FIXME: only if new protocol is detected + if (protocolVersion == aquamqtt::message::ProtocolVersion::PROTOCOL_LEGACY) + { + return false; + } doc["name"] = "Compressor Outlet Temp"; doc["stat_t"] = "~/main/compressorOutletTemp"; doc["stat_cla"] = "measurement"; @@ -238,12 +246,20 @@ static bool buildConfiguration(uint8_t* buffer, uint16_t identifier, MQTT_ITEM_S doc["ent_cat"] = "diagnostic"; break; case MQTT_ITEM_SENSOR::MAIN_ERROR_CODE: + if (protocolVersion == aquamqtt::message::ProtocolVersion::PROTOCOL_NEXT) + { + return false; + } doc["name"] = "Error Code"; doc["stat_t"] = "~/main/errorCode"; doc["ic"] = "mdi:alarm-light"; doc["uniq_id"] = make_unique(temp, identifier, "main_error_code"); break; case MQTT_ITEM_SENSOR::ENERGY_TOTAL_HEATING_ELEM_HOURS: + if (protocolVersion == aquamqtt::message::ProtocolVersion::PROTOCOL_NEXT) + { + return false; + } doc["name"] = "Total Heating Element Hours"; doc["stat_t"] = "~/energy/totalHeatingElemHours"; doc["unit_of_meas"] = "h"; @@ -268,6 +284,10 @@ static bool buildConfiguration(uint8_t* buffer, uint16_t identifier, MQTT_ITEM_S doc["uniq_id"] = make_unique(temp, identifier, "energy_total_h"); break; case MQTT_ITEM_SENSOR::ENERGY_TOTAL_ENERGY_WH: + if (protocolVersion == aquamqtt::message::ProtocolVersion::PROTOCOL_NEXT) + { + return false; + } doc["name"] = "Total Energy"; doc["stat_t"] = "~/energy/totalEnergyWh"; doc["unit_of_meas"] = "Wh"; @@ -277,6 +297,10 @@ static bool buildConfiguration(uint8_t* buffer, uint16_t identifier, MQTT_ITEM_S doc["dev_cla"] = "energy"; break; case MQTT_ITEM_SENSOR::ENERGY_POWER_TOTAL: + if (protocolVersion == aquamqtt::message::ProtocolVersion::PROTOCOL_NEXT) + { + return false; + } doc["name"] = "Power Consumed Total"; doc["stat_t"] = "~/energy/powerTotal"; doc["unit_of_meas"] = "W"; @@ -286,6 +310,10 @@ static bool buildConfiguration(uint8_t* buffer, uint16_t identifier, MQTT_ITEM_S doc["dev_cla"] = "power"; break; case MQTT_ITEM_SENSOR::ENERGY_POWER_HEAT_ELEMENT: + if (protocolVersion == aquamqtt::message::ProtocolVersion::PROTOCOL_NEXT) + { + return false; + } doc["name"] = "Power Consumed Heating Element"; doc["stat_t"] = "~/energy/powerHeatingElem"; doc["unit_of_meas"] = "W"; @@ -304,6 +332,10 @@ static bool buildConfiguration(uint8_t* buffer, uint16_t identifier, MQTT_ITEM_S doc["dev_cla"] = "power"; break; case MQTT_ITEM_SENSOR::ENERGY_TOTAL_WATER_PRODUCTION: + if (protocolVersion == aquamqtt::message::ProtocolVersion::PROTOCOL_NEXT) + { + return false; + } doc["name"] = "Total Water Production"; doc["stat_t"] = "~/energy/totalWaterProduction"; doc["unit_of_meas"] = "l"; @@ -506,6 +538,10 @@ static bool buildConfiguration(uint8_t* buffer, uint16_t identifier, MQTT_ITEM_S doc["ic"] = "mdi:calendar-clock"; break; case MQTT_ITEM_SENSOR::HMI_SETUP_STATE: + if (protocolVersion == aquamqtt::message::ProtocolVersion::PROTOCOL_NEXT) + { + return false; + } doc["name"] = "Setup State"; doc["stat_t"] = "~/hmi/setupState"; doc["uniq_id"] = make_unique(temp, identifier, "hmi_setup"); @@ -528,6 +564,10 @@ static bool buildConfiguration(uint8_t* buffer, uint16_t identifier, MQTT_ITEM_S doc["ent_cat"] = "diagnostic"; break; case MQTT_ITEM_SENSOR::MAIN_SETTING_PWM_01: + if (protocolVersion == aquamqtt::message::ProtocolVersion::PROTOCOL_NEXT) + { + return false; + } doc["name"] = "PWM Fan Level 1 "; doc["stat_t"] = "~/main/settingPWM_1"; doc["uniq_id"] = make_unique(temp, identifier, "main_setting_fan1"); @@ -535,6 +575,10 @@ static bool buildConfiguration(uint8_t* buffer, uint16_t identifier, MQTT_ITEM_S doc["ic"] = "mdi:fan-speed-1"; break; case MQTT_ITEM_SENSOR::MAIN_SETTING_PWM_02: + if (protocolVersion == aquamqtt::message::ProtocolVersion::PROTOCOL_NEXT) + { + return false; + } doc["name"] = "PWM Fan Level 2 "; doc["stat_t"] = "~/main/settingPWM_2"; doc["uniq_id"] = make_unique(temp, identifier, "main_setting_fan2"); @@ -542,6 +586,10 @@ static bool buildConfiguration(uint8_t* buffer, uint16_t identifier, MQTT_ITEM_S doc["ic"] = "mdi:fan-speed-2"; break; case MQTT_ITEM_SENSOR::MAIN_SETTING_PWM_03: + if (protocolVersion == aquamqtt::message::ProtocolVersion::PROTOCOL_NEXT) + { + return false; + } doc["name"] = "PWM Fan Level 3 "; doc["stat_t"] = "~/main/settingPWM_3"; doc["uniq_id"] = make_unique(temp, identifier, "main_setting_fan3"); @@ -549,6 +597,10 @@ static bool buildConfiguration(uint8_t* buffer, uint16_t identifier, MQTT_ITEM_S doc["ic"] = "mdi:fan-speed-3"; break; case MQTT_ITEM_SENSOR::MAIN_SETTING_MIN_TEMP_TARGET: + if (protocolVersion == aquamqtt::message::ProtocolVersion::PROTOCOL_NEXT) + { + return false; + } doc["name"] = "Minimum Water Target Temperature"; doc["stat_t"] = "~/main/settingMinTargetTemp"; doc["uniq_id"] = make_unique(temp, identifier, "main_setting_min_target_temp"); @@ -556,6 +608,10 @@ static bool buildConfiguration(uint8_t* buffer, uint16_t identifier, MQTT_ITEM_S doc["ic"] = "mdi:thermometer-chevron-down"; break; case MQTT_ITEM_SENSOR::MAIN_SETTING_MIN_TEMP_LEGIONELLA: + if (protocolVersion == aquamqtt::message::ProtocolVersion::PROTOCOL_NEXT) + { + return false; + } doc["name"] = "Minimum Water Temperature Anti-Legionella"; doc["stat_t"] = "~/main/settingMinLegionellaTemp"; doc["uniq_id"] = make_unique(temp, identifier, "main_setting_min_target_legionella_temp"); @@ -563,6 +619,10 @@ static bool buildConfiguration(uint8_t* buffer, uint16_t identifier, MQTT_ITEM_S doc["ic"] = "mdi:thermometer-plus"; break; case MQTT_ITEM_SENSOR::MAIN_SETTING_PWR_HEATELEM: + if (protocolVersion == aquamqtt::message::ProtocolVersion::PROTOCOL_NEXT) + { + return false; + } doc["name"] = "Wattage Installed Heat Element"; doc["stat_t"] = "~/main/settingWattageElement"; doc["uniq_id"] = make_unique(temp, identifier, "main_setting_wattage_he"); @@ -570,6 +630,10 @@ static bool buildConfiguration(uint8_t* buffer, uint16_t identifier, MQTT_ITEM_S doc["ic"] = "mdi:heating-coil"; break; case MQTT_ITEM_SENSOR::MAIN_SETTING_BOILER_CAP: + if (protocolVersion == aquamqtt::message::ProtocolVersion::PROTOCOL_NEXT) + { + return false; + } doc["name"] = "Boiler Capacity"; doc["stat_t"] = "~/main/settingBoilerCapacity"; doc["uniq_id"] = make_unique(temp, identifier, "main_setting_cap"); @@ -577,12 +641,20 @@ static bool buildConfiguration(uint8_t* buffer, uint16_t identifier, MQTT_ITEM_S doc["ic"] = "mdi:barrel"; break; case MQTT_ITEM_SENSOR::MAIN_SETTING_BOILER_BRAND: + if (protocolVersion == aquamqtt::message::ProtocolVersion::PROTOCOL_NEXT) + { + return false; + } doc["name"] = "Boiler Brand"; doc["stat_t"] = "~/main/settingBoilerBrand"; doc["uniq_id"] = make_unique(temp, identifier, "main_setting_brand"); doc["ic"] = "mdi:factory"; break; case MQTT_ITEM_SENSOR::HMI_TEST_MODE: + if (protocolVersion == aquamqtt::message::ProtocolVersion::PROTOCOL_NEXT) + { + return false; + } doc["name"] = "Test Mode Status"; doc["stat_t"] = "~/hmi/testModeStatus"; doc["uniq_id"] = make_unique(temp, identifier, "hmi_test_mode"); @@ -596,14 +668,17 @@ static bool buildConfiguration(uint8_t* buffer, uint16_t identifier, MQTT_ITEM_S case MQTT_ITEM_SENSOR::RESERVED_COUNT: default: return false; - } serializeJson(doc, buffer, config::MQTT_MAX_PAYLOAD_SIZE); return true; } -static bool buildConfiguration(uint8_t* buffer, uint16_t identifier, MQTT_ITEM_BINARY_SENSOR item) +static bool buildConfiguration( + uint8_t* buffer, + aquamqtt::message::ProtocolVersion protocolVersion, + uint16_t identifier, + MQTT_ITEM_BINARY_SENSOR item) { JsonDocument doc = createFromDefault(identifier); char temp[100]; @@ -776,6 +851,10 @@ static bool buildConfiguration(uint8_t* buffer, uint16_t identifier, MQTT_ITEM_B doc["ent_cat"] = "diagnostic"; break; case MQTT_ITEM_BINARY_SENSOR::MAIN_CAPABILITY_HEAT_EXC: + if (protocolVersion == aquamqtt::message::ProtocolVersion::PROTOCOL_NEXT) + { + return false; + } doc["name"] = "Capability Heat-Exchanger"; doc["stat_t"] = "~/main/capabilityHeatExchanger"; doc["ic"] = "mdi:expansion-card"; @@ -785,6 +864,10 @@ static bool buildConfiguration(uint8_t* buffer, uint16_t identifier, MQTT_ITEM_B doc["ent_cat"] = "diagnostic"; break; case MQTT_ITEM_BINARY_SENSOR::MAIN_CAPABILITY_CIRCULATION: + if (protocolVersion == aquamqtt::message::ProtocolVersion::PROTOCOL_NEXT) + { + return false; + } doc["name"] = "Capability Circulation"; doc["stat_t"] = "~/main/capabilityCirculation"; doc["ic"] = "mdi:expansion-card"; @@ -794,6 +877,10 @@ static bool buildConfiguration(uint8_t* buffer, uint16_t identifier, MQTT_ITEM_B doc["ent_cat"] = "diagnostic"; break; case MQTT_ITEM_BINARY_SENSOR::MAIN_CAPABILITY_PV_INPUT: + if (protocolVersion == aquamqtt::message::ProtocolVersion::PROTOCOL_NEXT) + { + return false; + } doc["name"] = "Capability PV Input"; doc["stat_t"] = "~/main/capabilityPVInput"; doc["ic"] = "mdi:expansion-card"; @@ -803,6 +890,10 @@ static bool buildConfiguration(uint8_t* buffer, uint16_t identifier, MQTT_ITEM_B doc["ent_cat"] = "diagnostic"; break; case MQTT_ITEM_BINARY_SENSOR::MAIN_CAPABILITY_EXT_COMM: + if (protocolVersion == aquamqtt::message::ProtocolVersion::PROTOCOL_NEXT) + { + return false; + } doc["name"] = "Capability External Communication"; doc["stat_t"] = "~/main/capabilityCommunication"; doc["ic"] = "mdi:expansion-card"; @@ -812,6 +903,10 @@ static bool buildConfiguration(uint8_t* buffer, uint16_t identifier, MQTT_ITEM_B doc["ent_cat"] = "diagnostic"; break; case MQTT_ITEM_BINARY_SENSOR::MAIN_CAPABILITY_DRY_HEATING: + if (protocolVersion == aquamqtt::message::ProtocolVersion::PROTOCOL_NEXT) + { + return false; + } doc["name"] = "Capability Anti Dry Heating"; doc["stat_t"] = "~/main/capabilityCommunication"; doc["ic"] = "mdi:expansion-card"; @@ -829,7 +924,11 @@ static bool buildConfiguration(uint8_t* buffer, uint16_t identifier, MQTT_ITEM_B return true; } -static bool buildConfiguration(uint8_t* buffer, uint16_t identifier, MQTT_ITEM_NUMBER item) +static bool buildConfiguration( + uint8_t* buffer, + aquamqtt::message::ProtocolVersion protocolVersion, + uint16_t identifier, + MQTT_ITEM_NUMBER item) { JsonDocument doc = createFromDefault(identifier); char temp[100]; @@ -856,7 +955,11 @@ static bool buildConfiguration(uint8_t* buffer, uint16_t identifier, MQTT_ITEM_N return true; } -static bool buildConfiguration(uint8_t* buffer, uint16_t identifier, MQTT_ITEM_BUTTON item) +static bool buildConfiguration( + uint8_t* buffer, + aquamqtt::message::ProtocolVersion protocolVersion, + uint16_t identifier, + MQTT_ITEM_BUTTON item) { JsonDocument doc = createFromDefault(identifier); char temp[100]; @@ -879,7 +982,11 @@ static bool buildConfiguration(uint8_t* buffer, uint16_t identifier, MQTT_ITEM_B return true; } -static bool buildConfiguration(uint8_t* buffer, uint16_t identifier, MQTT_ITEM_SELECT item) +static bool buildConfiguration( + uint8_t* buffer, + aquamqtt::message::ProtocolVersion protocolVersion, + uint16_t identifier, + MQTT_ITEM_SELECT item) { JsonDocument doc = createFromDefault(identifier); char temp[100]; @@ -953,7 +1060,11 @@ static bool buildConfiguration(uint8_t* buffer, uint16_t identifier, MQTT_ITEM_S return true; } -static bool buildConfiguration(uint8_t* buffer, uint16_t identifier, MQTT_ITEM_SWITCH item) +static bool buildConfiguration( + uint8_t* buffer, + aquamqtt::message::ProtocolVersion protocolVersion, + uint16_t identifier, + MQTT_ITEM_SWITCH item) { JsonDocument doc = createFromDefault(identifier); char temp[100]; @@ -1007,7 +1118,11 @@ static bool buildConfiguration(uint8_t* buffer, uint16_t identifier, MQTT_ITEM_S return true; } -static bool buildConfiguration(uint8_t* buffer, uint16_t identifier, MQTT_ITEM_WATER_HEATER item) +static bool buildConfiguration( + uint8_t* buffer, + aquamqtt::message::ProtocolVersion protocolVersion, + uint16_t identifier, + MQTT_ITEM_WATER_HEATER item) { JsonDocument doc = createFromDefault(identifier); char temp[100]; diff --git a/AquaMQTT/include/task/MQTTTask.h b/AquaMQTT/include/task/MQTTTask.h index 915c3f1..bdd970f 100644 --- a/AquaMQTT/include/task/MQTTTask.h +++ b/AquaMQTT/include/task/MQTTTask.h @@ -32,9 +32,13 @@ class MQTTTask static void messageReceived(String& topic, String& payload); void updateMainStatus(bool triggerFullUpdate, message::ProtocolVersion& version); + void updateHMIStatus(bool triggerFullUpdate, message::ProtocolVersion& version); + void updateEnergyStats(bool triggerFullUpdate, message::ProtocolVersion& version); + void updateErrorStatus(message::ProtocolVersion& version); + void updateStats(); private: @@ -46,6 +50,7 @@ class MQTTTask WiFiClient mWiFiClient; MQTTClient mMQTTClient; TaskHandle_t mTaskHandle; + bool mPublishedDiscovery; uint8_t* mLastProcessedHMIMessage; uint8_t* mLastProcessedEnergyMessage; @@ -64,9 +69,13 @@ class MQTTTask // helper to avoid code duplication void publishFloat(const char* subtopic, const char* topic, float value, bool retained = false); + void publishString(const char* subtopic, const char* topic, const char* value, bool retained = false); + void publishi(const char* subtopic, const char* topic, int value, bool retained = false); + void publishul(const char* subtopic, const char* topic, unsigned long value, bool retained = false); + void publishul( const char* subtopic_1, const char* subtopic_2, @@ -74,9 +83,14 @@ class MQTTTask unsigned long value, bool retained = false); - void enableDiscovery(); + void sendHomeassistantDiscovery(); + template - void publishDiscovery(uint16_t identifier, const char* haCategory, T enumClass); + void publishDiscovery( + uint16_t identifier, + aquamqtt::message::ProtocolVersion protocolVersion, + const char* haCategory, + T enumClass); void publishFiltered( std::unique_ptr& message, diff --git a/AquaMQTT/src/task/MQTTTask.cpp b/AquaMQTT/src/task/MQTTTask.cpp index e949e74..169ef50 100644 --- a/AquaMQTT/src/task/MQTTTask.cpp +++ b/AquaMQTT/src/task/MQTTTask.cpp @@ -49,6 +49,7 @@ MQTTTask::MQTTTask() , mEvaporatorUpperAirTempFiltered(0.0) , mCompressorTempFilter(config::KALMAN_MEA_E, config::KALMAN_EST_E, config::KALMAN_Q) , mCompressorTempFiltered(0.0) + , mPublishedDiscovery(false) { } @@ -317,6 +318,7 @@ void MQTTTask::check_mqtt_connection() vTaskDelay(pdMS_TO_TICKS(1000)); esp_task_wdt_reset(); } + mPublishedDiscovery = false; sprintf(reinterpret_cast(mTopicBuffer), "%s%s%s%s", @@ -343,8 +345,6 @@ void MQTTTask::check_mqtt_connection() mMQTTClient.subscribe(reinterpret_cast(mTopicBuffer)); } - enableDiscovery(); - Serial.println("[mqtt] is now connected"); } @@ -354,6 +354,8 @@ void MQTTTask::loop() auto mqttCycle = pdMS_TO_TICKS(5); + sendHomeassistantDiscovery(); + bool fullUpdate = (millis() - mLastFullUpdate) >= config::MQTT_FULL_UPDATE_MS; bool statsUpdate = (millis() - mLastStatsUpdate) >= config::MQTT_STATS_UPDATE_MS; @@ -1406,10 +1408,16 @@ void MQTTTask::publishul( mMQTTClient.publish(reinterpret_cast(mTopicBuffer), reinterpret_cast(mPayloadBuffer), retained, 0); } -// FIXME: discovery shall only include supported attributes, given by the protocol NEXT or LEGACY -void MQTTTask::enableDiscovery() +void MQTTTask::sendHomeassistantDiscovery() { - if (!config::ENABLE_HOMEASSISTANT_DISCOVERY_MODE) + if (!config::ENABLE_HOMEASSISTANT_DISCOVERY_MODE || mPublishedDiscovery) + { + return; + } + + // cannot send discovery yet, protocol is still unknown + ProtocolVersion protocolVersion = DHWState::getInstance().getVersion(); + if (protocolVersion == PROTOCOL_UNKNOWN) { return; } @@ -1418,21 +1426,23 @@ void MQTTTask::enableDiscovery() FastCRC16 crc; uint16_t identifier = crc.ccitt(reinterpret_cast(&mac), sizeof(mac)); - publishDiscovery(identifier, "sensor", discovery::MQTT_ITEM_SENSOR::RESERVED_COUNT); - publishDiscovery(identifier, "binary_sensor", discovery::MQTT_ITEM_BINARY_SENSOR::RESERVED_COUNT); - publishDiscovery(identifier, "number", discovery::MQTT_ITEM_NUMBER::RESERVED_COUNT); - publishDiscovery(identifier, "button", discovery::MQTT_ITEM_BUTTON::RESERVED_COUNT); - publishDiscovery(identifier, "switch", discovery::MQTT_ITEM_SWITCH::RESERVED_COUNT); - publishDiscovery(identifier, "select", discovery::MQTT_ITEM_SELECT::RESERVED_COUNT); - publishDiscovery(identifier, "water_heater", discovery::MQTT_ITEM_WATER_HEATER::RESERVED_COUNT); + publishDiscovery(identifier, protocolVersion, "sensor", discovery::MQTT_ITEM_SENSOR::RESERVED_COUNT); + publishDiscovery(identifier, protocolVersion, "binary_sensor", discovery::MQTT_ITEM_BINARY_SENSOR::RESERVED_COUNT); + publishDiscovery(identifier, protocolVersion, "number", discovery::MQTT_ITEM_NUMBER::RESERVED_COUNT); + publishDiscovery(identifier, protocolVersion, "button", discovery::MQTT_ITEM_BUTTON::RESERVED_COUNT); + publishDiscovery(identifier, protocolVersion, "switch", discovery::MQTT_ITEM_SWITCH::RESERVED_COUNT); + publishDiscovery(identifier, protocolVersion, "select", discovery::MQTT_ITEM_SELECT::RESERVED_COUNT); + publishDiscovery(identifier, protocolVersion, "water_heater", discovery::MQTT_ITEM_WATER_HEATER::RESERVED_COUNT); + + mPublishedDiscovery = true; } template -void MQTTTask::publishDiscovery(uint16_t identifier, const char* haCategory, T) +void MQTTTask::publishDiscovery(uint16_t identifier, ProtocolVersion protocolVersion, const char* haCategory, T) { for (int item = 0; item < static_cast(T::RESERVED_COUNT); ++item) { - if (discovery::buildConfiguration(mPayloadBuffer, identifier, static_cast(item))) + if (discovery::buildConfiguration(mPayloadBuffer, protocolVersion, identifier, static_cast(item))) { sprintf(reinterpret_cast(mTopicBuffer), "%s%s/aquamqtt_%u/%u/config", diff --git a/HOMEASSISTANT.md b/HOMEASSISTANT.md index 092c63d..d7a5df2 100644 --- a/HOMEASSISTANT.md +++ b/HOMEASSISTANT.md @@ -6,6 +6,7 @@ Since Release [v1.4.0](https://github.com/tspopp/AquaMQTT/releases/tag/v1.4.0) A - [x] AquaMQTT is connected to the MQTT broker of your HomeAssistant instance - [x] The correct home assistant mqtt prefix has been set and the MQTT discovery has been set to enabled within [Configuration.h](./AquaMQTT/include/config/Configuration.h) prior to flashing AquaMQTT on the Arduino. +- [x] The first valid message from the heat pump has been parsed successfully. Reason: There are different heat pump protocols and as soon the protocol version is known, we know the set of attributes available. If all these conditions are fullfilled, you will find the AquaMQTT device at `Settings` -> `Device` -> `MQTT/Devices` within your HomeAssistant web interface.