def iter_actions(self):
        """Yield the service's actions with their arguments.

        Yields:
            `Action`: the next action.

        Each action is an Action namedtuple, consisting of action_name
        (a string), in_args (a list of Argument namedtuples consisting of name
        and argtype), and out_args (ditto), eg::

            Action(
                name='SetFormat',
                in_args=[
                    Argument(name='DesiredTimeFormat', vartype=<Vartype>),
                    Argument(name='DesiredDateFormat', vartype=<Vartype>)],
                out_args=[]
            )
        """

        # pylint: disable=too-many-locals
        # pylint: disable=invalid-name
        ns = '{urn:schemas-upnp-org:service-1-0}'
        # get the scpd body as bytes, and feed directly to elementtree
        # which likes to receive bytes
        scpd_body = requests.get(self.base_url + self.scpd_url).content
        tree = XML.fromstring(scpd_body)
        # parse the state variables to get the relevant variable types
        vartypes = {}
        srvStateTables = tree.findall('{}serviceStateTable'.format(ns))
        for srvStateTable in srvStateTables:
            statevars = srvStateTable.findall('{}stateVariable'.format(ns))
            for state in statevars:
                name = state.findtext('{}name'.format(ns))
                datatype = state.findtext('{}dataType'.format(ns))
                default = state.findtext('{}defaultValue'.format(ns))
                value_list_elt = state.find('{}allowedValueList'.format(ns))
                if value_list_elt is None:
                    value_list_elt = ()
                value_list = [item.text for item in value_list_elt] or None
                value_range_elt = state.find('{}allowedValueRange'.format(ns))
                if value_range_elt is None:
                    value_range_elt = ()
                value_range = [item.text for item in value_range_elt] or None
                vartypes[name] = Vartype(datatype, default, value_list,
                                         value_range)
        # find all the actions
        actionLists = tree.findall('{}actionList'.format(ns))
        for actionList in actionLists:
            actions = actionList.findall('{}action'.format(ns))
            for i in actions:
                action_name = i.findtext('{}name'.format(ns))
                argLists = i.findall('{}argumentList'.format(ns))
                for argList in argLists:
                    args_iter = argList.findall('{}argument'.format(ns))
                    in_args = []
                    out_args = []
                    for arg in args_iter:
                        arg_name = arg.findtext('{}name'.format(ns))
                        direction = arg.findtext('{}direction'.format(ns))
                        related_variable = arg.findtext(
                            '{}relatedStateVariable'.format(ns))
                        vartype = vartypes[related_variable]
                        if direction == "in":
                            in_args.append(Argument(arg_name, vartype))
                        else:
                            out_args.append(Argument(arg_name, vartype))
                    yield Action(action_name, in_args, out_args)
Yield the service's actions with their arguments.

        Yields:
            `Action`: the next action.

        Each action is an Action namedtuple, consisting of action_name
        (a string), in_args (a list of Argument namedtuples consisting of name
        and argtype), and out_args (ditto), eg::

            Action(
                name='SetFormat',
                in_args=[
                    Argument(name='DesiredTimeFormat', vartype=<Vartype>),
                    Argument(name='DesiredDateFormat', vartype=<Vartype>)],
                out_args=[]
            )