Skip to content

Commit

Permalink
Zigbee2mqtt: fix power off lights on exit
Browse files Browse the repository at this point in the history
  • Loading branch information
awawa-dev committed Dec 29, 2024
1 parent 4a07528 commit 3730819
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 2 deletions.
2 changes: 2 additions & 0 deletions include/led-drivers/net/DriverNetZigbee2mqtt.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,11 @@ public slots:
std::atomic<int> _colorsFinished;
int _timeLogger;
QString _discoveryMessage;
int _mqttId;

std::mutex _mtx;
std::condition_variable _cv;

static int mqttId;
static bool isRegistered;
};
7 changes: 6 additions & 1 deletion include/mqtt/mqtt.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
#ifndef PCH_ENABLED
#include <QSet>
#include <QJsonDocument>
#include <QTimer>
#include <QTimer
#include <QStringList>
#include <map>
#endif

#include <utils/Logger.h>
Expand All @@ -30,6 +32,7 @@ public slots:

void handleSignalMqttSubscribe(bool subscribe, QString topic);
void handleSignalMqttPublish(QString topic, QString payload);
void handleSignalMqttLastWill(QString id, QStringList pairs);

private slots:
void connected();
Expand Down Expand Up @@ -61,6 +64,8 @@ private slots:
QJsonArray _resultArray;
bool _disableApiAccess;

std::map<QString, QStringList> _lastWill;

Logger* _log;
QMQTT::Client* _clientInstance;
};
3 changes: 3 additions & 0 deletions include/utils/GlobalSignals.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

#ifndef PCH_ENABLED
#include <QObject>
#include <QStringList>
#endif

#include <image/ColorRgb.h>
Expand Down Expand Up @@ -105,4 +106,6 @@ class GlobalSignals : public QObject
void SignalMqttReceived(QString topic, QString payload);

void SignalMqttPublish(QString topic, QString payload);

void SignalMqttLastWill(QString id, QStringList pairs);
};
2 changes: 2 additions & 0 deletions sources/hyperhdr/HyperHdrDaemon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,8 @@ void HyperHdrDaemon::freeObjects()
{
Info(_log, "Cleaning up HyperHdr before quit [preparing]");

emit GlobalSignals::getInstance()->SignalMqttLastWill(QString(), QStringList());

disconnect(GlobalSignals::getInstance(), nullptr, nullptr, nullptr);
disconnect(_instanceManager.get(), nullptr, nullptr, nullptr);
HyperHdrInstance::signalTerminateTriggered();
Expand Down
17 changes: 16 additions & 1 deletion sources/led-drivers/net/DriverNetZigbee2mqtt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ DriverNetZigbee2mqtt::DriverNetZigbee2mqtt(const QJsonObject& deviceConfig)
: LedDevice(deviceConfig),
_discoveryFinished(false),
_colorsFinished(0),
_timeLogger(0)
_timeLogger(0),
_mqttId(mqttId++)
{
}

Expand Down Expand Up @@ -60,6 +61,7 @@ bool DriverNetZigbee2mqtt::init(const QJsonObject& deviceConfig)
bool DriverNetZigbee2mqtt::powerOnOff(bool isOn)
{
QJsonDocument doc;
QStringList lastWill;

for (const auto& lamp : _zigInstance.lamps)
{
Expand All @@ -70,16 +72,28 @@ bool DriverNetZigbee2mqtt::powerOnOff(bool isOn)

doc.setObject(row);
emit GlobalSignals::getInstance()->SignalMqttPublish(topic, doc.toJson(QJsonDocument::Compact));

if (isOn)
{
row["state"] = "OFF";
doc.setObject(row);

lastWill.push_back(topic);
lastWill.push_back(doc.toJson(QJsonDocument::Compact));
}
}

if (_zigInstance.lamps.size() > 0)
{
QString lastWillId = QString("DriverNetZigbee2mqtt:%1").arg(_mqttId);
if (isOn)
{
emit GlobalSignals::getInstance()->SignalMqttLastWill(lastWillId, lastWill);
connect(GlobalSignals::getInstance(), &GlobalSignals::SignalMqttReceived, this, &DriverNetZigbee2mqtt::handlerSignalMqttReceived, Qt::DirectConnection);
}
else
{
emit GlobalSignals::getInstance()->SignalMqttLastWill(lastWillId, QStringList());
disconnect(GlobalSignals::getInstance(), &GlobalSignals::SignalMqttReceived, this, &DriverNetZigbee2mqtt::handlerSignalMqttReceived);
}
}
Expand Down Expand Up @@ -328,4 +342,5 @@ void DriverNetZigbee2mqtt::identify(const QJsonObject& params)
}
}

int DriverNetZigbee2mqtt::mqttId = 0;
bool DriverNetZigbee2mqtt::isRegistered = hyperhdr::leds::REGISTER_LED_DEVICE("zigbee2mqtt", "leds_group_2_network", DriverNetZigbee2mqtt::construct);
30 changes: 30 additions & 0 deletions sources/mqtt/mqtt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ mqtt::mqtt(const QJsonDocument& mqttConfig)
, _log(Logger::getInstance("MQTT"))
, _clientInstance(nullptr)
{
connect(GlobalSignals::getInstance(), &GlobalSignals::SignalMqttLastWill, this, &mqtt::handleSignalMqttLastWill, Qt::UniqueConnection);

handleSettingsUpdate(settings::type::MQTT, mqttConfig);
}

Expand Down Expand Up @@ -354,3 +356,31 @@ void mqtt::handleSignalMqttPublish(QString topic, QString payload)
_clientInstance->publish(message);
}
}

void mqtt::handleSignalMqttLastWill(QString id, QStringList pairs)
{
if (!id.isEmpty() && !pairs.isEmpty())
{
if ((pairs.size() % 2) == 0)
{
_lastWill[id] = pairs;
}
}
else if (!id.isEmpty())
{
_lastWill.erase(id);
}
else if (_lastWill.size() > 0)
{
for (const auto& current : _lastWill)
for (auto item = current.second.begin(); item != current.second.end(); ++item)
{
auto topic = *(item++);
if (item != current.second.end())
{
handleSignalMqttPublish(topic, *(item));
}
}
_lastWill.clear();
}
}

0 comments on commit 3730819

Please sign in to comment.