예제 #1
0
def _build_action_arguments():
    args = [
        action.Argument('InstanceID', 'in', 'A_ARG_TYPE_InstanceID'),
        action.Argument('CurrentBrightness', 'out', 'Brightness'),
        action.Argument('Color', 'in', 'Color'),
    ]
    return args
예제 #2
0
 def test_argument_as_tuple(self):
     """ Test Argument.as_tuples() """
     arg = action.Argument('SomeArgument', 'in-and-out', 'Brightness')
     self.assertEqual(arg.as_tuples(), [
         ('Name', 'SomeArgument'),
         ('Direction', 'in-and-out'),
         ('Related State Variable', 'Brightness'),
     ])
예제 #3
0
 def test_argument_as_dict(self):
     """ Test Argument.as_dict() """
     arg = action.Argument('SomeArgument', 'in-and-out', 'Brightness')
     self.assertEqual(
         arg.as_dict(), {
             'name': 'SomeArgument',
             'direction': 'in-and-out',
             'related_state_variable': 'Brightness',
         })
예제 #4
0
파일: service.py 프로젝트: Python3pkg/Cohen
        def gotPage(x):
            self.scpdXML, headers = x
            try:
                tree = etree.fromstring(self.scpdXML)
            except Exception as e:
                self.warning(
                    "Invalid service description received from %r: %r",
                    self.get_scpd_url(), e)
                return
            ns = UPNP_SERVICE_NS

            for action_node in tree.findall('.//{%s}action' % ns):
                name = action_node.findtext('{%s}name' % ns)
                arguments = []
                for argument in action_node.findall('.//{%s}argument' % ns):
                    arg_name = argument.findtext('{%s}name' % ns)
                    arg_direction = argument.findtext('{%s}direction' % ns)
                    arg_state_var = argument.findtext(
                        '{%s}relatedStateVariable' % ns)
                    arguments.append(
                        action.Argument(arg_name, arg_direction,
                                        arg_state_var))
                self._actions[name] = action.Action(self, name, 'n/a',
                                                    arguments)

            for var_node in tree.findall('.//{%s}stateVariable' % ns):
                send_events = var_node.attrib.get('sendEvents', 'yes')
                name = var_node.findtext('{%s}name' % ns)
                data_type = var_node.findtext('{%s}dataType' % ns)
                values = []
                """ we need to ignore this, as there we don't get there our
                    {urn:schemas-beebits-net:service-1-0}X_withVendorDefines
                    attibute there
                """
                for allowed in var_node.findall('.//{%s}allowedValue' % ns):
                    values.append(allowed.text)
                instance = 0
                self._variables.get(instance)[name] = variable.StateVariable(
                    self, name, 'n/a', instance, send_events, data_type,
                    values)
                """ we need to do this here, as there we don't get there our
                    {urn:schemas-beebits-net:service-1-0}X_withVendorDefines
                    attibute there
                """
                self._variables.get(instance)[name].has_vendor_values = True

            #print 'service parse:', self, self.device
            self.detection_completed = True
            louie.send('Coherence.UPnP.Service.detection_completed',
                       sender=self.device,
                       device=self.device)
            self.info(
                "send signal Coherence.UPnP.Service.detection_completed for %r",
                self)
            """
예제 #5
0
    def register_vendor_action(self,
                               name,
                               implementation,
                               arguments=None,
                               needs_callback=True):
        """
        enables a backend to add an own, vendor defined, Action to the service

        @ivar name: the name of the new Action
        @ivar implementation: either 'optional' or 'required'
        @ivar arguments: a C{list} if argument C{tuples},
                         like (name,direction,relatedStateVariable)
        @ivar needs_callback: this Action needs a method in the backend or service class
        """

        # FIXME
        # we should raise an Exception when there as an Action with that name already
        # we should raise an Exception when there is no related StateVariable for an Argument
        """ check for action in backend """
        callback = getattr(self.backend, "upnp_%s" % name, None)

        if callback == None:
            """ check for action in ServiceServer """
            callback = getattr(self, "upnp_%s" % name, None)

        if (needs_callback == True and callback == None):
            """ we have one or more 'A_ARG_TYPE_' variables
                issue a warning for now
            """
            if implementation == 'optional':
                self.info(
                    '%s has a missing callback for %s action %s, action disabled'
                    % (self.id, implementation, name))
                return
            else:
                if ((hasattr(self, 'implementation')
                     and self.implementation == 'required')
                        or not hasattr(self, 'implementation')):
                    self.warning(
                        '%s has a missing callback for %s action %s, service disabled'
                        % (self.id, implementation, name))
                raise LookupError("missing callback")

        arguments_list = []
        for argument in arguments:
            arguments_list.append(
                action.Argument(argument[0], argument[1].lower(), argument[2]))

        new_action = action.Action(self, name, implementation, arguments_list)
        self._actions[name] = new_action
        if callback != None:
            new_action.set_callback(callback)
            self.info('Add callback %s for %s/%s' % (callback, self.id, name))
        return new_action
예제 #6
0
    def init_var_and_actions(self):
        '''
        The method :meth:`init_var_and_actions` does two things:

            - retrieve all actions and create the Action classes for our
              (proxy) server.

            - retrieve all variables and create the StateVariable classes
              for our (proxy) server.
        '''
        xml = self.service.get_scpd_xml()
        tree = etree.fromstring(xml)
        ns = xml_constants.UPNP_SERVICE_NS

        for action_node in tree.findall(f'.//{{{ns}}}action'):
            name = action_node.findtext(f'{{{ns}}}name')
            arguments = []
            for argument in action_node.findall(f'.//{{{ns}}}argument'):
                arg_name = argument.findtext(f'{{{ns}}}name')
                arg_direction = argument.findtext(f'{{{ns}}}direction')
                arg_state_var = argument.findtext(
                    f'{{{ns}}}relatedStateVariable')
                arguments.append(
                    action.Argument(arg_name, arg_direction, arg_state_var))
            self._actions[name] = action.Action(self, name, 'n/a', arguments)

        for var_node in tree.findall(f'.//{{{ns}}}stateVariable'):
            send_events = var_node.attrib.get('sendEvents', 'yes')
            name = var_node.findtext(f'{{{ns}}}name')
            data_type = var_node.findtext(f'{{{ns}}}dataType')
            values = []
            ''' we need to ignore this, as there we don't get there our
                {urn:schemas-beebits-net:service-1-0}X_withVendorDefines
                attibute there
            '''
            for allowed in var_node.findall(f'.//{{{ns}}}allowedValue'):
                values.append(allowed.text)
            instance = 0
            self._variables.get(instance)[name] = variable.StateVariable(
                self,
                name,
                'n/a',
                instance,
                send_events,
                data_type,
                values,
            )
            ''' we need to do this here, as there we don't get there our
                {urn:schemas-beebits-net:service-1-0}X_withVendorDefines
                attibute there
            '''
            self._variables.get(instance)[name].has_vendor_values = True
예제 #7
0
        def gotPage(x):
            #print "gotPage"
            #print x
            self.scpdXML, headers = x
            tree = utils.parse_xml(self.scpdXML, 'utf-8').getroot()
            ns = "urn:schemas-upnp-org:service-1-0"

            for action_node in tree.findall('.//{%s}action' % ns):
                name = action_node.findtext('{%s}name' % ns)
                arguments = []
                for argument in action_node.findall('.//{%s}argument' % ns):
                    arg_name = argument.findtext('{%s}name' % ns)
                    arg_direction = argument.findtext('{%s}direction' % ns)
                    arg_state_var = argument.findtext(
                        '{%s}relatedStateVariable' % ns)
                    arguments.append(
                        action.Argument(arg_name, arg_direction,
                                        arg_state_var))
                self._actions[name] = action.Action(self, name, 'n/a',
                                                    arguments)

            for var_node in tree.findall('.//{%s}stateVariable' % ns):
                send_events = var_node.attrib.get('sendEvents', 'yes')
                name = var_node.findtext('{%s}name' % ns)
                data_type = var_node.findtext('{%s}dataType' % ns)
                values = []
                """ we need to ignore this, as there we don't get there our
                    {urn:schemas-beebits-net:service-1-0}X_withVendorDefines
                    attibute there
                """
                for allowed in var_node.findall('.//{%s}allowedValue' % ns):
                    values.append(allowed.text)
                instance = 0
                self._variables.get(instance)[name] = variable.StateVariable(
                    self, name, 'n/a', instance, send_events, data_type,
                    values)
                """ we need to do this here, as there we don't get there our
                    {urn:schemas-beebits-net:service-1-0}X_withVendorDefines
                    attibute there
                """
                self._variables.get(instance)[name].has_vendor_values = True

            #print 'service parse:', self, self.device
            self.detection_completed = True
            louie.send('Coherence.UPnP.Service.detection_completed',
                       sender=self.device,
                       device=self.device)
            self.info(
                "send signal Coherence.UPnP.Service.detection_completed for %r"
                % self)
            """
