Ejemplo n.º 1
0
    async def test_unknown_out_argument(self):
        r = UpnpTestRequester(RESPONSE_MAP)
        link_service = 'http://localhost:1234/dmr'
        service_type = 'urn:schemas-upnp-org:service:RenderingControl:1'
        test_action = 'GetVolume'

        factory = UpnpFactory(r)
        device = await factory.async_create_device(link_service)
        service = device.service(service_type)
        action = service.action(test_action)

        response = read_file('action_GetVolumeExtraOutParameter.xml')
        try:
            action.parse_response(service_type, {}, response)
            assert False
        except UpnpError:
            pass

        factory = UpnpFactory(r, disable_unknown_out_argument_error=True)
        device = await factory.async_create_device(link_service)
        service = device.service(service_type)
        action = service.action(test_action)

        try:
            action.parse_response(service_type, {}, response)
        except UpnpError:
            assert False
            pass
Ejemplo n.º 2
0
    async def test_unknown_out_argument(self):
        """Test calling an actino and handling an unknown out-argument."""
        requester = UpnpTestRequester(RESPONSE_MAP)
        link_service = "http://localhost:1234/dmr"
        service_type = "urn:schemas-upnp-org:service:RenderingControl:1"
        test_action = "GetVolume"

        factory = UpnpFactory(requester)
        device = await factory.async_create_device(link_service)
        service = device.service(service_type)
        action = service.action(test_action)

        response = read_file("action_GetVolumeExtraOutParameter.xml")
        try:
            action.parse_response(service_type, {}, response)
            assert False
        except UpnpError:
            pass

        factory = UpnpFactory(requester, non_strict=True)
        device = await factory.async_create_device(link_service)
        service = device.service(service_type)
        action = service.action(test_action)

        try:
            action.parse_response(service_type, {}, response)
        except UpnpError:
            assert False
Ejemplo n.º 3
0
def main():
    requester = AioHttpRequester()
    factory = UpnpFactory(requester)
    device = yield from factory.async_create_device(target)

    # get RenderingControle-service
    rc = device.service('urn:schemas-upnp-org:service:RenderingControl:1')

    # perform GetVolume action
    get_volume = rc.action('GetVolume')
    print("Action: {}".format(get_volume))
    result = yield from get_volume.async_call(InstanceID=0, Channel='Master')
    print("Action result: {}".format(result))
Ejemplo n.º 4
0
async def create_device(description_url: str) -> UpnpDevice:
    """Create UpnpDevice."""
    timeout = args.timeout
    requester = AiohttpRequester(timeout)
    non_strict = not args.strict
    factory = UpnpFactory(requester, non_strict=non_strict)
    return await factory.async_create_device(description_url)
Ejemplo n.º 5
0
    async def test_value_min_max(self):
        """Test min/max restrictions."""
        requester = UpnpTestRequester(RESPONSE_MAP)
        factory = UpnpFactory(requester)
        device = await factory.async_create_device("http://localhost:1234/dmr")
        service = device.service(
            "urn:schemas-upnp-org:service:RenderingControl:1")
        state_var = service.state_variable("Volume")

        assert state_var.min_value == 0
        assert state_var.max_value == 100

        state_var.value = 10
        assert state_var.value == 10

        try:
            state_var.value = -10
            assert False
        except UpnpValueError:
            pass

        try:
            state_var.value = 110
            assert False
        except UpnpValueError:
            pass
Ejemplo n.º 6
0
    async def test_format_request_escape(self):
        """Test escaping the request an action sends."""
        requester = UpnpTestRequester(RESPONSE_MAP)
        factory = UpnpFactory(requester)
        device = await factory.async_create_device("http://localhost:1234/dmr")
        service = device.service("urn:schemas-upnp-org:service:AVTransport:1")
        action = service.action("SetAVTransportURI")

        service_type = "urn:schemas-upnp-org:service:AVTransport:1"
        metadata = "<item>test thing</item>"
        _, _, body = action.create_request(
            InstanceID=0,
            CurrentURI="http://example.org/file.mp3",
            CurrentURIMetaData=metadata,
        )

        root = ET.fromstring(body)
        namespace = {"avt_service": service_type}
        assert root.find(".//avt_service:SetAVTransportURI",
                         namespace) is not None
        assert root.find(".//CurrentURIMetaData", namespace) is not None
        assert (root.findtext(".//CurrentURIMetaData", None,
                              namespace) == "<item>test thing</item>")

        current_uri_metadata_el = root.find(".//CurrentURIMetaData", namespace)
        assert current_uri_metadata_el is not None
        # This shouldn't have any children, due to its contents being escaped.
        assert current_uri_metadata_el.findall("./") == []
