From dbedf0d2f1958766a6e6b68b9154f10b58140de1 Mon Sep 17 00:00:00 2001 From: Nicu Hodos Date: Mon, 7 Oct 2024 22:01:25 +0200 Subject: [PATCH 1/6] fix typo --- library.json | 2 +- src/ha.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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/ha.h b/src/ha.h index c526e6d..c9a99c4 100644 --- a/src/ha.h +++ b/src/ha.h @@ -180,7 +180,7 @@ namespace Ha { return *this; } - Builder& withUnitMseasure(const char* value) { + Builder& withUnitMeasure(const char* value) { cmp->unitMeasure = value; return *this; } From 7327533b2420f1457547341c92881c756cfacf47 Mon Sep 17 00:00:00 2001 From: Nicu Hodos Date: Mon, 7 Oct 2024 22:06:26 +0200 Subject: [PATCH 2/6] detect a multi value sensor based on common id --- src/ha.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ha.h b/src/ha.h index c9a99c4..37ec441 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); @@ -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; } @@ -354,7 +356,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 +364,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(); From f1901a1b5318449fd901d3cbef14d8ae75c6731b Mon Sep 17 00:00:00 2001 From: Nicu Hodos Date: Tue, 8 Oct 2024 20:56:27 +0200 Subject: [PATCH 3/6] add support for precondfigured components - heap stats --- src/esp.h | 36 ++++++++++++++++++++++++++++++++++++ src/ha.h | 4 ++++ 2 files changed, 40 insertions(+) create mode 100644 src/esp.h diff --git a/src/esp.h b/src/esp.h new file mode 100644 index 0000000..1a97c90 --- /dev/null +++ b/src/esp.h @@ -0,0 +1,36 @@ +#pragma once + +#include "TaskScheduler.h" +#include "ha.h" + +using namespace Ha; + +namespace HaESP { + Task tHeap(1 * 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); + + 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() + ); + tHeap.enable(); + return builder; + } +} \ No newline at end of file diff --git a/src/ha.h b/src/ha.h index 37ec441..df756bc 100644 --- a/src/ha.h +++ b/src/ha.h @@ -223,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); From 6468db55650f3d236960eb54221c1bebda32b51a Mon Sep 17 00:00:00 2001 From: Nicu Hodos Date: Tue, 8 Oct 2024 21:03:55 +0200 Subject: [PATCH 4/6] add restart reason sensor --- src/esp.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/esp.h b/src/esp.h index 1a97c90..db65f76 100644 --- a/src/esp.h +++ b/src/esp.h @@ -12,6 +12,10 @@ namespace HaESP { 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" }) @@ -33,4 +37,11 @@ namespace HaESP { tHeap.enable(); return builder; } + + template + Builder& restartInfo(Builder& builder) { + builder.addDiagnostic(Builder::instance((new Sensor{"Restart reason", "restart_reason"})).build()); + tRestartInfo.enable(); + return builder; + } } \ No newline at end of file From 2456ae1dc880757fd79d1bdc2fb7a04262738e6c Mon Sep 17 00:00:00 2001 From: Nicu Hodos Date: Wed, 9 Oct 2024 00:02:41 +0200 Subject: [PATCH 5/6] use StatusRequest to signal mqtt connectivity - fixes updates being published only after mqtt has been connected --- src/esp.h | 15 +++++++++------ src/mqtt.h | 6 ++++++ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/esp.h b/src/esp.h index db65f76..00c4d51 100644 --- a/src/esp.h +++ b/src/esp.h @@ -1,20 +1,21 @@ #pragma once #include "TaskScheduler.h" +#include "mqtt.h" #include "ha.h" using namespace Ha; namespace HaESP { - Task tHeap(1 * TASK_MINUTE, TASK_FOREVER, []() { + 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); + Task tRestartInfo(TASK_IMMEDIATE, TASK_ONCE, []() { + Sensor::mapSensors["restart_reason"]->updateState(ESP.getResetReason().c_str()); + }, &ts); template Builder& heapStats(Builder& builder) { @@ -34,14 +35,16 @@ namespace HaESP { .withPrecision(0) .build() ); + Mqtt::connectedStatus.setWaiting(); tHeap.enable(); return builder; } template Builder& restartInfo(Builder& builder) { - builder.addDiagnostic(Builder::instance((new Sensor{"Restart reason", "restart_reason"})).build()); - tRestartInfo.enable(); + builder.addDiagnostic(Builder::instance((new Sensor{ "Restart reason", "restart_reason" })).build()); + Mqtt::connectedStatus.setWaiting(); + tRestartInfo.waitFor(&Mqtt::connectedStatus); return builder; } } \ No newline at end of file diff --git a/src/mqtt.h b/src/mqtt.h index 66e8d46..9572780 100644 --- a/src/mqtt.h +++ b/src/mqtt.h @@ -2,10 +2,15 @@ #include #include +#include +#include "ha.h" #define MAIN_TOPIC "homeassistant/+/" MAIN_DEVICE_ID "/#" +using namespace Ha; + namespace Mqtt { + StatusRequest connectedStatus; AsyncMqttClient client; @@ -61,6 +66,7 @@ namespace Mqtt { client.subscribe(MAIN_TOPIC, 0); tReConnect.disable(); Serial.println("Connected to MQTT"); + connectedStatus.signal(); if (onConnected) onConnected(); }); client.onDisconnect([onDisconnected](AsyncMqttClientDisconnectReason reason) { From 8f534cce940209e29928a892ddd40aea279e84b4 Mon Sep 17 00:00:00 2001 From: Nicu Hodos Date: Wed, 9 Oct 2024 08:43:45 +0200 Subject: [PATCH 6/6] keep track of enabled sensors using struct --- src/esp.h | 17 ++++++++++++----- src/mqtt.h | 6 ++---- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/esp.h b/src/esp.h index 00c4d51..0fe1095 100644 --- a/src/esp.h +++ b/src/esp.h @@ -1,12 +1,16 @@ #pragma once #include "TaskScheduler.h" -#include "mqtt.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()); @@ -35,16 +39,19 @@ namespace HaESP { .withPrecision(0) .build() ); - Mqtt::connectedStatus.setWaiting(); - tHeap.enable(); + activeSensors.heapStats = true; return builder; } template Builder& restartInfo(Builder& builder) { builder.addDiagnostic(Builder::instance((new Sensor{ "Restart reason", "restart_reason" })).build()); - Mqtt::connectedStatus.setWaiting(); - tRestartInfo.waitFor(&Mqtt::connectedStatus); + 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/mqtt.h b/src/mqtt.h index 9572780..9f2be03 100644 --- a/src/mqtt.h +++ b/src/mqtt.h @@ -3,15 +3,13 @@ #include #include #include -#include "ha.h" +#include "esp.h" #define MAIN_TOPIC "homeassistant/+/" MAIN_DEVICE_ID "/#" using namespace Ha; namespace Mqtt { - StatusRequest connectedStatus; - AsyncMqttClient client; Task tReConnect(TASK_MINUTE, TASK_FOREVER, []{ @@ -33,6 +31,7 @@ namespace Mqtt { if (firstTime) { Component::components.forEach([](Component* c) { c->publishConfig(); }); AbstractBuilder::deleteAll(); + HaESP::enableSensors(); firstTime = false; } } @@ -66,7 +65,6 @@ namespace Mqtt { client.subscribe(MAIN_TOPIC, 0); tReConnect.disable(); Serial.println("Connected to MQTT"); - connectedStatus.signal(); if (onConnected) onConnected(); }); client.onDisconnect([onDisconnected](AsyncMqttClientDisconnectReason reason) {