Source code for router_handler

# -*- coding: UTF-8 -*-


"""
| This Modules handles all the comunication to nodes.
| It will routes the varius commands knowing where to send them based on the node address.
|
| If the node_address of the given receiver is 0 the data will be written to the local OnosCenter pins.
|
| if the node_address of the given receiver is 1 the data will be sent to the OnosCenter serial port to an arduino (not implemented yet)
|
| If the node_address of the given receiver is between 2 to 255 :
|   OnosCenter will send the command to write the data to an arduino wich will then transmit it to the desired wireless node.(not implemented yet)
|
| If the node_address of the given receiver is a string greater than 6 characters:
    The data will be sent over ethernet commmunication.
|




"""




from globalVar import *
from node_query_handler import *



# Note for raspberry users, the GPIO numbers that you program here refer to the pins
# of the BCM2835 and *not* the numbers on the pin header. 
# So, if you want to activate GPIO7 on the header you should be 
# using GPIO4 in this script. Likewise if you want to activate GPIO0
# on the header you should be using GPIO17 here.


#echo "24" > /sys/class/gpio/export 
# to clean up a pin exported  : echo "4" > /sys/class/gpio/unexport
#echo "out" > /sys/class/gpio/gpio24/direction
#echo "1" > /sys/class/gpio/gpio24/value

#echo "in" > /sys/class/gpio/gpio23/direction
#cat /sys/class/gpio/gpio23/value




