diff --git a/src/ha.h b/src/ha.h index 74ccfa6..76e1f94 100644 --- a/src/ha.h +++ b/src/ha.h @@ -65,12 +65,32 @@ namespace Ha { }; struct Component { + + template + struct JsonPairs { + typedef pair JsonPair; + unordered_map jsonPairs; + + void add(JsonPair pair) { + jsonPairs.insert(pair); + } + + void addToJson(JsonDocument& jsonDoc) { + for (JsonPair el : jsonPairs) { + jsonDoc[el.first] = el.second; + } + } + }; + const char* entityCategory = nullptr; const char* deviceClass = nullptr; const char* name = nullptr; char* id = nullptr; const char* type = nullptr; char configTopic[TOPIC_SIZE]; + JsonPairs jsonBooleans; + JsonPairs jsonNumbers; + JsonPairs jsonStrings; DeviceConfig* mainDevice = nullptr; static List components; @@ -86,7 +106,9 @@ namespace Ha { sprintf(configTopic, "homeassistant/%s/%s/%s/config", type, MAIN_DEVICE_ID, id); } - virtual void buildConfig(JsonDocument& jsonDoc) { + virtual void buildComponentConfig(JsonDocument& jsonDoc) = 0; + + void buildConfig(JsonDocument& jsonDoc) { if (mainDevice) mainDevice->buildConfig(jsonDoc); if (entityCategory) jsonDoc["entity_category"] = entityCategory; if (deviceClass) jsonDoc["device_class"] = deviceClass; @@ -95,6 +117,12 @@ namespace Ha { buildUniqueId(uniqueId); jsonDoc["unique_id"] = uniqueId; buildConfigTopic(); + + buildComponentConfig(jsonDoc); + + jsonBooleans.addToJson(jsonDoc); + jsonNumbers.addToJson(jsonDoc); + jsonStrings.addToJson(jsonDoc); } void publishConfig() { @@ -167,6 +195,22 @@ namespace Ha { return *this; } + Builder& overrideConfig(const char* key, bool value) { + cmp->jsonBooleans.add({key, value}); + return *this; + } + + template + Builder& overrideConfig(const char* key, V value) { + cmp->jsonNumbers.add({key, value}); + return *this; + } + + Builder& overrideConfig(const char* key, const char* value) { + cmp->jsonStrings.add({key, value}); + return *this; + } + Builder& addSecondary(Component* c) { if (cmp->mainDevice) c->mainDevice = &DeviceConfig::create(cmp->mainDevice->id); return *this; @@ -218,10 +262,12 @@ namespace Ha { if (f) f(msg); } - void buildConfig(JsonDocument& jsonDoc) override { - Component::buildConfig(jsonDoc); + virtual void buildCommandConfig(JsonDocument& jsonDoc) = 0; + + void buildComponentConfig(JsonDocument& jsonDoc) override { jsonDoc["command_topic"] = commandTopic; if (retain) jsonDoc["retain"] = true; + buildCommandConfig(jsonDoc); } }; @@ -230,6 +276,8 @@ namespace Ha { Button(const char* name, const char* id, onMessage f = nullptr) : Command(name, id, "button", f) {} + void buildCommandConfig(JsonDocument& jsonDoc) override {} + }; struct StateConfig { @@ -256,8 +304,7 @@ namespace Ha { Switch(const char* name, const char* id, onMessage f = nullptr) : Command(name, id, "switch", f), StateConfig(this) {} - void buildConfig(JsonDocument& jsonDoc) override { - Command::buildConfig(jsonDoc); + void buildCommandConfig(JsonDocument& jsonDoc) override { StateConfig::buildConfig(jsonDoc); } @@ -276,8 +323,7 @@ namespace Ha { Number(const char* name, const char* id, unsigned int min, unsigned int max, unsigned int step, onMessage f) : Command(name, id, "number", f), StateConfig(this), min(min), max(max), step(step) {} - void buildConfig(JsonDocument& jsonDoc) override { - Command::buildConfig(jsonDoc); + void buildCommandConfig(JsonDocument& jsonDoc) override { StateConfig::buildConfig(jsonDoc); jsonDoc["min"] = min; jsonDoc["max"] = max; @@ -323,8 +369,7 @@ namespace Ha { } } - void buildConfig(JsonDocument& jsonDoc) override { - Component::buildConfig(jsonDoc); + void buildComponentConfig(JsonDocument& jsonDoc) override { StateConfig::buildConfig(jsonDoc); if (unitMeasure) jsonDoc["unit_of_measurement"] = unitMeasure; if (valueTemplate) jsonDoc["value_template"] = valueTemplate;