update HATriggers and BaseDeviceType

This commit is contained in:
Dawid Chyrzynski
2020-12-03 18:02:44 +01:00
parent c794f0d0db
commit f142eb41e8
4 changed files with 106 additions and 57 deletions
+15 -18
View File
@@ -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
+5 -8
View File
@@ -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;
};
+69 -27
View File
@@ -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
+17 -4
View File
@@ -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