def __init__(self, log, peripheralcontroller, localConfig): SharedInstances.static_commandProcessor = self; self.log = log self.peripheralcontroller = peripheralcontroller self.localConfig = localConfig; self.peri = LocalPeripherals(self.log); self.peri.load();
def threaded_function(self): self.localPeripherals = LocalPeripherals(self.log) self.localPeripherals.load() self.localPeripherals.initSwitchPeripherals(switch_callback); self.setLoadSchedules() self.exitThread = False self.log.write(self.MOD_NAME, "starting timer thread loop for peripheral controls") while self.exitThread == False: self.checkSchedules() # timer override the schedules in case it is on self.checkTimers() if(self.dbgcounter == 2): self.dbgcounter = 0 message = "" if(self.p_timers == None): message = message + "No timer" else: count = len(self.p_timers) message = message + str(count) + " timer(s)" self.log.write(self.MOD_NAME, "loop: "+ message) self.dbgcounter+= 1 time.sleep(5) self.log.write(self.MOD_NAME, "exiting thread loop")
class CommandProcessor: ST_CMD_NONE = "0" ST_CMD_UPDATE_PERIPHERALS_STATUS = "20" ST_CMD_GET_PERIPHERALS = "30" ST_CMD_UPDATE_COMMAND_STATUS = "50" ST_CMD_SET_REBOOT_DEVICE = "60" ST_CMD_SET_PERIPHERALS = "200" ST_CMD_SET_TIMER = "230" ST_CLIENT_ID = "cid" ST_CLIENT_PASSWORD = "******" ST_CMDC = "cmdc" ST_CMDCS = "cmds" ST_STI = "sti" #status id ST_STM = "stm" #status message ST_DATA = "data" ST_CMD_REF = "ref" ST_SUMMARY = "summary" STATUS_CODE_OK = "10" STATUS_MESSAGE_OK = "Ok" STATUS_CODE_UNKNOWN_COMMAND = "20" STATUS_MESSAGE_UNKNOWN_COMMAND = "Unknown command" STATUS_CODE_PERIPHERAL_NOT_FOUND = "30" STATUS_CODE_PERIPHERAL_NOT_FOUND_MESSAGE = "Peripheral not found" STATUS_CODE_DATA_NOT_FOUND = "40" STATUS_CODE_DATA_NOT_FOUND_MESSAGE = "Data section not found" STATUS_CODE_ERROR_SAVE_SCHEDULES = "50" STATUS_CODE_ERROR_SAVE_SCHEDULES_MSG = "Unable to save schedules" TIMER_MINUTES = "minutes" TIMER_DEVICE_ID = "peripheral_id" PERIPHERALS = "peri" MODULE_NAME = "CMDPROCESSOR" TIMEOUT15 = 15 ST_DATA_PERIPHERAL = "peripherals" log = None peripheralcontroller = None localConfig = None peri = None; pendingreplies = []; # there are the statuses awaiting to be sent to the server def __init__(self, log, peripheralcontroller, localConfig): SharedInstances.static_commandProcessor = self; self.log = log self.peripheralcontroller = peripheralcontroller self.localConfig = localConfig; self.peri = LocalPeripherals(self.log); self.peri.load(); def beginPostSwitchEvent(self,bcmchanel, newvalue): self.log.write("beginPostSwitchEvent", "readytopost"); self.posterth = Thread(target = self.posterSwitchEventThread, args = (bcmchanel, newvalue,)) self.posterth.start() FIELD_EVENT_PERIPHERAL_ID = "pid"; FIELD_EVENT_PERIPHERAL_TYPE = "ptype" FIELD_EVENT_TIME = "etime" FIELD_EVENT_PERIPHERAL_VALUE = "nvalue" def posterSwitchEventThread(self,bcmchanel,newvalue): lock = threading.RLock() with lock: peripheral = self.peri.findPeripheralByTypeAndGpio(LocalPeripherals.PERI_TYPE_SWITCH, bcmchanel); if(peripheral != None): payload = self.constructPostHeader(); date = str(datetime.datetime.now()); eventdata = { ''+self.FIELD_EVENT_PERIPHERAL_ID+'':'' + peripheral.devid + '',''+self.FIELD_EVENT_PERIPHERAL_TYPE + '':'' + peripheral.ptype + '',''+self.FIELD_EVENT_TIME + '':'' + date + '',''+self.FIELD_EVENT_PERIPHERAL_VALUE+ '':'' + newvalue+''} payload["event"] = eventdata; url = self.localConfig.serveraddress +":"+self.localConfig.serverport +"/diversityclient"; req = urllib.request.Request(url) req.add_header('Content-Type', 'application/json') self.log.write("POSTING the following: ", payload); data = json.dumps(payload) databytes = data.encode('utf-8') req.add_header('Content-Length', len(databytes)) try: response = urllib.request.urlopen(req, databytes, self.TIMEOUT15); self.pendingreplies = []; data = response.read() self.processCommands(data); self.connected_time += 1; except urllib.error.HTTPError as e: self.log.write("post", "HTTP Error: %d"% e.code) self.connection_issues += 1; except urllib.error.URLError as e: self.log.write("post", "URL Error: %s"% e.args) self.connection_issues += 1; except socket.timeout as e: self.log.write("post", "timeout") self.connection_issues += 1; else: self.log.write("beginPostSwitchEvent", "Peripheral not found"); #find the id of the peripheral def beginPost(self,postdata): self.posterth = Thread(target = self.posterThread, args = (postdata, )) self.posterth.start() def addPendingReplies(self, postdata): if len(self.pendingreplies) > 0: postdata["tasks"] = self.pendingreplies; else: self.log.write("addpending tasks", "No pending tasks"); return postdata; def posterThread(self,postdata): lock = threading.RLock() with lock: postdata = self.addPendingReplies(postdata); postdata = self.addPeripheralsStatus(postdata); url = self.localConfig.serveraddress +":"+self.localConfig.serverport +"/diversityclient"; req = urllib.request.Request(url) req.add_header('Content-Type', 'application/json') self.log.write("POSTING the following: ", postdata); data = json.dumps(postdata) databytes = data.encode('utf-8') req.add_header('Content-Length', len(databytes)) try: response = urllib.request.urlopen(req, databytes, self.TIMEOUT15); self.pendingreplies = []; data = response.read() self.processCommands(data); self.connected_time += 1; except urllib.error.HTTPError as e: self.log.write("post", "HTTP Error: %d"% e.code) self.connection_issues += 1; except urllib.error.URLError as e: self.log.write("post", "URL Error: %s"% e.args) self.connection_issues += 1; except socket.timeout as e: self.log.write("post", "timeout") self.connection_issues += 1; wantPost = False; def wantPostNow(self): # self.log.write("wantpost", self.wantPost) return self.wantPost; def postAlive(self): self.wantPost = False; result = self.constructPostHeader(); result[self.ST_SUMMARY] = self.constructSummary(); self.beginPost(result); connected_time = 0; connection_issues = 0; def constructSummary(self): summary = "Connecion success: " +str(self.connected_time)+\ " Failed: "+ str(self.connection_issues); return summary; #self.peripheralcontroller.getSummaryVerbose(); #return "test 123" def processCommands(self, commands): # self.log.write("----- processCommands ------", commands); jcmd = json.loads(commands.decode()); retvalcommands = []; if(self.ST_CMDCS in jcmd): cmds = jcmd[self.ST_CMDCS]; if(cmds != None): for cmd in cmds: onecmd = self.processCommand(cmd); if(onecmd != None): self.log.write(" Message","Adding command to array"); retvalcommands.append(onecmd); else: self.log.write(" Error","command not created"); else: self.log.write(" Error","cmds not found"); # self.log.write("***** processCommands end ******",retvalcommands ); self.pendingreplies.append(retvalcommands); return None; def processCommand(self, command): # self.log.write("------ processCommand ------", command); jcmd = command; commandid = "-1" if(jcmd != None): if(self.ST_CLIENT_ID in jcmd): commandid = jcmd[self.ST_CLIENT_ID] result = None; if(commandid == self.ST_CMD_GET_PERIPHERALS): result = self.cmdGetPeripherals(jcmd) self.wantPost = True; elif(commandid == self.ST_CMD_SET_TIMER): result = self.cmdSetTimer(jcmd) self.wantPost = True; elif(commandid == self.ST_CMD_SET_REBOOT_DEVICE): self.log.write(self.MODULE_NAME, "Will reboot") result = self.cmdReboot(jcmd); self.wantPost = True; else: self.log.write(self.MODULE_NAME, "unknown command") #self.ST_CMD_SET_TIMER, statuscode, statusmessage result = self.constructBaseCommand(commandid, self.STATUS_CODE_UNKNOWN_COMMAND, self.STATUS_MESSAGE_UNKNOWN_COMMAND); return result def cmdReboot(self,jcmd): OSCommands.rebootDevice(); response = { ''+self.ST_CMDC +'':'' + self.ST_CMD_UPDATE_COMMAND_STATUS + '',''+self.ST_CMD_REF + '':'' + jcmd[self.ST_CMD_REF]} return response; def addPeripheralsStatus(self, postdata): #peri = LocalPeripherals(self.log) #self.peri.load(); #jval = peri.toJSON(); postdata["peripherals_stat"] = self.peri.getPeripheralsStatus(self.peripheralcontroller); return postdata; def cmdGetPeripherals(self, jcmd): self.log.write(self.MODULE_NAME, "***********get peripherals************") #peri = LocalPeripherals(self.log) #peri.load(); jval = self.peri.toJSON(); self.log.write(self.MODULE_NAME, "- Create response") retval = self.createResponseSetPeripherals(jcmd[self.ST_CMD_REF], jval); return retval def createResponseSetPeripherals(self, reference, locper): # add aray of peripherals (locper) to response response = { ''+self.ST_CMDC +'':'' + self.ST_CMD_SET_PERIPHERALS + '',''+self.ST_CMD_REF + '':'' + reference + '',''+self.PERIPHERALS + '': locper } return response; #json.dumps(response) def cmdSetTimer(self, jcmd): self.log.write(self.MODULE_NAME, "*********** Set timer ************") datasection = jcmd[self.ST_DATA] # pdb.set_trace() minutes = None deviceid = None statuscode = None statusmessage = None if(datasection != None): minutes = datasection[self.TIMER_MINUTES] iminutes = 0 try: iminutes = int(minutes) except ValueError: iminutes = 0 pass deviceid = datasection[self.TIMER_DEVICE_ID] self.log.write(self.MODULE_NAME, "minutes: " + str(minutes) + " deviceid: " + deviceid); #peri = LocalPeripherals(self.log) #peri.load(); # pdb.set_trace() peripheralobject = self.peri.findPeripheral(deviceid) if(peripheralobject != None): #make sure that this peripheral support this service if(peripheralobject.ptype == LocalPeripherals.PERI_TYPE_OUT_SAINTSMART_RELAY or peripheralobject.ptype == LocalPeripherals.PERI_TYPE_OUT_PIFACE_RELAY): # set timer if(iminutes == 0): self.peripheralcontroller.turnOffPeripheral(peripheralobject) else: self.peripheralcontroller.addOneTimer(peripheralobject, iminutes) statuscode = self.STATUS_CODE_OK statusmessage = self.STATUS_MESSAGE_OK else: statuscode = self.STATUS_CODE_PERIPHERAL_NOT_FOUND statusmessage = self.STATUS_CODE_PERIPHERAL_NOT_FOUND_MESSAGE else: statuscode = self.STATUS_CODE_PERIPHERAL_NOT_FOUND statusmessage = self.STATUS_CODE_PERIPHERAL_NOT_FOUND_MESSAGE else: statuscode = self.STATUS_CODE_DATA_NOT_FOUND statusmessage = self.STATUS_CODE_DATA_NOT_FOUND_MESSAGE # create confirmation message jbase = self.constructBaseCommand(self.ST_CMD_SET_TIMER, statuscode, statusmessage); retval = self.addToData(jbase, self.ST_DATA_PERIPHERAL, deviceid) retval = self.createResponseSetTimerStatus(jcmd[self.ST_CMD_REF]); return retval def createResponseSetTimerStatus(self, reference): # add aray of peripherals (locper) to response response = { ''+self.ST_CMDC +'':'' + self.ST_CMD_UPDATE_COMMAND_STATUS + '',''+self.ST_CMD_REF + '':'' + reference } return response; def constructPostHeader(self): base = { ''+self.ST_CLIENT_ID +'':'' + self.localConfig.clientid + '',''+self.ST_CLIENT_PASSWORD + '':'' + self.localConfig.password + ''} return base def constructBaseCommand(self, commandid, statid, statmsg): base = { ''+self.ST_CMDC+'':'' + commandid + '',''+self.ST_STI + '':'' + statid + '',''+self.ST_STM + '':'' + statmsg+''} return json.dumps(base) def addToData(self, jbase, stkeyname, jdata): self.log.write(self.MODULE_NAME, "- addToData") basedic = json.loads(jbase) if(self.ST_DATA not in basedic): basedic[self.ST_DATA] = {} basedic[self.ST_DATA].update({ stkeyname : jdata }) return json.dumps(basedic)
class PeripheralController: exitThread = False tlock = None log = None MOD_NAME = "PERCON" dbgcounter = 0; piFaceController = None peripheralThread = None loadSchedule = False localPeripherals = None p_timers = [] p_pschedules = [] #PeripheralSchedulesObject def __init__(self): self.log = Logger("logs/controllerlog","txt", True) self.piFaceController = RPIFaceDigitalController() self.tlock = threading.Lock() def join(self): if(self.peripheralThread != None): self.peripheralThread.join() def threaded_function(self): self.localPeripherals = LocalPeripherals(self.log) self.localPeripherals.load() self.localPeripherals.initSwitchPeripherals(switch_callback); self.setLoadSchedules() self.exitThread = False self.log.write(self.MOD_NAME, "starting timer thread loop for peripheral controls") while self.exitThread == False: self.checkSchedules() # timer override the schedules in case it is on self.checkTimers() if(self.dbgcounter == 2): self.dbgcounter = 0 message = "" if(self.p_timers == None): message = message + "No timer" else: count = len(self.p_timers) message = message + str(count) + " timer(s)" self.log.write(self.MOD_NAME, "loop: "+ message) self.dbgcounter+= 1 time.sleep(5) self.log.write(self.MOD_NAME, "exiting thread loop") # self.testCallback(); def testCallback(self): switch_callback(4); def getPeripheralStatus(self, port): retval = "off" if(self.piFaceController.getPortStatus(int(port))): retval = "on" return retval; def getSummaryVerbose(self): text = ""; port1 = self.piFaceController.getPortStatus(0); port2 = self.piFaceController.getPortStatus(1); if(port1): text = "Valve 1 is on."; else: text = "Valve 1 is off."; if(port2): text += " Valve 2 is on."; else: text += " Valve 2 is off."; return text; def turnOffPeripheral(self, peripheralObject): # remove all timers associate to this peripheral self.tlock.acquire() if(self.p_timers != None): try: self.log.write(self.MOD_NAME, "turn off peripheral"); count = len(self.p_timers); for i in range(count-1,-1,-1): pto = self.p_timers[i]; portid = pto.getPeripheralSerialID(); # self.log.write(self.MOD_NAME, "here"); self.log.write(self.MOD_NAME,type(pto.peripheral)); self.log.write(self.MOD_NAME,type(peripheralObject)); if(peripheralObject.devid == pto.peripheral.devid): #delete self.log.write(self.MOD_NAME, "turn off (deleting)"); self.turnPeripheralOff(pto.peripheral); # if(pto.getPeripheralType() == LocalPeripherals.PERI_TYPE_OUT_RELAY): # setGPIOLow(self.pto.getPeripheralGPIO()); # elif(pto.getPeripheralType() == LocalPeripherals.PERI_TYPE_OUT_PIFACE_RELAY): # self.piFaceController.turnOffOutput(int(portid)) del self.p_timers[i] except: self.log.write(self.MOD_NAME, "turn off peripheral. exception"); self.tlock.release() def addOneTimer(self, peripheralObject, duration): pto = PeripheralTimerObject(peripheralObject, duration) self.log.write(self.MOD_NAME, "init relay timer for: "+ str(duration)); self.tlock.acquire() self.p_timers.append(pto) # pdb.set_trace() self.tlock.release() def checkTimers(self): # pdb.set_trace() self.tlock.acquire() if(self.p_timers != None): # self.log.write(self.MOD_NAME, "got timer"); count = len(self.p_timers); for i in range(count-1,-1,-1): pto = self.p_timers[i]; portid = pto.getPeripheralSerialID(); if(pto.isExpired() == True): #delete self.log.write(self.MOD_NAME, "Turning off (expired)"); self.turnPeripheralOff(pto.peripheral); # if(pto.getPeripheralType() == LocalPeripherals.PERI_TYPE_OUT_RELAY): # setGPIOLow(pto.getPeripheralGPIO()); # elif(pto.getPeripheralType() == LocalPeripherals.PERI_TYPE_OUT_PIFACE_RELAY): # self.piFaceController.turnOffOutput(int(portid)) # else: # self.log.write(self.MOD_NAME, "Not action (A) for peipheral type:" + pto.getPeripheralType()); del self.p_timers[i] else: self.turnPeripheralOn(pto.peripheral); #if(pto.getPeripheralType() == LocalPeripherals.PERI_TYPE_OUT_RELAY): # self.log.write(self.MOD_NAME, "Turning on GPIO "); # self.log.write(self.MOD_NAME, pto.getPeripheralGPIO()); # setGPIOHigh(pto.getPeripheralGPIO()); # elif(pto.getPeripheralType() == LocalPeripherals.PERI_TYPE_OUT_PIFACE_RELAY): # self.log.write(self.MOD_NAME, "Turning on (PIFACE) "); # self.piFaceController.turnOnOutput(int(portid)) # else: # self.log.write(self.MOD_NAME, "Not action (B) for peipheral type:" + pto.getPeripheralType()); #turn on self.tlock.release() def setLoadSchedules(self): self.tlock.acquire() self.loadSchedule = True self.tlock.release() _schedulesmessagecounter = 0 def checkSchedules(self): if(self.loadSchedule == True): self.loadSchedule = False self.loadSchedules() self.tlock.acquire() for periSched in self.p_pschedules: # pdb.set_trace() if(periSched != None): periobj = self.localPeripherals.findPeripheral(periSched._peripheralID) if(periSched.isItTime() == True): if(self._schedulesmessagecounter == 20): self._schedulesmessagecounter = 0; self.log.write(self.MOD_NAME, "**** schedule to open peripheral ****") self._schedulesmessagecounter = self._schedulesmessagecounter + 1 self.log.write(self.MOD_NAME, "schedule turning valve on" + periobj.serialid) self.turnPeripheralOn(periobj); # self.rpiController.turnOnOutput(int(periobj.serialid)) else: self.turnPeripheralOff(periobj); # self.rpiController.turnOffOutput(int(periobj.serialid)) self.tlock.release() def turnPeripheralOn(self, periobj): if(periobj.ptype == LocalPeripherals.PERI_TYPE_OUT_SAINTSMART_RELAY): self.log.write(self.MOD_NAME, "Turning on GPIO " + periobj.pgpio); self.log.write(self.MOD_NAME, periobj.pgpio); #Saintsmart relay turn on when gpio is low setGPIOLow(periobj.pgpio); elif(periobj.ptype == LocalPeripherals.PERI_TYPE_OUT_PIFACE_RELAY): self.log.write(self.MOD_NAME, "Turning on (PIFACE relay) "); self.piFaceController.turnOnOutput(int(periobj.serialid)) else: self.log.write(self.MOD_NAME, "Not action (B) for peipheral type:" + pto.getPeripheralType()); def turnPeripheralOff(self, periobj): if(periobj.ptype == LocalPeripherals.PERI_TYPE_OUT_SAINTSMART_RELAY): self.log.write(self.MOD_NAME, "Turning OFF GPIO "+ periobj.pgpio); #Saintsmart relay turn off when gpio is high setGPIOHigh(periobj.pgpio); elif(periobj.ptype == LocalPeripherals.PERI_TYPE_OUT_PIFACE_RELAY): self.log.write(self.MOD_NAME, "Turning OFF (PIFACE relay) "); self.piFaceController.turnOffOutput(int(periobj.serialid)) else: self.log.write(self.MOD_NAME, "Not action (A) for peipheral type:" + pto.getPeripheralType()); def loadSchedules(self): self.tlock.acquire() self.p_pschedules = [] self.log.write(self.MOD_NAME, "---- load schedules") peripherals = self.localPeripherals.getPeripherals() sce = Schedules(self.log) for periObj in peripherals: schedules = sce.loadSchedulesForPeripheral(periObj.devid) self.p_pschedules.append(schedules) self.tlock.release() def startThread(self): if(self.peripheralThread == None): self.peripheralThread = Thread(target = self.threaded_function, args = []) self.peripheralThread.start() def stopThread(self): self.piFaceController.stop(); if(self.peripheralThread != None): with self.tlock: self.exitThread = True