use Builder instead of EntityConfig
This commit is contained in:
parent
ee87deb2d0
commit
7b53efe1ca
@ -7,16 +7,20 @@
|
|||||||
using namespace Ha;
|
using namespace Ha;
|
||||||
|
|
||||||
DeviceConfig* gatewayDevice = (new DeviceConfig{MAIN_DEVICE_ID})->withName("RC Gateway")->withManufacturer("Adafruit")->withModel("Huzzah Esp8266");
|
DeviceConfig* gatewayDevice = (new DeviceConfig{MAIN_DEVICE_ID})->withName("RC Gateway")->withManufacturer("Adafruit")->withModel("Huzzah Esp8266");
|
||||||
DeviceConfig* atTinyDevice = (new DeviceConfig{})->withManufacturer("Atmel")->withModel("AtTiny85")->withParent(gatewayDevice);
|
|
||||||
|
|
||||||
struct OilTankRoomSensorBuilder {
|
struct OilTankRoomSensorBuilder {
|
||||||
static Sensor* build(const char* id) {
|
static Sensor* build(const char* id) {
|
||||||
auto device = (new DeviceConfig{*atTinyDevice})->withName("Oil tank room")->withArea("Basement");
|
auto device = (new DeviceConfig{ id })
|
||||||
device->id = id;
|
->withName("Oil tank room")
|
||||||
Sensor* sensor = (new Ha::TemperatureSensor(id))->asDevice(device);
|
->withManufacturer("Atmel")
|
||||||
(new VoltageSensor{sensor->id, "Battery voltage", "{{ value_json.sensor.diagnostic.voltage }}"})->ofDevice((id));
|
->withModel("AtTiny85")
|
||||||
(new BatterySensor{sensor->id, "Battery level", "{{ ((states('sensor.oil_tank_room_battery_voltage')|float-2.5)|round(2)*100/2)|int }}"})->ofDevice(id);
|
->withArea("Basement")
|
||||||
return sensor;
|
->withParent(gatewayDevice);
|
||||||
|
return Builder<TemperatureSensor>::instance(id)
|
||||||
|
.asDevice(device)
|
||||||
|
.withDiagnostic(new VoltageSensor{id, "Battery voltage", "{{ value_json.sensor.diagnostic.voltage }}"})
|
||||||
|
.withDiagnostic(new BatterySensor{id, "Battery level", "{{ ((states('sensor.oil_tank_room_battery_voltage')|float-2.5)|round(2)*100/2)|int }}"})
|
||||||
|
.build();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -45,13 +49,18 @@ struct OilTankLevelSensor : Sensor {
|
|||||||
|
|
||||||
struct OilSensorBuilder {
|
struct OilSensorBuilder {
|
||||||
static Sensor* build(const char* id) {
|
static Sensor* build(const char* id) {
|
||||||
auto device = (new DeviceConfig{*atTinyDevice})->withName("Oil tank")->withArea("Basement");
|
auto device = (new DeviceConfig{ id })
|
||||||
device->id = id;
|
->withName("Oil tank")
|
||||||
Sensor* sensor = (new OilTankSensor(id))->asDevice(device);
|
->withManufacturer("Arduino")
|
||||||
(new OilTankLevelSensor(sensor->id))->ofDevice(id);
|
->withModel("Pro Mini")
|
||||||
(new VoltageSensor{id, "Battery voltage", "{{ value_json.sensor.diagnostic.voltage }}"})->ofDevice(id);
|
->withArea("Basement")
|
||||||
(new BatterySensor{id, "Battery level", "{{ ((states('sensor.oil_tank_battery_voltage')|float-3.6)|round(2)*100/1.6)|int }}"})->ofDevice(id);
|
->withParent(gatewayDevice);
|
||||||
return sensor;
|
return Builder<OilTankSensor>::instance(id)
|
||||||
|
.asDevice(device)
|
||||||
|
.withSecondary(new OilTankLevelSensor(id))
|
||||||
|
.withDiagnostic(new VoltageSensor{id, "Battery voltage", "{{ value_json.sensor.diagnostic.voltage }}"})
|
||||||
|
.withDiagnostic(new BatterySensor{id, "Battery level", "{{ ((states('sensor.oil_tank_battery_voltage')|float-3.6)|round(2)*100/1.6)|int }}"})
|
||||||
|
.build();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -61,7 +70,7 @@ struct PollinSwitch : Switch {
|
|||||||
|
|
||||||
PollinSwitch(const char* name, const char* group, const unsigned char channel, const char* area = nullptr)
|
PollinSwitch(const char* name, const char* group, const unsigned char channel, const char* area = nullptr)
|
||||||
: Switch(name, Protocol_1::buildId(group, channel)), group(group), channel(channel) {
|
: Switch(name, Protocol_1::buildId(group, channel)), group(group), channel(channel) {
|
||||||
asDevice((new DeviceConfig{id})->withName(name)->withManufacturer("Pollin")->withArea(area)->withParent(gatewayDevice));
|
mainDevice = (new DeviceConfig{id})->withName(name)->withManufacturer("Pollin")->withArea(area)->withParent(gatewayDevice);
|
||||||
p1Switches.insert({ string(id), this });
|
p1Switches.insert({ string(id), this });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,7 +89,7 @@ struct EasyHomeSwitch : Switch {
|
|||||||
: Switch(name, id) {
|
: Switch(name, id) {
|
||||||
memcpy(&this->on[4], on, 4 * sizeof(unsigned long));
|
memcpy(&this->on[4], on, 4 * sizeof(unsigned long));
|
||||||
memcpy(&this->off[4], off, 4 * sizeof(unsigned long));
|
memcpy(&this->off[4], off, 4 * sizeof(unsigned long));
|
||||||
asDevice((new DeviceConfig{id})->withName(name)->withManufacturer("Intertek")->withModel("Easy Home")->withArea(area)->withParent(gatewayDevice));
|
mainDevice = (new DeviceConfig{id})->withName(name)->withManufacturer("Intertek")->withModel("Easy Home")->withArea(area)->withParent(gatewayDevice);
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
onSwitches.insert({ this->on[i], this });
|
onSwitches.insert({ this->on[i], this });
|
||||||
offSwitches.insert({ this->off[i], this });
|
offSwitches.insert({ this->off[i], this });
|
||||||
|
|||||||
@ -94,30 +94,55 @@ namespace Ha {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
|
||||||
struct EntityConfig : Component {
|
|
||||||
|
|
||||||
EntityConfig(const char* name, const char* id, const char* type) : Component(name, id, type) {
|
|
||||||
}
|
|
||||||
|
|
||||||
T* asDevice(DeviceConfig* deviceConfig) {
|
|
||||||
mainDevice = deviceConfig;
|
|
||||||
return static_cast<T*>(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
T* ofDevice(const char* id) {
|
|
||||||
mainDevice = new DeviceConfig{id};
|
|
||||||
return static_cast<T*>(this);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
List<Component> Component::components;
|
List<Component> Component::components;
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
struct Command : EntityConfig<T> {
|
struct Builder {
|
||||||
|
T* cmp;
|
||||||
|
|
||||||
|
Builder() {}
|
||||||
|
Builder(T* cmp) : cmp(cmp) {}
|
||||||
|
Builder(const char* id) {
|
||||||
|
cmp = new T{id};
|
||||||
|
}
|
||||||
|
|
||||||
|
static Builder& instance() {
|
||||||
|
return *(new Builder<T>());
|
||||||
|
}
|
||||||
|
|
||||||
|
static Builder& instance(T* c) {
|
||||||
|
return *(new Builder<T>(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Builder& instance(const char* id) {
|
||||||
|
return *(new Builder<T>(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
T* build() {
|
||||||
|
return static_cast<T*>(cmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
Builder& withSecondary(Component* c) {
|
||||||
|
c->mainDevice = new DeviceConfig{ cmp->id };
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Builder& withDiagnostic(Component* c) {
|
||||||
|
c->entityCategory = "diagnostic";
|
||||||
|
c->mainDevice = new DeviceConfig{ cmp->id };
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Builder& asDevice(DeviceConfig* deviceConfig) {
|
||||||
|
cmp->mainDevice = deviceConfig;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Command : Component {
|
||||||
char commandTopic[TOPIC_SIZE];
|
char commandTopic[TOPIC_SIZE];
|
||||||
|
|
||||||
Command(const char* name, const char* id, const char* type) : EntityConfig<T>(name, id, type) {
|
Command(const char* name, const char* id, const char* type) : Component(name, id, type) {
|
||||||
sprintf(commandTopic, "homeassistant/%s/%s/%s", type, MAIN_DEVICE_ID, id);
|
sprintf(commandTopic, "homeassistant/%s/%s/%s", type, MAIN_DEVICE_ID, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,17 +151,17 @@ namespace Ha {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void buildConfig(JsonDocument& jsonDoc) override {
|
void buildConfig(JsonDocument& jsonDoc) override {
|
||||||
EntityConfig<T>::buildConfig(jsonDoc);
|
Component::buildConfig(jsonDoc);
|
||||||
jsonDoc["command_topic"] = commandTopic;
|
jsonDoc["command_topic"] = commandTopic;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void (*onMessage)(const char* msg);
|
typedef void (*onMessage)(const char* msg);
|
||||||
struct Button : Command<Button> {
|
struct Button : Command {
|
||||||
onMessage f;
|
onMessage f;
|
||||||
|
|
||||||
Button(const char* name, const char* id, onMessage f) : Command(name, id, "button"), f(f) {}
|
Button(const char* name, const char* id, onMessage f = nullptr) : Command(name, id, "button"), f(f) {}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -150,7 +175,7 @@ namespace Ha {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Switch : Command<Switch>, StateConfig<Switch> {
|
struct Switch : Command, StateConfig<Switch> {
|
||||||
|
|
||||||
virtual void onCommand(const char* msg){}
|
virtual void onCommand(const char* msg){}
|
||||||
|
|
||||||
@ -171,11 +196,15 @@ namespace Ha {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Sensor : EntityConfig<Sensor>, StateConfig<Sensor> {
|
struct Sensor : Component, StateConfig<Sensor> {
|
||||||
const char* unitMeasure = nullptr;
|
const char* unitMeasure = nullptr;
|
||||||
const char* valueTemplate = nullptr;
|
const char* valueTemplate = nullptr;
|
||||||
|
|
||||||
Sensor(const char* name, const char* id) : EntityConfig(name, Protocol_2::buildId(id), "sensor") {
|
Sensor() : Component(name, Protocol_2::buildId(id), "sensor") {
|
||||||
|
withStateTopic();
|
||||||
|
}
|
||||||
|
|
||||||
|
Sensor(const char* name, const char* id) : Component(name, Protocol_2::buildId(id), "sensor") {
|
||||||
withStateTopic();
|
withStateTopic();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,7 +213,7 @@ namespace Ha {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void buildConfig(JsonDocument& jsonDoc) override {
|
void buildConfig(JsonDocument& jsonDoc) override {
|
||||||
EntityConfig::buildConfig(jsonDoc);
|
Component::buildConfig(jsonDoc);
|
||||||
if (unitMeasure) jsonDoc["unit_of_measurement"] = unitMeasure;
|
if (unitMeasure) jsonDoc["unit_of_measurement"] = unitMeasure;
|
||||||
if (valueTemplate) jsonDoc["value_template"] = valueTemplate;
|
if (valueTemplate) jsonDoc["value_template"] = valueTemplate;
|
||||||
jsonDoc["state_topic"] = stateTopic;
|
jsonDoc["state_topic"] = stateTopic;
|
||||||
@ -203,7 +232,6 @@ namespace Ha {
|
|||||||
struct VoltageSensor : Sensor {
|
struct VoltageSensor : Sensor {
|
||||||
VoltageSensor(const char* id, const char* name, const char* valueTemplate) : Sensor(name, id) {
|
VoltageSensor(const char* id, const char* name, const char* valueTemplate) : Sensor(name, id) {
|
||||||
this->valueTemplate = valueTemplate;
|
this->valueTemplate = valueTemplate;
|
||||||
entityCategory = "diagnostic";
|
|
||||||
deviceClass = "voltage";
|
deviceClass = "voltage";
|
||||||
unitMeasure = "V";
|
unitMeasure = "V";
|
||||||
}
|
}
|
||||||
@ -212,7 +240,6 @@ namespace Ha {
|
|||||||
struct BatterySensor : Sensor {
|
struct BatterySensor : Sensor {
|
||||||
BatterySensor(const char* id, const char* name, const char* valueTemplate) : Sensor(name, id) {
|
BatterySensor(const char* id, const char* name, const char* valueTemplate) : Sensor(name, id) {
|
||||||
this->valueTemplate = valueTemplate;
|
this->valueTemplate = valueTemplate;
|
||||||
entityCategory = "diagnostic";
|
|
||||||
deviceClass = "battery";
|
deviceClass = "battery";
|
||||||
unitMeasure = "%";
|
unitMeasure = "%";
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,12 +31,12 @@ namespace Mqtt {
|
|||||||
return client.publish(topic, 0, true, message);
|
return client.publish(topic, 0, true, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ha::Button* buttons[] = {
|
Button* buttons[] = {
|
||||||
(new Ha::Button{"Restart", "restart",
|
Builder<Button>::instance(new Button{"Restart", "restart",
|
||||||
[](const char* msg) {
|
[](const char* msg) {
|
||||||
if (String { "PRESS" }.equals(msg)) ESP.restart();
|
if (String { "PRESS" }.equals(msg)) ESP.restart();
|
||||||
}
|
}
|
||||||
})->asDevice(gatewayDevice)
|
}).asDevice(gatewayDevice).build()
|
||||||
};
|
};
|
||||||
|
|
||||||
Ha::Switch* switches[] = {
|
Ha::Switch* switches[] = {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user