| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- #include <HomeAssistantDiscoveryClient.h>
- HomeAssistantDiscoveryClient::HomeAssistantDiscoveryClient(Settings& settings, MqttClient* mqttClient)
- : settings(settings)
- , mqttClient(mqttClient)
- { }
- void HomeAssistantDiscoveryClient::sendDiscoverableDevices(const std::map<String, BulbId>& aliases) {
- #ifdef MQTT_DEBUG
- Serial.println(F("HomeAssistantDiscoveryClient: Sending discoverable devices..."));
- #endif
- for (auto itr = aliases.begin(); itr != aliases.end(); ++itr) {
- addConfig(itr->first.c_str(), itr->second);
- }
- }
- void HomeAssistantDiscoveryClient::removeConfig(const char* alias, const BulbId& bulbId) {
- // Remove by publishing an empty message
- String topic = buildTopic(bulbId);
- mqttClient->send(topic.c_str(), "", true);
- }
- void HomeAssistantDiscoveryClient::addConfig(const char* alias, const BulbId& bulbId) {
- String topic = buildTopic(bulbId);
- DynamicJsonDocument config(1024);
- config[F("schema")] = F("json");
- config[F("name")] = alias;
- config[F("command_topic")] = bindTopicVariables(settings.mqttTopicPattern, alias, bulbId);
- config[F("state_topic")] = bindTopicVariables(settings.mqttStateTopicPattern, alias, bulbId);
- // HomeAssistant only supports simple client availability
- if (settings.mqttClientStatusTopic.length() > 0 && settings.simpleMqttClientStatus) {
- config[F("availability_topic")] = settings.mqttClientStatusTopic;
- config[F("payload_available")] = F("connected");
- config[F("payload_not_available")] = F("disconnected");
- }
- // Configure supported commands based on the bulb type
- // All supported bulbs support brightness and night mode
- config[F("brightness")] = true;
- config[F("effect")] = true;
- JsonArray effects = config.createNestedArray(F("effect_list"));
- effects.add(F("night_mode"));
- // These bulbs support RGB color
- switch (bulbId.deviceType) {
- case REMOTE_TYPE_FUT089:
- case REMOTE_TYPE_RGB:
- case REMOTE_TYPE_RGB_CCT:
- case REMOTE_TYPE_RGBW:
- config[F("rgb")] = true;
- break;
- default:
- break; //nothing
- }
- // These bulbs support adjustable white values
- switch (bulbId.deviceType) {
- case REMOTE_TYPE_CCT:
- case REMOTE_TYPE_FUT089:
- case REMOTE_TYPE_FUT091:
- case REMOTE_TYPE_RGB_CCT:
- config[F("color_temp")] = true;
- break;
- default:
- break; //nothing
- }
- // These bulbs support switching between rgb/white, and have a "white_mode" command
- switch (bulbId.deviceType) {
- case REMOTE_TYPE_FUT089:
- case REMOTE_TYPE_RGB_CCT:
- case REMOTE_TYPE_RGBW:
- effects.add(F("white_mode"));
- break;
- default:
- break; //nothing
- }
- String message;
- serializeJson(config, message);
- #ifdef MQTT_DEBUG
- Serial.printf_P(PSTR("HomeAssistantDiscoveryClient: adding discoverable device: %s...\n"), alias);
- Serial.printf_P(PSTR(" topic: %s\nconfig: %s\n"), topic.c_str(), message.c_str());
- #endif
- mqttClient->send(topic.c_str(), message.c_str(), true);
- }
- // Topic syntax:
- // <discovery_prefix>/<component>/[<node_id>/]<object_id>/config
- //
- // source: https://www.home-assistant.io/docs/mqtt/discovery/
- String HomeAssistantDiscoveryClient::buildTopic(const BulbId& bulbId) {
- String topic = settings.homeAssistantDiscoveryPrefix;
- // Don't require the user to entier a "/" (or break things if they do)
- if (! topic.endsWith("/")) {
- topic += "/";
- }
- topic += "light/";
- // Use a static ID that doesn't depend on configuration.
- topic += "milight_hub_" + (ESP.getChipId());
- // make the object ID based on the actual parameters rather than the alias.
- topic += "/";
- topic += MiLightRemoteTypeHelpers::remoteTypeToString(bulbId.deviceType);
- topic += "_0x";
- topic += String(bulbId.deviceId, HEX);
- topic += "_";
- topic += bulbId.groupId;
- topic += "/config";
- return topic;
- }
- String HomeAssistantDiscoveryClient::bindTopicVariables(const String& topic, const char* alias, const BulbId& bulbId) {
- String boundTopic = topic;
- boundTopic.replace(":device_alias", alias);
- boundTopic.replace(":device_id", String("0x") + String(bulbId.deviceId, HEX));
- boundTopic.replace(":hex_device_id", String("0x") + String(bulbId.deviceId, HEX));
- boundTopic.replace(":dec_device_id", String(bulbId.deviceId));
- boundTopic.replace(":device_type", MiLightRemoteTypeHelpers::remoteTypeToString(bulbId.deviceType));
- boundTopic.replace(":group_id", String(bulbId.groupId));
- return boundTopic;
- }
|