diff --git a/gateway/include/ha.h b/gateway/include/ha.h index d7d550c..c69830b 100644 --- a/gateway/include/ha.h +++ b/gateway/include/ha.h @@ -18,22 +18,19 @@ namespace Ha { DeviceConfig* parent = nullptr; DeviceConfig() {} + DeviceConfig(const char* id) : id(id) {} DeviceConfig(const char* id, const char* name) : id(id), name(name) {} DeviceConfig(DeviceConfig& d) : id(d.id), name(d.name), model(d.model), manufacturer(d.manufacturer), area(d.area), parent(d.parent) {} void buildConfig(JsonDocument& jsonDoc) { JsonObject device = jsonDoc.createNestedObject("device"); - device["name"] = name; - // JsonArray connections = device.createNestedArray("connections"); - // JsonArray mac = connections.createNestedArray(); - // mac.add("mac"); - // mac.add(WiFi.macAddress()); - JsonArray identifiers = device.createNestedArray("identifiers"); - identifiers.add(id); + if (name) device["name"] = name; if (model) device["model"] = model; if (manufacturer) device["manufacturer"] = manufacturer; if (area) device["suggested_area"] = area; if (parent) device["via_device"] = parent->id; + JsonArray identifiers = device.createNestedArray("identifiers"); + identifiers.add(id); } DeviceConfig* withModel(const char* value) { @@ -58,6 +55,8 @@ namespace Ha { }; struct Component { + const char* entityCategory = nullptr; + const char* deviceClass = nullptr; const char* name = nullptr; char* id = nullptr; const char* type = nullptr; @@ -66,14 +65,19 @@ namespace Ha { static List components; Component(const char* name, const char* id, const char* type) : name(name), id((char*)id), type(type) { - sprintf(configTopic, "homeassistant/%s/%s/%s/config", type, MAIN_DEVICE_ID, id); components.add(this); } virtual void buildUniqueId(char* uniqueId) = 0; virtual void buildConfig(JsonDocument& jsonDoc) { + if (String{"diagnostic"}.equals(entityCategory)) { + sprintf(configTopic, "homeassistant/%s/%s/%s_%s/config", type, MAIN_DEVICE_ID, deviceClass, id); + } else { + sprintf(configTopic, "homeassistant/%s/%s/%s/config", type, MAIN_DEVICE_ID, id); + } if (mainDevice) mainDevice->buildConfig(jsonDoc); + if (entityCategory) jsonDoc["entity_category"] = entityCategory; jsonDoc["name"] = name; char uniqueId[50]; buildUniqueId(uniqueId); @@ -101,6 +105,7 @@ namespace Ha { mainDevice = new DeviceConfig{*deviceConfig}; mainDevice->id = id; mainDevice->name = name; + mainDevice->parent = deviceConfig->parent; return static_cast(this); } }; @@ -166,23 +171,25 @@ namespace Ha { }; struct Sensor : EntityConfig, StateConfig { - const char* deviceClass = nullptr; const char* unitMeasure = nullptr; const char* valueTemplate = nullptr; - Sensor(const char* name, const char* id) : EntityConfig(name, id, "sensor") { + Sensor(const char* name, const char* id) : EntityConfig(name, Protocol_2::buildId(id), "sensor") { + withStateTopic(); } void buildUniqueId(char* uniqueId) override { - sprintf(uniqueId, "%s", id); + sprintf(uniqueId, "%s_%s", deviceClass, id); } void buildConfig(JsonDocument& jsonDoc) override { EntityConfig::buildConfig(jsonDoc); + if (entityCategory) jsonDoc["entity_category"] = entityCategory; jsonDoc["device_class"] = deviceClass; jsonDoc["unit_of_measurement"] = unitMeasure; - jsonDoc["value_template"] = valueTemplate; - if (stateTopic[0]) jsonDoc["state_topic"] = stateTopic; + if (valueTemplate) jsonDoc["value_template"] = valueTemplate; + jsonDoc["state_topic"] = stateTopic; + jsonDoc["suggested_display_precision"] = 2; } Sensor* withDeviceName(const char* value) { @@ -199,6 +206,24 @@ namespace Ha { } }; + struct VoltageSensor : Sensor { + VoltageSensor(const char* id, const char* name, const char* valueTemplate) : Sensor(name, id) { + this->valueTemplate = valueTemplate; + entityCategory = "diagnostic"; + deviceClass = "voltage"; + unitMeasure = "V"; + } + }; + + struct BatterySensor : Sensor { + BatterySensor(const char* id, const char* name, const char* valueTemplate) : Sensor(name, id) { + this->valueTemplate = valueTemplate; + entityCategory = "diagnostic"; + deviceClass = "battery"; + unitMeasure = "%"; + } + }; + struct HumiditySensor : Sensor { HumiditySensor(const char* name, const char* id) : Sensor(name, id) { name = "Humidity"; @@ -217,11 +242,11 @@ namespace Ha { } }; - struct AltitudeSensor : Sensor { - AltitudeSensor(const char* name, const char* id) : Sensor(name, id) { - deviceClass = "distance"; - unitMeasure = "m"; - valueTemplate = "{{ value_json.sensor.altitude }}"; - } - }; + // struct AltitudeSensor : Sensor { + // AltitudeSensor(const char* name, const char* id) : Sensor(name, id) { + // deviceClass = "distance"; + // unitMeasure = "m"; + // valueTemplate = "{{ value_json.sensor.altitude }}"; + // } + // }; } diff --git a/gateway/include/mqtt.h b/gateway/include/mqtt.h index 0e9cd02..cd4950b 100644 --- a/gateway/include/mqtt.h +++ b/gateway/include/mqtt.h @@ -32,14 +32,6 @@ namespace Mqtt { return client.publish(topic, 0, true, message); } - Ha::Sensor* sensors[] = { - (new Ha::TemperatureSensor{"id4"})->withStateTopic()->copyFromDevice(atTinyDevice)->withDeviceName("Oil tank room1")->withArea("Basement") - // new Ha::TemperatureSensor{"Temperature", "temperature"}, - // new Ha::HumiditySensor{"Humidity", "humidity"}, - // new Ha::PressureSensor{"Pressure", "pressure"}, - // new Ha::AltitudeSensor{"Altitude", "altitude"} - }; - Ha::Button* buttons[] = { (new Ha::Button{"Restart", "restart", [](const char* msg) { @@ -57,6 +49,14 @@ namespace Mqtt { (new EasyHomeSwitch{"Outside", "easy_home_b", (unsigned long[4]) { 4483140, 4626804, 4661556, 4819636 }, (unsigned long[4]) { 4326548, 4537108, 4767524, 4972708 }})->withArea("Basement")->withStateTopic() }; + Ha::Sensor* sensors[] = { + SensorBuilder::withVoltage((new Ha::TemperatureSensor{"4"})->copyFromDevice(atTinyDevice)->withDeviceName("Oil tank room")->withArea("Basement")) + // new Ha::TemperatureSensor{"Temperature", "temperature"}, + // new Ha::HumiditySensor{"Humidity", "humidity"}, + // new Ha::PressureSensor{"Pressure", "pressure"}, + // new Ha::AltitudeSensor{"Altitude", "altitude"} + }; + void publishComponentConfig(Ha::Component& component) { StaticJsonDocument jsonDoc; component.buildConfig(jsonDoc);