async def get_service_info(service_type, name): print(service_type, name) dns_type = dns_discovery.BREWBLOX_DNS_TYPE if name == 'id0': return ServiceInfo( service_type, f'{name}.{dns_type}', address=inet_aton('0.0.0.0') ) if name == 'id1': return ServiceInfo( service_type, f'{name}.{dns_type}', server=f'{name}.local.', address=inet_aton('1.2.3.4'), port=1234 ) if name == 'id2': return ServiceInfo( service_type, f'{name}.{dns_type}', server=f'{name}.local.', address=inet_aton('4.3.2.1'), port=4321 )
async def publish_zeroconf(zconf, ip_address, port): """Publish zeroconf service for ATV proxy instance.""" props = { b'ModelName': 'Apple TV', b'AllowPairing': b'YES', b'macAddress': b'40:cb:c0:12:34:56', b'BluetoothAddress': False, b'Name': DEVICE_NAME.encode(), b'UniqueIdentifier': SERVER_IDENTIFIER.encode(), b'SystemBuildVersion': b'17K499', b'LocalAirPlayReceiverPairingIdentity': AIRPLAY_IDENTIFIER.encode(), } service = ServiceInfo( '_mediaremotetv._tcp.local.', DEVICE_NAME + '._mediaremotetv._tcp.local.', address=socket.inet_aton(ip_address), port=port, weight=0, priority=0, properties=props) await zconf.register_service(service) _LOGGER.debug('Published zeroconf service: %s', service) return service
async def async_setup(hass, config): """Set up Zeroconf and make Home Assistant discoverable.""" from aiozeroconf import Zeroconf, ServiceInfo zeroconf_name = '{}.{}'.format(hass.config.location_name, ZEROCONF_TYPE) params = { 'version': __version__, 'base_url': hass.config.api.base_url, # always needs authentication 'requires_api_password': True, } info = ServiceInfo(ZEROCONF_TYPE, zeroconf_name, port=hass.http.server_port, properties=params) zeroconf = Zeroconf(hass.loop) await zeroconf.register_service(info) async def stop_zeroconf(event): """Stop Zeroconf.""" await zeroconf.unregister_service(info) await zeroconf.close() hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, stop_zeroconf) return True
def __init__(self, service_type, port): '''Create a TCP server''' self.__logger = logging.getLogger(__name__) self.connection_changed = Event(sender='server') # this keeps track of all the clients that connected to our # server. It can be useful in some cases, for instance to # kill client connections or to broadcast some data to all # clients... self.__clients = {} # task -> (reader, writer) self.__port = port self.__server = None self.__loop = None self.__shutdown_in_progress = False self.__queue = asyncio.Queue() self.__info = ServiceInfo( service_type, 'TTC-%s.%s' % ( uuid.uuid3(uuid.NAMESPACE_DNS, socket.gethostname()), service_type), socket.inet_aton( socket.gethostbyname(socket.gethostname())), self.__port, 0, 0, {}, socket.gethostname() + '.')
async def test_run(r): print("1. Testing registration of a service...") desc = {'version': '0.10', 'a': 'test value', 'b': 'another value'} info = ServiceInfo("_http._tcp.local.", "My Service Name._http._tcp.local.", address=socket.inet_aton("127.0.0.1"), port=1234, weight=0, priority=0, properties=desc) print(" Registering service...") await r.register_service(info) print(" Registration done.") print("2. Testing query of service information...") print(" Getting ZOE service: %s" % (await r.get_service_info( "_http._tcp.local.", "ZOE._http._tcp.local."))) print(" Query done.") print("3. Testing query of own service...") info = await r.get_service_info("_http._tcp.local.", "My Service Name._http._tcp.local.") assert info print(" Getting self: %s" % (info, )) print(" Query done.") print("4. Testing unregister of service information...") await r.unregister_service(info) print(" Unregister done.") await r.close()
async def run_me(loop): type_ = "_http._tcp.local." registration_name = "xxxyyy.%s" % type_ def on_service_state_change(zeroconf, service_type, state_change, name): if name == registration_name: if state_change is ServiceStateChange.Added: service_added.set() elif state_change is ServiceStateChange.Removed: service_removed.set() zeroconf_browser = Zeroconf(loop, [netifaces.AF_INET], iface="lo") browser = ServiceBrowser(zeroconf_browser, type_, [on_service_state_change]) zeroconf_registrar = Zeroconf(loop, [netifaces.AF_INET], iface="lo") desc = {'path': '/~paulsm/'} info = ServiceInfo(type_, registration_name, socket.inet_aton("10.0.1.2"), 80, 0, 0, desc, "ash-2.local.") zeroconf_registrar.register_service(info) try: await asyncio.sleep(1) assert service_added.is_set() # Don't remove service, allow close() to cleanup finally: await zeroconf_registrar.close() browser.cancel() await zeroconf_browser.close()
async def publish_zeroconf(zconf, ip_address, port): """Publish zeroconf service for ATV proxy instance.""" props = { b"ModelName": "Apple TV", b"AllowPairing": b"YES", b"macAddress": b"40:cb:c0:12:34:56", b"BluetoothAddress": False, b"Name": DEVICE_NAME.encode(), b"UniqueIdentifier": SERVER_IDENTIFIER.encode(), b"SystemBuildVersion": b"17K499", b"LocalAirPlayReceiverPairingIdentity": AIRPLAY_IDENTIFIER.encode(), } service = ServiceInfo( "_mediaremotetv._tcp.local.", DEVICE_NAME + "._mediaremotetv._tcp.local.", address=socket.inet_aton(ip_address), port=port, weight=0, priority=0, properties=props, ) await zconf.register_service(service) _LOGGER.debug("Published zeroconf service: %s", service) return service
async def run_test(zc): global info, desc desc = {'path': '/~paulsm/'} info = ServiceInfo("_http._tcp.local.", "Paul's Test Web Site._http._tcp.local.", address=socket.inet_aton("127.0.0.1"), port=80, weight=0, priority=0, properties=desc, server="ash-2.local.") print("Registration of a service, press Ctrl-C to exit...") await zc.register_service(info)
async def run_test(zc): global info, desc desc = {'path': '/~paulsm/'} info = ServiceInfo("_http._tcp.local.", "Paul's Test Web Site._http._tcp.local.", socket.inet_aton("127.0.0.1"), 80, 0, 0, desc, "ash-2.local.") print("Registration of a service, press Ctrl-C to exit...") await zc.register_service(info)
def test_service_info_dunder(self): type_ = "_test-srvc-type._tcp.local." name = "xxxyyy" registration_name = "%s.%s" % (name, type_) info = ServiceInfo(type_, registration_name, socket.inet_aton("10.0.1.2"), 80, 0, 0, None, "ash-2.local.") assert not info != info repr(info)
def verify_name_change(self, zc, type_, name, number_hosts): desc = {'path': '/~paulsm/'} info_service = ServiceInfo(type_, '%s.%s' % (name, type_), socket.inet_aton("10.0.1.2"), 80, 0, 0, desc, "ash-2.local.") # verify name conflict self.assertRaises(r.NonUniqueNameException, zc.register_service, info_service) zc.register_service(info_service, allow_name_change=True) assert info_service.name.split('.')[0] == '%s-%d' % (name, number_hosts + 1)
async def publish_service(zconf, service, name, address, port, props): """Publish a Zeroconf service.""" service = ServiceInfo( service, name + "." + service, address=socket.inet_aton(address), port=port, properties=props, ) await zconf.register_service(service) _LOGGER.debug("Published zeroconf service: %s", service) return service
async def get_service_info(service_type, name): dns_type = connect_funcs.BREWBLOX_DNS_TYPE if name == 'id0': return ServiceInfo( service_type, f'{name}.{dns_type}', address=inet_aton('0.0.0.0'), properties={b'ID': name.encode()}, ) if name == 'id1': return ServiceInfo( service_type, f'{name}.{dns_type}', server=f'{name}.local.', address=inet_aton('1.2.3.4'), port=1234, properties={b'ID': name.encode()}, ) if name == 'id2': return ServiceInfo( service_type, f'{name}.{dns_type}', server=f'{name}.local.', address=inet_aton('4.3.2.1'), port=4321, properties={b'ID': name.encode()}, ) if name == 'id3': return ServiceInfo( service_type, f'{name}.{dns_type}', server=f'{name}.local.', address=inet_aton('4.3.2.1'), port=4321, properties={}, # Will be discarded )
async def run_test(zc): global info, desc desc = {} local_ip = ip4_address() info = ServiceInfo("_http._tcp.local.", "Openbot Web Site._http._tcp.local.", address=socket.inet_aton(local_ip), port=8000, weight=0, priority=0, properties=desc, server="openbot.local.") print("Registration of a service, press Ctrl-C to exit...") await zc.register_service(info)
def mrp_service(service_name, atv_name, address, identifier, port=49152): """Create a MediaRemote service simulating an Apple TV.""" props = { b'ModelName': b'Mac', b'SystemBuildVersion': b'16G29', b'Name': atv_name, b'AllowPairing': b'YES', b'UniqueIdentifier': identifier.encode('utf-8') } return ServiceInfo('_mediaremotetv._tcp.local.', service_name + '._mediaremotetv._tcp.local.', address=address, port=port, properties=props)
def mrp_service(service_name, atv_name, address, identifier, port=49152): """Create a MediaRemote service simulating an Apple TV.""" props = { b"ModelName": b"Mac", b"SystemBuildVersion": b"16G29", b"Name": atv_name, b"AllowPairing": b"YES", b"UniqueIdentifier": identifier.encode("utf-8"), } return ServiceInfo( "_mediaremotetv._tcp.local.", service_name + "._mediaremotetv._tcp.local.", address=address, port=port, properties=props, )
async def run_me(zeroconf_registrar): type_ = "_test-srvc-type._tcp.local." name = "xxxyyy" registration_name = "%s.%s" % (name, type_) desc = {'path': '/~paulsm/'} info = ServiceInfo(type_, registration_name, socket.inet_aton("10.0.1.2"), 80, 0, 0, desc, "ash-2.local.") await zeroconf_registrar.register_service(info) try: service_types = await ZeroconfServiceTypes.find( zc=zeroconf_registrar, timeout=0.5) assert type_ in service_types finally: await zeroconf_registrar.close()
async def run_test(zc): desc = {} local_ip = ip4_address() name = (os.getenv("OPENBOT_NAME", socket.gethostname()).replace(".local", "").replace(".", "-")) info = ServiceInfo( SERVICE_TYPE, f"{name}.{SERVICE_TYPE}", address=socket.inet_aton(local_ip), port=8000, weight=0, priority=0, properties=desc, ) print("Registration of the service with name:", name) await zc.register_service(info)
def device_service(service_name, atv_name, address): """Create a service representing an Apple TV with no home-sharing.""" props = { b'DvTy': b'AppleTV', b'Ver': b'131077', b'DvSv': b'1792', b'atCV': b'65539', b'atSV': b'65541', b'txtvers': b'1', b'DbId': b'AAAAAAAAAAAAAAAA', b'CtlN': atv_name } return ServiceInfo('_touch-able._tcp.local.', service_name + '._touch-able._tcp.local.', address=address, port=3689, server='AppleTV-2.local.', properties=props)
def airplay_service(atv_name, address, deviceid, port=7000): """Create a MediaRemote service simulating an Apple TV.""" props = { b'deviceid': deviceid.encode('utf-8'), b'model': b'AppleTV3,1', b'pi': b'4EE5AF58-7E5D-465A-935E-82E4DB74385D', b'flags': b'0x44', b'vv': b'2', b'features': b'0x5A7FFFF7,0xE', b'pk': b'3853c0e2ce3844727ca0cb1b86a3e3875e66924d2648d8f8caf71f8118793d98', # noqa b'srcvers': b'220.68' } return ServiceInfo('_airplay._tcp.local.', atv_name + '._airplay._tcp.local.', address=address, port=port, properties=props)
async def publish_zeroconf(zconf, ip_address, port): """Publish zeroconf service for ATV proxy instance.""" props = { b'ModelName': False, b'AllowPairing': b'YES', b'BluetoothAddress': False, b'Name': b'ATVProxy', b'UniqueIdentifier': '4d797fd3-3538-427e-a47b-a32fc6cf3a69'.encode(), b'SystemBuildVersion': b'15K600', } service = ServiceInfo('_mediaremotetv._tcp.local.', 'ATVProxy._mediaremotetv._tcp.local.', address=socket.inet_aton(ip_address), port=port, weight=0, priority=0, properties=props) await zconf.register_service(service) _LOGGER.debug('Published zeroconf service: %s', service)
def airplay_service(atv_name, address, deviceid, port=7000): """Create a MediaRemote service simulating an Apple TV.""" props = { b"deviceid": deviceid.encode("utf-8"), b"model": b"AppleTV3,1", b"pi": b"4EE5AF58-7E5D-465A-935E-82E4DB74385D", b"flags": b"0x44", b"vv": b"2", b"features": b"0x5A7FFFF7,0xE", b"pk": b"3853c0e2ce3844727ca0cb1b86a3e3875e66924d2648d8f8caf71f8118793d98", # noqa b"srcvers": b"220.68", } return ServiceInfo( "_airplay._tcp.local.", atv_name + "._airplay._tcp.local.", address=address, port=port, properties=props, )
async def run_me(zeroconf_registrar): subtype_ = "_subtype._sub" type_ = "_type._tcp.local." name = "xxxyyy" # Note: discovery returns only DNS-SD type not subtype discovery_type = "%s.%s" % (subtype_, type_) registration_name = "%s.%s" % (name, type_) desc = {'path': '/~paulsm/'} info = ServiceInfo(discovery_type, registration_name, socket.inet_aton("10.0.1.2"), 80, 0, 0, desc, "ash-2.local.") await zeroconf_registrar.register_service(info) try: service_types = await ZeroconfServiceTypes.find( zc=zeroconf_registrar, timeout=0.5) assert discovery_type in service_types finally: await zeroconf_registrar.close()
async def _publish_service(self, address, port): props = { b'DvNm': self._name, b'RemV': b'10000', b'DvTy': b'iPod', b'RemN': b'Remote', b'txtvers': b'1', b'Pair': self._pairing_guid } service = ServiceInfo('_touch-remote._tcp.local.', '{0:040d}._touch-remote._tcp.local.'.format( int(address)), address=socket.inet_aton(str(address)), port=port, weight=0, priority=0, properties=props) await self._zeroconf.register_service(service) _LOGGER.debug('Published zeroconf service: %s', service)
def device_service(service_name, atv_name, address): """Create a service representing an Apple TV with no home-sharing.""" props = { b"DvTy": b"AppleTV", b"Ver": b"131077", b"DvSv": b"1792", b"atCV": b"65539", b"atSV": b"65541", b"txtvers": b"1", b"DbId": b"AAAAAAAAAAAAAAAA", b"CtlN": atv_name, } return ServiceInfo( "_touch-able._tcp.local.", service_name + "._touch-able._tcp.local.", address=address, port=3689, server="AppleTV-2.local.", properties=props, )
def homesharing_service(service_name, atv_name, address, hsgid): """Create a new home sharing service simulating an Apple TV.""" # Mostly default values here for now props = { b'DFID': b'2', b'PrVs': b'65538', b'hG': hsgid, b'Name': atv_name, b'txtvers': b'1', b'atSV': b'65541', b'MiTPV': b'196611', b'EiTS': b'1', b'fs': b'2', b'MniT': b'167845888' } return ServiceInfo('_appletv-v2._tcp.local.', service_name + '._appletv-v2._tcp.local.', address=address, port=3689, properties=props)
async def _publish_service(self, address, port): props = { b"DvNm": self._name, b"RemV": b"10000", b"DvTy": b"iPod", b"RemN": b"Remote", b"txtvers": b"1", b"Pair": self._pairing_guid, } service = ServiceInfo( "_touch-remote._tcp.local.", "{0:040d}._touch-remote._tcp.local.".format(int(address)), address=socket.inet_aton(str(address)), port=port, weight=0, priority=0, properties=props, ) await self._zeroconf.register_service(service) _LOGGER.debug("Published zeroconf service: %s", service)
def homesharing_service(service_name, atv_name, address, hsgid): """Create a new home sharing service simulating an Apple TV.""" # Mostly default values here for now props = { b"DFID": b"2", b"PrVs": b"65538", b"hG": hsgid, b"Name": atv_name, b"txtvers": b"1", b"atSV": b"65541", b"MiTPV": b"196611", b"EiTS": b"1", b"fs": b"2", b"MniT": b"167845888", } return ServiceInfo( "_appletv-v2._tcp.local.", service_name + "._appletv-v2._tcp.local.", address=address, port=3689, properties=props, )
def test_coroutine(): aio_zc = asyncio_zeroconf.pop("zeroconf") ipaddr = Faker().ipv4_private() port = find_free_port() service_name = "{}.{}".format(Faker().pystr(), DNSSDDiscoveryService.WOT_SERVICE_TYPE) server = "{}.local.".format(Faker().pystr()) info = ServiceInfo(DNSSDDiscoveryService.WOT_SERVICE_TYPE, service_name, address=socket.inet_aton(ipaddr), port=port, properties={}, server=server) yield aio_zc.register_service(info) with pytest.raises(ValueError): yield dnssd_discovery.find() yield dnssd_discovery.start() assert (ipaddr, port) in (yield dnssd_discovery.find(timeout=3))
async def run_me(zcbrowser, zcregistrar): subtype_name = "My special Subtype" type_ = "_http._tcp.local." subtype = subtype_name + "._sub." + type_ name = "xxxyyy" registration_name = "%s.%s" % (name, type_) class MyListener(object): def add_service(self, zeroconf, type, name): asyncio.ensure_future( self.async_add_service(zeroconf, type, name)) async def async_add_service(self, zeroconf, type, name): await zeroconf.get_service_info(type, name) service_added.set() def remove_service(self, zeroconf, type, name): service_removed.set() listener = MyListener() zcbrowser.add_service_listener(subtype, listener=listener) properties = dict( prop_none=None, prop_string=b'a_prop', prop_float=1.0, prop_blank=b'a blanked string', prop_true=1, prop_false=0, ) desc = {'path': '/~paulsm/'} desc.update(properties) info_service = ServiceInfo(subtype, registration_name, socket.inet_aton("10.0.1.2"), 80, 0, 0, desc, "ash-2.local.") await zcregistrar.register_service(info_service) try: await asyncio.sleep(2) assert service_added.is_set() # short pause to allow multicast timers to expire await asyncio.sleep(2) # clear the answer cache to force query for record in zcbrowser.cache.entries(): zcbrowser.cache.remove(record) # get service info without answer cache info = await zcbrowser.get_service_info( type_, registration_name) assert info.properties[b'prop_none'] is False assert info.properties[b'prop_string'] == properties[ 'prop_string'] assert info.properties[b'prop_float'] is False assert info.properties[b'prop_blank'] == properties[ 'prop_blank'] assert info.properties[b'prop_true'] is True assert info.properties[b'prop_false'] is False info = await zcbrowser.get_service_info( subtype, registration_name) assert info.properties[b'prop_none'] is False await zcregistrar.unregister_service(info_service) await asyncio.sleep(1) assert service_removed.is_set() finally: await zcregistrar.close() zcbrowser.remove_service_listener(listener) await zcbrowser.close()