add support for tag scanner

This commit is contained in:
Dawid Chyrzynski
2020-12-04 21:04:22 +01:00
parent 5681c549d5
commit 0315aacc56
6 changed files with 167 additions and 9 deletions
+1
View File
@@ -1,4 +1,5 @@
#include "HADevice.h"
#include "HAMqtt.h"
#include "device-types/HASwitch.h"
#include "device-types/HATagScanner.h"
#include "device-types/HATriggers.h"
+1
View File
@@ -7,6 +7,7 @@
// Here is the list of available defines:
// #define NO_HA_TRIGGERS
// #define NO_HA_TAG_SCANNER
// #define NO_HA_SWITCH
// In order to get them working just put proper #define before including the ArduinoHA.h header
+2 -2
View File
@@ -6,7 +6,7 @@
#include "ArduinoHADefines.h"
#include "device-types/BaseDeviceType.h"
static const char DefaultDiscoveryPrefix[] PROGMEM = {"homeassistant"};
static const char* DefaultDiscoveryPrefix = "homeassistant";
HAMqtt* instance = nullptr;
void onMessageReceived(char* topic, uint8_t* payload, uint16_t length)
@@ -24,6 +24,7 @@ HAMqtt::HAMqtt(const char* clientId, Client& netClient, HADevice& device) :
_device(device),
_hasDevice(true),
_initialized(false),
_discoveryPrefix(DefaultDiscoveryPrefix),
_mqtt(new PubSubClient(netClient)),
_serverIp(new IPAddress()),
_serverPort(0),
@@ -34,7 +35,6 @@ HAMqtt::HAMqtt(const char* clientId, Client& netClient, HADevice& device) :
_devicesTypes(nullptr)
{
instance = this;
strcpy_P(_discoveryPrefix, DefaultDiscoveryPrefix);
}
bool HAMqtt::begin(
+131
View File
@@ -0,0 +1,131 @@
#ifndef NO_HA_TAG_SCANNER
#include "HATagScanner.h"
#include "../ArduinoHADefines.h"
#include "../HAMqtt.h"
#include "../HADevice.h"
#include "../HAUtils.h"
// todo: move all variables to progmem
static const char* HAComponentName = "tag";
HATagScanner::HATagScanner(const char* name, HAMqtt& mqtt) :
BaseDeviceType(mqtt),
_name(name)
{
}
HATagScanner::~HATagScanner()
{
}
void HATagScanner::onMqttConnected()
{
if (strlen(_name) == 0) {
return;
}
publishConfig();
}
bool HATagScanner::tagScanned(const char* tag)
{
const uint16_t& topicSize = calculateTopicLength(
HAComponentName,
_name,
EventTopic
);
char topic[topicSize];
generateTopic(
topic,
HAComponentName,
_name,
EventTopic
);
return mqtt()->publish(topic, tag);
}
void HATagScanner::publishConfig()
{
const HADevice* device = mqtt()->getDevice();
const uint16_t& deviceLength = device->calculateSerializedLength();
char serializedDevice[deviceLength];
device->serialize(serializedDevice);
const uint16_t& topicLength = calculateTopicLength(HAComponentName, _name, ConfigTopic);
const uint16_t& dataLength = calculateSerializedLength(serializedDevice);
char topic[topicLength];
generateTopic(topic, HAComponentName, _name, ConfigTopic);
if (mqtt()->beginPublish(topic, dataLength, true)) {
writeSerializedTrigger(serializedDevice);
mqtt()->endPublish();
}
}
uint16_t HATagScanner::calculateSerializedLength(
const char* serializedDevice
) const
{
const uint16_t& eventTopicLength = calculateTopicLength(
HAComponentName,
_name,
EventTopic,
false
);
uint16_t size =
2 + // opening and closing bracket (without null terminator)
eventTopicLength + 6 + // 6 - length of the JSON data for this field
strlen(serializedDevice) + 7; // 7 - length of the JSON data for this field
return size;
}
bool HATagScanner::writeSerializedTrigger(const char* serializedDevice) const
{
static const char QuotationSign[] PROGMEM = {"\""};
// command topic
{
const uint16_t& topicSize = calculateTopicLength(
HAComponentName,
_name,
EventTopic
);
char topic[topicSize];
generateTopic(
topic,
HAComponentName,
_name,
EventTopic
);
static const char DataBefore[] PROGMEM = {"{\"t\":\""};
mqtt()->writePayload_P(DataBefore);
mqtt()->writePayload(topic, strlen(topic));
mqtt()->writePayload_P(QuotationSign);
}
// device
if (serializedDevice != nullptr) {
static const char Data[] PROGMEM = {",\"dev\":"};
mqtt()->writePayload_P(Data);
mqtt()->writePayload(serializedDevice, strlen(serializedDevice));
}
{
static const char Data[] PROGMEM = {"}"};
mqtt()->writePayload_P(Data);
}
return true;
}
#endif
+25
View File
@@ -0,0 +1,25 @@
#ifndef HATAGSCANNER_H
#ifndef NO_HA_TAG_SCANNER
#define HATAGSCANNER_H
#include "BaseDeviceType.h"
class HATagScanner : public BaseDeviceType
{
public:
HATagScanner(const char* name, HAMqtt& mqtt);
virtual ~HATagScanner();
virtual void onMqttConnected() override;
bool tagScanned(const char* tag);
private:
void publishConfig();
uint16_t calculateSerializedLength(const char* serializedDevice) const;
bool writeSerializedTrigger(const char* serializedDevice) const;
const char* _name;
};
#endif
#endif
+7 -7
View File
@@ -12,11 +12,7 @@ HATriggers::HATriggers(HAMqtt& mqtt) :
_triggers(nullptr),
_triggersNb(0)
{
#if defined(ARDUINOHA_DEBUG)
if (mqtt.getDevice() == nullptr) {
Serial.println(F("HATriggers requires HADevice to be defined."));
}
#endif
}
HATriggers::~HATriggers()
@@ -34,7 +30,7 @@ void HATriggers::onMqttConnected()
bool HATriggers::add(const char* type, const char* subtype)
{
if (mqtt()->getDevice() == nullptr) {
return false; // device is required for triggers
return false;
}
HATrigger* triggers = realloc(_triggers, sizeof(HATrigger) * (_triggersNb + 1));
@@ -73,7 +69,11 @@ bool HATriggers::trigger(const char* type, const char* subtype)
return false;
}
const uint16_t& size = calculateTopicLength(HAComponentName, trigger, EventTopic);
const uint16_t& size = calculateTopicLength(
HAComponentName,
trigger,
EventTopic
);
char topic[size];
generateTopic(topic, HAComponentName, trigger, EventTopic);