support state for EasyHome switches

This commit is contained in:
Nicu Hodos 2024-04-30 16:22:55 +02:00
parent 41e2e1359a
commit 9611b2c564
3 changed files with 53 additions and 21 deletions

View File

@ -70,14 +70,15 @@ namespace Ha {
}; };
typedef uint16_t (*publisherFunc)(const char* topic, const char* message);
struct Switch : Command { struct Switch : Command {
static constexpr const char* type = "switch"; static constexpr const char* type = "switch";
char stateTopic[TOPIC_SIZE]; char stateTopic[TOPIC_SIZE];
const char* area; const char* area;
uint16_t (*publisher)(const char* topic, const char* message); publisherFunc publisher;
virtual void onCommand(const char* msg){} virtual void onCommand(const char* msg){}
Switch(const char* name, const char* id, uint16_t (*publisher)(const char* topic, const char* message) = nullptr) Switch(const char* name, const char* id, publisherFunc publisher = nullptr)
: Command(name, id, type), publisher(publisher) { : Command(name, id, type), publisher(publisher) {
sprintf(commandTopic, "homeassistant/%s/rc-gateway/%s/set", type, id); sprintf(commandTopic, "homeassistant/%s/rc-gateway/%s/set", type, id);
} }
@ -119,7 +120,7 @@ namespace Ha {
const char* group; const char* group;
unsigned char channel; unsigned char channel;
PollinSwitch(const char* name, const char* group, const unsigned char channel, uint16_t (*publisher)(const char* topic, const char* message)) PollinSwitch(const char* name, const char* group, const unsigned char channel, publisherFunc publisher)
: Switch(name, Protocol_1::buildId(group, channel), publisher), group(group), channel(channel) { : Switch(name, Protocol_1::buildId(group, channel), publisher), group(group), channel(channel) {
sprintf(commandTopic, "homeassistant/%s/rc-gateway/%s/set", type, id); sprintf(commandTopic, "homeassistant/%s/rc-gateway/%s/set", type, id);
} }
@ -138,16 +139,18 @@ namespace Ha {
}; };
struct EasyHomeSwitch : Switch { struct EasyHomeSwitch : Switch {
const char* on; unsigned long *on;
const char* off; unsigned long *off;
EasyHomeSwitch(const char* name, const char* id, const char* on, const char* off) : Switch(name, id), on(on), off(off) { EasyHomeSwitch(const char* name, const char* id, unsigned long on[4], unsigned long off[4], publisherFunc publisher)
sprintf(commandTopic, "homeassistant/%s/rc-gateway/easy_home_%s/set", type, id); : Switch(name, id, publisher), on(on), off(off) {
sprintf(commandTopic, "homeassistant/%s/rc-gateway/%s/set", type, id);
} }
void onCommand(const char* msg) override { void onCommand(const char* msg) override {
mySwitch.setProtocol(4); mySwitch.setProtocol(4);
String{ "ON" }.equals(msg) ? mySwitch.send(on) : mySwitch.send(off); String{ "ON" }.equals(msg) ? mySwitch.send(on[0], 24) : mySwitch.send(off[0], 24);
publisher(stateTopic, msg);
} }
void buildConfig(JsonDocument& jsonDoc) override { void buildConfig(JsonDocument& jsonDoc) override {
@ -156,7 +159,6 @@ namespace Ha {
device["manufacturer"] = "Intertek"; device["manufacturer"] = "Intertek";
device["model"] = "Easy Home"; device["model"] = "Easy Home";
} }
}; };
struct Sensor : Component { struct Sensor : Component {

View File

@ -46,21 +46,31 @@ namespace Board {
Mqtt::publish("homeassistant/sensor/rc-gateway/raw", message); Mqtt::publish("homeassistant/sensor/rc-gateway/raw", message);
if (jsonDoc.containsKey("rcSwitch")) { if (jsonDoc.containsKey("rcSwitch")) {
JsonObjectConst rcSwitch = jsonDoc["rcSwitch"]; JsonObjectConst rcSwitch = jsonDoc["rcSwitch"];
string id;
switch ((unsigned int)rcSwitch["protocol"]) { switch ((unsigned int)rcSwitch["protocol"]) {
case 1: case 1: {
// buildId returns a new pointer, should it be deleted, or string will take care of it? // buildId returns a new pointer, should it be deleted, or string will take care of it?
id = Protocol_1::buildId((const char*)rcSwitch["group"], (int)rcSwitch["channel"]); string id = Protocol_1::buildId((const char*)rcSwitch["group"], (int)rcSwitch["channel"]);
break;
case 2:
break;
default:
break;
}
Ha::Switch* el = Mqtt::mapSwitches[id]; Ha::Switch* el = Mqtt::mapSwitches[id];
if (el != nullptr) { if (el != nullptr) {
el->publishState((bool)rcSwitch["state"]); el->publishState((bool)rcSwitch["state"]);
} }
break;
}
case 2:
break;
default: {
unsigned long value = rcSwitch["value"];
Ha::Switch* aSwitch = Mqtt::onSwitches[value];
if (aSwitch != nullptr) {
aSwitch->publishState(true);
} else {
aSwitch = Mqtt::offSwitches[value];
if (aSwitch != nullptr) {
aSwitch->publishState(false);
}
}
}
}
} }
} }

View File

@ -51,11 +51,18 @@ namespace Mqtt {
(new Ha::PollinSwitch{"Meeting sensor", "00001", 1, publish})->withArea("Dining room")->withStateTopic(), (new Ha::PollinSwitch{"Meeting sensor", "00001", 1, publish})->withArea("Dining room")->withStateTopic(),
(new Ha::PollinSwitch{"Fire Tv", "00001", 2, publish})->withArea("Living room")->withStateTopic(), (new Ha::PollinSwitch{"Fire Tv", "00001", 2, publish})->withArea("Living room")->withStateTopic(),
(new Ha::PollinSwitch{"Diningroom player", "00001", 3, publish})->withArea("Dining room")->withStateTopic(), (new Ha::PollinSwitch{"Diningroom player", "00001", 3, publish})->withArea("Dining room")->withStateTopic(),
(new Ha::PollinSwitch{"Train", "11111", 4, publish})->withArea("Playroom")->withStateTopic(), (new Ha::PollinSwitch{"Train", "11111", 4, publish})->withArea("Playroom")->withStateTopic()
(new Ha::EasyHomeSwitch{"FritzBox", "easy_home_a", "010001101001100101110000", "010010111110000010100000"})->withArea("Basement") };
Ha::EasyHomeSwitch* fritz = new Ha::EasyHomeSwitch{"FritzBox", "easy_home_a", (unsigned long[4]){4483136, 4626800, 4819632, 4661552}, (unsigned long[4]){4767520, 4537104, 4326544, 4972704}, publish};
Ha::EasyHomeSwitch* otherSwitches[] = {
fritz
}; };
unordered_map<string, Ha::Switch*> mapSwitches; unordered_map<string, Ha::Switch*> mapSwitches;
unordered_map<unsigned long, Ha::EasyHomeSwitch*> onSwitches;
unordered_map<unsigned long, Ha::EasyHomeSwitch*> offSwitches;
void publishComponentConfig(Ha::Component& component) { void publishComponentConfig(Ha::Component& component) {
StaticJsonDocument<JSON_SIZE> jsonDoc; StaticJsonDocument<JSON_SIZE> jsonDoc;
@ -71,6 +78,8 @@ namespace Mqtt {
// for (Ha::Component* cmp : sensors) { // for (Ha::Component* cmp : sensors) {
// publishComponentConfig(*cmp); // publishComponentConfig(*cmp);
// } // }
fritz->withArea("Basement");
fritz->withStateTopic();
for (Ha::Component* cmp : buttons) { for (Ha::Component* cmp : buttons) {
publishComponentConfig(*cmp); publishComponentConfig(*cmp);
} }
@ -78,6 +87,11 @@ namespace Mqtt {
mapSwitches.insert({string(cmp->id), cmp}); mapSwitches.insert({string(cmp->id), cmp});
publishComponentConfig(*cmp); publishComponentConfig(*cmp);
} }
for (Ha::EasyHomeSwitch* cmp : otherSwitches) {
for (int i = 0; i < 4; i++) onSwitches.insert({cmp->on[i], cmp});
for (int i = 0; i < 4; i++) offSwitches.insert({cmp->off[i], cmp});
publishComponentConfig(*cmp);
}
ts.deleteTask(tPublishInit); ts.deleteTask(tPublishInit);
} }
@ -108,6 +122,12 @@ namespace Mqtt {
return; return;
} }
} }
for (Ha::Switch* cmd : otherSwitches) {
if (String{ cmd->commandTopic }.equals(topic)) {
cmd->onCommand(msg);
return;
}
}
} }
void setup() { void setup() {