Ejemplo n.º 1
0
 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()
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
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()
Ejemplo n.º 4
0
 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()
Ejemplo n.º 5
0
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)
Ejemplo n.º 6
0
    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
Ejemplo n.º 7
0
    def start(self):
        """ Starts discovery. """
        self.zeroconf = zeroconf.Zeroconf()

        for service in self.services:
            self._browsers.append(
                zeroconf.ServiceBrowser(self.zeroconf, service.typ, service))
Ejemplo n.º 8
0
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)
Ejemplo n.º 9
0
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
Ejemplo n.º 10
0
 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)
Ejemplo n.º 11
0
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
Ejemplo n.º 12
0
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
Ejemplo n.º 13
0
 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)
Ejemplo n.º 14
0
    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 = {}
Ejemplo n.º 15
0
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 
Ejemplo n.º 16
0
    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)
Ejemplo n.º 18
0
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)
Ejemplo n.º 19
0
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
Ejemplo n.º 20
0
 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)
Ejemplo n.º 21
0
    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")
Ejemplo n.º 22
0
    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()
Ejemplo n.º 23
0
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
Ejemplo n.º 24
0
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)
Ejemplo n.º 25
0
    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)
Ejemplo n.º 27
0
    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 = {}
Ejemplo n.º 28
0
 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 = []
Ejemplo n.º 29
0
    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])
Ejemplo n.º 30
0
 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)