xiaomi_gateway/__init__.py
def discover_gateways(self):
        """Discover gateways using multicast"""

        _socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        _socket.settimeout(5.0)
        if self._interface != 'any':
            _socket.bind((self._interface, 0))

        for gateway in self._gateways_config:
            host = gateway.get('host')
            port = gateway.get('port')
            sid = gateway.get('sid')

            if not (host and port and sid):
                continue
            try:
                ip_address = socket.gethostbyname(host)
                if gateway.get('disable'):
                    _LOGGER.info(
                        'Xiaomi Gateway %s is disabled by configuration', sid)
                    self.disabled_gateways.append(ip_address)
                    continue
                _LOGGER.info(
                    'Xiaomi Gateway %s configured at IP %s:%s',
                    sid, ip_address, port)

                self.gateways[ip_address] = XiaomiGateway(
                    ip_address, port, sid,
                    gateway.get('key'), self._device_discovery_retries,
                    self._interface, gateway.get('proto'))
            except OSError as error:
                _LOGGER.error(
                    "Could not resolve %s: %s", host, error)

        try:
            _socket.sendto('{"cmd":"whois"}'.encode(),
                           (self.MULTICAST_ADDRESS, self.GATEWAY_DISCOVERY_PORT))

            while True:
                data, (ip_add, _) = _socket.recvfrom(1024)
                if len(data) is None or ip_add in self.gateways:
                    continue

                if ip_add in self.gateways.keys() or ip_add in self.disabled_gateways:
                    continue

                resp = json.loads(data.decode())
                if resp["cmd"] != 'iam':
                    _LOGGER.error("Response does not match return cmd")
                    continue

                if resp["model"] not in GATEWAY_MODELS:
                    _LOGGER.error("Response must be gateway model")
                    continue

                disabled = False
                gateway_key = None
                for gateway in self._gateways_config:
                    sid = gateway.get('sid')
                    if sid is None or sid == resp["sid"]:
                        gateway_key = gateway.get('key')
                    if sid and sid == resp['sid'] and gateway.get('disable'):
                        disabled = True

                sid = resp["sid"]
                if disabled:
                    _LOGGER.info("Xiaomi Gateway %s is disabled by configuration",
                                 sid)
                    self.disabled_gateways.append(ip_add)
                else:
                    _LOGGER.info('Xiaomi Gateway %s found at IP %s', sid, ip_add)
                    self.gateways[ip_add] = XiaomiGateway(
                        ip_add, resp["port"], sid, gateway_key,
                        self._device_discovery_retries, self._interface,
                        resp["proto_version"] if "proto_version" in resp else None)

        except socket.timeout:
            _LOGGER.info("Gateway discovery finished in 5 seconds")
            _socket.close()
def discover_gateways(self):
        """Discover gateways using multicast"""

        _socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        _socket.settimeout(5.0)
        if self._interface != 'any':
            _socket.bind((self._interface, 0))

        for gateway in self._gateways_config:
            host = gateway.get('host')
            port = gateway.get('port')
            sid = gateway.get('sid')

            if not (host and port and sid):
                continue
            try:
                ip_address = socket.gethostbyname(host)
                if gateway.get('disable'):
                    _LOGGER.info(
                        'Xiaomi Gateway %s is disabled by configuration', sid)
                    self.disabled_gateways.append(ip_address)
                    continue
                _LOGGER.info(
                    'Xiaomi Gateway %s configured at IP %s:%s',
                    sid, ip_address, port)

                self.gateways[ip_address] = XiaomiGateway(
                    ip_address, port, sid,
                    gateway.get('key'), self._device_discovery_retries,
                    self._interface, gateway.get('proto'))
            except OSError as error:
                _LOGGER.error(
                    "Could not resolve %s: %s", host, error)

        try:
            _socket.sendto('{"cmd":"whois"}'.encode(),
                           (self.MULTICAST_ADDRESS, self.GATEWAY_DISCOVERY_PORT))

            while True:
                data, (ip_add, _) = _socket.recvfrom(1024)
                if len(data) is None or ip_add in self.gateways:
                    continue

                if ip_add in self.gateways.keys() or ip_add in self.disabled_gateways:
                    continue

                resp = json.loads(data.decode())
                if resp["cmd"] != 'iam':
                    _LOGGER.error("Response does not match return cmd")
                    continue

                if resp["model"] not in GATEWAY_MODELS:
                    _LOGGER.error("Response must be gateway model")
                    continue

                disabled = False
                gateway_key = None
                for gateway in self._gateways_config:
                    sid = gateway.get('sid')
                    if sid is None or sid == resp["sid"]:
                        gateway_key = gateway.get('key')
                    if sid and sid == resp['sid'] and gateway.get('disable'):
                        disabled = True

                sid = resp["sid"]
                if disabled:
                    _LOGGER.info("Xiaomi Gateway %s is disabled by configuration",
                                 sid)
                    self.disabled_gateways.append(ip_add)
                else:
                    _LOGGER.info('Xiaomi Gateway %s found at IP %s', sid, ip_add)
                    self.gateways[ip_add] = XiaomiGateway(
                        ip_add, resp["port"], sid, gateway_key,
                        self._device_discovery_retries, self._interface,
                        resp["proto_version"] if "proto_version" in resp else None)

        except socket.timeout:
            _LOGGER.info("Gateway discovery finished in 5 seconds")
            _socket.close()
