From 3862088e8ba26ae2a8e0c3ab8882644f8a59f001 Mon Sep 17 00:00:00 2001 From: enesbcs Date: Tue, 15 Dec 2020 21:10:45 +0100 Subject: [PATCH] PWM command fix, C002 controller optional ping support, P201 serial reconnection --- _C002_DomoMQTT.py | 55 ++++++++++++++++++++++++++++++++++--------- _P001_Switch.py | 12 +++++----- _P201_GenSerial.py | 31 ++++++++++++++++++------ lib/lib_gpiohelper.py | 35 +++++++++++++++++++++++---- rpieGlobals.py | 2 +- 5 files changed, 105 insertions(+), 30 deletions(-) diff --git a/_C002_DomoMQTT.py b/_C002_DomoMQTT.py index c9e4d07..d6b3ec4 100644 --- a/_C002_DomoMQTT.py +++ b/_C002_DomoMQTT.py @@ -41,6 +41,7 @@ def __init__(self,controllerindex): self.certfile = "" self.laststatus = -1 self.keepalive = 60 + self.useping = True def controller_init(self,enablecontroller=None): if enablecontroller != None: @@ -50,6 +51,10 @@ def controller_init(self,enablecontroller=None): ls = self.laststatus except: self.laststatus = -1 + try: + ls = self.useping + except: + self.useping = True self.mqttclient = DMQTTClient() self.mqttclient.subscribechannel = self.outchannel self.mqttclient.controllercb = self.on_message @@ -119,6 +124,7 @@ def connect(self): 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)) + self.laststatus = 0 return self.isconnected() def disconnect(self): @@ -139,19 +145,25 @@ def isconnected(self,ForceCheck=True): res = False if self.enabled and self.initialized: if ForceCheck==False: - return self.laststatus + return (self.laststatus==1) if self.mqttclient is not None: - gtopic = self.inchannel - gval = "PING" - mres = 1 - try: - (mres,mid) = self.mqttclient.publish(gtopic,gval) - except: - mres = 1 - if mres==0: - res = 1 # connected + if self.useping==False: + try: + res = self.mqttclient.is_connected() + except: + res = 0 else: - res = 0 # not connected + gtopic = self.inchannel + gval = "PING" + mres = 1 + try: + (mres,mid) = self.mqttclient.publish(gtopic,gval) + except: + 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) @@ -169,6 +181,10 @@ def webform_load(self): # create html page for settings kp = self.keepalive except: kp = 60 + try: + p = self.useping + except: + p = True webserver.addFormNumericBox("Keepalive time","keepalive",kp,2,600) webserver.addUnit("s") try: @@ -183,6 +199,8 @@ def webform_load(self): # create html page for settings webserver.addFormTextBox("Server certificate file","c002_cert",str(fname),120) webserver.addBrowseButton("Browse","c002_cert",startdir=str(fname)) webserver.addFormNote("Upload certificate first at filelist then select here!") + webserver.addFormCheckBox("Check conn & reconnect if needed at every 30 sec","c002_reconnect",self.timer30s) + webserver.addFormCheckBox("Use PING messages to check connection","c002_ping",self.useping) return True def webform_save(self,params): # process settings post reply @@ -212,12 +230,27 @@ def webform_save(self,params): # process settings post reply self.keepalive = 60 if pval != self.keepalive: pchange = True + if (webserver.arg("c002_reconnect",params)=="on"): + self.timer30s = True + else: + self.timer30s = False + if (webserver.arg("c002_ping",params)=="on"): + self.useping = True + else: + self.useping = False if pchange and self.enabled: self.disconnect() time.sleep(0.1) self.connect() return True + def timer_thirty_second(self): + if self.enabled: + if self.isconnected()==False: + misc.addLog(rpieGlobals.LOG_LEVEL_DEBUG,"MQTT: Try to reconnect") + self.connect() + return self.timer30s + def on_message(self, msg): if self.enabled: msg2 = msg.payload.decode('utf-8') diff --git a/_P001_Switch.py b/_P001_Switch.py index aded591..b1e2576 100644 --- a/_P001_Switch.py +++ b/_P001_Switch.py @@ -6,12 +6,12 @@ # Can only be used with devices that supports GPIO operations! # # Available commands: (It is evident, that you have to enable at least one P001 device if you want to use it's commands) -# gpio,26,1 - set pin GPIO26 to 1 (HIGH) -# pwm,18,50,20000 - set pin GPIO18 to PWM mode with 20000Hz sample rate and 50% fill ratio -# PWM is software based if not one of the dedicated H-PWM pins -# H-PWM has to be set before use this command and may need root rights! -# pulse,26,1,500 - set pin GPIO26 to 1 for 500 msec than set back to 0 (blocking mode) -# longpulse,26,1,10 - set pin GPIO26 to 1 for 10 seconds than set back to 0 (non-blocking mode) +# gpio,26,1 - set pin GPIO26 to 1 (HIGH) +# pwm,18,50,100,20000 - set pin GPIO18 to PWM mode with 100msec fade and 20000Hz sample rate and 50% fill ratio +# PWM is software based if not one of the dedicated H-PWM pins +# H-PWM has to be set before use this command and may need root rights! +# pulse,26,1,500 - set pin GPIO26 to 1 for 500 msec than set back to 0 (blocking mode) +# longpulse,26,1,10 - set pin GPIO26 to 1 for 10 seconds than set back to 0 (non-blocking mode) # # Also be sure to set up pin using mode at Hardware->Pinout&Ports menu. # diff --git a/_P201_GenSerial.py b/_P201_GenSerial.py index d9a1ba7..a06529f 100644 --- a/_P201_GenSerial.py +++ b/_P201_GenSerial.py @@ -78,6 +78,8 @@ def plugin_init(self,enableplugin=None): self.bgproc = threading.Thread(target=self.bgreceiver) self.bgproc.daemon = True self.bgproc.start() + else: + misc.addLog(rpieGlobals.LOG_LEVEL_ERROR,"Serial init failed") else: self.baud = 0 self.ports = 0 @@ -124,7 +126,7 @@ def webform_load(self): choice6 = self.taskdevicepluginconfig[6] options = ["Hex values","String"] optionvalues = [0,1] - webserver.addFormSelector("Data format","p201_fmt",len(optionvalues),options,optionvalues,None,int(choice6)) + webserver.addFormSelector("Input Data format","p201_fmt",len(optionvalues),options,optionvalues,None,int(choice6)) else: webserver.addFormNote("No serial ports found") return True @@ -132,7 +134,7 @@ def webform_load(self): def webform_save(self,params): par = webserver.arg("p201_addr",params) self.taskdevicepluginconfig[0] = str(par) - try: + try: baud = webserver.arg("p201_spd",params) self.taskdevicepluginconfig[1] = int(baud) except: @@ -158,7 +160,7 @@ def webform_save(self,params): self.calctimeout() self.plugin_init() return True - + def convert(self,inbuf): res = "" if len(inbuf)>0: @@ -194,7 +196,7 @@ def convert(self,inbuf): res += "0x"+str(inbuf[s].hex()) except: res += str(inbuf[s]) - return res + return res def connect(self): try: @@ -215,6 +217,7 @@ def connect(self): def bgreceiver(self): if self.initialized: recdata = [] + askreconnect = 0 while self.enabled: if self.serdev is not None: # tt = rpieTime.millis() @@ -233,7 +236,13 @@ def bgreceiver(self): time.sleep(0.001) except Exception as e: time.sleep(0.5) -# self.connect() + if askreconnect==0: + askreconnect = time.time() + if askreconnect>0: + if time.time()-askreconnect>10: + askreconnect = 0 + if self.serdev.isopened()==False: #for some reason it will never be false? + self.connect() #may cause a lot problems as it is running from separated thread try: self.serdev.close() except: @@ -261,9 +270,17 @@ def plugin_write(self,cmd): sbuf = str(text) if cmdarr[0] == "serialwriteln": sbuf += "\n" + written = 0 if self.serdev is not None: try: - self.serdev.write(sbuf) + written = self.serdev.write(sbuf) except Exception as e: pass - return res + if written<=0: + self.connect() + if self.serdev is not None: + try: + written = self.serdev.write(sbuf) + except Exception as e: + pass + return (written>0) diff --git a/lib/lib_gpiohelper.py b/lib/lib_gpiohelper.py index 83a66a1..293e9a4 100644 --- a/lib/lib_gpiohelper.py +++ b/lib/lib_gpiohelper.py @@ -83,18 +83,43 @@ def gpio_commands(cmd): except: pin = -1 prop = -1 + fade = 0 + try: + fade = int(cmdarr[3].strip()) + except: + fade = 0 freq = 1000 try: - freq = int(cmdarr[3].strip()) + freq = int(cmdarr[4].strip()) except: freq = 1000 if pin>-1 and prop>-1: suc = False try: suc = True - gpios.HWPorts.output_pwm(pin,prop,freq) - logline = "BCM"+str(pin)+" PWM "+str(prop)+"% "+str(freq)+"Hz" - misc.addLog(rpieGlobals.LOG_LEVEL_DEBUG,logline) + if fade==0: + gpios.HWPorts.output_pwm(pin,prop,freq) + logline = "BCM"+str(pin)+" PWM "+str(prop)+"% "+str(freq)+"Hz" + misc.addLog(rpieGlobals.LOG_LEVEL_DEBUG,logline) + else: + cs = gpios.GPIO_get_statusid(pin) + prev_value = 0 + try: + if cs>-1: + if gpios.GPIOStatus[cs]["mode"] == "pwm": + prev_value = int(gpios.GPIOStatus[cs]["state"]) + except: + prev_value = 0 + step_value = (int(prop - prev_value) << 12) / fade + curr_value = int(prev_value) << 12 + i = fade + while i>0: + curr_value += step_value + new_value = int(curr_value) >> 12 + gpios.HWPorts.output_pwm(pin,new_value,freq) + time.sleep(0.001) # 1 millisecond in theory, more in reality.. + i -= 1 + gpios.HWPorts.output_pwm(pin,prop,freq) gi = gpios.GPIO_refresh_status(pin,pstate=prop,pluginid=1,pmode="pwm",logtext=logline) except Exception as e: misc.addLog(rpieGlobals.LOG_LEVEL_ERROR,"BCM"+str(pin)+" PWM "+str(e)) @@ -294,4 +319,4 @@ def play_rtttl(pin,notestr): play_tone(pin,int(note['frequency']),float(note['duration'])) except: pass - gpios.HWPorts.output_pwm(pin,0,0) # stop sound + gpios.HWPorts.output_pwm(pin,0,0) # stop sound diff --git a/rpieGlobals.py b/rpieGlobals.py index 5694273..13b1f7d 100644 --- a/rpieGlobals.py +++ b/rpieGlobals.py @@ -6,7 +6,7 @@ # Copyright (C) 2018-2020 by Alexander Nagy - https://bitekmindenhol.blog.hu/ # PROGNAME = "RPIEasy" -BUILD = 20348 +BUILD = 20350 PROGVER = str(BUILD)[:1]+"."+str(BUILD)[1:2]+"."+str(BUILD)[2:] gpMenu = []