MycilaHADiscovery
Simple and efficient Home Assistant Discovery library for Arduino / ESP32
Features
- Supports diagnostic sensors, config sensors and normal sensors
- Editable components:
- button
- switch / outlet
- select
- slider / box with min, max, step
- input (number and text)
- Sensors:
- text
- binary (state)
- gauge
- counter
- Supports regex validation
- Supports availability (global and per component)
- Supports device class, icon, state class, unit of measurement
Basic Usage
Setup:
haDiscovery.setWillTopic("~/status");
// begin takes the Device, base topic and a callback to publish messages
haDiscovery.begin({
.id = "my-app-1234",
.name = "My Application Name",
.version = "1.0.1",
.model = "OSS",
.manufacturer = "Mathieu Carbou",
.url = "http://" + WiFi.localIP().toString(),
},
"/my-app", // base topic
[](const char* topic, const char* payload) {
// Here, you would call your mqttClient.publish() code
});
Then query state:
// some diagnostic info
haDiscovery.publish<Mycila::HA::Button>("restart", "Restart", "~/system/restart", "restart", nullptr, Mycila::HA::Category::DIAGNOSTIC);
haDiscovery.publish<Mycila::HA::Counter>("uptime", "Uptime", "~/system/uptime", "duration", nullptr, "s", Mycila::HA::Category::DIAGNOSTIC);
haDiscovery.publish<Mycila::HA::Gauge>("memory_used", "Memory Used", "~/system/heap_used", "data_size", "mdi:memory", "B", Mycila::HA::Category::DIAGNOSTIC);
haDiscovery.publish<Mycila::HA::State>("ntp", "NTP", "~/ntp/synced", "true", "false", "connectivity", nullptr, Mycila::HA::Category::DIAGNOSTIC);
haDiscovery.publish<Mycila::HA::Value>("hostname", "Hostname", "~/config/hostname", nullptr, "mdi:lan", Mycila::HA::Category::DIAGNOSTIC);
// some configuration
haDiscovery.publish<Mycila::HA::Text>("mqtt_publish_interval", "MQTT Publish Interval", "~/config/mqtt_interval/set", "~/config/mqtt_interval", "^\\d+$", "mdi:timer-sand", Mycila::HA::Category::CONFIG);
haDiscovery.publish<Mycila::HA::Number>("relay1_power_threshold", "Relay 1 Power Threshold", "~/config/rel1_power/set", "~/config/rel1_power", Mycila::HA::NumberMode::SLIDER, 0, 3000, 50, "mdi:flash", Mycila::HA::Category::CONFIG);
haDiscovery.publish<Mycila::HA::Switch>("output1_auto_bypass_enable", "Output 1 Auto Bypass", "~/config/switch/set", "~/config/switch", "true", "false", "mdi:water-boiler-auto", Mycila::HA::Category::CONFIG);
haDiscovery.publish<Mycila::HA::Select>("day", "Day", "~/config/day/set", "~/config/day", nullptr, Mycila::HA::Category::CONFIG, std::vector<const char*>{"mon", "tue", "wed", "thu", "fri", "sat", "sun"});
// some sensors
haDiscovery.publish<Mycila::HA::State>("grid", "Grid Electricity", "~/grid/online", "true", "false", "connectivity");
// when you need to modify a component after construction, use std::make_unique + std::move
std::unique_ptr<Mycila::HA::Outlet> relay1Commute = std::make_unique<Mycila::HA::Outlet>("rel_commute", "Relay 1", "~/relays/rel1/state/set", "~/relays/rel1/state", "on", "off");
relay1Commute->availabilityTopic = "~/relays/rel1/enabled";
relay1Commute->payloadAvailable = "true";
relay1Commute->payloadNotAvailable = "false";
haDiscovery.publish(std::move(relay1Commute));
haDiscovery.end();
API overview
publish() and unpublish() accept either:
-
A
std::unique_ptr<Component>— for cases where you need to modify the component after construction (e.g. settingavailabilityTopic):auto relay = std::make_unique<Mycila::HA::Outlet>("relay1", "Relay 1", "~/relays/rel1/set", "~/relays/rel1", "on", "off"); relay->availabilityTopic = "~/relays/rel1/enabled"; haDiscovery.publish(std::move(relay)); -
Template parameters — for the common case where you construct and publish in one call (component is allocated on the heap internally):
haDiscovery.publish<Mycila::HA::Button>("restart", "Restart", "~/system/restart", "restart"); haDiscovery.publish<Mycila::HA::Gauge>("temperature", "Temperature", "~/sensor/temp", "temperature", nullptr, "°C");
Usage example in YaSolR: https://github.com/mathieucarbou/YaSolR/blob/main/src/yasolr_mqtt.cpp