def _onServiceChanged(self, zeroconf, service_type, name, state_change): if state_change == ServiceStateChange.Added: Logger.log("d", "Bonjour service added: %s" % name) # First try getting info from zeroconf cache info = ServiceInfo(service_type, name, properties = {}) for record in zeroconf.cache.entries_with_name(name.lower()): info.update_record(zeroconf, time.time(), record) for record in zeroconf.cache.entries_with_name(info.server): info.update_record(zeroconf, time.time(), record) if info.address: break # Request more data if info is not complete if not info.address: Logger.log("d", "Trying to get address of %s", name) info = zeroconf.get_service_info(service_type, name) if info: type_of_device = info.properties.get(b"type", None).decode("utf-8") if type_of_device == "printer": address = '.'.join(map(lambda n: str(n), info.address)) self.addPrinterSignal.emit(str(name), address, info.properties) else: Logger.log("w", "The type of the found device is '%s', not 'printer'! Ignoring.." %type_of_device ) else: Logger.log("w", "Could not get information about %s" % name) elif state_change == ServiceStateChange.Removed: Logger.log("d", "Bonjour service removed: %s" % name) self.removePrinterSignal.emit(str(name))
def test_multiple_addresses(): type_ = "_http._tcp.local." registration_name = "xxxyyy.%s" % type_ desc = {'path': '/~paulsm/'} address = socket.inet_aton("10.0.1.2") # Old way info = ServiceInfo(type_, registration_name, address, 80, 0, 0, desc, "ash-2.local.") assert info.address == address assert info.addresses == [address] # Updating works address2 = socket.inet_aton("10.0.1.3") info.address = address2 assert info.address == address2 assert info.addresses == [address2] info.address = None assert info.address is None assert info.addresses == [] # Compatibility way info = ServiceInfo(type_, registration_name, [address, address], 80, 0, 0, desc, "ash-2.local.") assert info.addresses == [address, address] # New kwarg way info = ServiceInfo( type_, registration_name, None, 80, 0, 0, desc, "ash-2.local.", addresses=[address, address] ) assert info.addresses == [address, address]
def test_service_info_text_properties_not_given(self): type_ = "_test-srvc-type._tcp.local." name = "xxxyyy" registration_name = "%s.%s" % (name, type_) info = ServiceInfo( type_=type_, name=registration_name, address=socket.inet_aton("10.0.1.2"), port=80, server="ash-2.local.", ) assert isinstance(info.text, bytes) repr(info)
def __init__(self, announce_address, announce_port, desc=None): if type(desc) is 'dict': del self.desc self.desc = desc logging.debug( "Requested announce server at address {}".format(announce_address)) self.zeroconf = Zeroconf() self.info = ServiceInfo( "_midiband-hub._tcp.local.", socket.gethostname() + "._midiband-hub._tcp.local.", socket.inet_aton(announce_address), announce_port, 0, 0, self.desc, socket.gethostname() + ".local.") logging.info("Announcing server") self.zeroconf.register_service(self.info)
def run(self): # wait until zeroconf is available (tinypilot booting) while True: try: # register zeroconf service from zeroconf import IPVersion, ServiceInfo, Zeroconf except: time.sleep(10) continue # try again break addresses = [] zeroconf = {} info = {} #ip_version = IPVersion.All #ip_version = IPVersion.V6Only ip_version = IPVersion.V4Only while True: t = time.time() i = get_local_addresses() #print("t", time.time()-t) if i != addresses: print('zeroconf addresses', i, len(i)) # close addresses for address in zeroconf: zeroconf[address].unregister_service(info[address]) zeroconf[address].close() zeroconf = {} info = {} addresses = i # register addresses for address in addresses: #print('zeroconf registering address', address) info[address] = ServiceInfo( "_pypilot._tcp.local.", "pypilot._pypilot._tcp.local.", addresses=[socket.inet_aton(address)], port=DEFAULT_PORT, properties={'version': strversion}) zeroconf[address] = Zeroconf(ip_version=ip_version, interfaces=[address]) zeroconf[address].register_service(info[address]) time.sleep(60)
def test_find_with_device(self): zeroconf = Zeroconf() desc = {'id': '00:00:02:00:00:02'} info = ServiceInfo('_hap._tcp.local.', 'foo1._hap._tcp.local.', address=socket.inet_aton('127.0.0.1'), port=1234, properties=desc, weight=0, priority=0) zeroconf.unregister_all_services() zeroconf.register_service(info, allow_name_change=True) result = find_device_ip_and_port('00:00:02:00:00:02', 10) zeroconf.unregister_all_services() self.assertIsNotNone(result) self.assertEqual(result['ip'], '127.0.0.1')
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)
def test_discover_homekit_devices_missing_md(self): zeroconf = Zeroconf() desc = {'c#': '1', 'id': '00:00:01:00:00:04', 's#': '1', 'ci': '5'} info = ServiceInfo('_hap._tcp.local.', 'foo4._hap._tcp.local.', address=socket.inet_aton('127.0.0.1'), port=1234, properties=desc, weight=0, priority=0) zeroconf.unregister_all_services() zeroconf.register_service(info, allow_name_change=True) result = discover_homekit_devices() test_device = self.find_device(desc, result) zeroconf.unregister_all_services() self.assertIsNone(test_device)
def get_service_info(self, type_, name, timeout=3000): id = _id_from_name(name) info = ServiceInfo( SERVICE_TYPE, name=".".join([id, SERVICE_TYPE]), server=".".join([id, LOCAL_DOMAIN, ""]), address=socket.inet_aton(MOCK_INTERFACE_IP), port=MOCK_PORT, properties={ "facilities": "[]", "channels": "[]" }, ) return info
def main(): logging.basicConfig(level=logging.DEBUG) parser = argparse.ArgumentParser() parser.add_argument('--debug', action='store_true') parser.add_argument("--name", dest="name", default=None, help="mdns service name") version_group = parser.add_mutually_exclusive_group() version_group.add_argument('--v6', action='store_true') version_group.add_argument('--v6-only', action='store_true') args = parser.parse_args() if args.debug: logging.getLogger('zeroconf').setLevel(logging.DEBUG) if args.v6: ip_version = IPVersion.All elif args.v6_only: ip_version = IPVersion.V6Only else: ip_version = IPVersion.V4Only properties = {'who': 'codelab'} # 详细信息 name = args.name if args.name else uuid.uuid4().hex[:8] service_type = "_http._tcp.local." service_name = f"{name}._http._tcp.local." server = f"{name}.local." port = 12358 info = ServiceInfo( service_type, service_name, addresses=[socket.inet_aton(get_local_ip())], port=port, properties=properties, server=server, ) print(info) zeroconf = Zeroconf(ip_version=ip_version) print("Registration of a service, press Ctrl-C to exit...") zeroconf.register_service(info) try: while True: sleep(0.1) except KeyboardInterrupt: pass finally: print("Unregistering...") zeroconf.unregister_service(info) zeroconf.close()
def __init__(self, zconf, type, name, address, port, weight=0, priority=0, properties=None): self.zconf = zconf self.info = ServiceInfo(type, "{}.{}".format(name, type), socket.inet_aton(address), int(port), weight, priority, properties) self.zconf.register_service(self.info)
def __start_advertising(self): self.service = ServiceInfo("{}._tcp.local.".format(self.type), "{}.{}._tcp.local.".format(self.name, self.type), socket.inet_aton(self.address), self.port, 0, 0, self.properties, "{}.local.".format(self.server)) zeroconf = Zeroconf() zeroconf.register_service(self.service) while self.alive: time.sleep(.1) zeroconf.unregister_service(self.service) zeroconf.close()
def mock_homekit_info(service_type, name): return ServiceInfo( service_type, name, addresses=[b"\n\x00\x00\x14"], port=80, weight=0, priority=0, server="name.local.", properties={ b"md": model.encode(), b"sf": pairing_status }, )
def zeroConf(self): print("starting zeroconf") logging.basicConfig(level=logging.DEBUG) desc = {} info = ServiceInfo("_printer._tcp.local.", "e-Paper._printer._tcp.local.", socket.inet_aton(self.PRINTER_IP), self.PRINTER_PORT, 0, 0, desc, "ash-2.local.") zeroconf = Zeroconf() zeroconf.register_service(info) print("zeroconf registered device")
def test_mdns_services_register_unregister_multiple(self): """Ensure that `adb mdns services` correctly adds and removes multiple services """ from zeroconf import IPVersion, ServiceInfo with adb_server() as server_port: output = subprocess.check_output( ["adb", "-P", str(server_port), "mdns", "services"]).strip() self.assertTrue( output.startswith(b"List of discovered mdns services")) """TODO(joshuaduong): Add ipv6 tests once we have it working in adb""" """Register/Unregister a service""" with zeroconf_context(IPVersion.V4Only) as zc: srvs = { 'mdns_name': ["testservice0", "testservice1", "testservice2"], 'mdns_type': "_" + self.service_name + "._tcp.", 'ipaddr': [ socket.inet_aton("192.168.0.1"), socket.inet_aton("10.0.0.255"), socket.inet_aton("172.16.1.100") ], 'port': [10000, 20000, 65535] } srv_infos = [] for i in range(len(srvs['mdns_name'])): srv_infos.append( ServiceInfo(srvs['mdns_type'] + "local.", name=srvs['mdns_name'][i] + "." + srvs['mdns_type'] + "local.", addresses=[srvs['ipaddr'][i]], port=srvs['port'][i])) """ Register all devices, then unregister""" with zeroconf_register_services(zc, srv_infos) as infos: """Give adb some time to register the service""" time.sleep(1) for i in range(len(srvs['mdns_name'])): self.assertTrue( any((srvs['mdns_name'][i] in line and srvs['mdns_type'] in line) for line in MdnsTest._mdns_services(server_port))) """Give adb some time to unregister the service""" time.sleep(1) for i in range(len(srvs['mdns_name'])): self.assertFalse( any((srvs['mdns_name'][i] in line and srvs['mdns_type'] in line) for line in MdnsTest._mdns_services(server_port)))
def get_service_info(service_type, name): dns_type = discovery.BREWBLOX_DNS_TYPE service_name = f'{name}.{dns_type}' if name == 'id0': return ServiceInfo( service_type, service_name, addresses=[inet_aton('0.0.0.0')], properties={ b'ID': b'id0', b'HW': b'Spark 3', }, ) if name == 'id1': return ServiceInfo( service_type, service_name, server=f'{name}.local.', addresses=[inet_aton('1.2.3.4')], port=1234, properties={ b'ID': b'id1', b'HW': b'Spark 3', }, ) if name == 'id2': return ServiceInfo( service_type, service_name, server=f'{name}.local.', addresses=[inet_aton('4.3.2.1')], port=4321, properties={ b'ID': b'id2', b'HW': b'Spark 4', }, )
def register_service(self, port: Optional[int] = None, name: Optional[str] = None, udp: bool = False): """ Initialize the Zeroconf service configuration for this backend. """ try: from zeroconf import ServiceInfo, Zeroconf from platypush.plugins.zeroconf import ZeroconfListener except ImportError: self.logger.warning( 'zeroconf package not available, service discovery will be disabled.' ) return self.zeroconf = Zeroconf() srv_desc = { 'name': 'Platypush', 'vendor': 'Platypush', 'version': __version__, } name = name or re.sub(r'Backend$', '', self.__class__.__name__).lower() srv_type = '_platypush-{name}._{proto}.local.'.format( name=name, proto='udp' if udp else 'tcp') srv_name = '{host}.{type}'.format(host=self.device_id, type=srv_type) if port: srv_port = port else: srv_port = self.port if hasattr(self, 'port') else None self.zeroconf_info = ServiceInfo( srv_type, srv_name, addresses=[socket.inet_aton(self._get_ip())], port=srv_port, weight=0, priority=0, properties=srv_desc) self.zeroconf.register_service(self.zeroconf_info) self.bus.post( ZeroconfServiceAddedEvent( service_type=srv_type, service_name=srv_name, service_info=ZeroconfListener.parse_service_info( self.zeroconf_info)))
async def test_find_with_device(mock_zeroconf): desc = {b"id": b"00:00:02:00:00:02"} info = ServiceInfo( "_hap._tcp.local.", "foo1._hap._tcp.local.", addresses=[socket.inet_aton("127.0.0.1")], port=1234, properties=desc, weight=0, priority=0, ) mock_zeroconf.get_service_info.return_value = info result = await async_find_device_ip_and_port("00:00:02:00:00:02", 0) assert result == ("127.0.0.1", 1234)
def update_txt(self, txt): args = list(self.args) args[6] = self.txt_rec(txt) self.args = tuple(args) si = ServiceInfo(*self.args) try: self.zeroconf.update_service(si) self.service = si except KeyError as e: #probably a race condition with cleanup log("update_txt(%s)", txt, exc_info=True) log.warn("Warning: failed to update service") log.warn(" %s", e) except Exception: log.error("Error: failed to update service", exc_info=True)
def start_zeroconf(self): self.zeroconf = Zeroconf() self.service_ident = auth.get_singleton().get_ident() self.service_name = "%s.%s" % (self.service_ident, SERVICE_TYPE) self.info = ServiceInfo(SERVICE_TYPE, self.service_name, socket.inet_aton(util.get_ip()), prefs.get_port(), properties={'hostname': util.get_hostname()}) self.zeroconf.register_service(self.info) return False
def get_service_info_mock(service_type, name): """Return service info for get_service_info.""" return ServiceInfo( service_type, name, address=b"\n\x00\x00\x14", port=80, weight=0, priority=0, server="name.local.", properties={ b"macaddress": b"ABCDEF012345", b"non-utf8-value": b"ABCDEF\x8a" }, )
def setup_discovery(): zeroconf_type = "_hue._tcp.local." info = ServiceInfo( zeroconf_type, name= f"Philips Hue - {self.config.bridge_id[-6:]}.{zeroconf_type}", addresses=[get_ip_pton()], port=80, properties={ "bridgeid": self.config.bridge_id, "modelid": self.config.definitions["bridge"]["modelid"], }, ) zeroconf.register_service(info)
def register_zeroconf_service() -> Tuple[Zeroconf, ServiceInfo]: ip = get_ip() if not ip: raise ValueError("Can't obtain IP address") info = ServiceInfo( "_grpc._tcp.local.", f"Input Server ({socket.gethostname()})._grpc._tcp.local.", addresses=[socket.inet_aton(ip)], port=17863) zeroconf = Zeroconf(ip_version=IPVersion.All) zeroconf.register_service(info) return zeroconf, info
def verify_name_change(self, zc, type_, name, number_hosts): desc = {'path': '/~paulsm/'} info_service = ServiceInfo( type_, '%s.%s' % (name, type_), 80, 0, 0, desc, "ash-2.local.", addresses=[socket.inet_aton("10.0.1.2")], ) # verify name conflict self.assertRaises(r.NonUniqueNameException, zc.register_service, info_service) # verify no name conflict https://tools.ietf.org/html/rfc6762#section-6.6 zc.register_service(info_service, cooperating_responders=True) # Create a new object since allow_name_change will mutate the # original object and then we will have the wrong service # in the registry info_service2 = ServiceInfo( type_, '%s.%s' % (name, type_), 80, 0, 0, desc, "ash-2.local.", addresses=[socket.inet_aton("10.0.1.2")], ) zc.register_service(info_service2, allow_name_change=True) assert info_service2.name.split('.')[0] == '%s-%d' % (name, number_hosts + 1)
def __init__(self, name, address, port, description): self.zeroconf = Zeroconf() self.name = name self.description = description self.address = address self.port = port self.full_name = get_full_name(name) self.info = ServiceInfo(type_=TYPE, name=self.full_name, address=socket.inet_aton(self.address), port=self.port, weight=0, priority=0, properties=self.description)
def registerService(self, ip): info = ServiceInfo("_http._tcp.local.", "Raspberry Pi Sleep Monitor._http._tcp.local.", socket.inet_aton(ip), self.portNumber, 0, 0, {}, "sleepmonitor.local.") zeroconf = Zeroconf() log("Registering zeroconf service...") zeroconf.register_service(info) def unregisterService(): log("Unregistering zeroconf service...") zeroconf.unregister_service(info) reactor.addSystemEventTrigger('before', 'shutdown', unregisterService)
def register(): global zeroconf desc = {'path': 'fire.properties'} info = ServiceInfo( "_http._tcp.local.", "fire._http._tcp.local.", addresses=[socket.inet_aton("127.0.0.1")], port=50052, properties=desc, server="fire.local.", ) zeroconf = Zeroconf() zeroconf.register_service(info) print('registered...')
def setup(hass, config): """Set up Zeroconf and make Home Assistant discoverable.""" from zeroconf import Zeroconf, ServiceInfo zeroconf = Zeroconf() zeroconf_name = '{}.{}'.format(hass.config.location_name, ZEROCONF_TYPE) requires_api_password = hass.config.api.api_password is not None params = { 'version': __version__, 'base_url': hass.config.api.base_url, 'requires_api_password': requires_api_password, } try: info = ServiceInfo( ZEROCONF_TYPE, zeroconf_name, socket.inet_pton(socket.AF_INET, hass.config.api.host), hass.config.api.port, 0, 0, params) except socket.error: info = ServiceInfo( ZEROCONF_TYPE, zeroconf_name, socket.inet_pton(socket.AF_INET6, hass.config.api.host), hass.config.api.port, 0, 0, params) zeroconf.register_service(info) def stop_zeroconf(event): """Stop Zeroconf.""" zeroconf.unregister_service(info) zeroconf.close() hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_zeroconf) return True
def startBonjour(self): if len(sys.argv) > 1: assert sys.argv[1:] == ['--debug'] self.logging.getLogger('zeroconf').setLevel(logging.DEBUG) #desc = {'path': '/~paulsm/'} self.info = ServiceInfo("_dartsconnect._tcp.local.", "Dartboard._dartsconnect._tcp.local.", socket.inet_aton(self.ip), self.port, 0, 0, {}, None) self.zeroconf = Zeroconf() print("DartsConnectBonjour --> DartsConnect service registered") self.zeroconf.register_service(self.info)
def mrp_service(service_name, atv_name, address): """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': b'4EE5AF58-7E5D-465A-935E-82E4DB74385D' } return ServiceInfo('_mediaremotetv._tcp.local.', service_name + '._mediaremotetv._tcp.local.', address=address, port=49152, properties=props)
def get_service_info(self): type_ = "_ewelink._tcp.local." registration_name = "eWeLink_%s.%s" % (self._name, type_) service_info = ServiceInfo( type_, registration_name, socket.inet_aton(self._ip), port=self._port, properties=self._properties, server="eWeLink_" + self._name + ".local.", ) return service_info
def register_mdns(self): logging.info("registering MDNS") desc = {'path': '/'} self.zeroconf_info = \ ServiceInfo("_http._tcp.local.", "spotify-registration._http._tcp.local.", socket.inet_aton(get_ip()), MYSERVER_PORT_NUMBER, 0, 0, desc, "spotify-registration.local.") self.zeroconf = Zeroconf() logging.info("Registration of spotify-registration.local. in mDNS") self.zeroconf.register_service(self.zeroconf_info)