Open xchwarze opened 2 years ago
IMO, we should make upnp async.
Maybe we could use this as a dependency? https://github.com/StevenLooman/async_upnp_client
Yes, and the implementation would be similar to what they did here https://github.com/balmli/com.samsung.smart/blob/master/lib/UPnPClient.js
This is what I just tried at my end, using pip install async_upnp_client
.
import aiohttp
import asyncio
import logging
from async_upnp_client.aiohttp import AiohttpSessionRequester
from async_upnp_client.client_factory import UpnpFactory
from async_upnp_client.exceptions import UpnpActionResponseError
logging.basicConfig(level=logging.DEBUG)
host = "1.2.3.4"
SVC_RENDERINGCONTROL = "urn:schemas-upnp-org:service:RenderingControl:1"
async def main():
async with aiohttp.ClientSession() as session:
upnp_requester = AiohttpSessionRequester(session)
upnp_factory = UpnpFactory(upnp_requester)
upnp_device = await upnp_factory.async_create_device(f"http://{host}:9197/dmr")
svc_renderingcontrol = upnp_device.service(SVC_RENDERINGCONTROL)
get_volume_response = await svc_renderingcontrol.action("GetVolume").async_call(InstanceID=0, Channel="Master")
print(f"GetVolume: {get_volume_response}")
get_mute_response = await svc_renderingcontrol.action("GetMute").async_call(InstanceID=0, Channel="Master")
print(f"GetMute: {get_mute_response}")
try:
set_mute_response = await svc_renderingcontrol.action("SetMute").async_call(InstanceID=0, Channel="Master", DesiredMute=True)
print(f"SetMute: {set_mute_response}")
except UpnpActionResponseError as err:
print(f"Failed to SetMute: {err.__repr__()}")
try:
set_volume_response = await svc_renderingcontrol.action("SetVolume").async_call(InstanceID=0, Channel="Master", DesiredVolume=50)
print(f"SetVolume: {set_volume_response}")
except UpnpActionResponseError as err:
print(f"Failed to SetVolume: {err.__repr__()}")
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Sadly it seems to always return bad values on my TV:
Volume: 0
Mute: False
I have updated my sample above.
These are my results:
GetVolume: {'CurrentVolume': 0}
GetMute: {'CurrentMute': False}
Failed to SetMute: UpnpActionResponseError('Error during async_call(), status: 500, upnp error: 501 (Action Failed)')
Failed to SetVolume: UpnpActionResponseError('Error during async_call(), status: 500, upnp error: 501 (Action Failed)')
The feature seems to be on all TVs (Legacy, Encrypted and Tizen) via UPnP, but in the information api (https://192.168.1.xxx:8002/api/v2/) I can't see any indicator if it is present/enabled. Maybe there to implement it and if the request fails throw an error that it is not supported.