Ejemplo n.º 7
0
    async def test_on_notify_upnp_event(self):
        changed_vars = []

        def change_handler(self, changed_state_variables):
            nonlocal changed_vars
            changed_vars = changed_state_variables

        r = UpnpTestRequester(RESPONSE_MAP)
        factory = UpnpFactory(r)
        device = await factory.async_create_device('http://localhost:1234/dmr')
        service = device.service(
            'urn:schemas-upnp-org:service:RenderingControl:1')
        service._subscription_sid = 'uuid:e540ce62-7be8-11e8-b1a6-a619ad6a4b38'
        service.on_state_variable_change = change_handler

        headers = {
            'NT': 'upnp:event',
            'NTS': 'upnp:propchange',
            'SID': service._subscription_sid,
        }
        body = """
<e:propertyset xmlns:e="urn:schemas-upnp-org:event-1-0">
    <e:property>
        <Volume>60</Volume>
    </e:property>
</e:propertyset>
"""
        result = service.on_notify(headers, body)
        assert result == 200
        assert changed_vars

        state_var = service.state_variable('Volume')
        assert state_var.value == 60
Ejemplo n.º 8
0
    async def test_value_min_max(self):
        r = UpnpTestRequester(RESPONSE_MAP)
        factory = UpnpFactory(r)
        device = await factory.async_create_device('http://localhost:1234/dmr')
        service = device.service(
            'urn:schemas-upnp-org:service:RenderingControl:1')
        sv = service.state_variable('Volume')

        assert sv.min_value == 0
        assert sv.max_value == 100

        sv.value = 10
        assert sv.value == 10

        try:
            sv.value = -10
            assert False
        except UpnpValueError:
            pass

        try:
            sv.value = 110
            assert False
        except UpnpValueError:
            pass
Ejemplo n.º 9
0
async def create_device(description_url: str) -> UpnpDevice:
    """Create UpnpDevice."""
    timeout = args.timeout
    requester = AiohttpRequester(timeout)
    disable_validation = not args.strict
    factory = UpnpFactory(requester, disable_state_variable_validation=disable_validation)
    return await factory.async_create_device(description_url)
Ejemplo n.º 10
0
    async def test_on_notify_upnp_event(self):
        changed_vars: List[UpnpStateVariable] = []

        def on_event(self, changed_state_variables):
            nonlocal changed_vars
            changed_vars = changed_state_variables

        r = UpnpTestRequester(RESPONSE_MAP)
        factory = UpnpFactory(r)
        device = await factory.async_create_device('http://localhost:1234/dmr')
        service = device.service('urn:schemas-upnp-org:service:RenderingControl:1')
        service.on_event = on_event
        event_handler = UpnpEventHandler('http://localhost:11302', r)
        await event_handler.async_subscribe(service)

        headers = {
            'NT': 'upnp:event',
            'NTS': 'upnp:propchange',
            'SID': 'uuid:dummy',
        }
        body = """
<e:propertyset xmlns:e="urn:schemas-upnp-org:event-1-0">
    <e:property>
        <Volume>60</Volume>
    </e:property>
</e:propertyset>
"""

        result = await event_handler.handle_notify(headers, body)
        assert result == 200

        assert len(changed_vars) == 1

        state_var = service.state_variable('Volume')
        assert state_var.value == 60
Ejemplo n.º 11
0
    async def test_valid_arguments(self):
        """Test validating arguments of an action."""
        requester = UpnpTestRequester(RESPONSE_MAP)
        factory = UpnpFactory(requester)
        device = await factory.async_create_device("http://localhost:1234/dmr")
        service = device.service(
            "urn:schemas-upnp-org:service:RenderingControl:1")
        action = service.action("SetVolume")

        # all ok
        action.validate_arguments(InstanceID=0,
                                  Channel="Master",
                                  DesiredVolume=10)

        # invalid type for InstanceID
        try:
            action.validate_arguments(InstanceID="0",
                                      Channel="Master",
                                      DesiredVolume=10)
            assert False
        except UpnpValueError:
            pass

        # missing DesiredVolume
        try:
            action.validate_arguments(InstanceID="0", Channel="Master")
            assert False
        except UpnpValueError:
            pass
