Skip to content

Commit 13f9b3f

Browse files
committed
Zigbee2mqtt: fix power off lights on exit
1 parent 4a07528 commit 13f9b3f

File tree

6 files changed

+58
-2
lines changed

6 files changed

+58
-2
lines changed

Diff for: include/led-drivers/net/DriverNetZigbee2mqtt.h

+2
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,11 @@ public slots:
6262
std::atomic<int> _colorsFinished;
6363
int _timeLogger;
6464
QString _discoveryMessage;
65+
int _mqttId;
6566

6667
std::mutex _mtx;
6768
std::condition_variable _cv;
6869

70+
static int mqttId;
6971
static bool isRegistered;
7072
};

Diff for: include/mqtt/mqtt.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
#ifndef PCH_ENABLED
44
#include <QSet>
55
#include <QJsonDocument>
6-
#include <QTimer>
6+
#include <QTimer
7+
#include <QStringList>
78
#endif
89

910
#include <utils/Logger.h>
@@ -30,6 +31,7 @@ public slots:
3031

3132
void handleSignalMqttSubscribe(bool subscribe, QString topic);
3233
void handleSignalMqttPublish(QString topic, QString payload);
34+
void handleSignalMqttLastWill(QString id, QStringList pairs);
3335

3436
private slots:
3537
void connected();
@@ -61,6 +63,8 @@ private slots:
6163
QJsonArray _resultArray;
6264
bool _disableApiAccess;
6365

66+
std::map<QString, QStringList> _lastWill;
67+
6468
Logger* _log;
6569
QMQTT::Client* _clientInstance;
6670
};

Diff for: include/utils/GlobalSignals.h

+3
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
#ifndef PCH_ENABLED
3131
#include <QObject>
32+
#include <QStringList>
3233
#endif
3334

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

107108
void SignalMqttPublish(QString topic, QString payload);
109+
110+
void SignalMqttLastWill(QString id, QStringList pairs);
108111
};

Diff for: sources/hyperhdr/HyperHdrDaemon.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,8 @@ void HyperHdrDaemon::freeObjects()
238238
{
239239
Info(_log, "Cleaning up HyperHdr before quit [preparing]");
240240

241+
emit GlobalSignals::getInstance()->SignalMqttLastWill(QString(), QStringList());
242+
241243
disconnect(GlobalSignals::getInstance(), nullptr, nullptr, nullptr);
242244
disconnect(_instanceManager.get(), nullptr, nullptr, nullptr);
243245
HyperHdrInstance::signalTerminateTriggered();

Diff for: sources/led-drivers/net/DriverNetZigbee2mqtt.cpp

+16-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ DriverNetZigbee2mqtt::DriverNetZigbee2mqtt(const QJsonObject& deviceConfig)
1313
: LedDevice(deviceConfig),
1414
_discoveryFinished(false),
1515
_colorsFinished(0),
16-
_timeLogger(0)
16+
_timeLogger(0),
17+
_mqttId(mqttId++)
1718
{
1819
}
1920

@@ -60,6 +61,7 @@ bool DriverNetZigbee2mqtt::init(const QJsonObject& deviceConfig)
6061
bool DriverNetZigbee2mqtt::powerOnOff(bool isOn)
6162
{
6263
QJsonDocument doc;
64+
QStringList lastWill;
6365

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

7173
doc.setObject(row);
7274
emit GlobalSignals::getInstance()->SignalMqttPublish(topic, doc.toJson(QJsonDocument::Compact));
75+
76+
if (isOn)
77+
{
78+
row["state"] = "OFF";
79+
doc.setObject(row);
80+
81+
lastWill.push_back(topic);
82+
lastWill.push_back(doc.toJson(QJsonDocument::Compact));
83+
}
7384
}
7485

7586
if (_zigInstance.lamps.size() > 0)
7687
{
88+
QString lastWillId = QString("DriverNetZigbee2mqtt:%1").arg(_mqttId);
7789
if (isOn)
7890
{
91+
emit GlobalSignals::getInstance()->SignalMqttLastWill(lastWillId, lastWill);
7992
connect(GlobalSignals::getInstance(), &GlobalSignals::SignalMqttReceived, this, &DriverNetZigbee2mqtt::handlerSignalMqttReceived, Qt::DirectConnection);
8093
}
8194
else
8295
{
96+
emit GlobalSignals::getInstance()->SignalMqttLastWill(lastWillId, QStringList());
8397
disconnect(GlobalSignals::getInstance(), &GlobalSignals::SignalMqttReceived, this, &DriverNetZigbee2mqtt::handlerSignalMqttReceived);
8498
}
8599
}
@@ -328,4 +342,5 @@ void DriverNetZigbee2mqtt::identify(const QJsonObject& params)
328342
}
329343
}
330344

345+
int DriverNetZigbee2mqtt::mqttId = 0;
331346
bool DriverNetZigbee2mqtt::isRegistered = hyperhdr::leds::REGISTER_LED_DEVICE("zigbee2mqtt", "leds_group_2_network", DriverNetZigbee2mqtt::construct);

Diff for: sources/mqtt/mqtt.cpp

+30
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ mqtt::mqtt(const QJsonDocument& mqttConfig)
2929
, _log(Logger::getInstance("MQTT"))
3030
, _clientInstance(nullptr)
3131
{
32+
connect(GlobalSignals::getInstance(), &GlobalSignals::SignalMqttLastWill, this, &mqtt::handleSignalMqttLastWill, Qt::UniqueConnection);
33+
3234
handleSettingsUpdate(settings::type::MQTT, mqttConfig);
3335
}
3436

@@ -354,3 +356,31 @@ void mqtt::handleSignalMqttPublish(QString topic, QString payload)
354356
_clientInstance->publish(message);
355357
}
356358
}
359+
360+
void mqtt::handleSignalMqttLastWill(QString id, QStringList pairs)
361+
{
362+
if (!id.isEmpty() && !pairs.isEmpty())
363+
{
364+
if ((pairs.size() % 2) == 0)
365+
{
366+
_lastWill[id] = pairs;
367+
}
368+
}
369+
else if (!id.isEmpty())
370+
{
371+
_lastWill.erase(id);
372+
}
373+
else if (_lastWill.size() > 0)
374+
{
375+
for (const auto& current : _lastWill)
376+
for (auto item = current.second.begin(); item != current.second.end(); ++item)
377+
{
378+
auto topic = *(item++);
379+
if (item != current.second.end())
380+
{
381+
handleSignalMqttPublish(topic, *(item));
382+
}
383+
}
384+
_lastWill.clear();
385+
}
386+
}

0 commit comments

Comments
 (0)