Quantcast
Channel: Raspberry Pi Forums
Viewing all articles
Browse latest Browse all 1251

Python • Help with MQTT restart code

$
0
0
Morning All,

For a while I've been using a Pi Zero W with a python script, sensors and relays to run my heating system, in combination with Home Assistant (HA). HA runs the thermostats, GUI etc. and sends settings and calls for heating to the Pi via MQTT and the Pi sends temperature and status data back to HA for logging and display, with all of the logic happening on the Pi. When all is well, it works. There have been a few occasions recently however when the two have lost contact and I've woken up to a cold house, e.g. when we get a power blip. I've set the pi up to connect to the MQTT server on HA on start-up and request the latest settings, sent by HA using an automation. This all works fine if the pi is restarted but if both re-start, the pi is much faster and sends its connection request too soon and fails to connect. It will also loose connection if HA re-boots and the pi doesn't. Basically, I'd like to add some code to monitor responses from HA and re-connect the MQTT if there is no response for a period of time. I have a "count" value that the pi sends to HA and when HA sees "count" > 9, it sends a message to the pi, which re-sets count to 0 again. What I'd like to do is re-set the MQTT connection is "count" > 12.

My MQTT code is as follows:-

Code:

def Send(): # Send data back to Home Assistant Server    client.publish("heating/t1", Temps['T1']);    client.publish("heating/t2", Temps['T2']);    client.publish("heating/t3", Temps['T3']);    client.publish("heating/t4", Temps['T4']);    client.publish("heating/t5", Temps['T5']);    client.publish("heating/room", room);    client.publish("heating/floor", floor);    client.publish("heating/boiler", Boilerst);    client.publish("heating/status", count);    def on_connect(client, userdata, flags, rc, properties):    print("Connected to MQTT broker with result code: " + str(rc))    client.subscribe(TS1,0)    client.subscribe(TS2,0)    client.subscribe(TH1,0)    client.subscribe(TS3,0)    client.subscribe(TH3,0)    client.subscribe(TS4,0)    client.subscribe(TTmax,0)    client.subscribe(Tdhw,0)    client.subscribe(TEco,0)    client.subscribe(Thols,0)    client.subscribe(Room,0)    client.subscribe(Floor,0)    client.subscribe(Upstairs,0)    client.subscribe(OK,0)    print("Controller Connected")def on_message(client, userdata, msg): # can remove print functions once verified    global s1, s2, h1, s3, h3, s4, hmode, smax, hols, dhw, Roomheating, Floorheating, US    print("Message received: " + msg.topic + " - " + msg.payload.decode())    now=datetime.datetime.now()    time=str("%02d"%(now.hour)) + ":" + str("%02d"%(now.minute))    if msg.topic == TS1:        s1=float(msg.payload.decode())        print("s1 = " , s1 ," : " +time)    if msg.topic == TS2:        s2=float(msg.payload.decode())        print("s2 = " , s2 ," : " +time)    if msg.topic == TH1:        h1=float(msg.payload.decode())        print("h1 = " , h1 ," : " +time)    if msg.topic == Tdhw:        dhw=msg.payload.decode()        print("dhw = " , dhw , " : " +time)    if msg.topic == TS3:        s3=float(msg.payload.decode())        print("s3 = " , s3 ," : " +time)    if msg.topic == TH3:        h3=float(msg.payload.decode())        print("h3 = " , h3 ," : " +time)    if msg.topic == TS4:        s4=float(msg.payload.decode())        print("s4 = " , s4 ," : " +time)    if msg.topic == TTmax:        smax=float(msg.payload.decode())        print("smax = " , smax ," : " +time)    if msg.topic == Thols:        hols=msg.payload.decode()        print("hols = " , hols ," : " +time)    if msg.topic == Room:        Roomheating=msg.payload.decode()        print("Room Heating = ", Roomheating, " : " +time)    if msg.topic == Floor:        Floorheating=msg.payload.decode()        print("Floor Heating = ", Floorheating, " : " +time)    if msg.topic == Upstairs:        US=msg.payload.decode()        print("Upstairs Heating = ", US, " : " +time)    if msg.topic == OK:        response = msg.payload.decode()        count=0        print("Response = ", response, " : " +time)def MQTT():    client.on_connect = on_connect    client.on_message = on_message    client.connect(clientIP,clientport,60)    client.loop_forever()
The programme runs the MQTT and the control logic in 2 threads:-

Code:

th1 = threading.Thread(target=work)th2 = threading.Thread(target=MQTT)th2.start()th1.start()
The "count" is increased with each pass through the "work" subroutine and reset on receipt of the "OK" message from HA. Can I drop in an if statement in the MQTT subroutine to say something like:-

Code:

def MQTT():    client.on_connect = on_connect    client.on_message = on_message    client.connect(clientIP,clientport,60)        if count > 12:        client.disconnect();        client.on_connect = on_connect        client.on_message = on_message        client.connect(clientIP,clientport,60)            client.loop_forever()
I'm not familiar with how the client.loop_forever() command works so not sure if I can just dump an if in there. Can anybody point me in the right direction?

My other option is to have HA reboot the pi if there are no messages received for a period of time but that will involve another device to shut off the power to the pi and an automation to look for "no change", which isn't so straight forward.

Many thanks,

Phil

Statistics: Posted by philmulrain — Tue Feb 11, 2025 9:29 am



Viewing all articles
Browse latest Browse all 1251

Trending Articles