Skip to content

Commit

Permalink
Trying to fix MQTT controller disconnect issues. Prepare for PME supp…
Browse files Browse the repository at this point in the history
…ort. Handle batteryval conversion, and other minor bugs
  • Loading branch information
enesbcs committed Jan 16, 2019
1 parent 379f493 commit 8078e7b
Show file tree
Hide file tree
Showing 9 changed files with 217 additions and 73 deletions.
4 changes: 4 additions & 0 deletions _C001_DomoHTTP.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ def webform_save(self,params):
def senddata(self,idx,sensortype,value,userssi=-1,usebattery=-1,tasknum=-1,changedvalue=-1):
if self.enabled:
if int(idx) != 0:
try:
usebattery = float(usebattery)
except:
userbattery = -1
if int(sensortype)==rpieGlobals.SENSOR_TYPE_SWITCH:
url = "/json.htm?type=command&param=switchlight&idx="
url += str(idx)
Expand Down
127 changes: 94 additions & 33 deletions _C002_DomoMQTT.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,36 +41,42 @@ def __init__(self,controllerindex):
self.authmode = 0
self.certfile = ""
self.laststatus = -1
self.pwset = False
self.keepalive = 60

def controller_init(self,enablecontroller=None):
if enablecontroller != None:
self.enabled = enablecontroller
self.connectinprogress = 0
try:
ls = self.laststatus
except:
self.laststatus = -1
self.mqttclient = DMQTTClient()
self.mqttclient.subscribechannel = self.outchannel
self.mqttclient.controllercb = self.on_message
self.mqttclient.connectcb = self.on_connect
self.mqttclient.disconnectcb = self.on_disconnect
if self.controllerpassword=="*****":
self.controllerpassword=""
self.pwset=False
self.initialized = True
if self.enabled:
self.connect()
if self.isconnected()==False:
misc.addLog(rpieGlobals.LOG_LEVEL_DEBUG,"MQTT: Try to connect")
self.connect()
else:
self.disconnect()
return True

def connect(self):
if self.enabled and self.initialized:
if self.isconnected():
misc.addLog(rpieGlobals.LOG_LEVEL_DEBUG,"Already connected force disconnect!")
self.disconnect()
self.connectinprogress = 1
self.lastreconnect = time.time()
if (self.controlleruser!="" or self.controllerpassword!="") and (self.pwset==False):
if (self.controlleruser!="" or self.controllerpassword!="") and (self.isconnected() == False):
self.mqttclient.username_pw_set(self.controlleruser,self.controllerpassword)
self.pwset=True
misc.addLog(rpieGlobals.LOG_LEVEL_DEBUG,"Set MQTT password")
try:
am = self.authmode
except:
Expand Down Expand Up @@ -106,37 +112,61 @@ def connect(self):
except:
pass
try:
self.mqttclient.connect(self.controllerip,int(self.controllerport))
self.mqttclient.loop_start()
kp = self.keepalive
except:
misc.addLog(rpieGlobals.LOG_LEVEL_ERROR,"MQTT controller: "+self.controllerip+":"+str(self.controllerport)+" connection failed")
self.keepalive = 60
try:
self.mqttclient.connect(self.controllerip,int(self.controllerport),keepalive=self.keepalive) # connect_async() is faster but maybe not the best for user/pass method
self.mqttclient.loop_start()
except Exception as e:
misc.addLog(rpieGlobals.LOG_LEVEL_ERROR,"MQTT controller: "+self.controllerip+":"+str(self.controllerport)+" connection failed "+str(e))
return self.isconnected()

def disconnect(self):
try:
self.mqttclient.loop_stop(True)
self.mqttclient.disconnect()
self.mqttclient.connected=False
except:
pass
stat=self.isconnected()
if stat==False:
self.on_disconnect()
return stat

def isconnected(self):
def isconnected(self,ForceCheck=True):
res = False
if self.enabled and self.initialized:
if ForceCheck==False:
return self.laststatus
if self.mqttclient is not None:
gtopic = self.inchannel
gval = "PING"
mres = 1
try:
res = self.mqttclient.connected
(mres,mid) = self.mqttclient.publish(gtopic,gval)
except:
res = False
mres = 1
if mres==0:
res = 1 # connected
else:
res = 0 # not connected
if res != self.laststatus:
if res==0:
commands.rulesProcessing("DomoMQTT#Disconnected",rpieGlobals.RULE_SYSTEM)
else:
commands.rulesProcessing("DomoMQTT#Connected",rpieGlobals.RULE_SYSTEM)
self.laststatus = res
if res == 1 and self.connectinprogress==1:
self.connectinprogress=0
return res