[docs]class RouterHandler: def __init__(self,hardwareModelDict,router_sn): self.router_sn=router_sn self.bash_pin_enable=0 #os.system("echo classe >> numero_classi_raspberry_handler") self.pins_mode={} self.pins_status={} self.old_pins_status={} self.hwModelName=hardwareModelDict["hwName"] self.__hardware_type=hardwareModelDict["hardware_type"] self.__node_name=self.router_sn # RouterGL0001 self.exit=0 self.router_pin_numbers=[] #self.read_thread_running=0 self.arduino_used=0 self.local_pin_enabled=0 self.__maxPin=hardwareModelDict["max_pin"] #17 -2 used for uart self.router_pin_numbers=getListUsedPinsByHardwareModel(self.hwModelName) print "pin used =" print self.router_pin_numbers #print "digital input router pin total number= " #print (getListPinsConfigByHardwareModel(self.hwModelName,"digital_input")) self.router_input_pin=getListPinsConfigByHardwareModel(self.hwModelName,"digital_input") self.total_in_pin=len(self.router_input_pin) #get the number of digital inputs if self.__hardware_type=="rasberry_b_rev2_only": #banana to import this from hardwareModelDict self.bash_pin_enable=1 if self.__hardware_type=="gl.inet_only": self.bash_pin_enable=1 if self.__hardware_type=="gl.inet_with_arduino2009": self.arduino_used=1 arduino=arduino_handler.ArduinoHandler() self.bash_pin_enable=1 if (os.path.exists("/sys/class/gpio")==1) : #if the directory exist ,then the hardware has embedded IO pins print "discovered local hardware io pins" self.bash_pin_enable=1 else: self.bash_pin_enable=0 #disable embedded pins because the harware hasn't got any print "no embedded IO pins founded , are you running onos on a pc?" error_number=0 #count how many errors.. if self.bash_pin_enable==1: for pin in self.router_pin_numbers: self.pins_status[pin]=0 # create the pin var in the dictionary try: print "i try to execute echo "+str(pin)+" > /sys/class/gpio/export " #os.popen('echo '+str(pin)+' > /sys/class/gpio/unexport ').read() #remove a GPIO file access with lock_bash_cmd: subprocess.call('echo '+str(pin)+' > /sys/class/gpio/unexport ', shell=True) #os.popen('echo '+str(pin)+' > /sys/class/gpio/export ').read() #Create a GPIO file access subprocess.call('echo '+str(pin)+' > /sys/class/gpio/export ', shell=True,close_fds=True) except Exception, e : error_number=error_number+1 print "error can't create GPIO pin:"+str(pin)+" and set its mode :"+str(e.args) errorQueue.put("error can't create GPIO pin:"+str(pin)+" and set its mode :"+str(e.args)) time.sleep(1) if pin in self.router_input_pin: self.pins_mode[pin]=0 # set the pin as input try: with lock_bash_cmd: subprocess.call('echo in > /sys/class/gpio/gpio'+str(pin)+'/direction', shell=True,close_fds=True) #os.popen('echo in > /sys/class/gpio/gpio'+str(pin)+'/direction').read() #set the GPIO as input except Exception, e : print "error trying to read a router pin :"+str(e.args) errorQueue.put( "error trying to read a router pin :"+str(e.args)) error_number=error_number+1 time.sleep(1) try: print "i try to read the status with: cat /sys/class/gpio/gpio"+str(pin)+"/value" with lock_bash_cmd: status=subprocess.check_output("cat /sys/class/gpio/gpio"+str(pin)+"/value", shell=True,close_fds=True) #status=os.popen("cat /sys/class/gpio/gpio"+str(pin)+"/value").read() self.pins_status[pin]=int(status[0]) except Exception, e : self.pins_status[pin]=0 print "error in reading pin"+str(pin) errorQueue.put("error in reading pin"+str(pin) ) error_number=error_number+1 else: self.pins_mode[pin]=1 # set the pin as output print "i try to set the pin as output" try: with lock_bash_cmd: #os.popen('echo out > /sys/class/gpio/gpio'+str(pin)+'/direction').read() #set the GPIO as output subprocess.call('echo out > /sys/class/gpio/gpio'+str(pin)+'/direction', shell=True,close_fds=True) except Exception, e : error_number=error_number+1 print "error setting pin"+str(pin)+ "as output" errorQueue.put( "error setting pin"+str(pin)+ "as output") errorQueue.put(e.args) if error_number >5: self.bash_pin_enable=0 #disable the bash pin command if too many error happen print "too many error commandi the router pins , are you running onos on a pc?" errorQueue.put("too many error commandi the router pins , are you running onos on a pc?" ) # if ( (len (self.pin_numbers) >0)&(self.bash_pin_enable==1)): # #if the router hardware has any hardware pins ..then run the thread in order to read them # self.exit==0 # self.tr_read = threading.Thread(target=self.read_router_pins) # self.tr_read.daemon = True #make the thread a daemon thread # self.tr_read.start() # else: # print "i don't start the reading thread because i can't read the hw pins"
[docs] def read_router_pins(self): # thread function to read changing of pin status #print "read_router_pins() executed" if ( (len (self.router_pin_numbers) >0)&(self.bash_pin_enable==1)): #if the router hardware has any hardware pins ..then run the thread in order to read them #print "starting to read pins" x=0 #void operation else: print "i don't start the reading function because i can't read the router hw pins" errorQueue.put("i don't start the reading function because i can't read the router hw pins") return(-1) if (self.total_in_pin<1) :#there is no input pin to read print "there is no input pin to read" errorQueue.put("there is no input pin to read") return(-1) #time.sleep(3) #wait for the webserver if (self.exit==0): # if is not exiting time for pin in self.router_pin_numbers: if (self.exit==1): return #print "pin to read="+str(pin) if self.pins_mode[pin]==0: #if the pin is an input one current_state=self.pins_status[pin] #total_in_pin=total_in_pin+1 #print "foud a input pin in the router, pin number"+str(pin) #try: with lock_bash_cmd: status=subprocess.check_output("cat /sys/class/gpio/gpio"+str(pin)+"/value", shell=True,close_fds=True) #status=os.popen("cat /sys/class/gpio/gpio"+str(pin)+"/value").read() current_state=int(status[0]) #print "the current pin status is: "+str(current_state) #except: # print "error in reading pin"+str(pin) # continue #restart the loop if self.pins_status[pin]!=current_state: #if the value is different from the old one self.pins_status[pin]=current_state # update the old pin status with the current one print "the router pin: "+str(pin) +" input status changed to: "+str(current_state) #priority=99 usersDict["onos_node"]["priority"] priority=99 #99 will allow the x but will not increase the object priority priorityCmdQueue.put( {"cmd":"setNodePin","node_sn":self.router_sn,"pinNumber":int(pin),"status_to_set":int(current_state),"write_to_hw":0,"user":"onos_node","priority":priority,"mail_report_list":[] } ) return(1)
[docs] def composeChangeNodeOutputPinStatusQuery(self,pinNumbers,node_obj,objName,status_to_set,node_serial_number,out_type,user,priority,mail_report_list) : print "composeChangeNodeOutputPinStatusQuery() executed" numeric_serial_number=node_serial_number[-4:] # example get 0001 from "ProminiA0001" address=node_obj.getNodeAddress() base_query='' #' ''http://'''+address+''':'''+str(node_webserver_port) if (out_type=="sr_relay"): pin1=str(pinNumbers[0]) pin0=str(pinNumbers[1]) if (len (pin0) <2): pin0='0'+pin0 if (len (pin1) <2): pin1='0'+pin1 query=base_query+'''onos_r'''+pin0+pin1+'''v'''+str(status_to_set)+'''s'''+numeric_serial_number+'''_#]''' if (out_type=="digital_output"): if type(pinNumbers) not in (tuple, list): #if c is not a list , trasform it in a list of one element pinNumbers=[pinNumbers] pin=str(pinNumbers[0]) if (len (pin) <2): pin='0'+pin #onos_d07v001s0001_#] query=base_query+'''onos_d'''+pin+'''v'''+'''00'''+str(status_to_set)+'''s'''+numeric_serial_number+'''_#]''' if (out_type=="servo_output"): if type(pinNumbers) not in (tuple, list): #if c is not a list , trasform it in a list of one element pinNumbers=[pinNumbers] pin=str(pinNumbers[0]) if (len (pin) <2): pin='0'+pin status_to_set=str(status_to_set) while (len(status_to_set)) <3: status_to_set='0'+status_to_set #onos_s07v180s0001_#] query=base_query+'''onos_s'''+pin+'''v'''+status_to_set+'''s'''+numeric_serial_number+'''_#]''' if (out_type=="analog_output"): if type(pinNumbers) not in (tuple, list): #if c is not a list , trasform it in a list of one element pinNumbers=[pinNumbers] pin=str(pinNumbers[0]) if (len (pin) <2): pin='0'+pin status_to_set=str(status_to_set) while (len(status_to_set)) <3: status_to_set='0'+status_to_set #onos_a07v100s0001_#] query=base_query+'''onos_a'''+pin+'''v'''+status_to_set+'''s'''+numeric_serial_number+'''_#]''' print "query to remote node:"+query queryToNodeQueue.put({"node_serial_number":node_serial_number,"address":address,"query":query,"objName":objName,"status_to_set":status_to_set,"user":user,"priority":priority,"mail_report_list":mail_report_list}) with lock1_current_node_handler_list: print "lock1a from router_handler"+node_serial_number print "current_node_handler_list:",current_node_handler_list node_not_being_contacted=(node_serial_number not in current_node_handler_list) #with lock2_query_threads: #query_threads_number=node_query_threads_executing if (node_not_being_contacted) : #there is not a query thread running for this node thread executing print "no handler running for this node" #handle_new_query_to_remote_node(node_serial_number,address,query,objName,status_to_set,user,priority,mail_report_list) if (node_query_threads_executing<max_number_of_node_query_threads_executing): # there are less than x node query thread running tr_handle_new_query_to_remote_node = threading.Thread(target=handle_new_query_to_remote_node_thread) tr_handle_new_query_to_remote_node.daemon = True #make the thread a daemon thread tr_handle_new_query_to_remote_node.start() else: print "too many node_query_threads_executing: ",query_threads_number else:#there is already a query thread running for this node print "there is already a query thread running for this node :"+node_serial_number return()
[docs] def outputWrite(self,node_serial_number,pinList,statusList,node_obj,objName,previous_status,statusToSet,output_type,user,priority,mail_report_list): print "executed router_handler digitalwrite()" node_address=node_obj.getNodeAddress() remoteNodeHwModel=node_obj.getNodeHwModel() if len(pinList)<1: print "error len pinList<1 ,len="+str(len(pinList)) errorQueue.put( "error len pinList<1 ,len="+str(len(pinList))) if len(pinList)!=len(statusList): print "error in the router handler, len pinlist!=statusList" errorQueue.put("error in the router handler, len pinlist!=statusList" ) try: print "len pinlist="+str(len(pinList))+ " len statusList="+str(len(statusList)) except Exception, e : print "can't print len of statusList or pinlist" print (e.args) return(-1) # if (previous_status==statusToSet): #if nothing needs to be changed...i will return # print "statusToSet equal to previous status.." # return(1) if ((str(node_address))=="0"): #if is selected the router as node print "the node selected is the router one" if ((output_type=="analog_output")or(output_type=="servo_output")): print "error the router cannot handle "+output_type+" type" errorQueue.put( "error the router cannot handle "+output_type+" type") return(-1) if (self.bash_pin_enable==1): # if the router has IO pins print "the router has the pin io enabled" i=0 print "len pinlist="+str(len(pinList)) while i <len(pinList) : pinNumber=pinList[i] tmp_status_to_set=statusList[i] if (pinNumber not in self.router_pin_numbers )or((tmp_status_to_set!=0)and(tmp_status_to_set!=1)): print 'error the pin value is out of range of rasberry '+self.hwModelName+"pin_number="+str(pinNumber) errorQueue.put('error the pin value is out of range of rasberry '+self.hwModelName+"pin_number="+str(pinNumber) ) print "status to set="+str(tmp_status_to_set) errorQueue.put( "status to set="+str(tmp_status_to_set)) return(-1) if self.pins_mode[pinNumber]==0: # if the pin is setted as input.. then set it as output self.pins_mode[pinNumber]=1 print "pin setted as input i try to set it as output" errorQueue.put("pin setted as input i try to set it as output") try: #os.system('echo out > /sys/class/gpio/gpio'+str(pinNumber)+'/direction') #set the GPIO as output with lock_bash_cmd: subprocess.call('echo out > /sys/class/gpio/gpio'+str(pinNumber)+'/direction', shell=True,close_fds=True) print "pin"+str(pinNumber)+" setted as output " except Exception, e : print "error can't configure the pin:"+str(pinNumber)+" as output and set it to "+str(tmp_status_to_set) errorQueue.put("error can't configure the pin:"+str(pinNumber)+" as output and set it to "+str(tmp_status_to_set) ) errorQueue.put(e.args) i=i+1 return(-1) try: #os.popen('echo '+str(tmp_status_to_set)+' > /sys/class/gpio/gpio'+str(pinNumber)+'/value').read() with lock_bash_cmd: subprocess.check_output('echo '+str(tmp_status_to_set)+' > /sys/class/gpio/gpio'+str(pinNumber)+'/value', shell=True,close_fds=True) print "pin"+str(pinNumber)+" setted to "+str(tmp_status_to_set) except Exception, e : print "error can't set the pin:"+str(pinNumber)+" to "+str(tmp_status_to_set) errorQueue.put("error can't set the pin:"+str(pinNumber)+" to "+str(tmp_status_to_set) ) errorQueue.put(e.args) return(-1) i=i+1 #self.makeChangeWebObjectStatusQuery(objName,statusToSet) priorityCmdQueue.put( {"cmd":"setSts","webObjectName":objName,"status_to_set":statusToSet,"write_to_hw":0,"user":user,"priority":priority,"mail_report_list":mail_report_list }) return(1) else: #the router has't got IO pins print "the router has no IO pin" return (-1) if ((str(node_address))=="1"): #a local arduino selected not implemented yet print "i write to/from a remote node selected" #self.makeChangeWebObjectStatusQuery(objName,statusToSet) #banana to remove if ((self.arduino_used==1)&(node_address=="1")): #check if arduino is enabled correctly and is selected with 1 print "digital write used on arduino" if len(pinList) >1: print "i have to set more than a pin at the same time" packet_list=[] i=0 pinList=pinList.sort() #order the list by pin number previus_section=-1 section=previus_section while (i<len(pinList)): section=node_obj.getNodeSectionStatusByPin(pinList[i])[0] if(section!=previus_section): previus_section=section section_status=node_obj.getNodeSectionStatusByPin(pinList[i])[1]#get the section status packet_list.append(section,section_status) i=i+1 #now inside packet_list i have a tuple #where the first element is the pin byte section and the second the data is the status byte for that section i=0 for a in packet_list: #write to arduino all the registers arduino.digitalWriteSection(node_address,a[0],a[1],objName,previous_status,statusToSet) else: #only one pin to set arduino.digitalWrite(node_address,pinList[0],statusList[0],objName,previous_status,statusToSet)#write to arduino to set a pin else: #str(node_address))!="1" and !=0 ---> remote node selected print "i write to/from a remote node with address:"+str(node_address) i=0 print "len address="+str(len(node_address)) print "len pinlist="+str(len(pinList)) if (output_type=="sr_relay"): if (len(pinList)==2): self.composeChangeNodeOutputPinStatusQuery(pinList,node_obj,objName,statusToSet,node_serial_number,output_type,user,priority,mail_report_list) return(1) else: print "error number of pins !=2" errorQueue.put("error number of pins !=2" ) return(-1) while i <len(pinList) : pinNumber=pinList[i] tmp_status_to_set=statusList[i] if (pinNumber not in node_obj.getUsedPins()): print 'error the pin value is out of range of node :'+remoteNodeHwModel+"pin_number="+str(pinNumber) errorQueue.put('error the pin value is out of range of node :'+remoteNodeHwModel+"pin_number="+str(pinNumber) ) print "status to set="+str(tmp_status_to_set) errorQueue.put("status to set="+str(tmp_status_to_set) ) print str(pinNumber) errorQueue.put(str(pinNumber)) return(-1) self.composeChangeNodeOutputPinStatusQuery(pinNumber,node_obj,objName,tmp_status_to_set,node_serial_number,output_type,user,priority,mail_report_list) i=i+1 #start a thread query to the node return(1)
[docs] def setHwPinMode(self,node_address,pinNumber,mode): print "router_handler setHwPinMode() executed" if node_address=="0" : #the node is the router itself if pinNumber in self.router_pin_numbers : if (self.bash_pin_enable==1): if mode=="DOUTPUT": self.pins_mode[pinNumber]=1 try: with lock_bash_cmd: subprocess.check_output('echo "out" > /sys/class/gpio/gpio'+str(pinNumber)+'/direction', shell=True,close_fds=True) #os.popen('echo "out" > /sys/class/gpio/gpio'+str(pinNumber)+'/direction').read() #set the GPIO as output except Exception, e : print "error can't set the direction of the pin: /sys/class/gpio/gpio"+str(pinNumber) errorQueue.put("error can't set the direction of the pin: /sys/class/gpio/gpio"+str(pinNumber) ) errorQueue.put(e.args) for a in self.pins_mode: #check every pin to understand if there are pin setted as input if a==0: self.total_in_pin=self.total_in_pin+1 if mode=="DINPUT": self.pins_mode[pinNumber]=0 try: with lock_bash_cmd: subprocess.check_output('echo "in" > /sys/class/gpio/gpio'+str(pinNumber)+'/direction', shell=True,close_fds=True) #os.popen('echo "in" > /sys/class/gpio/gpio'+str(pinNumber)+'/direction').read() #set the GPIO as input except Exception, e : print "error can't set the direction of the pin: /sys/class/gpio/gpio"+str(pinNumber) errorQueue.put( "error can't set the direction of the pin: /sys/class/gpio/gpio"+str(pinNumber)) errorQueue.put(e.args) #if self.read_thread_running==0: #if the thread is not running then run it # self.tr_read = threading.Thread(target=self.read_router_pins) # self.tr_read.daemon = True #make the thread a daemon thread # self.tr_read.start() else: print "the router has no IO pin" return(-1) else: print "pinNumber out of range" return(-1) else: #banana make there the configuration pin of remote nodes print "the node address to write to is "+str(node_address)
[docs] def getRouterName(self): return(self.hwModelName)
[docs] def close(self): self.exit=1 print "class router_handler destroyed" try: os.close(self.fd) except : print "tried to close serial port"