doorstate: automatically reconnect if mqtt broker fails

We had a bug: doorstate didn't reconnect to the broker if it temporarily
disappeared.

Fix this by using start_loop() (which starts a thread that observes the
broker and automatically reconnects) instead of the synchronous loop()
method.

Thomas Basler <github.thomas@familie-basler.net>
Signed-off-by: Ralf Ramsauer <ralf@binary-kitchen.de>
This commit is contained in:
Ralf Ramsauer 2019-07-07 23:15:10 +02:00
parent 71e55ec523
commit 8b49c2f332
1 changed files with 28 additions and 3 deletions

View File

@ -77,13 +77,23 @@ class AudioPlayer(Thread):
self._process = Popen(['mpg123', self._filename]) self._process = Popen(['mpg123', self._filename])
def mqtt_on_connect(client, userdata, flags, rc): def mqtt_on_connect(client, userdata, flags, rc):
global mqtt_connected
if rc == 0: if rc == 0:
print("MqTT: Connection returned result: " + mqtt.connack_string(rc)) print("MqTT: Connection returned result: " + mqtt.connack_string(rc))
client.subscribe(topic_alarm) client.subscribe(topic_alarm)
client.subscribe(topic_lockstate) client.subscribe(topic_lockstate)
mqtt_connected = True
else: else:
print("MqTT: Bad connection Returned code=", rc) print("MqTT: Bad connection Returned code=", rc)
def mqtt_on_disconnect(client, userdata, rc):
global mqtt_connected
if rc != 0:
print("Unexpected MQTT disconnection")
mqtt_connected = False
def mqtt_on_lockstate(client, userdata, message): def mqtt_on_lockstate(client, userdata, message):
global is_locked global is_locked
is_locked = message.payload.decode('utf-8') == 'locked' is_locked = message.payload.decode('utf-8') == 'locked'
@ -113,6 +123,7 @@ f_door_call = os.path.join(sounds_prefix, 'door_call.mp3')
mqttc = mqtt.Client(client_id=prog) mqttc = mqtt.Client(client_id=prog)
mqttc.username_pw_set(cfg.str('MQTT_USERNAME'), cfg.str('MQTT_PASSWORD')) mqttc.username_pw_set(cfg.str('MQTT_USERNAME'), cfg.str('MQTT_PASSWORD'))
mqttc.on_connect = mqtt_on_connect mqttc.on_connect = mqtt_on_connect
mqttc.on_disconnect = mqtt_on_disconnect
mqttc.message_callback_add(topic_alarm, mqtt_on_alarm) mqttc.message_callback_add(topic_alarm, mqtt_on_alarm)
mqttc.message_callback_add(topic_lockstate, mqtt_on_lockstate) mqttc.message_callback_add(topic_lockstate, mqtt_on_lockstate)
mqttc.connect(cfg.str('MQTT_HOST')) mqttc.connect(cfg.str('MQTT_HOST'))
@ -134,10 +145,13 @@ door_open = line.get_value() == 1
door_alarm_set = False door_alarm_set = False
while True: global mqtt_connected
# Synchronous loops: MQTT + GPIO mqtt_connected = False
mqttc.loop(timeout=0.5, max_packets=1)
mqttc.loop_start()
while True:
# Synchronous loop: GPIO
ev_line = line.event_wait(sec=1) ev_line = line.event_wait(sec=1)
if ev_line: if ev_line:
event = line.event_read() event = line.event_read()
@ -145,6 +159,15 @@ while True:
print('door_open: %s' % door_open) print('door_open: %s' % door_open)
publish_doorstate() publish_doorstate()
if not mqtt_connected:
print('No MQTT connection!')
if door_alarm_set:
player_door_call.set(False)
door_alarm_set = False
player_alarm.set(False)
continue
# Door State stuff # Door State stuff
if is_locked is not None: if is_locked is not None:
if is_locked is False: if is_locked is False:
@ -160,6 +183,8 @@ while True:
player_door_call.set(False) player_door_call.set(False)
door_alarm_set = False door_alarm_set = False
mqttc.loop_stop()
player_alarm.shutdown() player_alarm.shutdown()
player_alarm.join() player_alarm.join()