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
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
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))
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)
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
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("./") == []
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
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
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)
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
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
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
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) == '<item>test thing</item>' 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
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)
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
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'
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)
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
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
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
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)
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}
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"
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)
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
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
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)
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'
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)
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)