#pragma once #include #include "display.h" #define JSON_SIZE 512 #define TOPIC_SIZE 255 namespace Ha { struct Component { const char* name; const char* id; const char* type; char configTopic[TOPIC_SIZE]; Component(const char* name, const char* id, const char* type) { this->name = name; this->id = id; this->type = type; sprintf(configTopic, "homeassistant/%s/esp_clock/%s/config", type, id); } virtual void buildUniqueId(char* uniqueId) = 0; virtual void buildConfig(JsonDocument& jsonDoc) { buildDeviceConfig(jsonDoc); jsonDoc["name"] = name; char uniqueId[50]; buildUniqueId(uniqueId); jsonDoc["unique_id"] = uniqueId; } void buildDeviceConfig(JsonDocument& jsonDoc) { JsonObject device = jsonDoc.createNestedObject("device"); device["name"] = "ESP Clock"; device["suggested_area"] = "Living room"; JsonArray connections = device.createNestedArray("connections"); JsonArray mac = connections.createNestedArray(); mac.add("mac"); mac.add(WiFi.macAddress()); } }; typedef void (*onMessage)(const char* msg); struct Command : Component { char commandTopic[TOPIC_SIZE]; char stateTopic[TOPIC_SIZE]; onMessage f; Command(const char* name, const char* id, const char* type, onMessage f) : Component(name, id, type) { this->f = f; } void buildUniqueId(char* uniqueId) override { sprintf(uniqueId, "esp_clock_%s", id); } void buildConfig(JsonDocument& jsonDoc) override { Component::buildConfig(jsonDoc); jsonDoc["command_topic"] = commandTopic; if (stateTopic[0]) jsonDoc["state_topic"] = stateTopic; } Command* withStateTopic() { sprintf(stateTopic, "homeassistant/%s/esp_clock/%s/state", type, id); return this; } }; struct Button : Command { static constexpr const char* type = "button"; Button(const char* name, const char* id, onMessage f) : Command(name, id, type, f) { sprintf(commandTopic, "homeassistant/%s/esp_clock/%s", type, id); } }; struct Switch : Command { static constexpr const char* type = "switch"; Switch(const char* name, const char* id, onMessage f) : Command(name, id, type, f) { sprintf(commandTopic, "homeassistant/%s/esp_clock/%s/set", type, id); } }; struct Brightness : Command { static constexpr const char* type = "number"; Brightness(const char* name, const char* id, onMessage f) : Command(name, id, type, f) { sprintf(commandTopic, "homeassistant/%s/esp_clock/%s", type, id); } void buildConfig(JsonDocument& jsonDoc) override { Command::buildConfig(jsonDoc); jsonDoc["min"] = BRIGHTNESS_MIN; jsonDoc["max"] = BRIGHTNESS_MAX; jsonDoc["step"] = BRIGHTNESS_STEP; } }; struct Sensor : Component { const char* deviceClass; const char* unitMeasure; const char* valueTemplate; static constexpr const char* stateTopic = "homeassistant/sensor/esp_clock/state"; Sensor(const char* name, const char* id) : Component(name, id, "sensor") { } void buildUniqueId(char* uniqueId) override { sprintf(uniqueId, "living_room_%s", id); } void buildConfig(JsonDocument& jsonDoc) override { Component::buildConfig(jsonDoc); jsonDoc["device_class"] = deviceClass; jsonDoc["unit_of_measurement"] = unitMeasure; jsonDoc["value_template"] = valueTemplate; jsonDoc["state_topic"] = stateTopic; } }; struct TemperatureSensor : Sensor { TemperatureSensor(const char* name, const char* id) : Sensor(name, id) { deviceClass = "temperature"; unitMeasure = "°C"; valueTemplate = "{{ value_json.temperature }}"; } }; struct PressureSensor : Sensor { PressureSensor(const char* name, const char* id) : Sensor(name, id) { deviceClass = "pressure"; unitMeasure = "hPa"; valueTemplate = "{{ value_json.pressure }}"; } }; struct AltitudeSensor : Sensor { AltitudeSensor(const char* name, const char* id) : Sensor(name, id) { deviceClass = "distance"; unitMeasure = "m"; valueTemplate = "{{ value_json.altitude }}"; } }; }