def __init__(self, id, category=None, name=None, desc=None, positions=None, parser=None, validator=None, formatter=None, unit=None, flags=FLAG_NONE): if not isinstance(id, str) or len(id) == 0: raise Exception("Invalid Elemenet ID: %s" % (id)) # Short name (no restrictions, as yet) self._id = id # Category for grouping self._category = category # Human-readable name self._name = name # Description self._desc = desc # Offset of relevant data if positions is not None and (isinstance(positions, list) or isinstance(positions, dict)): positions = ByteOffset(positions) self._positions = positions or utils.find_subclass( CustomOffset, [parser, validator, formatter]) if self._positions is None: raise Exception("Element '%s' must have a supplier of offsets" % (id)) #print "%s: %s" % (id, self._positions.get_trigger_indices()) # Parser takes raw data picked by 'positions' definition and assembles final value self._parser = parser or utils.find_subclass( Parser, [validator, formatter, positions]) if self._parser is None: raise Exception("Element '%s' does not have a parser" % (id)) # Validator takes final value and determines the values correctness/goodness self._validator = validator or utils.find_subclass( Validator, [parser, formatter, positions]) or Validator() # Formatter will determine how final value is printed self._formatter = formatter or utils.find_subclass( Formatter, [parser, validator, positions]) or Formatter() # Unit of value self._unit = unit # Flags self._flags = flags
def __init__(self, id, category=None, name=None, desc=None, positions=None, parser=None, validator=None, formatter=None, unit=None, flags=FLAG_NONE): if not isinstance(id, str) or len(id) == 0: raise Exception("Invalid Elemenet ID: %s" % (id)) # Short name (no restrictions, as yet) self._id = id # Category for grouping self._category = category # Human-readable name self._name = name # Description self._desc = desc # Offset of relevant data if positions is not None and (isinstance(positions, list) or isinstance(positions, dict)): positions = ByteOffset(positions) self._positions = positions or utils.find_subclass(CustomOffset, [parser, validator, formatter]) if self._positions is None: raise Exception("Element '%s' must have a supplier of offsets" % (id)) #print "%s: %s" % (id, self._positions.get_trigger_indices()) # Parser takes raw data picked by 'positions' definition and assembles final value self._parser = parser or utils.find_subclass(Parser, [validator, formatter, positions]) if self._parser is None: raise Exception("Element '%s' does not have a parser" % (id)) # Validator takes final value and determines the values correctness/goodness self._validator = validator or utils.find_subclass(Validator, [parser, formatter, positions]) or Validator() # Formatter will determine how final value is printed self._formatter = formatter or utils.find_subclass(Formatter, [parser, validator, positions]) or Formatter() # Unit of value self._unit = unit # Flags self._flags = flags
def run(self): with self.update_lock: for update in self.pending_updates: client_address, msg = update client = self.get_client(client_address) # Lock released below if not client: raise Exception("Client went missing: %s" % (str(client_address))) successful_elements, failed_elements = [], [] response = {'action':None, 'result':(successful_elements,failed_elements), 'error':None, 'seq':None} try: action = msg['action'].lower() data = msg['data'] response['action'] = action response['seq'] = msg['seq'] if action == "register": for element_id in data: element_state = self.element_state_manager.get_element_state(element_id, safe=False) if element_state is None: failed_elements += [element_id] continue trigger_indices = element_state.get_element().positions().get_trigger_indices(mode=self.engine.options.mode) self.engine.track(trigger_indices, self) for trigger_index in trigger_indices: if trigger_index not in self.registration_map.keys(): self.registration_map[trigger_index] = [] self.registration_map[trigger_index] += [client_address] if trigger_index not in client.registration_map.keys(): client.registration_map[trigger_index] = [] client.registration_map[trigger_index] += [element_state] element_info = {'id':element_id} element_info['unit'] = element_state.get_element().unit() range_info = utils.find_subclass(primitives.RangeInfo, [element_state.get_element().validator(), element_state.get_element().formatter()]) if range_info: element_info['range_raw'] = (min(range_info.rng), max(range_info.rng)) element_info['range_out'] = (min(range_info.points), max(range_info.points)) successful_elements += [element_info] self.log("%s: Registered: %s" % (client_address, ", ".join([x['id'] for x in successful_elements]))) elif action == "unregister": self.log("%s: Unregistering: %s" % (client_address, ", ".join(map(str, data)))) registered_element_states = self._get_client_element_states(client) element_states = [] # Filter out bad elements, or those that aren't registered for this client for element_id in data: element_state = self.element_state_manager.get_element_state(element_id, safe=False) if element_state is None or element_state not in registered_element_states: failed_elements += [element_id] continue if element_id in successful_elements: continue successful_elements += [element_id] element_states += [element_state] # Remove the elements from the client's map. If the trigger's list is then empty, remove it too, and then remove the client from the server's map. triggers_to_remove = [] for element_state in element_states: for trigger_index in client.registration_map.keys(): client_registration_list = client.registration_map[trigger_index] if element_state in client_registration_list: client_registration_list.remove(element_state) if len(client_registration_list) == 0: del client.registration_map[trigger_index] triggers_to_remove += [trigger_index] # If the client no longer tracks a trigger index, remove the client from the server's map. If the server's list for that trigger index is empty, remove it too. for trigger_index in triggers_to_remove: if trigger_index not in self.registration_map.keys(): raise Exception("Client %s trigger index %s not in server map %s" % (client_address, trigger_index, self.registration_map.keys())) client_address_list = self.registration_map[trigger_index] if client_address not in client_address_list: raise Exception("Client %s not in server's trigger index %s list %s" % (client_address, trigger_index, client_address_list)) client_address_list.remove(client_address) if len(client_address_list) == 0: del self.registration_map[trigger_index] untracked_elements = self._untrack(element_states, client) self.log("%s: Unregistered: %s" % (client_address, ", ".join([x.get_element().id() for x in untracked_elements]))) else: res['error'] = "Action unrecognised: '%s'" % (msg['action']) except Exception, e: print "While Server was handling message:", e res['error'] = str(e) raise client.post(response) self.server.client_lock.release() self.pending_updates = []
def run(self): with self.update_lock: for update in self.pending_updates: client_address, msg = update client = self.get_client(client_address) # Lock released below if not client: raise Exception("Client went missing: %s" % (str(client_address))) successful_elements, failed_elements = [], [] response = { 'action': None, 'result': (successful_elements, failed_elements), 'error': None, 'seq': None } try: action = msg['action'].lower() data = msg['data'] response['action'] = action response['seq'] = msg['seq'] if action == "register": for element_id in data: element_state = self.element_state_manager.get_element_state( element_id, safe=False) if element_state is None: failed_elements += [element_id] continue trigger_indices = element_state.get_element( ).positions().get_trigger_indices( mode=self.engine.options.mode) self.engine.track(trigger_indices, self) for trigger_index in trigger_indices: if trigger_index not in self.registration_map.keys( ): self.registration_map[trigger_index] = [] self.registration_map[trigger_index] += [ client_address ] if trigger_index not in client.registration_map.keys( ): client.registration_map[trigger_index] = [] client.registration_map[trigger_index] += [ element_state ] element_info = {'id': element_id} element_info['unit'] = element_state.get_element( ).unit() range_info = utils.find_subclass( primitives.RangeInfo, [ element_state.get_element().validator(), element_state.get_element().formatter() ]) if range_info: element_info['range_raw'] = (min( range_info.rng), max(range_info.rng)) element_info['range_out'] = (min( range_info.points), max(range_info.points)) successful_elements += [element_info] self.log( "%s: Registered: %s" % (client_address, ", ".join( [x['id'] for x in successful_elements]))) elif action == "unregister": self.log("%s: Unregistering: %s" % (client_address, ", ".join(map(str, data)))) registered_element_states = self._get_client_element_states( client) element_states = [] # Filter out bad elements, or those that aren't registered for this client for element_id in data: element_state = self.element_state_manager.get_element_state( element_id, safe=False) if element_state is None or element_state not in registered_element_states: failed_elements += [element_id] continue if element_id in successful_elements: continue successful_elements += [element_id] element_states += [element_state] # Remove the elements from the client's map. If the trigger's list is then empty, remove it too, and then remove the client from the server's map. triggers_to_remove = [] for element_state in element_states: for trigger_index in client.registration_map.keys( ): client_registration_list = client.registration_map[ trigger_index] if element_state in client_registration_list: client_registration_list.remove( element_state) if len(client_registration_list) == 0: del client.registration_map[trigger_index] triggers_to_remove += [trigger_index] # If the client no longer tracks a trigger index, remove the client from the server's map. If the server's list for that trigger index is empty, remove it too. for trigger_index in triggers_to_remove: if trigger_index not in self.registration_map.keys( ): raise Exception( "Client %s trigger index %s not in server map %s" % (client_address, trigger_index, self.registration_map.keys())) client_address_list = self.registration_map[ trigger_index] if client_address not in client_address_list: raise Exception( "Client %s not in server's trigger index %s list %s" % (client_address, trigger_index, client_address_list)) client_address_list.remove(client_address) if len(client_address_list) == 0: del self.registration_map[trigger_index] untracked_elements = self._untrack( element_states, client) self.log("%s: Unregistered: %s" % (client_address, ", ".join([ x.get_element().id() for x in untracked_elements ]))) else: res['error'] = "Action unrecognised: '%s'" % ( msg['action']) except Exception, e: print "While Server was handling message:", e res['error'] = str(e) raise client.post(response) self.server.client_lock.release() self.pending_updates = []