mirror of
https://github.com/mrcory/arduino-home-assistant.git
synced 2026-08-02 15:24:26 -04:00
add support for tag scanner
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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
@@ -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(
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user