Beispiel #1
0
    def _parse_ircc(self):
        response = self._send_http(
            self.ircc_url, method=HttpMethod.GET, raise_errors=True)

        upnp_device = "{}device".format(URN_UPNP_DEVICE)
        # the action list contains everything the device supports
        self.actionlist_url = find_in_xml(
            response.text,
            [upnp_device,
             "{}X_UNR_DeviceInfo".format(URN_SONY_AV),
             "{}X_CERS_ActionList_URL".format(URN_SONY_AV)]
        ).text
        services = find_in_xml(
            response.text,
            [upnp_device,
             "{}serviceList".format(URN_UPNP_DEVICE),
             ("{}service".format(URN_UPNP_DEVICE), True)],
        )

        lirc_url = urlparse(self.ircc_url)
        for service in services:
            service_id = service.find(
                "{0}serviceId".format(URN_UPNP_DEVICE))

            if service_id is None or \
                    URN_SONY_IRCC not in service_id.text:
                continue

            service_location = service.find(
                "{0}controlURL".format(URN_UPNP_DEVICE)).text

            if service_location.startswith('http://'):
                service_url = ''
            else:
                service_url = lirc_url.scheme + "://" + lirc_url.netloc
            self.control_url = service_url + service_location

        categories = find_in_xml(
            response.text,
            [upnp_device,
             "{}X_IRCC_DeviceInfo".format(URN_SONY_AV),
             "{}X_IRCC_CategoryList".format(URN_SONY_AV),
             ("{}X_IRCC_Category".format(URN_SONY_AV), True)]
        )

        for category in categories:
            category_info = category.find(
                "{}X_CategoryInfo".format(URN_SONY_AV))
            if category_info is None:
                continue

            self._ircc_categories.add(category_info.text)
Beispiel #2
0
    def _parse_dmr(self, data):
        lirc_url = urlparse(self.ircc_url)
        xml_data = xml.etree.ElementTree.fromstring(data)

        for device in find_in_xml(xml_data, [
                ("{0}device".format(URN_UPNP_DEVICE), True),
                "{0}serviceList".format(URN_UPNP_DEVICE)
        ]):
            for service in device:
                service_id = service.find(
                    "{0}serviceId".format(URN_UPNP_DEVICE))
                if "urn:upnp-org:serviceId:AVTransport" not in service_id.text:
                    continue
                transport_location = service.find(
                    "{0}controlURL".format(URN_UPNP_DEVICE)).text
                self.av_transport_url = "{0}://{1}:{2}{3}".format(
                    lirc_url.scheme, lirc_url.netloc.split(":")[0],
                    self.dmr_port, transport_location
                )

        # this is only true for v4 devices.
        if WEBAPI_SERVICETYPE not in data:
            return

        self.api_version = 4
        device_info_name = "{0}X_ScalarWebAPI_DeviceInfo".format(
            URN_SCALAR_WEB_API_DEVICE_INFO
        )

        search_params = [
            ("{0}device".format(URN_UPNP_DEVICE), True),
            (device_info_name, True),
            "{0}X_ScalarWebAPI_BaseURL".format(URN_SCALAR_WEB_API_DEVICE_INFO),
        ]
        for device in find_in_xml(xml_data, search_params):
            for xml_url in device:
                self.base_url = xml_url.text
                if not self.base_url.endswith("/"):
                    self.base_url = "{}/".format(self.base_url)

                action = XmlApiObject({})
                action.url = urljoin(self.base_url, "accessControl")
                action.mode = 4
                self.actions["register"] = action

                action = XmlApiObject({})
                action.url = urljoin(self.base_url, "system")
                action.value = "getRemoteControllerInfo"
                self.actions["getRemoteCommandList"] = action
                self.control_url = urljoin(self.base_url, "IRCC")
