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