예제 #8
0
    def init_var_and_actions(self):
        """ retrieve all actions and create the Action
            classes for our (proxy) server

            retrieve all variables and create the StateVariable
            classes for our (proxy) server
        """
        xml = self.service.get_scpd_xml()
        tree = parse_xml(xml, 'utf-8').getroot()
        ns = "urn:schemas-upnp-org:service-1-0"

        for action_node in tree.findall('.//{%s}action' % ns):
            name = action_node.findtext('{%s}name' % ns)
            arguments = []
            for argument in action_node.findall('.//{%s}argument' % ns):
                arg_name = argument.findtext('{%s}name' % ns)
                arg_direction = argument.findtext('{%s}direction' % ns)
                arg_state_var = argument.findtext('{%s}relatedStateVariable' % ns)
                arguments.append(action.Argument(arg_name, arg_direction,
                                                 arg_state_var))
            self._actions[name] = action.Action(self, name, 'n/a', arguments)

        for var_node in tree.findall('.//{%s}stateVariable' % ns):
            send_events = var_node.attrib.get('sendEvents','yes')
            name = var_node.findtext('{%s}name' % ns)
            data_type = var_node.findtext('{%s}dataType' % ns)
            values = []
            """ we need to ignore this, as there we don't get there our
                {urn:schemas-beebits-net:service-1-0}X_withVendorDefines
                attibute there
            """
            for allowed in var_node.findall('.//{%s}allowedValue' % ns):
                values.append(allowed.text)
            instance = 0
            self._variables.get(instance)[name] = variable.StateVariable(self, name,
                                                           'n/a',
                                                           instance, send_events,
                                                           data_type, values)
            """ we need to do this here, as there we don't get there our
                {urn:schemas-beebits-net:service-1-0}X_withVendorDefines
                attibute there
            """
            self._variables.get(instance)[name].has_vendor_values = True
