Allow controlling any blind in the house
This commit is contained in:
108
src/main.cpp
108
src/main.cpp
@@ -28,6 +28,8 @@ EspMQTTClient client(
|
|||||||
auto timer = Timer<10, millis, uint16_t>();
|
auto timer = Timer<10, millis, uint16_t>();
|
||||||
|
|
||||||
void processPacket(const Packet*);
|
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 sendOpenPacket(uint16_t destination);
|
||||||
bool sendClosePacket(uint16_t destination);
|
bool sendClosePacket(uint16_t destination);
|
||||||
@@ -38,11 +40,34 @@ bool sendPacket(Packet *packet);
|
|||||||
|
|
||||||
bool updatePosition(uint16_t shadeID);
|
bool updatePosition(uint16_t shadeID);
|
||||||
|
|
||||||
|
struct Shade {
|
||||||
|
uint16_t ID;
|
||||||
|
String name;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<Shade> shades;
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
Serial.begin(SER_BAUDRATE);
|
Serial.begin(SER_BAUDRATE);
|
||||||
|
|
||||||
Serial.println("Starting up");
|
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);
|
powerView.setPacketCallback(processPacket);
|
||||||
if (!powerView.begin()) {
|
if (!powerView.begin()) {
|
||||||
Serial.println("Failed to start RFPowerView");
|
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++) {
|
for (size_t i = 0; i < parameters.fields.size(); i++) {
|
||||||
Field field = parameters.fields[i];
|
Field field = parameters.fields[i];
|
||||||
if (field.identifier == 0x50) {
|
if (field.identifier == 0x50) {
|
||||||
if (packet->source == 0x4EF1) {
|
for (size_t i = 0; i < shades.size(); i++) {
|
||||||
uint16_t value = std::get<uint16_t>(field.value);
|
if (packet->source == shades[i].ID) {
|
||||||
uint8_t position = (uint8_t)std::round(((float)value / 0xFFFF) * 100);
|
uint16_t value = std::get<uint16_t>(field.value);
|
||||||
String payload = String(position);
|
uint8_t position = (uint8_t)std::round(((float)value / 0xFFFF) * 100);
|
||||||
client.publish("hotdog/test_mqtt_blind/position", payload, true);
|
String payload = String(position);
|
||||||
|
client.publish("hotdog/" + shades[i].name + "/position", payload, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -89,32 +116,10 @@ void processPacket(const Packet *packet) {
|
|||||||
void onConnectionEstablished() {
|
void onConnectionEstablished() {
|
||||||
Serial.println("Connection established");
|
Serial.println("Connection established");
|
||||||
|
|
||||||
client.subscribe("hotdog/test_mqtt_blind/set", [] (const String &payload) {
|
for (int i = 0; i < shades.size(); i++) {
|
||||||
uint16_t shadeID = 0x4EF1;
|
client.subscribe("hotdog/" + shades[i].name + "/set", processSetMessage);
|
||||||
if (payload == "OPEN") {
|
client.subscribe("hotdog/" + shades[i].name + "/set_position", processSetPositionMessage);
|
||||||
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);
|
|
||||||
});
|
|
||||||
|
|
||||||
client.publish("hotdog/availability", "online", true);
|
client.publish("hotdog/availability", "online", true);
|
||||||
}
|
}
|
||||||
@@ -200,4 +205,45 @@ bool updatePosition(uint16_t shadeID) {
|
|||||||
Serial.println("Triggering position update");
|
Serial.println("Triggering position update");
|
||||||
sendFetchPosition(shadeID);
|
sendFetchPosition(shadeID);
|
||||||
return false;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user