Beispiel #3
0
    def _parse_action_list(self):
        response = self._send_http(self.actionlist_url, method=HttpMethod.GET)
        if not response:
            return

        for element in find_in_xml(response.text, [("action", True)]):
            action = XmlApiObject(element.attrib)
            self.actions[action.name] = action

            if action.mode is None:
                action.mode = self.api_version
            if action.url is None and action.name:
                action.url = urljoin(self.actionlist_url,
                                     "?action={}".format(action.name))
                separator = "&"
            else:
                separator = "?"

            if action.name == "register":
                # the authentication is based on the device id and the mac
                action.url = \
                    "{0}{1}name={2}&registrationType=initial&deviceId={3}"\
                    .format(
                        action.url,
                        separator,
                        quote(self.nickname),
                        quote(self.client_id))
                self.api_version = action.mode
                if action.mode == 3:
                    action.url = action.url + "&wolSupport=true"
Beispiel #4
0
    def _parse_system_information(self):
        response = self._send_http(
            self._get_action("getSystemInformation").url,
            method=HttpMethod.GET)
        if not response:
            return

        for element in find_in_xml(response.text, [("supportFunction", "all"),
                                                   ("function", True)]):
            for function in element:
                if function.attrib["name"] == "WOL":
                    self.mac = function.find("functionItem").attrib["value"]
Beispiel #5
0
    def get_playing_status(self):
        """Get the status of playback from the device"""
        data = """<m:GetTransportInfo xmlns:m="urn:schemas-upnp-org:service:AVTransport:1">
            <InstanceID>0</InstanceID>
            </m:GetTransportInfo>"""

        action = "urn:schemas-upnp-org:service:AVTransport:1#GetTransportInfo"

        content = self._post_soap_request(
            url=self.av_transport_url, params=data, action=action)
        if not content:
            return "OFF"
        return find_in_xml(content, [".//CurrentTransportState"]).text
Beispiel #6
0
    def _update_applist(self):
        """Update the list of apps which are supported by the device."""
        if self.api_version < 4:
            url = self.app_url + "/appslist"
            response = self._send_http(url, method=HttpMethod.GET)
        else:
            url = 'http://{}/DIAL/sony/applist'.format(self.host)
            response = self._send_http(url,
                                       method=HttpMethod.GET,
                                       cookies=self._recreate_auth_cookie())

        if response:
            for app in find_in_xml(response.text, [(".//app", True)]):
                data = XmlApiObject({
                    "name": app.find("name").text,
                    "id": app.find("id").text,
                })
                self.apps[data.name] = data
Beispiel #7
0
    def _parse_command_list(self):
        """Parse the list of available command in devices with the legacy api."""
        action_name = "getRemoteCommandList"
        if action_name not in self.actions:
            _LOGGER.debug(
                "Action list not set in device, try calling init_device")
            return

        action = self.actions[action_name]
        url = action.url
        response = self._send_http(url, method=HttpMethod.GET)
        if not response:
            _LOGGER.debug(
                "Failed to get response for command list, device might be off")
            return

        for command in find_in_xml(response.text, [("command", True)]):
            name = command.get("name")
            self.commands[name] = XmlApiObject(command.attrib)
Beispiel #8
0
    def get_status_SOAP(self, param):
        '''
        get status using a SOAP call (if type is AVTransport)
        Spec for UPNP-av-AVTransport: http://upnp.org/specs/av/UPnP-av-AVTransport-v1-Service.pdf
        '''
        params = param.split("::")
        data = '<m:' + params[
            0] + ' xmlns:m="urn:schemas-upnp-org:service:AVTransport:1"><InstanceID>0</InstanceID></m:' + params[
                0] + '>'
        action = "urn:schemas-upnp-org:service:AVTransport:1#" + params[0]

        if self.get_status("power"):
            if "SOAP_" + params[
                    0] not in self.cache or self.cache_time + 5 < time.time():
                try:
                    content = self.device._post_soap_request(
                        url=self.device.av_transport_url,
                        params=data,
                        action=action)
                    self.cache["SOAP_" + params[0]] = content
                    self.cache_time = time.time()

                except Exception as e:
                    return "ERROR: Request failed (" + str(e) + ")"

            else:
                content = self.cache["SOAP_" + params[0]]

            if params[1]:
                result = find_in_xml(content, [".//" + params[1]]).text
            else:
                result = str(content)
            return result

        else:
            return "ERROR: Device is off (SONY)."