Exemplo n.º 1
0
    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
Exemplo n.º 2
0
	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
Exemplo n.º 3
0
	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 = []
Exemplo n.º 4
0
    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 = []