Python script occasionally disconnects -- paho.mqtt


#1

Hello

I have a simple python script adapted from ‘Steve’s Internet Guides’ which connects to the myqtthub broker and publishes to a default topic a timestamp, the local ip and it’s ssid.

The script works ( although I should like to send it more securely in a future version ) but my problem right now is that it occasionally disconnects and doesn’t reconnect. I think either I need to extend the keepalive or maybe have it start a new session every half an hour, or something.

Would you please be so kind as to take a look and offer me any advice?

Many thanks

Robin

#! python3.4

import paho.mqtt.client as mqtt
import time,json,datetime,socket,os,subprocess
import alarminfo

clientid = alarminfo.alarminfo[“clientid”]
rmname = alarminfo.alarminfo[“roomname”]
broker = alarminfo.alarminfo[“broker”]
port = alarminfo.alarminfo[“port”] # port of broker
port = int(port) # have to convert the port to an integer to work
topic = alarminfo.alarminfo[“topic”] # topic
username = alarminfo.alarminfo[“username”] #
password= alarminfo.alarminfo[“password”] #
onionssid = subprocess.check_output([“uci”, “get”,
“wireless.@wifi-iface[0].ssid”])
onionssid = onionssid.rstrip("\n\r")

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect((“8.8.8.8”, 80))
localip = (s.getsockname()[0])
s.close()

def on_log(client, userdata, level, buf):
print(buf)
def on_connect(client, userdata, flags, rc):
if rc==0:
client.connected_flag=True #set flag
print(“connected OK”)
else:
print(“Bad connection Returned code=”,rc)
client.loop_stop()
def on_disconnect(client, userdata, rc):
print(“client disconnected ok”)
def on_publish(client, userdata, mid):
print("In on_pub callback mid= " ,mid)
count=0

mqtt.Client.connected_flag=False#create flag in class
mqtt.Client.suppress_puback_flag=False
client = mqtt.Client(clientid) #create new instance
#client.on_log=on_log
client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.on_publish = on_publish
if username !="":
pass
client.username_pw_set(username, password)

client.connect(broker,port) #establish connection
while not client.connected_flag: #wait in loop
client.loop()
time.sleep(1)
time.sleep(3)
data=dict()
for i in range(100):
localtime = datetime.datetime.now().strftime("%H:%M")

x = {
"time": localtime,
"Local_IP": localip,
"Local_SSID": onionssid,
"room_name": rmname

}

data_out=json.dumps(x) #create JSON object
print("publish topic",topic, "data out= ",data_out,)
ret=client.publish(topic,data_out,0)    #publish
time.sleep(60)
client.loop()

client.disconnect()


#2

Hello Robin.

I suspect it is a keepalive issue. From posted example, calling to create a MQTT connection with the following code:

client = mqtt.Client(clientid)

…will create a session with keepalive=60 (seconds) as indicated by:

https://pypi.org/project/paho-mqtt/
connect(host, port=1883, keepalive=60, bind_address="")

Taking into account this, at the end of the loop example, you have a:

time.sleep(60)

…which will cause your client to freeze during 60 seconds, thus,
triggering keepalive connection close as indicated by the MQTT
standard.

This also matches with what we are getting logged at our side:

MYQTT: 10-11-2018 05:38:55 INFO [MyQtt-akka.actor.default-dispatcher-10] e.a.r.m.l.MyQttConn - DISCONNECT : Read error :: 10003 :: TcpConnection.processBytesReceived (10003) :: ListenerRole :: found exception java.io.IOException: Connection closed by remote peer while reading, stopping actor (0x10074) : domainName=xxx : userName=2KM_xx_Usr : clientId=2KM_xxx : role=server : RemoteAddr=X.X.X.X

Try to reduce that time.sleep() to something smaller:

time.sleep (30)

than 60 or to create a mqtt.Client with keepalive increased:

client.connect(broker,port, keepalive=90)

Best Regards