$search
00001 """ 00002 dispatch.py 00003 00004 By Paul Malmsten, 2010 00005 pmalmsten@gmail.com 00006 00007 Provides the Dispatch class, which allows one to filter incoming data 00008 packets from an XBee device and call an appropriate method when 00009 one arrives. 00010 """ 00011 00012 from xbee import XBee 00013 00014 class Dispatch(object): 00015 def __init__(self, ser=None, xbee=None): 00016 self.xbee = None 00017 if xbee: 00018 self.xbee = xbee 00019 elif ser: 00020 self.xbee = XBee(ser) 00021 00022 self.handlers = [] 00023 self.names = set() 00024 00025 def register(self, name, callback, filter): 00026 """ 00027 register: string, function: string, data -> None, function: data -> boolean -> None 00028 00029 Register will save the given name, callback, and filter function 00030 for use when a packet arrives. When one arrives, the filter 00031 function will be called to determine whether to call its associated 00032 callback function. If the filter method returns true, the callback 00033 method will be called with its associated name string and the packet 00034 which triggered the call. 00035 """ 00036 if name in self.names: 00037 raise ValueError("A callback has already been registered with the name '%s'" % name) 00038 00039 self.handlers.append( 00040 {'name':name, 00041 'callback':callback, 00042 'filter':filter} 00043 ) 00044 00045 self.names.add(name) 00046 00047 def run(self, oneshot=False): 00048 """ 00049 run: boolean -> None 00050 00051 run will read and dispatch any packet which arrives from the 00052 XBee device 00053 """ 00054 if not self.xbee: 00055 raise ValueError("Either a serial port or an XBee must be provided to __init__ to execute run()") 00056 00057 while True: 00058 self.dispatch(self.xbee.wait_read_frame()) 00059 00060 if oneshot: 00061 break 00062 00063 def dispatch(self, packet): 00064 """ 00065 dispatch: XBee data dict -> None 00066 00067 When called, dispatch checks the given packet against each 00068 registered callback method and calls each callback whose filter 00069 function returns true. 00070 """ 00071 for handler in self.handlers: 00072 if handler['filter'](packet): 00073 # Call the handler method with its associated 00074 # name and the packet which passed its filter check 00075 handler['callback'](handler['name'], packet)