def test_launch_and_close_v6_only(self): rv = r.Zeroconf(interfaces=r.InterfaceChoice.All, ip_version=r.IPVersion.V6Only) rv.close() rv = r.Zeroconf(interfaces=r.InterfaceChoice.Default, ip_version=r.IPVersion.V6Only) rv.close()
def test_launch_and_close_context_manager(self): with r.Zeroconf(interfaces=r.InterfaceChoice.All) as rv: assert rv.done is False assert rv.done is True with r.Zeroconf(interfaces=r.InterfaceChoice.Default) as rv: assert rv.done is False assert rv.done is True
async def async_run_logs(config, address): conf = config["api"] port: int = int(conf[CONF_PORT]) password: str = conf[CONF_PASSWORD] noise_psk: Optional[str] = None if CONF_ENCRYPTION in conf: noise_psk = conf[CONF_ENCRYPTION][CONF_KEY] _LOGGER.info("Starting log output from %s using esphome API", address) zc = zeroconf.Zeroconf() cli = APIClient( address, port, password, client_info=f"ESPHome Logs {__version__}", noise_psk=noise_psk, ) first_connect = True def on_log(msg): time_ = datetime.now().time().strftime("[%H:%M:%S]") text = msg.message.decode("utf8", "backslashreplace") safe_print(time_ + text) async def on_connect(): nonlocal first_connect try: await cli.subscribe_logs( on_log, log_level=LogLevel.LOG_LEVEL_VERY_VERBOSE, dump_config=first_connect, ) first_connect = False except APIConnectionError: cli.disconnect() async def on_disconnect(): _LOGGER.warning("Disconnected from API") zc = zeroconf.Zeroconf() reconnect = ReconnectLogic( client=cli, on_connect=on_connect, on_disconnect=on_disconnect, zeroconf_instance=zc, ) await reconnect.start() try: while True: await asyncio.sleep(60) except KeyboardInterrupt: await reconnect.stop() zc.close()
def _server_register(self): with self._zconf_lock: hostname = socket.gethostname() ips = socket.gethostbyname_ex(hostname)[-1] if ips: compname = self._get_server_name().decode('utf-8') hostaddr = ips[0] desc = {'platform': self._SERVER_PLATFORM, 'version': '%s.%s.%s'%self._SERVER_VERSION} info = zeroconf.ServiceInfo(self._ZEROCONF_TYPE, '%s.'%compname + self._ZEROCONF_TYPE, socket.inet_aton(hostaddr), self._tcp_srv_port, 0, 0, desc, '%s.'%hostname) self._zconf = zeroconf.Zeroconf(bindaddress=hostaddr) self._zconf.register_service(info) else: self._zconf = zeroconf.Zeroconf()
def device_scan(hosts, action, do_all, dry_run, silent_run, mode, exclude, version, variant, stock_release_info, homekit_release_info): ffw = version logger.debug(f"\n{WHITE}device_scan{NC}") logger.debug(f"hosts: {hosts}") logger.debug(f"action: {action}") logger.debug(f"do_all: {do_all}") logger.debug(f"dry_run: {dry_run}") logger.debug(f"silent_run: {silent_run}") logger.debug(f"mode: {mode}") logger.debug(f"exclude: {exclude}") logger.debug(f"version: {version}") logger.debug(f"variant: {variant}") logger.debug(f"ffw: {ffw}") if not do_all: for device in hosts: logger.info(f"{WHITE}Probing Shelly device for info...\n{NC}") if not '.local' in device: device = device + '.local' probe_info(device, action, dry_run, silent_run, mode, exclude, version, variant, stock_release_info, homekit_release_info) else: logger.info(f"{WHITE}Scanning for Shelly devices...\n{NC}") zc = zeroconf.Zeroconf() listener = MyListener() browser = zeroconf.ServiceBrowser(zc, '_http._tcp.local.', listener) time.sleep(5) zc.close() logger.debug(f"device_test: {listener.device_list}") # logger.debug(f"\nproperties: {listener.p_list}") listener.device_list.sort() for device in listener.device_list: probe_info(device + '.local', action, dry_run, silent_run, mode, exclude, version, variant, stock_release_info, homekit_release_info)
def _RegisterService(self, name, ip, port): # name: fully qualified service name self.service_name = '%s.%s' % (name, service_type) self.name = name self.port = port if ip == "0.0.0.0": print("MDNS brodcasted on all interfaces") interfaces = zeroconf.InterfaceChoice.All ip = self.gethostaddr() else: interfaces = [ip] self.server = zeroconf.Zeroconf(interfaces=interfaces) print("MDNS brodcasted service address :" + ip) self.ip_32b = socket.inet_aton(ip) self.server.register_service( zeroconf.ServiceInfo(service_type, self.service_name, self.ip_32b, self.port, properties=self.serviceproperties)) self.retrytimer = None
def start(self): """ Starts discovery. """ self.zeroconf = zeroconf.Zeroconf() for service in self.services: self._browsers.append( zeroconf.ServiceBrowser(self.zeroconf, service.typ, service))
def discover_chromecasts(max_devices=None, timeout=DISCOVER_TIMEOUT, zeroconf_instance=None): """ Discover chromecasts on the network. Returns a tuple of: A list of chromecast devices, or an empty list if no matching chromecasts were found. A service browser to keep the Chromecast mDNS data updated. When updates are (no longer) needed, call browser.stop_discovery(). :param zeroconf_instance: An existing zeroconf instance. """ def add_callback(_uuid, _service): """Called when zeroconf has discovered a new chromecast.""" if max_devices is not None and browser.count >= max_devices: discover_complete.set() discover_complete = threading.Event() zconf = zeroconf_instance or zeroconf.Zeroconf() browser = CastBrowser(SimpleCastListener(add_callback), zconf) browser.start_discovery() # Wait for the timeout or the maximum number of devices discover_complete.wait(timeout) return (browser.devices.values(), browser)
def cast_device_discovery_agent(): global gv_cast_devices_dict global gv_zconf def cast_device_add_callback(uuid, name): # Add discovered device to global dict # keyed on friendly name and stores the full # service record friendly_name = cast_listener.services[uuid][3] gv_cast_devices_dict[friendly_name] = cast_listener.services[uuid] def cast_device_remove_callback(uuid, name, service): # purge removed devices from the global dict friendly_name = cast_listener.services[uuid][3] if friendly_name in gv_cast_devices_dict: del gv_cast_devices_dict[friendly_name] # cast listener (add, remove, update) # treat update as add cast_listener = pychromecast.CastListener(cast_device_add_callback, cast_device_remove_callback, cast_device_add_callback) gv_zconf = zeroconf.Zeroconf() cast_browser = pychromecast.discovery.start_discovery( cast_listener, gv_zconf) while (True): time.sleep(30) log_message( 0, 'All discovered cast devices: %s' % (list(gv_cast_devices_dict.keys()))) return
def scanChromecast(self): self.listener = pychromecast.CastListener(self.cc_added_callback, self.cc_removed_callback, self.cc_updated_callback) zconf = zeroconf.Zeroconf() self.browser = pychromecast.discovery.start_discovery( self.listener, zconf)
def resolve_host(host, timeout=3.0, zeroconf_instance: zeroconf.Zeroconf = None): from aioesphomeapi import APIConnectionError try: zc = zeroconf_instance or zeroconf.Zeroconf() except Exception: raise APIConnectionError( "Cannot start mDNS sockets, is this a docker container without " "host network mode?") try: info = HostResolver(host + '.') address = None if info.request(zc, timeout): address = socket.inet_ntoa(info.address) except Exception as err: raise APIConnectionError( "Error resolving mDNS hostname: {}".format(err)) finally: if not zeroconf_instance: zc.close() if address is None: raise APIConnectionError( "Error resolving address with mDNS: Did not respond. " "Maybe the device is offline.") return address
def _locate_ha() -> Optional[str]: _zeroconf = zeroconf.Zeroconf() listener = _ZeroconfListener() zeroconf.ServiceBrowser(_zeroconf, "_home-assistant._tcp.local.", listener) try: import time retries = 0 while not listener.services and retries < 5: _LOGGING.info( "Trying to locate Home Assistant on local network...") time.sleep(0.5) retries = retries + 1 finally: _zeroconf.close() if listener.services: if len(listener.services) > 1: _LOGGING.warning( "Found multiple Home Assistants at %s", ", ".join(listener.services), ) _LOGGING.warning("Use --server to explicitly specify one.") return None _, service = listener.services.popitem() base_url = service.properties[b'base_url'].decode('utf-8') _LOGGING.info("Found and using %s as server", base_url) return cast(str, base_url) _LOGGING.warning( "Found no Home Assistant on local network. Using defaults.") return None
def run_zeroconf(self): if not ZEROCONF_AVAILABLE: return self.zeroconf = zeroconf.Zeroconf() self.zeroconf.listener = self self.browser = zeroconf.ServiceBrowser(self.zeroconf, self.service_type, self)
def __init__(self): self.zc = zeroconf.Zeroconf() self.info_entries = [] self.our_ip = None self.browser = zeroconf.ServiceBrowser(self.zc, "_apt_proxy._tcp.local.", self) self.service_ip_ports_by_name = {}
def chromecast_agent(): global gv_discovered_devices global gv_zconf def chromecast_add_callback(uuid, name): # Add discovered device to global dict # keyed on friendly name and stores the full # service record friendly_name = cast_listener.services[uuid][3] gv_discovered_devices[friendly_name] = cast_listener.services[uuid] def chromecast_remove_callback(uuid, name, service): # purge removed devices from the global dict friendly_name = cast_listener.services[uuid][3] if friendly_name in gv_discovered_devices: del gv_discovered_devices[friendly_name] cast_listener = pychromecast.CastListener( chromecast_add_callback, chromecast_remove_callback) gv_zconf = zeroconf.Zeroconf() cast_browser = pychromecast.discovery.start_discovery( cast_listener, gv_zconf) while (1): time.sleep(30) log_message('Discovered cast devices: %s' % ( list(gv_discovered_devices.keys()))) return
def __init__(self, master=False, noNM=False, disable_zeroconf=False, verbosity=0): super(DfmsDaemon, self).__init__() self._shutting_down = False self._verbosity = verbosity # The three processes we run self._nm_proc = None self._dim_proc = None self._mm_proc = None # Zeroconf for NM and MM self._zeroconf = None if disable_zeroconf else zc.Zeroconf() self._nm_info = None self._mm_browser = None # Starting managers app = self.app app.post('/managers/node', callback=self.rest_startNM) app.post('/managers/dataisland', callback=self.rest_startDIM) app.post('/managers/master', callback=self.rest_startMM) # Querying about managers app.get('/managers/node', callback=self.rest_getNMInfo) app.get('/managers/dataisland', callback=self.rest_getDIMInfo) app.get('/managers/master', callback=self.rest_getMMInfo) # Automatically start those that we need if master: self.startMM() if not noNM: self.startNM()
def start(self, force_local_ip=True): ''' force_local_ip: if zeroconf enabled, forces the use of a local ip address when advertising this service ( 192.168.x , 172.16.x, or 10.x ) ''' self.request_handler._set_state(self.registry) # pass reference self.request_handler._last_contacted(datetime.datetime.now()) self.httpdt = _httpd_Thread(host=self.host, port=self.port, handler=self.request_handler) self.httpdt.start() if not zeroconf or self.zeroconf_disabled: info( 'python-zeroconf not found, or disabled! Unable to configure network autodiscovery.' ) self.zeroconf = None else: self.service_info = zeroconf.ServiceInfo( "_http._tcp.local.", "{0}._http._tcp.local.".format(self.service_name), address=self._get_address(force_local_ip), port=self.port, properties={'path': '/'}) self.zeroconf = zeroconf.Zeroconf() try: self.zeroconf.registerService(self.service_info) except AssertionError as e: debug(e)
def device_scan(hosts, action, do_all, dry_run, silent_run, mode, exclude, version, variant, stock_release_info, homekit_release_info): logger.debug(f"\n{WHITE}device_scan{NC}") logger.debug(f"devices: {hosts}") logger.debug(f"action: {action}") logger.debug(f"do_all: {do_all}") logger.debug(f"dry_run: {dry_run}") logger.debug(f"silent_run: {silent_run}") logger.debug(f"mode: {mode}") logger.debug(f"exclude: {exclude}") logger.debug(f"version: {version}") logger.debug(f"variant: {variant}") if not do_all: device_list = [] logger.info(f"{WHITE}Probing Shelly device for info...\n{NC}") for host in hosts: info = get_info(host) if info is not None: device_list.append(info) else: logger.info(f"{WHITE}Scanning for Shelly devices...\n{NC}") zc = zeroconf.Zeroconf() listener = MyListener() browser = zeroconf.ServiceBrowser(zc, '_http._tcp.local.', listener) time.sleep(10) zc.close() device_list = listener.device_list sorted_device_list = sorted(device_list, key=lambda k: k['host']) logger.trace(f"device_test: {sorted_device_list}") # logger.debug(f"\nproperties: {listener.p_list}") for device in sorted_device_list: parse_info(device, action, dry_run, silent_run, mode, exclude, version, variant, stock_release_info, homekit_release_info)
def look_for(service_name, timeout=None, get_many=True, type_="_http._tcp.local."): services = [] Added = zeroconf.ServiceStateChange.Added # stupid but necessary # semaphore used for synchronization # listen for just first one, or for many until timeout handler_done = multiprocessing.Event() def on_service_state_change(zeroconf, service_type, name, state_change): nonlocal services, handler_done if state_change is Added: info = zeroconf.get_service_info(service_type, name) if name.startswith(service_name): address = socket.inet_ntoa(info.address) port = info.port if get_many or len(services)==0: services.append([name, address, port]) if not get_many: handler_done.set() # register a listner for zeroconf events zc = zeroconf.Zeroconf() zeroconf.ServiceBrowser(zc, type_=type_, handlers=[on_service_state_change]) # wait until the listener found what we are looking for handler_done.wait(timeout) zc.close() return services
def publish(self): import zeroconf # zeroconf doesn't do this for us # .. pick one at random? Ideally, zeroconf would publish all valid # addresses as the A record.. but doesn't seem to do so addrs = zeroconf.get_all_addresses(socket.AF_INET) address = None if addrs: for addr in addrs: if addr != '127.0.0.1': address = socket.inet_aton(addrs[0]) type_ = self.stype + ".local." self.info = zeroconf.ServiceInfo( type_, self.name + "." + type_, address=address, port=self.port, properties=self.text, server=self.host if self.host else None ) self.zc = zeroconf.Zeroconf() self.zc.register_service(self.info)
def validate(self, context): """ Component validated """ # Get the framework UID self._fw_uid = context.get_property(pelix.constants.FRAMEWORK_UID) # Get the host address self._address = socket.inet_aton( socket.gethostbyname(socket.gethostname())) # Prepare Zeroconf self._zeroconf = zeroconf.Zeroconf() # Register the dispatcher servlet as a service self.__register_servlet() # Listen to our types self._browsers.append( zeroconf.ServiceBrowser(self._zeroconf, ZeroconfDiscovery.DNS_DISPATCHER_TYPE, self)) self._browsers.append( zeroconf.ServiceBrowser(self._zeroconf, self._rs_type, self)) _logger.debug("Zeroconf discovery validated")
def _start_listener(self): parent = self class Listener(pychromecast.discovery.AbstractCastListener): """Receive chromecast discovery updates""" def add_cast(self, uuid, service): self.update_cast(uuid, service) def remove_cast(self, uuid, service, cast_info): del parent.devices[uuid] if parent.callback_fn is not None: parent.callback_fn() def update_cast(self, uuid, service): with sentry_sdk.start_transaction( op="cc_update", name="Chromecast update recieved"): svcs = parent.browser.services cast = pychromecast.get_chromecast_from_cast_info( svcs[uuid], parent.zconf) cast.wait(timeout=2) # We only care about devices that we can cast to (i.e., not # audio devices) if cast.cast_info.cast_type != 'cast': return if uuid not in parent.devices: parent.devices[uuid] = {"cast": cast, "enabled": False} else: parent.devices[uuid]["cast"] = cast if parent.callback_fn is not None: parent.callback_fn() self.zconf = zeroconf.Zeroconf() self.browser = pychromecast.discovery.CastBrowser( Listener(), self.zconf) self.browser.start_discovery()
def start_discovery(add_callback=None, remove_callback=None): """ Start discovering chromecasts on the network. This method will start discovering chromecasts on a separate thread. When a chromecast is discovered, the callback will be called with the discovered chromecast's zeroconf name. This is the dictionary key to find the chromecast metadata in listener.services. This method returns the CastListener object and the zeroconf ServiceBrowser object. The CastListener object will contain information for the discovered chromecasts. To stop discovery, call the stop_discovery method with the ServiceBrowser object. """ listener = CastListener(add_callback, remove_callback) service_browser = False try: service_browser = zeroconf.ServiceBrowser( zeroconf.Zeroconf(), "_googlecast._tcp.local.", listener ) except ( zeroconf.BadTypeInNameException, NotImplementedError, OSError, socket.error, zeroconf.NonUniqueNameException, ): pass return listener, service_browser
def discover_chromecasts(max_devices=None, timeout=DISCOVER_TIMEOUT, zeroconf_instance=None): """ Discover chromecasts on the network. Returns a tuple of: A list of chromecast services, or an empty list if no matching chromecasts were found. A service browser to keep the Chromecast mDNS data updated. When updates are (no longer) needed, pass the browser object to pychromecast.discovery.stop_discovery(). :param zeroconf_instance: An existing zeroconf instance. """ # pylint: disable=unused-argument def callback(uuid, name): """Called when zeroconf has discovered a new chromecast.""" if max_devices is not None and listener.count >= max_devices: discover_complete.set() discover_complete = Event() listener = CastListener(callback) zconf = zeroconf_instance or zeroconf.Zeroconf() browser = start_discovery(listener, zconf) # Wait for the timeout or the maximum number of devices discover_complete.wait(timeout) return (listener.devices, browser)
def __init__(self, ledfx): super().__init__(ledfx, Device, self.PACKAGE_NAME) def cleanup_effects(e): self.clear_all_effects() self._ledfx.events.add_listener(cleanup_effects, Event.LEDFX_SHUTDOWN) self._zeroconf = zeroconf.Zeroconf()
def target(self): """This thread scans for Bonjour/mDNS devices and emits deviceDiscovered signal with its name, address and info object""" self.zc = zeroconf.Zeroconf() self.browser = zeroconf.ServiceBrowser(self.zc, "_http._tcp.local.", handlers=[self.on_state_change]) while True: time.sleep(0.5)
def __init__(self): """ Construct a new Bonjour/Zeroconf server. This server takes `DAAPServer` instances and advertises them. """ self.zeroconf = zeroconf.Zeroconf(zeroconf.InterfaceChoice.All) self.daap_servers = {}
def __init__(self, driver, interval): assert isinstance(driver, z42.driver.Driver) assert isinstance(interval, int) assert interval > 0 self.driver = driver self.interval = interval self.zc = zeroconf.Zeroconf() self.services = []
def __init__(self, _exaile, _menu): """ Sets up the zeroconf listener. """ GObject.GObject.__init__(self) self.services = {} self.menu = _menu if ZEROCONF_LEGACY: logger.info("Using zeroconf legacy API") zc = zeroconf.Zeroconf() else: logger.info("Using zeroconf new API") zc = zeroconf.Zeroconf(ip_version=zeroconf.IPVersion.All) self.browser = zeroconf.ServiceBrowser( zc, '_daap._tcp.local.', handlers=[self.on_service_state_change])
def __init__(self, protocol = '_pyme-pyro'): self._protocol = protocol self._services = {} self.zc = zeroconf.Zeroconf() self.listener = ZCListener(self._protocol) self.browser = zeroconf.ServiceBrowser(self.zc, "%s._tcp.local." % self._protocol, self.listener)