async def get_inputs(self) -> List[Input]: """Return list of available outputs.""" res = await self.services["avContent"][ "getCurrentExternalTerminalsStatus"]() return [ Input.make(services=self.services, **x) for x in res if 'meta:zone:output' not in x['meta'] ]
async def get_inputs(self) -> List[Input]: """Return list of available outputs.""" if "avContent" in self.services: res = await self.services["avContent"][ "getCurrentExternalTerminalsStatus"]() return [ Input.make(services=self.services, **x) for x in res if "meta:zone:output" not in x["meta"] ] else: if self._upnp_discovery is None: raise SongpalException( "avContent service not available and UPnP fallback failed") return await self._get_inputs_upnp()
async def _get_inputs_upnp(self): await self._get_upnp_services() content_directory = self._upnp_device.service( next(s for s in self._upnp_discovery.upnp_services if "ContentDirectory" in s)) browse = content_directory.action("Browse") filter = ( "av:BIVL,av:liveType,av:containerClass,dc:title,dc:date," "res,res@duration,res@resolution,upnp:albumArtURI," "upnp:albumArtURI@dlna:profileID,upnp:artist,upnp:album,upnp:genre" ) result = await browse.async_call( ObjectID="0", BrowseFlag="BrowseDirectChildren", Filter=filter, StartingIndex=0, RequestedCount=25, SortCriteria="", ) root_items = didl_lite.from_xml_string(result["Result"]) input_item = next( (i for i in root_items if isinstance(i, didl_lite.Container) and i.title == "Input"), None, ) result = await browse.async_call( ObjectID=input_item.id, BrowseFlag="BrowseDirectChildren", Filter=filter, StartingIndex=0, RequestedCount=25, SortCriteria="", ) av_transport = self._upnp_renderer.service( next(s for s in self._upnp_renderer.services if "AVTransport" in s)) media_info = await av_transport.action("GetMediaInfo").async_call( InstanceID=0) current_uri = media_info.get("CurrentURI") inputs = didl_lite.from_xml_string(result["Result"]) def is_input_active(input, current_uri): if not current_uri: return False # when input is switched on device, uri can have file:// format if current_uri.startswith("file://"): # UPnP 'Bluetooth AUDIO' can be file://Bluetooth # UPnP 'AUDIO' can be file://Audio return current_uri.lower() in "file://" + input.title.lower() if current_uri.startswith("local://"): # current uri can have additional query params, such as zone return input.resources[0].uri in current_uri return [ Input.make( title=i.title, uri=i.resources[0].uri, active="active" if is_input_active(i, current_uri) else "", avTransport=av_transport, uriMetadata=didl_lite.to_xml_string(i).decode("utf-8"), ) for i in inputs ]