def mrp_service_handler( mdns_service: mdns.Service, response: mdns.Response) -> Optional[ScanHandlerReturn]: """Parse and return a new MRP service.""" enabled = True # Disable this service if tvOS version is >= 15 as it doesn't work anymore build = mdns_service.properties.get("SystemBuildVersion", "") match = re.match(r"^(\d+)[A-Z]", build) if match: base = int(match.groups()[0]) if base >= 19: _LOGGER.debug("Disabling MRP service since tvOS >= 15") enabled = False name = mdns_service.properties.get("Name", "Unknown") service = MutableService( get_unique_id(mdns_service.type, mdns_service.name, mdns_service.properties), Protocol.MRP, mdns_service.port, properties=mdns_service.properties, enabled=enabled, ) return name, service
def get_unique_identifiers( response: mdns.Response, ) -> Generator[Optional[str], None, None]: """Return (yield) all unique identifiers for a response.""" for service in response.services: unique_id = get_unique_id(service.type, service.name, service.properties) if unique_id: yield unique_id
def airplay_service_handler( mdns_service: mdns.Service, response: mdns.Response) -> Optional[ScanHandlerReturn]: """Parse and return a new AirPlay service.""" service = MutableService( get_unique_id(mdns_service.type, mdns_service.name, mdns_service.properties), Protocol.AirPlay, mdns_service.port, properties=mdns_service.properties, ) return mdns_service.name, service
def dmap_service_handler( mdns_service: mdns.Service, response: mdns.Response ) -> Optional[ScanHandlerReturn]: """Parse and return a new DMAP service.""" name = mdns_service.properties.get("CtlN", "Unknown") service = MutableService( get_unique_id(mdns_service.type, mdns_service.name, mdns_service.properties), Protocol.DMAP, mdns_service.port, mdns_service.properties, ) return name, service
def raop_service_handler( mdns_service: mdns.Service, response: mdns.Response) -> Optional[ScanHandlerReturn]: """Parse and return a new RAOP service.""" _, name = mdns_service.name.split("@", maxsplit=1) service = MutableService( get_unique_id(mdns_service.type, mdns_service.name, mdns_service.properties), Protocol.RAOP, mdns_service.port, mdns_service.properties, ) return name, service
def hscp_service_handler( mdns_service: mdns.Service, response: mdns.Response ) -> Optional[ScanHandlerReturn]: """Parse and return a new HSCP service.""" name = mdns_service.properties.get("Machine Name", "Unknown") service = MutableService( get_unique_id(mdns_service.type, mdns_service.name, mdns_service.properties), Protocol.DMAP, port=mdns_service.port, properties=mdns_service.properties, ) service.credentials = mdns_service.properties.get("hG") return name, service
def homesharing_service_handler( mdns_service: mdns.Service, response: mdns.Response ) -> Optional[ScanHandlerReturn]: """Parse and return a new DMAP (Home Sharing) service.""" name = mdns_service.properties.get("Name", "Unknown") service = MutableService( get_unique_id(mdns_service.type, mdns_service.name, mdns_service.properties), Protocol.DMAP, mdns_service.port, mdns_service.properties, ) service.credentials = mdns_service.properties.get("hG") return name, service
async def async_step_zeroconf(self, discovery_info): """Handle device found via zeroconf.""" service_type = discovery_info[CONF_TYPE][:-1] # Remove leading . name = discovery_info[CONF_NAME].replace(f".{service_type}.", "") properties = discovery_info["properties"] # Extract unique identifier from service self.scan_filter = get_unique_id(service_type, name, properties) if self.scan_filter is None: return self.async_abort(reason="unknown") # Scan for the device in order to extract _all_ unique identifiers assigned to # it. Not doing it like this will yield multiple config flows for the same # device, one per protocol, which is undesired. return await self.async_find_device_wrapper(self.async_found_zeroconf_device)
async def async_step_zeroconf( self, discovery_info: zeroconf.ZeroconfServiceInfo ) -> data_entry_flow.FlowResult: """Handle device found via zeroconf.""" host = discovery_info.host self._async_abort_entries_match({CONF_ADDRESS: host}) service_type = discovery_info.type[:-1] # Remove leading . name = discovery_info.name.replace(f".{service_type}.", "") properties = discovery_info.properties # Extract unique identifier from service unique_id = get_unique_id(service_type, name, properties) if unique_id is None: return self.async_abort(reason="unknown") if existing_unique_id := self._entry_unique_id_from_identifers( {unique_id}): await self.async_set_unique_id(existing_unique_id) self._abort_if_unique_id_configured(updates={CONF_ADDRESS: host})
def test_get_unique_id_(service_type, service_name, properties, expected_id): assert helpers.get_unique_id(service_type, service_name, properties) == expected_id