fine tunning:

- use namespace for oil tank builders
- use factory method for creating DeviceConfig
- use C's strcmp for comparing strings
- split parsing of incoming RCSwitch states
This commit is contained in:
Nicu Hodos 2024-05-16 10:37:11 +02:00
parent 77594581ff
commit 3d7895e916
4 changed files with 52 additions and 49 deletions

View File

@ -8,9 +8,9 @@ using namespace Ha;
DeviceConfig* gatewayDevice = (new DeviceConfig{MAIN_DEVICE_ID})->withName("RC Gateway")->withManufacturer("Adafruit")->withModel("Huzzah Esp8266");
struct OilTankRoomSensorBuilder {
static Sensor* build(const char* id) {
auto device = (new DeviceConfig{ id })
namespace OilTank {
Sensor* buildRoomSensor(const char* id) {
auto device = DeviceConfig::create(id)
->withName("Oil tank room")
->withManufacturer("Atmel")
->withModel("AtTiny85")
@ -23,11 +23,9 @@ struct OilTankRoomSensorBuilder {
.withDiagnostic(new BatterySensor{id, "Battery level", "{{ ((states('sensor.oil_tank_room_battery_voltage')|float-2.5)|round(2)*100/2)|int }}"})
.build();
}
};
struct OilSensorBuilder {
static Sensor* build(const char* id) {
auto device = (new DeviceConfig{ id })
Sensor* buildTankSensor(const char* id) {
auto device = DeviceConfig::create(id)
->withName("Oil tank")
->withManufacturer("Arduino")
->withModel("Pro Mini")
@ -48,7 +46,7 @@ struct OilSensorBuilder {
.withDiagnostic(new BatterySensor{id, "Battery level", "{{ ((states('sensor.oil_tank_battery_voltage')|float-3.6)|round(2)*100/1.6)|int }}"})
.build();
}
};
}
struct PollinSwitch : Switch {
const char* group;
@ -68,7 +66,7 @@ struct PollinSwitch : Switch {
}
void onCommand(const char* msg) override {
(String{ "ON" }.equals(msg)) ? mySwitch.switchOn(group, channel) : mySwitch.switchOff(group, channel);
strcmp("ON", msg) == 0 ? mySwitch.switchOn(group, channel) : mySwitch.switchOff(group, channel);
publisher(stateTopic, msg);
}
@ -92,7 +90,7 @@ struct EasyHomeSwitch : Switch {
void onCommand(const char* msg) override {
mySwitch.setProtocol(4);
String{ "ON" }.equals(msg) ? mySwitch.send(on[4], 24) : mySwitch.send(off[4], 24);
strcmp("ON", msg) == 0 ? mySwitch.send(on[4], 24) : mySwitch.send(off[4], 24);
publisher(stateTopic, msg);
}
};

View File

@ -19,7 +19,10 @@ namespace Ha {
DeviceConfig* parent = nullptr;
DeviceConfig(const char* id) : id(id) {}
DeviceConfig(DeviceConfig& d) : id(d.id), name(d.name), model(d.model), manufacturer(d.manufacturer), area(d.area), parent(d.parent) {}
static DeviceConfig* create(const char* id) {
return new DeviceConfig{ id };
}
void buildConfig(JsonDocument& jsonDoc) {
JsonObject device = jsonDoc.createNestedObject("device");

View File

@ -48,43 +48,46 @@ namespace Board {
ts.execute();
}
void parseSwitches(JsonDocument& jsonDoc) {
JsonObjectConst rcSwitch = jsonDoc["rcSwitch"];
switch ((unsigned int)rcSwitch["protocol"]) {
case 1: {
string id = Protocol_1::buildId((const char*)rcSwitch["group"], (int)rcSwitch["channel"]);
Ha::Switch* el = p1Switches[id];
if (el) el->publishState((bool)rcSwitch["state"]);
break;
}
case 2:
break;
default: {
unsigned long value = rcSwitch["value"];
auto range = onSwitches.equal_range(value);
for_each(range.first, range.second, [](mapswitches::value_type& x){
x.second->publishState(true);
});
range = offSwitches.equal_range(value);
for_each(range.first, range.second, [](mapswitches::value_type& x){
x.second->publishState(false);
});
}
}
}
void parseSensors(JsonDocument& jsonDoc, char* message) {
JsonObjectConst json = jsonDoc["sensor"];
string id = to_string((unsigned int)json["id"]);
char stateTopic[TOPIC_SIZE];
sprintf(stateTopic, "homeassistant/sensor/%s/%s/state", MAIN_DEVICE_ID, id.c_str());
Mqtt::publish(stateTopic, message);
}
void publishResponse(JsonDocument& jsonDoc) {
char message[255];
serializeJson(jsonDoc, message);
Mqtt::publish("homeassistant/sensor/rc-gateway/raw", message);
if (jsonDoc.containsKey("rcSwitch")) {
JsonObjectConst rcSwitch = jsonDoc["rcSwitch"];
switch ((unsigned int)rcSwitch["protocol"]) {
case 1: {
string id = Protocol_1::buildId((const char*)rcSwitch["group"], (int)rcSwitch["channel"]);
Ha::Switch* el = p1Switches[id];
if (el != nullptr) {
el->publishState((bool)rcSwitch["state"]);
}
break;
}
case 2:
break;
default: {
unsigned long value = rcSwitch["value"];
auto range = onSwitches.equal_range(value);
for_each(range.first, range.second, [](mapswitches::value_type& x){
x.second->publishState(true);
});
range = offSwitches.equal_range(value);
for_each(range.first, range.second, [](mapswitches::value_type& x){
x.second->publishState(false);
});
}
}
}
if (jsonDoc.containsKey("sensor")) {
JsonObjectConst json = jsonDoc["sensor"];
string id = to_string((unsigned int)json["id"]);
char stateTopic[TOPIC_SIZE];
sprintf(stateTopic, "homeassistant/sensor/%s/%s/state", MAIN_DEVICE_ID, id.c_str());
Mqtt::publish(stateTopic, message);
}
if (jsonDoc.containsKey("rcSwitch")) parseSwitches(jsonDoc);
if (jsonDoc.containsKey("sensor")) parseSensors(jsonDoc, message);
}
void handleJsonError(JsonDocument& jsonError) {

View File

@ -12,12 +12,11 @@ namespace Mqtt {
AsyncMqttClient client;
void publishInit();
void disconnect();
Task tReConnect(5 * TASK_MINUTE, TASK_FOREVER, []() {
Serial.println("Connecting to MQTT...");
client.connect();
}, &ts);
void publishInit();
Task tPublishInit(TASK_IMMEDIATE, TASK_ONCE, publishInit, &ts);
const char* mainTopic = "homeassistant/+/rc-gateway/#";
@ -34,7 +33,7 @@ namespace Mqtt {
Command* commands[] = {
Builder<Button>::instance(new Button{"Restart", "restart",
[](const char* msg) {
if (String { "PRESS" }.equals(msg)) ESP.restart();
if (strcmp("PRESS", msg) == 0) ESP.restart();
}
}).asDevice(gatewayDevice).build(),
(new EasyHomeSwitch{"FritzBox", "easy_home_a", (unsigned long[4]) { 4483136, 4626800, 4661552, 4819632 }, (unsigned long[4]) { 4326544, 4537104, 4767520, 4972704 }, "Basement"})->withStateTopic(),
@ -46,8 +45,8 @@ namespace Mqtt {
};
Sensor* sensors[] = {
OilTankRoomSensorBuilder::build("4"),
OilSensorBuilder::build("7")
OilTank::buildRoomSensor("4"),
OilTank::buildTankSensor("7")
};
void publishInit() {