Ejemplo n.º 12
0
    async def test_valid_arguments(self):
        r = UpnpTestRequester(RESPONSE_MAP)
        factory = UpnpFactory(r)
        device = await factory.async_create_device('http://localhost:1234/dmr')
        service = device.service(
            'urn:schemas-upnp-org:service:RenderingControl:1')
        action = service.action('SetVolume')

        # all ok
        action.validate_arguments(InstanceID=0,
                                  Channel='Master',
                                  DesiredVolume=10)

        # invalid type for InstanceID
        try:
            action.validate_arguments(InstanceID='0',
                                      Channel='Master',
                                      DesiredVolume=10)
            assert False
        except UpnpValueError:
            pass

        # missing DesiredVolume
        try:
            action.validate_arguments(InstanceID='0', Channel='Master')
            assert False
        except UpnpValueError:
            pass
Ejemplo n.º 13
0
    async def test_format_request_escape(self):
        r = UpnpTestRequester(RESPONSE_MAP)
        factory = UpnpFactory(r)
        device = await factory.async_create_device('http://localhost:1234/dmr')
        service = device.service('urn:schemas-upnp-org:service:AVTransport:1')
        action = service.action('SetAVTransportURI')

        service_type = 'urn:schemas-upnp-org:service:AVTransport:1'
        metadata = '<item>test thing</item>'
        url, headers, body = action.create_request(
            InstanceID=0,
            CurrentURI='http://example.org/file.mp3',
            CurrentURIMetaData=metadata)

        root = ET.fromstring(body)
        ns = {'avt_service': service_type}
        assert root.find('.//avt_service:SetAVTransportURI', ns) is not None
        assert root.find('.//CurrentURIMetaData', ns) is not None
        #assert root.findtext('.//CurrentURIMetaData', ns) == '&lt;item&gt;test thing&lt;/item&gt;'
        assert root.findtext(
            './/CurrentURIMetaData', None,
            ns) == '<item>test thing</item>'  # ET escapes for us...

        current_uri_metadata_el = root.find('.//CurrentURIMetaData', ns)
        assert current_uri_metadata_el is not None
        assert current_uri_metadata_el.findall('./') == [
        ]  # this shouldn't have any children, due to its contents being escaped
Ejemplo n.º 14
0
async def async_create_upnp_device(hass: HomeAssistant,
                                   ssdp_location: str) -> UpnpDevice:
    """Create UPnP device."""
    session = async_get_clientsession(hass)
    requester = AiohttpSessionRequester(session, with_sleep=True, timeout=20)

    factory = UpnpFactory(requester, disable_state_variable_validation=True)
    return await factory.async_create_device(ssdp_location)
Ejemplo n.º 15
0
    async def test_action_not_exists(self):
        r = UpnpTestRequester(RESPONSE_MAP)
        factory = UpnpFactory(r)
        device = await factory.async_create_device('http://localhost:1234/dmr')
        event_handler = UpnpEventHandler('http://localhost:11302', r)
        profile = DmrDevice(device, event_handler=event_handler)

        # doesn't error
        assert profile._action('RC', 'NonExisting') is None
Ejemplo n.º 16
0
    async def test_init(self):
        r = UpnpTestRequester(RESPONSE_MAP)
        factory = UpnpFactory(r)
        device = await factory.async_create_device('http://localhost:1234/dmr')
        service = device.service('urn:schemas-upnp-org:service:RenderingControl:1')
        action = service.action('GetVolume')

        assert action
        assert action.name == 'GetVolume'
Ejemplo n.º 17
0
 def __init__(self, hass: HomeAssistant) -> None:
     """Initialize global data."""
     self.lock = asyncio.Lock()
     session = aiohttp_client.async_get_clientsession(hass,
                                                      verify_ssl=False)
     self.requester = AiohttpSessionRequester(session, with_sleep=True)
     self.upnp_factory = UpnpFactory(self.requester, non_strict=True)
     self.event_notifiers = {}
     self.event_notifier_refs = defaultdict(int)