def webform_load(self): # create html page for settings
webserver.addFormTextBox("Controller Publish","inchannel",self.inchannel,255)
webserver.addFormTextBox("Controller Subscribe","outchannel",self.outchannel,255)
try:
kp = self.keepalive
except:
kp = 60
webserver.addFormNumericBox("Keepalive time","keepalive",kp,2,600)
webserver.addUnit("s")
try:
am = self.authmode
fname = self.certfile
Expand All @@ -152,14 +182,36 @@ def webform_load(self): # create html page for settings
return True

def webform_save(self,params): # process settings post reply
pchange = False
pval = self.inchannel
self.inchannel = webserver.arg("inchannel",params)
if pval != self.inchannel:
pchange = True
pval = self.outchannel
self.outchannel = webserver.arg("outchannel",params)
if pval != self.outchannel:
pchange = True
try:
p1 = self.authmode
p2 = self.certfile
self.authmode = int(webserver.arg("c002_mode",params))
self.certfile = webserver.arg("c002_cert",params)
if p1 != self.authmode or p2 != self.certfile:
pchange = True
except:
self.authmode = 0
self.certfile = ""
pval = self.keepalive
try:
self.keepalive = int(webserver.arg("keepalive",params))
except:
self.keepalive = 60
if pval != self.keepalive:
pchange = True
if pchange and self.enabled:
self.disconnect()
time.sleep(0.1)
self.connect()
return True

def on_message(self, msg):
Expand Down Expand Up @@ -239,6 +291,10 @@ def senddata(self,idx,sensortype,value,userssi=-1,usebattery=-1,tasknum=-1,chang
domosmsgw = '{{"command": "switchlight", "idx": {0}, "switchcmd": "Set Level", "level":"{1}", "RSSI": {2} }}'
domosmsgwb = '{{"command": "switchlight", "idx": {0}, "switchcmd": "Set Level", "level":"{1}", "RSSI": {2}, "Battery": {3} }}'
if self.isconnected():
try:
usebattery = float(usebattery)
except:
userbattery = -1
if int(idx) > 0:
if usebattery != -1 and usebattery != 255:
bval = usebattery
Expand All @@ -259,8 +315,13 @@ def senddata(self,idx,sensortype,value,userssi=-1,usebattery=-1,tasknum=-1,chang
msg = domosmsgwb.format(str(idx), str(value[0]), mapRSSItoDomoticz(userssi),str(bval))
else:
msg = domomsgwb.format(str(idx), 0, formatDomoticzSensorType(sensortype,value), mapRSSItoDomoticz(userssi),str(bval))
# print(msg) #DEBUG
self.mqttclient.publish(self.inchannel,msg)
mres = 1
try:
(mres,mid) = self.mqttclient.publish(self.inchannel,msg)
except:
mres = 1
if mres!=0:
self.isconnected()
else:
misc.addLog(rpieGlobals.LOG_LEVEL_ERROR,"MQTT idx error, sending failed.")
else:
Expand All @@ -270,47 +331,47 @@ def senddata(self,idx,sensortype,value,userssi=-1,usebattery=-1,tasknum=-1,chang

def on_connect(self):
if self.enabled and self.initialized:
if self.connectinprogress==1:
commands.rulesProcessing("DomoMQTT#Connected",rpieGlobals.RULE_SYSTEM)
self.laststatus = 1
self.connectinprogress=0
self.isconnected()
else:
self.disconnect()

def on_disconnect(self):
if self.initialized:
if self.laststatus==1:
commands.rulesProcessing("DomoMQTT#Disconnected",rpieGlobals.RULE_SYSTEM)
self.laststatus = 0
self.isconnected()

class DMQTTClient(mqtt.Client):
subscribechannel = ""
controllercb = None
connected = False
disconnectcb = None
connectcb = None

def on_connect(self, client, userdata, flags, rc):
try:
rc = int(rc)
except:
rc=-1
if rc==0:
self.subscribe(self.subscribechannel,0)
self.connected = True
if self.connectcb is not None:
self.connectcb()
else:
except Exception as e:
misc.addLog(rpieGlobals.LOG_LEVEL_ERROR,"MQTT connection error: "+str(e))
try:
rc = int(rc)
except:
rc=-1
if rc !=0:
estr = str(rc)
if rc==1:
estr += " Protocol version error!"
if rc==3:
estr += " Server unavailable!"
if rc==4:
estr += " User/pass error!"
if rc==5:
estr += " Invalid user/pass!"
estr += " Not authorized!"
misc.addLog(rpieGlobals.LOG_LEVEL_ERROR,"MQTT connection error: "+estr)

def on_disconnect(self, client, userdata, rc):
self.connected = False
if self.disconnectcb is not None:
self.disconnectcb()

def on_message(self, mqttc, obj, msg):
if self.connected and self.controllercb is not None:
if self.controllercb is not None:
self.controllercb(msg)
Loading

0 comments on commit 8078e7b

Please sign in to comment.