From 77c6f699a0170d4064d41284f670f69489376cdf Mon Sep 17 00:00:00 2001
From: Fabio Manganiello <info@fabiomanganiello.com>
Date: Sat, 13 Feb 2021 15:54:21 +0100
Subject: [PATCH 1/2] Keep track of the last state of the Zigbee controller so
 that new messages on the `bridge/state` topic won't trigger new events unless
 the state has actually changed [see #183]

---
 platypush/backend/zigbee/mqtt.py | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/platypush/backend/zigbee/mqtt.py b/platypush/backend/zigbee/mqtt.py
index 2637bb759..9b58c0b4e 100644
--- a/platypush/backend/zigbee/mqtt.py
+++ b/platypush/backend/zigbee/mqtt.py
@@ -86,6 +86,7 @@ class ZigbeeMqttBackend(MqttBackend):
         self.base_topic = base_topic or plugin.base_topic
         self._devices = {}
         self._groups = {}
+        self._last_state = None
         self.server_info = {
             'host': host or plugin.host,
             'port': port or plugin.port or self._default_mqtt_port,
@@ -109,6 +110,9 @@ class ZigbeeMqttBackend(MqttBackend):
         super().__init__(subscribe_default_topic=False, listeners=listeners, *args, **kwargs)
 
     def _process_state_message(self, client, msg):
+        if msg == self._last_state:
+            return
+
         if msg == 'online':
             evt = ZigbeeMqttOnlineEvent
         elif msg == 'offline':
@@ -119,6 +123,7 @@ class ZigbeeMqttBackend(MqttBackend):
 
         # noinspection PyProtectedMember
         self.bus.post(evt(host=client._host, port=client._port))
+        self._last_state = msg
 
     def _process_log_message(self, client, msg):
         msg_type = msg.get('type')

From ee7407a7cc08ef4771b8e99969f142395c5abdec Mon Sep 17 00:00:00 2001
From: Fabio Manganiello <info@fabiomanganiello.com>
Date: Mon, 15 Feb 2021 22:02:58 +0100
Subject: [PATCH 2/2] Don't create an MQTT client connection if there are no
 topics to subscribe.

If we open multiple connections from multiple MQTT-based backends to the
same host, with some of them having no topics subscribed, Paho-MQTT can
mess up which client is supposed to receive which message and we may end
up with lost messages on the platypush_bus_mqt/<host> topic.
---
 platypush/backend/mqtt.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/platypush/backend/mqtt.py b/platypush/backend/mqtt.py
index 53a6e1040..40e583e56 100644
--- a/platypush/backend/mqtt.py
+++ b/platypush/backend/mqtt.py
@@ -319,8 +319,8 @@ class MqttBackend(Backend):
     def run(self):
         super().run()
 
-        if self.host:
-            topics = [self.topic] if self.subscribe_default_topic else []
+        if self.host and self.subscribe_default_topic:
+            topics = [self.topic]
             client = self._get_client(host=self.host, port=self.port, topics=topics, username=self.username,
                                       password=self.password, client_id=self.client_id,
                                       tls_cafile=self.tls_cafile, tls_certfile=self.tls_certfile,