def discover_gateways ( self ) : _socket = socket . socket ( socket . AF_INET , socket . SOCK_DGRAM ) _socket . settimeout ( 5.0 ) if self . _interface != 'any' : _socket . bind ( ( self . _interface , 0 ) ) for gateway in self . _gateways_config : host = gateway . get ( 'host' ) port = gateway . get ( 'port' ) sid = gateway . get ( 'sid' ) if not ( host and port and sid ) : continue try : ip_address = socket . gethostbyname ( host ) if gateway . get ( 'disable' ) : _LOGGER . info ( 'Xiaomi Gateway %s is disabled by configuration' , sid ) self . disabled_gateways . append ( ip_address ) continue _LOGGER . info ( 'Xiaomi Gateway %s configured at IP %s:%s' , sid , ip_address , port ) self . gateways [ ip_address ] = XiaomiGateway ( ip_address , port , sid , gateway . get ( 'key' ) , self . _device_discovery_retries , self . _interface , gateway . get ( 'proto' ) ) except OSError as error : _LOGGER . error ( "Could not resolve %s: %s" , host , error ) try : _socket . sendto ( '{"cmd":"whois"}' . encode ( ) , ( self . MULTICAST_ADDRESS , self . GATEWAY_DISCOVERY_PORT ) ) while True : data , ( ip_add , _ ) = _socket . recvfrom ( 1024 ) if len ( data ) is None or ip_add in self . gateways : continue if ip_add in self . gateways . keys ( ) or ip_add in self . disabled_gateways : continue resp = json . loads ( data . decode ( ) ) if resp [ "cmd" ] != 'iam' : _LOGGER . error ( "Response does not match return cmd" ) continue if resp [ "model" ] not in GATEWAY_MODELS : _LOGGER . error ( "Response must be gateway model" ) continue disabled = False gateway_key = None for gateway in self . _gateways_config : sid = gateway . get ( 'sid' ) if sid is None or sid == resp [ "sid" ] : gateway_key = gateway . get ( 'key' ) if sid and sid == resp [ 'sid' ] and gateway . get ( 'disable' ) : disabled = True sid = resp [ "sid" ] if disabled : _LOGGER . info ( "Xiaomi Gateway %s is disabled by configuration" , sid ) self . disabled_gateways . append ( ip_add ) else : _LOGGER . info ( 'Xiaomi Gateway %s found at IP %s' , sid , ip_add ) self . gateways [ ip_add ] = XiaomiGateway ( ip_add , resp [ "port" ] , sid , gateway_key , self . _device_discovery_retries , self . _interface , resp [ "proto_version" ] if "proto_version" in resp else None ) except socket . timeout : _LOGGER . info ( "Gateway discovery finished in 5 seconds" ) _socket . close ( )
Discover gateways using multicast
Discover gateways using multicast