add support for configuring components with any json property

This commit is contained in:
Nicu Hodos 2024-06-30 13:19:49 +02:00
parent 6c78efa3c2
commit 1dea02cd0d

View File

@ -65,12 +65,32 @@ namespace Ha {
};
struct Component {
template <typename V>
struct JsonPairs {
typedef pair<const char*, V> JsonPair;
unordered_map<const char*, V> 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<bool> jsonBooleans;
JsonPairs<float> jsonNumbers;
JsonPairs<const char*> jsonStrings;
DeviceConfig* mainDevice = nullptr;
static List<Component> 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 <typename V>
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;