Ejemplo n.º 18
0
    async def test_subscribe(self):
        r = UpnpTestRequester(RESPONSE_MAP)
        factory = UpnpFactory(r)
        device = await factory.async_create_device('http://localhost:1234/dmr')
        event_handler = UpnpEventHandler('http://localhost:11302', r)

        service = device.service(
            'urn:schemas-upnp-org:service:RenderingControl:1')
        await event_handler.async_subscribe(service)
        assert event_handler.service_for_sid('uuid:dummy') == service
Ejemplo n.º 19
0
    async def test_unsubscribe(self):
        r = UpnpTestRequester(RESPONSE_MAP)
        factory = UpnpFactory(r)
        device = await factory.async_create_device('http://localhost:1234/dmr')
        service = device.service('urn:schemas-upnp-org:service:RenderingControl:1')
        service._subscription_sid = 'uuid:dummy'

        assert service.subscription_sid == 'uuid:dummy'
        await service.async_unsubscribe()
        assert service.subscription_sid is None
Ejemplo n.º 20
0
    async def test_action_not_exists(self):
        """Test getting non-existing action."""
        r = UpnpTestRequester(RESPONSE_MAP)
        factory = UpnpFactory(r)
        device = await factory.async_create_device("http://localhost:1234/dmr")
        event_handler = UpnpEventHandler("http://localhost:11302", r)
        profile = DmrDevice(device, event_handler=event_handler)

        # doesn't error
        assert profile._action("RC", "NonExisting") is None
Ejemplo n.º 21
0
    async def test_value_date_time(self):
        r = UpnpTestRequester(RESPONSE_MAP)
        factory = UpnpFactory(r, disable_state_variable_validation=True)
        device = await factory.async_create_device('http://localhost:1234/dmr')
        service = device.service('urn:schemas-upnp-org:service:RenderingControl:1')
        sv = service.state_variable('SV1')

        # should be ok
        sv.upnp_value = '1985-04-12T10:15:30'
        assert sv.value == datetime(1985, 4, 12, 10, 15, 30)
Ejemplo n.º 22
0
    async def test_parse_response(self):
        r = UpnpTestRequester(RESPONSE_MAP)
        factory = UpnpFactory(r)
        device = await factory.async_create_device('http://localhost:1234/dmr')
        service = device.service('urn:schemas-upnp-org:service:RenderingControl:1')
        action = service.action('GetVolume')

        service_type = 'urn:schemas-upnp-org:service:RenderingControl:1'
        response = read_file('action_GetVolume.xml')
        result = action.parse_response(service_type, {}, response)
        assert result == {'CurrentVolume': 3}
Ejemplo n.º 23
0
    async def test_init(self):
        """Test Initializing a UpnpAction."""
        requester = UpnpTestRequester(RESPONSE_MAP)
        factory = UpnpFactory(requester)
        device = await factory.async_create_device("http://localhost:1234/dmr")
        service = device.service(
            "urn:schemas-upnp-org:service:RenderingControl:1")
        action = service.action("GetVolume")

        assert action
        assert action.name == "GetVolume"
Ejemplo n.º 24
0
    async def async_create_upnp_device(cls, hass: HomeAssistant,
                                       ssdp_location: str) -> UpnpDevice:
        """Create UPnP device."""
        # Build async_upnp_client requester.
        session = async_get_clientsession(hass)
        requester = AiohttpSessionRequester(session, True, 10)

        # Create async_upnp_client device.
        factory = UpnpFactory(requester,
                              disable_state_variable_validation=True)
        return await factory.async_create_device(ssdp_location)
Ejemplo n.º 25
0
    async def test_init(self):
        r = UpnpTestRequester(RESPONSE_MAP)
        factory = UpnpFactory(r)
        device = await factory.async_create_device('http://localhost:1234/dmr')
        assert device

        service = device.service('urn:schemas-upnp-org:service:RenderingControl:1')
        assert service

        state_var = service.state_variable('Volume')
        assert state_var
