diff --git a/src/main.cpp b/src/main.cpp index 3772333..b555bbc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -28,6 +28,8 @@ EspMQTTClient client( auto timer = Timer<10, millis, uint16_t>(); void processPacket(const Packet*); +void processSetMessage(const String& topic, const String &payload); +void processSetPositionMessage(const String& topic, const String &payload); bool sendOpenPacket(uint16_t destination); bool sendClosePacket(uint16_t destination); @@ -38,11 +40,34 @@ bool sendPacket(Packet *packet); bool updatePosition(uint16_t shadeID); +struct Shade { + uint16_t ID; + String name; +}; + +std::vector shades; + void setup() { Serial.begin(SER_BAUDRATE); Serial.println("Starting up"); + shades.push_back(Shade{0x4EF1, "study_blind"}); + shades.push_back(Shade{0xA51F, "studio_blockout_left_blind"}); + shades.push_back(Shade{0xDAEF, "studio_blockout_right_blind"}); + shades.push_back(Shade{0x7687, "studio_left_blind"}); + shades.push_back(Shade{0xB0DE, "studio_right_blind"}); + shades.push_back(Shade{0xB451, "bedroom_door_blockout_blind"}); + shades.push_back(Shade{0x48A6, "bedroom_window_blockout_blind"}); + shades.push_back(Shade{0x9E14, "bedroom_door_blind"}); + shades.push_back(Shade{0x061C, "bedroom_window_blind"}); + shades.push_back(Shade{0x2959, "bathroom_blind"}); + shades.push_back(Shade{0x6FAD, "kitchen_door_blind"}); + shades.push_back(Shade{0xFB21, "kitchen_window_blind"}); + shades.push_back(Shade{0x8B10, "living_room_big_window_blind"}); + shades.push_back(Shade{0x3EB8, "living_room_door_blind"}); + shades.push_back(Shade{0x5463, "living_room_window_blind"}); + powerView.setPacketCallback(processPacket); if (!powerView.begin()) { Serial.println("Failed to start RFPowerView"); @@ -75,11 +100,13 @@ void processPacket(const Packet *packet) { for (size_t i = 0; i < parameters.fields.size(); i++) { Field field = parameters.fields[i]; if (field.identifier == 0x50) { - if (packet->source == 0x4EF1) { - uint16_t value = std::get(field.value); - uint8_t position = (uint8_t)std::round(((float)value / 0xFFFF) * 100); - String payload = String(position); - client.publish("hotdog/test_mqtt_blind/position", payload, true); + for (size_t i = 0; i < shades.size(); i++) { + if (packet->source == shades[i].ID) { + uint16_t value = std::get(field.value); + uint8_t position = (uint8_t)std::round(((float)value / 0xFFFF) * 100); + String payload = String(position); + client.publish("hotdog/" + shades[i].name + "/position", payload, true); + } } } } @@ -89,32 +116,10 @@ void processPacket(const Packet *packet) { void onConnectionEstablished() { Serial.println("Connection established"); - client.subscribe("hotdog/test_mqtt_blind/set", [] (const String &payload) { - uint16_t shadeID = 0x4EF1; - if (payload == "OPEN") { - sendOpenPacket(shadeID); - } else if (payload == "CLOSE") { - sendClosePacket(shadeID); - } else if (payload == "STOP") { - sendStopPacket(shadeID); - // TODO: Schedule fetching position of blind - sendFetchPosition(shadeID); - } - }); - - client.subscribe("hotdog/test_mqtt_blind/set_position", [] (const String &payload) { - uint16_t shadeID = 0x4EF1; - float percentage = payload.toInt() / 100.0f; - sendSetPosition(shadeID, percentage); - // TODO: Schedule fetching position of blind - timer.in(1000, updatePosition, 0x4EF1); - timer.in(3000, updatePosition, 0x4EF1); - timer.in(5000, updatePosition, 0x4EF1); - timer.in(7000, updatePosition, 0x4EF1); - timer.in(9000, updatePosition, 0x4EF1); - timer.in(15000, updatePosition, 0x4EF1); - timer.in(30000, updatePosition, 0x4EF1); - }); + for (int i = 0; i < shades.size(); i++) { + client.subscribe("hotdog/" + shades[i].name + "/set", processSetMessage); + client.subscribe("hotdog/" + shades[i].name + "/set_position", processSetPositionMessage); + } client.publish("hotdog/availability", "online", true); } @@ -200,4 +205,45 @@ bool updatePosition(uint16_t shadeID) { Serial.println("Triggering position update"); sendFetchPosition(shadeID); return false; +} + +void processSetMessage(const String &topic, const String &payload) { + int startIndex = topic.indexOf("/") + 1; + int endIndex = topic.indexOf("/", startIndex); + String shadeName = topic.substring(startIndex, endIndex); + + for (size_t i = 0; i < shades.size(); i++) { + if (shades[i].name == shadeName) { + if (payload == "OPEN") { + sendOpenPacket(shades[i].ID); + } else if (payload == "CLOSE") { + sendClosePacket(shades[i].ID); + } else if (payload == "STOP") { + sendStopPacket(shades[i].ID); + // TODO: Schedule fetching position of blind + sendFetchPosition(shades[i].ID); + } + } + } +} + +void processSetPositionMessage(const String& topic, const String &payload) { + int startIndex = topic.indexOf("/") + 1; + int endIndex = topic.indexOf("/", startIndex); + String shadeName = topic.substring(startIndex, endIndex); + + for (size_t i = 0; i < shades.size(); i++) { + if (shades[i].name == shadeName) { + float percentage = payload.toInt() / 100.0f; + sendSetPosition(shades[i].ID, percentage); + // TODO: Schedule fetching position of blind + timer.in(1000, updatePosition, shades[i].ID); + timer.in(3000, updatePosition, shades[i].ID); + timer.in(5000, updatePosition, shades[i].ID); + timer.in(7000, updatePosition, shades[i].ID); + timer.in(9000, updatePosition, shades[i].ID); + timer.in(15000, updatePosition, shades[i].ID); + timer.in(30000, updatePosition, shades[i].ID); + } + } } \ No newline at end of file