#include "ArduinoHADefines.h" #include "HADevice.h" #include "HAMqtt.h" #include "utils/HAUtils.h" #include "utils/HASerializer.h" #define HADEVICE_INIT \ _ownsUniqueId(false), \ _serializer(new HASerializer(nullptr, 5)), \ _availabilityTopic(nullptr), \ _sharedAvailability(false), \ _available(true) // device will be available by default HADevice::HADevice() : _uniqueId(nullptr), HADEVICE_INIT { } HADevice::HADevice(const char* uniqueId) : _uniqueId(uniqueId), HADEVICE_INIT { _serializer->set(AHATOFSTR(HADeviceIdentifiersProperty), _uniqueId); } HADevice::HADevice(const byte* uniqueId, const uint16_t length) : _uniqueId(HAUtils::byteArrayToStr(uniqueId, length)), HADEVICE_INIT { _ownsUniqueId = true; _serializer->set(AHATOFSTR(HADeviceIdentifiersProperty), _uniqueId); } HADevice::~HADevice() { delete _serializer; if (_availabilityTopic) { delete _availabilityTopic; } if (_ownsUniqueId) { delete[] _uniqueId; } } bool HADevice::setUniqueId(const byte* uniqueId, const uint16_t length) { if (_uniqueId) { return false; // unique ID cannot be changed at runtime once it's set } _uniqueId = HAUtils::byteArrayToStr(uniqueId, length); _ownsUniqueId = true; _serializer->set(AHATOFSTR(HADeviceIdentifiersProperty), _uniqueId); return true; } void HADevice::setManufacturer(const char* manufacturer) { _serializer->set(AHATOFSTR(HADeviceManufacturerProperty), manufacturer); } void HADevice::setModel(const char* model) { _serializer->set(AHATOFSTR(HADeviceModelProperty), model); } void HADevice::setName(const char* name) { _serializer->set(AHATOFSTR(HANameProperty), name); } void HADevice::setSoftwareVersion(const char* softwareVersion) { _serializer->set( AHATOFSTR(HADeviceSoftwareVersionProperty), softwareVersion ); } void HADevice::setAvailability(bool online) { _available = online; publishAvailability(); } bool HADevice::enableSharedAvailability() { if (_sharedAvailability) { return true; // already enabled } const uint16_t topicLength = HASerializer::calculateDataTopicLength( nullptr, AHATOFSTR(HAAvailabilityTopic) ); if (topicLength == 0) { return false; } _availabilityTopic = new char[topicLength]; if (HASerializer::generateDataTopic( _availabilityTopic, nullptr, AHATOFSTR(HAAvailabilityTopic) ) > 0) { _sharedAvailability = true; return true; } return false; } void HADevice::enableLastWill() { HAMqtt* mqtt = HAMqtt::instance(); if (!mqtt || !_availabilityTopic) { return; } mqtt->setLastWill( _availabilityTopic, "offline", true ); } void HADevice::publishAvailability() const { HAMqtt* mqtt = HAMqtt::instance(); if (!_availabilityTopic || !mqtt) { return; } const char* payload = _available ? HAOnline : HAOffline; const uint16_t length = strlen_P(payload); if (mqtt->beginPublish(_availabilityTopic, length, true)) { mqtt->writePayload(AHATOFSTR(payload)); mqtt->endPublish(); } }