Ejemplo n.º 26
0
    async def test_subscribe(self):
        r = UpnpTestRequester(RESPONSE_MAP)
        factory = UpnpFactory(r)
        device = await factory.async_create_device('http://localhost:1234/dmr')
        service = device.service('urn:schemas-upnp-org:service:RenderingControl:1')

        callback_uri = 'http://callback_uri'
        sid = 'uuid:dummy'

        received_sid = await service.async_subscribe(callback_uri)
        assert sid == received_sid
        assert sid == service.subscription_sid
Ejemplo n.º 27
0
    async def test_value_date_time(self):
        """Test parsing of datetime."""
        requester = UpnpTestRequester(RESPONSE_MAP)
        factory = UpnpFactory(requester, non_strict=True)
        device = await factory.async_create_device("http://localhost:1234/dmr")
        service = device.service(
            "urn:schemas-upnp-org:service:RenderingControl:1")
        state_var = service.state_variable("SV1")

        # should be ok
        state_var.upnp_value = "1985-04-12T10:15:30"
        assert state_var.value == datetime(1985, 4, 12, 10, 15, 30)
Ejemplo n.º 28
0
    async def test_init(self):
        r = UpnpTestRequester(RESPONSE_MAP)
        factory = UpnpFactory(r)
        device = await factory.async_create_device('http://localhost:1234/dmr')
        service = device.service('urn:schemas-upnp-org:service:RenderingControl:1')

        base_url = 'http://localhost:1234'
        assert service
        assert service.service_type == 'urn:schemas-upnp-org:service:RenderingControl:1'
        assert service.control_url == base_url + '/upnp/control/RenderingControl1'
        assert service.event_sub_url == base_url + '/upnp/event/RenderingControl1'
        assert service.scpd_url == base_url + '/RenderingControl_1.xml'
Ejemplo n.º 29
0
async def async_setup_platform(hass: HomeAssistantType,
                               config,
                               async_add_entities,
                               discovery_info=None):
    """Set up DLNA DMR platform."""
    if config.get(CONF_URL) is not None:
        url = config[CONF_URL]
        name = config.get(CONF_NAME)
    elif discovery_info is not None:
        url = discovery_info["ssdp_description"]
        name = discovery_info.get("name")

    if DLNA_DMR_DATA not in hass.data:
        hass.data[DLNA_DMR_DATA] = {}

    if "lock" not in hass.data[DLNA_DMR_DATA]:
        hass.data[DLNA_DMR_DATA]["lock"] = asyncio.Lock()

    # build upnp/aiohttp requester
    from async_upnp_client.aiohttp import AiohttpSessionRequester

    session = async_get_clientsession(hass)
    requester = AiohttpSessionRequester(session, True)

    # ensure event handler has been started
    with await hass.data[DLNA_DMR_DATA]["lock"]:
        server_host = config.get(CONF_LISTEN_IP)
        if server_host is None:
            server_host = get_local_ip()
        server_port = config.get(CONF_LISTEN_PORT, DEFAULT_LISTEN_PORT)
        callback_url_override = config.get(CONF_CALLBACK_URL_OVERRIDE)
        event_handler = await async_start_event_handler(
            hass, server_host, server_port, requester, callback_url_override)

    # create upnp device
    from async_upnp_client import UpnpFactory

    factory = UpnpFactory(requester, disable_state_variable_validation=True)
    try:
        upnp_device = await factory.async_create_device(url)
    except (asyncio.TimeoutError, aiohttp.ClientError):
        raise PlatformNotReady()

    # wrap with DmrDevice
    from async_upnp_client.profiles.dlna import DmrDevice

    dlna_device = DmrDevice(upnp_device, event_handler)

    # create our own device
    device = DlnaDmrDevice(dlna_device, name)
    _LOGGER.debug("Adding device: %s", device)
    async_add_entities([device], True)
Ejemplo n.º 30
0
    async def async_create_device(cls, hass: HomeAssistantType, ssdp_description: str):
        """Create UPnP/IGD device."""
        # build async_upnp_client requester
        session = async_get_clientsession(hass)
        requester = AiohttpSessionRequester(session, True)

        # create async_upnp_client device
        factory = UpnpFactory(requester, disable_state_variable_validation=True)
        upnp_device = await factory.async_create_device(ssdp_description)

        igd_device = IgdDevice(upnp_device, None)

        return cls(igd_device)