From a5c5a7ac198a0863124a3d99f6a94fda948d6582 Mon Sep 17 00:00:00 2001 From: Matt Way Date: Thu, 4 Jan 2024 21:16:05 +1100 Subject: [PATCH] Allow Home Assistant to discover the blinds --- src/main.cpp | 68 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 53 insertions(+), 15 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index a3b76ae..1ec2775 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -46,9 +46,12 @@ void startFetchingPosition(uint16_t shadeID, int8_t targetPosition); void publishPosition(const String& shadeName, const uint8_t position); void publishState(const String& shadeName, const String& state); +void publishDiscoveryTopics(); + struct Shade { uint16_t ID; String name; + String friendlyName; int8_t lastTargetPosition; int8_t lastPosition; uint8_t samePositionCount; @@ -63,21 +66,21 @@ void setup() { Serial.println("Starting up"); - shades.push_back(Shade{0x4EF1, "study_blind", -1, -1, 0, 0, nullptr}); - shades.push_back(Shade{0xA51F, "studio_blockout_left_blind", -1, -1, 0, 0, nullptr}); - shades.push_back(Shade{0xDAEF, "studio_blockout_right_blind", -1, -1, 0, 0, nullptr}); - shades.push_back(Shade{0x7687, "studio_left_blind", -1, -1, 0, 0, nullptr}); - shades.push_back(Shade{0xB0DE, "studio_right_blind", -1, -1, 0, 0, nullptr}); - shades.push_back(Shade{0xB451, "bedroom_door_blockout_blind", -1, -1, 0, 0, nullptr}); - shades.push_back(Shade{0x48A6, "bedroom_window_blockout_blind", -1, -1, 0, 0, nullptr}); - shades.push_back(Shade{0x9E14, "bedroom_door_blind", -1, -1, 0, 0, nullptr}); - shades.push_back(Shade{0x061C, "bedroom_window_blind", -1, -1, 0, 0, nullptr}); - shades.push_back(Shade{0x2959, "bathroom_blind", -1, -1, 0, 0, nullptr}); - shades.push_back(Shade{0x6FAD, "kitchen_door_blind", -1, -1, 0, 0, nullptr}); - shades.push_back(Shade{0xFB21, "kitchen_window_blind", -1, -1, 0, 0, nullptr}); - shades.push_back(Shade{0x8B10, "living_room_big_window_blind", -1, -1, 0, 0, nullptr}); - shades.push_back(Shade{0x3EB8, "living_room_door_blind", -1, -1, 0, 0, nullptr}); - shades.push_back(Shade{0x5463, "living_room_window_blind", -1, -1, 0, 0, nullptr}); + shades.push_back(Shade{0x4EF1, "study_blind", "Study Blind", -1, -1, 0, 0, nullptr}); + shades.push_back(Shade{0xA51F, "studio_blockout_left_blind", "Studio Blockout Left Blind", -1, -1, 0, 0, nullptr}); + shades.push_back(Shade{0xDAEF, "studio_blockout_right_blind", "Studio Blockout Right Blind", -1, -1, 0, 0, nullptr}); + shades.push_back(Shade{0x7687, "studio_left_blind", "Studio Left Blind", -1, -1, 0, 0, nullptr}); + shades.push_back(Shade{0xB0DE, "studio_right_blind", "Studio Right Blind", -1, -1, 0, 0, nullptr}); + shades.push_back(Shade{0xB451, "bedroom_door_blockout_blind", "Bedroom Door Blockout Blind", -1, -1, 0, 0, nullptr}); + shades.push_back(Shade{0x48A6, "bedroom_window_blockout_blind", "Bedroom Window Blockout Blind", -1, -1, 0, 0, nullptr}); + shades.push_back(Shade{0x9E14, "bedroom_door_blind", "Bedroom Door Blind", -1, -1, 0, 0, nullptr}); + shades.push_back(Shade{0x061C, "bedroom_window_blind", "Bedroom Window Blind", -1, -1, 0, 0, nullptr}); + shades.push_back(Shade{0x2959, "bathroom_blind", "Bathroom Blind", -1, -1, 0, 0, nullptr}); + shades.push_back(Shade{0x6FAD, "kitchen_door_blind", "Kitchen Door Blind", -1, -1, 0, 0, nullptr}); + shades.push_back(Shade{0xFB21, "kitchen_window_blind", "Kitchen Window Blind", -1, -1, 0, 0, nullptr}); + shades.push_back(Shade{0x8B10, "living_room_big_window_blind", "Living Room Big Window Blind", -1, -1, 0, 0, nullptr}); + shades.push_back(Shade{0x3EB8, "living_room_door_blind", "Living Room Door Blind", -1, -1, 0, 0, nullptr}); + shades.push_back(Shade{0x5463, "living_room_window_blind", "Living Room Window Blind", -1, -1, 0, 0, nullptr}); powerView.setPacketCallback(processPacket); if (!powerView.begin()) { @@ -88,6 +91,7 @@ void setup() { client.setKeepAlive(10); client.enableLastWillMessage("hotdog/availability", "offline", true); client.enableDebuggingMessages(); + client.setMaxPacketSize(2048); delay(100); Serial.println("Ready"); @@ -140,6 +144,14 @@ void onConnectionEstablished() { } client.publish("hotdog/availability", "online", true); + + publishDiscoveryTopics(); + + client.subscribe("homeassistant/status", [] (const String& topic, const String& message) { + if (message == "online") { + publishDiscoveryTopics(); + } + }); } bool sendOpenPacket(uint16_t destination) { @@ -316,4 +328,30 @@ void publishState(const String& shadeName, const String& state) { void publishPosition(const String& shadeName, const uint8_t position) { client.publish("hotdog/" + shadeName + "/position", String(position), true); +} + +void publishDiscoveryTopics() { + char buffer[1024]; + + for (size_t i = 0; i < shades.size(); i++) { + Shade shade = shades[i]; + String objectID = String(shade.ID, HEX); + + JsonDocument doc; + + doc["name"] = shade.friendlyName; + doc["unique_id"] = objectID; + doc["availability_topic"] = "hotdog/availability"; + doc["state_topic"] = "hotdog/" + shade.name + "/state"; + doc["command_topic"] = "hotdog/" + shade.name + "/set"; + doc["position_topic"] = "hotdog/" + shade.name + "/position"; + doc["set_position_topic"] = "hotdog/" + shade.name + "/set_position"; + doc["position_open"] = 100; + doc["position_closed"] = 0; + doc["optimistic"] = false; + + serializeJson(doc, buffer); + + client.publish("homeassistant/cover/" + objectID + "/config", buffer); + } } \ No newline at end of file