diff --git a/library.json b/library.json index e9134ae..73d2f45 100644 --- a/library.json +++ b/library.json @@ -1,7 +1,7 @@ { "$schema": "https://raw.githubusercontent.com/platformio/platformio-core/develop/platformio/assets/schema/library.json", "name": "ha-mqtt", - "version": "1.2.0", + "version": "1.3.0", "description": "Home Assistant classes for integration with MQTT auto discovery", "repository": { "type": "git", diff --git a/src/esp.h b/src/esp.h new file mode 100644 index 0000000..0fe1095 --- /dev/null +++ b/src/esp.h @@ -0,0 +1,57 @@ +#pragma once + +#include "TaskScheduler.h" +#include "ha.h" + +using namespace Ha; + +namespace HaESP { + struct { + bool heapStats = false; + bool restartInfo = false; + } activeSensors; + + Task tHeap(5 * TASK_MINUTE, TASK_FOREVER, []() { + Sensor::mapSensors["heap_fragmentation"]->updateState(to_string(ESP.getHeapFragmentation()).c_str()); + Sensor::mapSensors["heap_free"]->updateState(to_string(ESP.getFreeHeap()).c_str()); + Sensor::mapSensors["heap_max_free_block"]->updateState(to_string(ESP.getMaxFreeBlockSize()).c_str()); + }, &ts); + + Task tRestartInfo(TASK_IMMEDIATE, TASK_ONCE, []() { + Sensor::mapSensors["restart_reason"]->updateState(ESP.getResetReason().c_str()); + }, &ts); + + template + Builder& heapStats(Builder& builder) { + builder.addDiagnostic(Builder::instance(new Sensor{ "Heap fragmentation", "heap_fragmentation" }) + .withUnitMeasure("%") + .withPrecision(0) + .build()); + builder.addDiagnostic(Builder::instance(new Sensor{ "Heap free", "heap_free" }) + .withDeviceClass("data_size") + .withUnitMeasure("B") + .withPrecision(0) + .build() + ); + builder.addDiagnostic(Builder::instance(new Sensor{ "Heap max free block", "heap_max_free_block" }) + .withDeviceClass("data_size") + .withUnitMeasure("B") + .withPrecision(0) + .build() + ); + activeSensors.heapStats = true; + return builder; + } + + template + Builder& restartInfo(Builder& builder) { + builder.addDiagnostic(Builder::instance((new Sensor{ "Restart reason", "restart_reason" })).build()); + activeSensors.restartInfo = true; + return builder; + } + + void enableSensors() { + if (activeSensors.heapStats) tHeap.enable(); + if (activeSensors.restartInfo) tRestartInfo.enable(); + } +} \ No newline at end of file diff --git a/src/ha.h b/src/ha.h index c526e6d..df756bc 100644 --- a/src/ha.h +++ b/src/ha.h @@ -93,6 +93,7 @@ namespace Ha { JsonPairs jsonStrings; DeviceConfig* mainDevice = nullptr; static List components; + bool multiValueComponent = false; Component(const char* name, const char* id, const char* type) : name(name), id((char*)id), type(type) { components.add(this); @@ -180,7 +181,7 @@ namespace Ha { return *this; } - Builder& withUnitMseasure(const char* value) { + Builder& withUnitMeasure(const char* value) { cmp->unitMeasure = value; return *this; } @@ -213,6 +214,7 @@ namespace Ha { Builder& addSecondary(Component* c) { if (cmp->mainDevice) c->mainDevice = &DeviceConfig::create(cmp->mainDevice->id).withName(cmp->mainDevice->name); + if (!strcmp(cmp->id, c->id)) c->multiValueComponent = true; return *this; } @@ -221,6 +223,10 @@ namespace Ha { return addSecondary(c); } + Builder& addPreconfigured(Builder& (*factoryBuilder)(Builder& builder)) { + return factoryBuilder(*this); + } + Builder& addConfiguration(Component* c) { c->entityCategory = "config"; return addSecondary(c); @@ -354,7 +360,7 @@ namespace Ha { } void buildUniqueId(char* uniqueId) override { - if (deviceClass) { + if (multiValueComponent && deviceClass) { sprintf(uniqueId, "%s_%s_%s", MAIN_DEVICE_ID, deviceClass, id); } else { Component::buildUniqueId(uniqueId); @@ -362,7 +368,7 @@ namespace Ha { } void buildConfigTopic() override { - if (deviceClass) { + if (multiValueComponent && deviceClass) { sprintf(configTopic, "homeassistant/%s/%s/%s_%s/config", type, MAIN_DEVICE_ID, deviceClass, id); } else { Component::buildConfigTopic(); diff --git a/src/mqtt.h b/src/mqtt.h index 66e8d46..9f2be03 100644 --- a/src/mqtt.h +++ b/src/mqtt.h @@ -2,11 +2,14 @@ #include #include +#include +#include "esp.h" #define MAIN_TOPIC "homeassistant/+/" MAIN_DEVICE_ID "/#" -namespace Mqtt { +using namespace Ha; +namespace Mqtt { AsyncMqttClient client; Task tReConnect(TASK_MINUTE, TASK_FOREVER, []{ @@ -28,6 +31,7 @@ namespace Mqtt { if (firstTime) { Component::components.forEach([](Component* c) { c->publishConfig(); }); AbstractBuilder::deleteAll(); + HaESP::enableSensors(); firstTime = false; } }