HASwitch improvements

This commit is contained in:
Dawid Chyrzynski
2020-12-04 22:32:25 +01:00
parent f4b35666ce
commit 44cad44512
2 changed files with 86 additions and 56 deletions
+39 -52
View File
@@ -34,7 +34,7 @@ void HASwitch::onMqttConnected()
}
publishConfig();
publishCurrentState();
publishState(_currentState);
subscribeCommandTopic();
}
@@ -44,7 +44,9 @@ void HASwitch::onMqttMessage(
const uint16_t& length
)
{
// todo: find a faster way of topic's verification
if (strlen(_name) == 0) {
return;
}
static const char Slash[] PROGMEM = {"/"};
uint8_t suffixLength = strlen(_name) + strlen(CommandTopic) + 3; // two slashes + null terminator
@@ -61,35 +63,27 @@ void HASwitch::onMqttMessage(
}
}
void HASwitch::setState(bool state)
bool HASwitch::setState(bool state)
{
if (state) {
turnOn();
} else {
turnOff();
if (_currentState == state) {
return true;
}
}
void HASwitch::turnOn()
{
_currentState = true;
triggerCallback(_currentState);
publishCurrentState();
}
if (strlen(_name) == 0) {
return false;
}
void HASwitch::turnOff()
{
_currentState = false;
triggerCallback(_currentState);
publishCurrentState();
if (publishState(state)) {
_currentState = state;
triggerCallback(_currentState);
return true;
}
return false;
}
void HASwitch::onStateChanged(HASWITCH_CALLBACK)
{
if (_stateCallback != nullptr) {
return; // only one callback may be assigned to the switch
}
_stateCallback = callback;
}
@@ -139,10 +133,10 @@ void HASwitch::publishConfig()
}
}
void HASwitch::publishCurrentState()
bool HASwitch::publishState(bool state)
{
if (strlen(_name) == 0) {
return;
return false;
}
const uint16_t& topicSize = calculateTopicLength(
@@ -151,7 +145,7 @@ void HASwitch::publishCurrentState()
StateTopic
);
if (topicSize == 0) {
return;
return false;
}
char topic[topicSize];
@@ -163,10 +157,10 @@ void HASwitch::publishCurrentState()
);
if (strlen(topic) == 0) {
return;
return false;
}
mqtt()->publish(topic, (_currentState ? StateOn : StateOff), true);
return mqtt()->publish(topic, (state ? StateOn : StateOff), true);
}
void HASwitch::subscribeCommandTopic()
@@ -225,21 +219,21 @@ uint16_t HASwitch::calculateSerializedLength(const char* serializedDevice) const
strlen(_name) + 10; // 10 - length of the JSON data for this field
// unique ID
if (serializedDevice == nullptr) {
size += strlen(_name) + 13; // 13 - length of the JSON data for this field
} else {
size += strlen(mqtt()->getDevice()->getUniqueId());
size += strlen(_name) + 14; // 14 - length of the JSON data for this field
size += strlen(mqtt()->getDevice()->getUniqueId());
size += strlen(_name) + 14; // 14 - length of the JSON data for this field
// device
size += strlen(serializedDevice) + 7; // 7 - length of the JSON data for this field
}
// device
size += strlen(serializedDevice) + 7; // 7 - length of the JSON data for this field
return size;
}
bool HASwitch::writeSerializedTrigger(const char* serializedDevice) const
{
if (serializedDevice == nullptr) {
return false;
}
static const char QuotationSign[] PROGMEM = {"\""};
// command topic
@@ -313,30 +307,23 @@ bool HASwitch::writeSerializedTrigger(const char* serializedDevice) const
// unique ID
{
static const char Underscore[] PROGMEM = {"_"};
static const char DataBefore[] PROGMEM = {",\"uniq_id\":\""};
const HADevice* device = mqtt()->getDevice();
uint8_t uniqueIdLength = strlen(_name) + strlen(device->getUniqueId()) + 2; // underscore and null temrinator
char uniqueId[uniqueIdLength];
strcpy(uniqueId, _name);
strcat_P(uniqueId, Underscore);
strcat(uniqueId, device->getUniqueId());
mqtt()->writePayload_P(DataBefore);
if (device == nullptr) {
mqtt()->writePayload(_name, strlen(_name));
} else {
static const char Underscore[] PROGMEM = {"_"};
uint8_t uniqueIdLength = strlen(_name) + strlen(device->getUniqueId()) + 2; // underscore and null temrinator
char uniqueId[uniqueIdLength];
strcpy(uniqueId, _name);
strcat_P(uniqueId, Underscore);
strcat(uniqueId, device->getUniqueId());
mqtt()->writePayload(uniqueId, strlen(uniqueId));
}
mqtt()->writePayload(uniqueId, strlen(uniqueId));
mqtt()->writePayload_P(QuotationSign);
}
// device
if (serializedDevice != nullptr) {
{
static const char Data[] PROGMEM = {",\"dev\":"};
mqtt()->writePayload_P(Data);
+47 -4
View File
@@ -9,6 +9,13 @@
class HASwitch : public BaseDeviceType
{
public:
/**
* Initializes switch.
*
* @param name Name of the switch. Recommendes characters: [a-z0-9\-_]
* @param initialState Initial state of the switch.
It will be published right after "config" message in order to update HA state.
*/
HASwitch(
const char* name,
bool initialState,
@@ -16,25 +23,61 @@ public:
);
virtual ~HASwitch();
/**
* Publishes configuration of the sensor to the MQTT.
*/
virtual void onMqttConnected() override;
/**
* Processes message received from the MQTT broker.
* The method updates state of the switch (if message matches switch'es topic).
*/
virtual void onMqttMessage(
const char* topic,
const char* payload,
const uint16_t& length
) override;
/**
* Returns name of the switch assigned via constructor.
*/
inline const char* getName() const
{ return _name; }
void setState(bool state);
void turnOn();
void turnOff();
/**
* Changes state of the switch and publishes MQTT message.
* Please note that if a new value is the same as previous one,
* the MQTT message won't be published.
*
* @param state New state of the switch.
* @returns Returns true if MQTT message has been published successfully.
*/
bool setState(bool state);
/**
* Alias for setState(true).
*/
inline bool turnOn()
{ return setState(true); }
/**
* Alias for setState(false).
*/
inline bool turnOff()
{ return setState(false); }
/**
* Registers callback that will be called each time the value of the switch changes.
* Please note that it's not possible to register multiple callbacks for the same switch.
*
* @param callback
*/
void onStateChanged(HASWITCH_CALLBACK);
private:
void triggerCallback(bool state);
void publishConfig();
void publishCurrentState();
bool publishState(bool state);
void subscribeCommandTopic();
uint16_t calculateSerializedLength(const char* serializedDevice) const;
bool writeSerializedTrigger(const char* serializedDevice) const;