예제 #9
0
    def init_var_and_actions(self):
        desc_file = util.sibpath(
            __file__,
            os.path.join('xml-service-descriptions',
                         '%s%d.xml' % (self.id, int(self.version))))
        tree = ET.parse(desc_file)

        for action_node in tree.findall('.//action'):
            name = action_node.findtext('name')
            implementation = 'required'
            needs_callback = False
            if action_node.attrib.get(
                    '{urn:schemas-beebits-net:service-1-0}X_needs_backend',
                    None) != None:
                needs_callback = True
            if action_node.find('Optional') != None:
                implementation = 'optional'
                if (action_node.find('Optional').attrib.get(
                        '{urn:schemas-beebits-net:service-1-0}X_needs_backend',
                        None
                ) != None or action_node.attrib.get(
                        '{urn:schemas-beebits-net:service-1-0}X_needs_backend',
                        None) != None):
                    needs_callback = True

            arguments = []
            for argument in action_node.findall('.//argument'):
                arg_name = argument.findtext('name')
                arg_direction = argument.findtext('direction')
                arg_state_var = argument.findtext('relatedStateVariable')
                arguments.append(
                    action.Argument(arg_name, arg_direction, arg_state_var))
                if (arg_state_var[0:11] == 'A_ARG_TYPE_'
                        and arg_direction == 'out'):
                    needs_callback = True
                #print arg_name, arg_direction, needs_callback
            """ check for action in backend """
            callback = getattr(self.backend, "upnp_%s" % name, None)

            if callback == None:
                """ check for action in ServiceServer """
                callback = getattr(self, "upnp_%s" % name, None)

            if (needs_callback == True and callback == None):
                """ we have one or more 'A_ARG_TYPE_' variables
                    issue a warning for now
                """
                if implementation == 'optional':
                    self.info(
                        '%s has a missing callback for %s action %s, action disabled'
                        % (self.id, implementation, name))
                    continue
                else:
                    if ((hasattr(self, 'implementation')
                         and self.implementation == 'required')
                            or not hasattr(self, 'implementation')):
                        self.warning(
                            '%s has a missing callback for %s action %s, service disabled'
                            % (self.id, implementation, name))
                    raise LookupError, "missing callback"

            new_action = action.Action(self, name, implementation, arguments)
            self._actions[name] = new_action
            if callback != None:
                new_action.set_callback(callback)
                self.info('Add callback %s for %s/%s' %
                          (callback, self.id, name))

        backend_vendor_value_defaults = getattr(self.backend,
                                                "vendor_value_defaults", None)
        service_value_defaults = None
        if backend_vendor_value_defaults:
            service_value_defaults = backend_vendor_value_defaults.get(
                self.id, None)

        backend_vendor_range_defaults = getattr(self.backend,
                                                "vendor_range_defaults", None)
        service_range_defaults = None
        if backend_vendor_range_defaults:
            service_range_defaults = backend_vendor_range_defaults.get(self.id)

        for var_node in tree.findall('.//stateVariable'):
            instance = 0
            name = var_node.findtext('name')
            implementation = 'required'
            if action_node.find('Optional') != None:
                implementation = 'optional'

            #if implementation == 'optional':
            #    for action_object in self._actions.values():
            #        if name in [a.get_state_variable() for a in action_object.arguments_list]:
            #            break
            #    else:
            #        continue

            send_events = var_node.findtext('sendEventsAttribute')
            data_type = var_node.findtext('dataType')
            values = []
            for allowed in var_node.findall('.//allowedValue'):
                values.append(allowed.text)
            self._variables.get(instance)[name] = variable.StateVariable(
                self, name, implementation, instance, send_events, data_type,
                values)

            dependant_variable = var_node.findtext(
                '{urn:schemas-beebits-net:service-1-0}X_dependantVariable')
            if dependant_variable:
                self._variables.get(
                    instance)[name].dependant_variable = dependant_variable
            default_value = var_node.findtext('defaultValue')
            if default_value:
                self._variables.get(instance)[name].set_default_value(
                    default_value)
            if var_node.find('sendEventsAttribute') != None:
                never_evented = var_node.find(
                    'sendEventsAttribute'
                ).attrib.get(
                    '{urn:schemas-beebits-net:service-1-0}X_no_means_never',
                    None)
                if never_evented is not None:
                    self._variables.get(instance)[name].set_never_evented(
                        never_evented)

            allowed_value_list = var_node.find('allowedValueList')
            if allowed_value_list != None:
                vendor_values = allowed_value_list.attrib.get(
                    '{urn:schemas-beebits-net:service-1-0}X_withVendorDefines',
                    None)
                if service_value_defaults:
                    variable_value_defaults = service_value_defaults.get(
                        name, None)
                    if variable_value_defaults:
                        self.info("overwriting %s default value with %s" %
                                  (name, variable_value_defaults))
                        self._variables.get(instance)[name].set_allowed_values(
                            variable_value_defaults)

                if vendor_values != None:
                    self._variables.get(
                        instance)[name].has_vendor_values = True

            allowed_value_range = var_node.find('allowedValueRange')
            if allowed_value_range:
                vendor_values = allowed_value_range.attrib.get(
                    '{urn:schemas-beebits-net:service-1-0}X_withVendorDefines',
                    None)
                range = {}
                for e in list(allowed_value_range):
                    range[e.tag] = e.text
                    if (vendor_values != None):
                        if service_range_defaults:
                            variable_range_defaults = service_range_defaults.get(
                                name)
                            if (variable_range_defaults != None
                                    and variable_range_defaults.get(
                                        e.tag) != None):
                                self.info(
                                    "overwriting %s attribute %s with %s" %
                                    (name, e.tag,
                                     str(variable_range_defaults[e.tag])))
                                range[e.tag] = variable_range_defaults[e.tag]
                            elif e.text == None:
                                self.info(
                                    "missing vendor definition for %s, attribute %s"
                                    % (name, e.tag))
                self._variables.get(instance)[name].set_allowed_value_range(
                    **range)
                if vendor_values != None:
                    self._variables.get(
                        instance)[name].has_vendor_values = True
            elif service_range_defaults:
                variable_range_defaults = service_range_defaults.get(name)
                if variable_range_defaults != None:
                    self._variables.get(
                        instance)[name].set_allowed_value_range(
                            **variable_range_defaults)
                    self._variables.get(
                        instance)[name].has_vendor_values = True

        for v in self._variables.get(0).values():
            if isinstance(v.dependant_variable, str):
                v.dependant_variable = self._variables.get(instance).get(
                    v.dependant_variable)
예제 #10
0
 def test_argument(self):
     """ Test initialization of Argument() instance """
     arg = action.Argument('SomeArgument', 'in-and-out', 'Brightness')
     self.assertEqual(arg.get_name(), 'SomeArgument')
     self.assertEqual(arg.get_direction(), 'in-and-out')
     self.assertEqual(arg.get_state_variable(), 'Brightness')