mirror of
https://github.com/mrcory/arduino-home-assistant.git
synced 2026-08-02 15:24:26 -04:00
update HATriggers and BaseDeviceType
This commit is contained in:
@@ -2,11 +2,10 @@
|
||||
#include "../HAMqtt.h"
|
||||
#include "../HADevice.h"
|
||||
|
||||
const char* BaseDeviceType::ConfigTopic = "config";
|
||||
const char* BaseDeviceType::ConfigTopic = "config"; // todo: move to progmem
|
||||
const char* BaseDeviceType::EventTopic = "event";
|
||||
|
||||
BaseDeviceType::BaseDeviceType(const char* uniqueId, HAMqtt& mqtt) :
|
||||
_uniqueId(uniqueId),
|
||||
BaseDeviceType::BaseDeviceType(HAMqtt& mqtt) :
|
||||
_mqtt(mqtt)
|
||||
{
|
||||
_mqtt.addDeviceType(this);
|
||||
@@ -18,9 +17,8 @@ BaseDeviceType::~BaseDeviceType()
|
||||
}
|
||||
|
||||
uint16_t BaseDeviceType::calculateTopicLength(
|
||||
const char* haNamespace,
|
||||
const char* type,
|
||||
const char* subtype,
|
||||
const char* component,
|
||||
const char* objectId,
|
||||
const char* suffix,
|
||||
bool includeNullTerminator
|
||||
) const
|
||||
@@ -29,11 +27,15 @@ uint16_t BaseDeviceType::calculateTopicLength(
|
||||
const char* prefix = _mqtt.getDiscoveryPrefix();
|
||||
uint16_t size =
|
||||
strlen(prefix) + 1 + // with slash
|
||||
strlen(haNamespace) + 1 + // with slash
|
||||
strlen(type) + 1 + // with underscore
|
||||
strlen(subtype) + 1 + // with slash
|
||||
strlen(component) + 1 + // with slash
|
||||
strlen(suffix); // with null terminator
|
||||
|
||||
if (objectId != nullptr) {
|
||||
size += strlen(objectId) + 1; // with slash
|
||||
} else {
|
||||
size += 1; // slash
|
||||
}
|
||||
|
||||
if (_mqtt.getDevice() != nullptr) {
|
||||
size += strlen(_mqtt.getDevice()->getUniqueId()) + 1; // with slash
|
||||
}
|
||||
@@ -47,20 +49,17 @@ uint16_t BaseDeviceType::calculateTopicLength(
|
||||
|
||||
uint16_t BaseDeviceType::generateTopic(
|
||||
char* output,
|
||||
const char* haNamespace,
|
||||
const char* type,
|
||||
const char* subtype,
|
||||
const char* component,
|
||||
const char* objectId,
|
||||
const char* suffix
|
||||
) const
|
||||
{
|
||||
// prevent from wasting RAM
|
||||
static const char Slash[] PROGMEM = {"/"};
|
||||
static const char Underscore[] PROGMEM = {"_"};
|
||||
|
||||
const char* prefix = _mqtt.getDiscoveryPrefix();
|
||||
strcpy(output, prefix);
|
||||
strcat_P(output, Slash);
|
||||
strcat(output, haNamespace);
|
||||
strcat(output, component);
|
||||
strcat_P(output, Slash);
|
||||
|
||||
if (_mqtt.getDevice() != nullptr) {
|
||||
@@ -68,9 +67,7 @@ uint16_t BaseDeviceType::generateTopic(
|
||||
strcat_P(output, Slash);
|
||||
}
|
||||
|
||||
strcat(output, subtype);
|
||||
strcat_P(output, Underscore);
|
||||
strcat(output, type);
|
||||
strcat(output, objectId);
|
||||
strcat_P(output, Slash);
|
||||
strcat(output, suffix);
|
||||
return strlen(output) + 1; // size with null terminator
|
||||
|
||||
@@ -11,7 +11,7 @@ public:
|
||||
static const char* ConfigTopic;
|
||||
static const char* EventTopic;
|
||||
|
||||
BaseDeviceType(const char* uniqueId, HAMqtt& mqtt);
|
||||
BaseDeviceType(HAMqtt& mqtt);
|
||||
virtual ~BaseDeviceType();
|
||||
|
||||
virtual void onMqttConnected() = 0;
|
||||
@@ -23,23 +23,20 @@ protected:
|
||||
{ return &_mqtt; }
|
||||
|
||||
virtual uint16_t calculateTopicLength(
|
||||
const char* haNamespace,
|
||||
const char* type,
|
||||
const char* subtype,
|
||||
const char* component,
|
||||
const char* objectId,
|
||||
const char* suffix,
|
||||
bool includeNullTerminator = true
|
||||
) const final;
|
||||
|
||||
virtual uint16_t generateTopic(
|
||||
char* output,
|
||||
const char* haNamespace,
|
||||
const char* type,
|
||||
const char* subtype,
|
||||
const char* component,
|
||||
const char* objectId,
|
||||
const char* suffix
|
||||
) const final;
|
||||
|
||||
private:
|
||||
const char* _uniqueId;
|
||||
HAMqtt& _mqtt;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
#ifndef NO_HA_TRIGGERS
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "HATriggers.h"
|
||||
#include "../ArduinoHADefines.h"
|
||||
#include "../HAMqtt.h"
|
||||
#include "../HADevice.h"
|
||||
|
||||
const char* HATriggers::MqttNamespace = "device_automation";
|
||||
static const char* HAComponentName = "device_automation"; // todo: move to progmem
|
||||
|
||||
HATriggers::HATriggers(HAMqtt& mqtt) :
|
||||
BaseDeviceType(nullptr, mqtt),
|
||||
BaseDeviceType(mqtt),
|
||||
_triggers(nullptr),
|
||||
_triggersNb(0)
|
||||
{
|
||||
@@ -20,27 +22,30 @@ HATriggers::HATriggers(HAMqtt& mqtt) :
|
||||
|
||||
HATriggers::~HATriggers()
|
||||
{
|
||||
free(_triggers);
|
||||
if (_triggers != nullptr) {
|
||||
free(_triggers);
|
||||
}
|
||||
}
|
||||
|
||||
void HATriggers::onMqttConnected()
|
||||
{
|
||||
const HADevice* device = mqtt()->getDevice();
|
||||
uint16_t deviceLength = (device == nullptr ? 0 : device->calculateSerializedLength());
|
||||
char serializedDevice[deviceLength];
|
||||
|
||||
if (device != nullptr) {
|
||||
device->serialize(serializedDevice);
|
||||
if (device == nullptr) {
|
||||
return; // device is required for triggers
|
||||
}
|
||||
|
||||
uint16_t deviceLength = device->calculateSerializedLength();
|
||||
char serializedDevice[deviceLength];
|
||||
device->serialize(serializedDevice);
|
||||
|
||||
for (uint8_t i = 0; i < _triggersNb; i++) {
|
||||
const HATrigger* trigger = &_triggers[i];
|
||||
const uint16_t& topicLength = calculateTopicLength(MqttNamespace, trigger->type, trigger->subtype, ConfigTopic);
|
||||
const uint16_t& topicLength = calculateTopicLength(HAComponentName, trigger, ConfigTopic);
|
||||
const uint16_t& dataLength = calculateSerializedLength(trigger, serializedDevice);
|
||||
|
||||
char topic[topicLength];
|
||||
char data[dataLength];
|
||||
generateTopic(topic, MqttNamespace, trigger->type, trigger->subtype, ConfigTopic);
|
||||
generateTopic(topic, HAComponentName, trigger, ConfigTopic);
|
||||
|
||||
if (mqtt()->beginPublish(topic, dataLength, true)) {
|
||||
writeSerializedTrigger(trigger, serializedDevice);
|
||||
@@ -78,36 +83,73 @@ bool HATriggers::add(const char* type, const char* subtype)
|
||||
|
||||
bool HATriggers::trigger(const char* type, const char* subtype)
|
||||
{
|
||||
bool found = false;
|
||||
HATrigger* trigger = nullptr;
|
||||
for (uint8_t i = 0; i < _triggersNb; i++) {
|
||||
const HATrigger* trigger = &_triggers[i];
|
||||
if (strcmp(trigger->type, type) == 0 &&
|
||||
strcmp(trigger->subtype, subtype) == 0) {
|
||||
found = true;
|
||||
if (strcmp(_triggers[i].type, type) == 0 &&
|
||||
strcmp(_triggers[i].subtype, subtype) == 0) {
|
||||
trigger = &_triggers[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
if (trigger == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint16_t& size = calculateTopicLength(MqttNamespace, type, subtype, EventTopic);
|
||||
const uint16_t& size = calculateTopicLength(HAComponentName, trigger, EventTopic);
|
||||
char topic[size];
|
||||
|
||||
generateTopic(topic, MqttNamespace, type, subtype, EventTopic);
|
||||
generateTopic(topic, HAComponentName, trigger, EventTopic);
|
||||
mqtt()->publish(topic, "");
|
||||
}
|
||||
|
||||
uint16_t HATriggers::calculateTopicLength(
|
||||
const char* component,
|
||||
HATrigger *trigger,
|
||||
const char* suffix,
|
||||
bool includeNullTerminator
|
||||
) const
|
||||
{
|
||||
uint8_t length = strlen(trigger->type) + strlen(trigger->subtype) + 1; // + underscore
|
||||
return BaseDeviceType::calculateTopicLength(
|
||||
component,
|
||||
nullptr,
|
||||
suffix,
|
||||
includeNullTerminator
|
||||
) + length;
|
||||
}
|
||||
|
||||
uint16_t HATriggers::generateTopic(
|
||||
char* output,
|
||||
const char* component,
|
||||
HATrigger *trigger,
|
||||
const char* suffix
|
||||
) const
|
||||
{
|
||||
static const char Underscore[] PROGMEM = {"_"};
|
||||
uint8_t length = strlen(trigger->type) + strlen(trigger->subtype) + 2; // slash + null terminator
|
||||
char objectId[length];
|
||||
|
||||
strcpy(objectId, trigger->subtype);
|
||||
strcat_P(objectId, Underscore);
|
||||
strcat(objectId, trigger->type);
|
||||
|
||||
return BaseDeviceType::generateTopic(
|
||||
output,
|
||||
component,
|
||||
objectId,
|
||||
suffix
|
||||
);
|
||||
}
|
||||
|
||||
uint16_t HATriggers::calculateSerializedLength(
|
||||
const HATrigger* trigger,
|
||||
const char* serializedDevice
|
||||
) const
|
||||
{
|
||||
const uint16_t& topicLength = calculateTopicLength(
|
||||
MqttNamespace,
|
||||
trigger->type,
|
||||
trigger->subtype,
|
||||
HAComponentName,
|
||||
trigger,
|
||||
EventTopic,
|
||||
false
|
||||
);
|
||||
@@ -141,16 +183,14 @@ bool HATriggers::writeSerializedTrigger(
|
||||
// topic
|
||||
{
|
||||
const uint16_t& topicSize = calculateTopicLength(
|
||||
MqttNamespace,
|
||||
trigger->type,
|
||||
trigger->subtype,
|
||||
HAComponentName,
|
||||
trigger,
|
||||
EventTopic
|
||||
);
|
||||
char eventTopic[topicSize];
|
||||
generateTopic(eventTopic,
|
||||
MqttNamespace,
|
||||
trigger->type,
|
||||
trigger->subtype,
|
||||
HAComponentName,
|
||||
trigger,
|
||||
EventTopic
|
||||
);
|
||||
|
||||
@@ -194,3 +234,5 @@ bool HATriggers::writeSerializedTrigger(
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
#ifndef HATRIGGERS_H
|
||||
#ifndef NO_HA_TRIGGERS
|
||||
#define HATRIGGERS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "BaseDeviceType.h"
|
||||
|
||||
struct HATrigger {
|
||||
@@ -13,8 +12,6 @@ struct HATrigger {
|
||||
class HATriggers : public BaseDeviceType
|
||||
{
|
||||
public:
|
||||
static const char* MqttNamespace;
|
||||
|
||||
HATriggers(HAMqtt& mqtt);
|
||||
virtual ~HATriggers();
|
||||
|
||||
@@ -23,6 +20,21 @@ public:
|
||||
bool add(const char* type, const char* subtype);
|
||||
bool trigger(const char* type, const char* subtype);
|
||||
|
||||
protected:
|
||||
uint16_t calculateTopicLength(
|
||||
const char* component,
|
||||
HATrigger *trigger,
|
||||
const char* suffix,
|
||||
bool includeNullTerminator = true
|
||||
) const;
|
||||
|
||||
uint16_t generateTopic(
|
||||
char* output,
|
||||
const char* component,
|
||||
HATrigger *trigger,
|
||||
const char* suffix
|
||||
) const;
|
||||
|
||||
private:
|
||||
uint16_t calculateSerializedLength(
|
||||
const HATrigger* trigger,
|
||||
@@ -39,3 +51,4 @@ private:
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user