async def async_step_zeroconf(
        self, discovery_info: zeroconf.ZeroconfServiceInfo
    ) -> FlowResult:
        """Handle a discovered Hue bridge.

        This flow is triggered by the Zeroconf component. It will check if the
        host is already configured and delegate to the import step if not.
        """
        # Ignore if host is IPv6
        if is_ipv6_address(discovery_info.host):
            return self.async_abort(reason="invalid_host")

        # abort if we already have exactly this bridge id/host
        # reload the integration if the host got updated
        bridge_id = normalize_bridge_id(discovery_info.properties["bridgeid"])
        await self.async_set_unique_id(bridge_id)
        self._abort_if_unique_id_configured(
            updates={CONF_HOST: discovery_info.host}, reload_on_update=True
        )

        # we need to query the other capabilities too
        self.bridge = await self._get_bridge(
            discovery_info.host, discovery_info.properties["bridgeid"]
        )
        return await self.async_step_link()
Esempio n. 2
0
 async def async_step_zeroconf(
         self, discovery_info: zeroconf.ZeroconfServiceInfo) -> FlowResult:
     """Handle zeroconf discovery."""
     properties = discovery_info.properties
     ip_address = discovery_info.host
     if is_ipv6_address(ip_address):
         return self.async_abort(reason="ipv6_not_supported")
     uuid = properties["uuid"]
     model = properties["model"]
     name = properties["name"]
     await self.async_set_unique_id(uuid)
     self._abort_if_unique_id_configured(
         updates={CONF_IP_ADDRESS: ip_address})
     self.discovery = BAFDiscovery(ip_address, name, uuid, model)
     return await self.async_step_discovery_confirm()
    async def async_step_ssdp(self, discovery_info: ssdp.SsdpServiceInfo) -> FlowResult:
        """Handle a discovered Hue bridge.

        This flow is triggered by the SSDP component. It will check if the
        host is already configured and delegate to the import step if not.
        """
        # Filter out non-Hue bridges #1
        if (
            discovery_info.upnp.get(ssdp.ATTR_UPNP_MANUFACTURER_URL)
            not in HUE_MANUFACTURERURL
        ):
            return self.async_abort(reason="not_hue_bridge")

        # Filter out non-Hue bridges #2
        if any(
            name in discovery_info.upnp.get(ssdp.ATTR_UPNP_FRIENDLY_NAME, "")
            for name in HUE_IGNORED_BRIDGE_NAMES
        ):
            return self.async_abort(reason="not_hue_bridge")

        if (
            not discovery_info.ssdp_location
            or ssdp.ATTR_UPNP_SERIAL not in discovery_info.upnp
        ):
            return self.async_abort(reason="not_hue_bridge")

        url = urlparse(discovery_info.ssdp_location)
        if not url.hostname:
            return self.async_abort(reason="not_hue_bridge")

        # Ignore if host is IPv6
        if is_ipv6_address(url.hostname):
            return self.async_abort(reason="invalid_host")

        # abort if we already have exactly this bridge id/host
        # reload the integration if the host got updated
        bridge_id = normalize_bridge_id(discovery_info.upnp[ssdp.ATTR_UPNP_SERIAL])
        await self.async_set_unique_id(bridge_id)
        self._abort_if_unique_id_configured(
            updates={CONF_HOST: url.hostname}, reload_on_update=True
        )

        self.bridge = await self._get_bridge(
            url.hostname, discovery_info.upnp[ssdp.ATTR_UPNP_SERIAL]
        )
        return await self.async_step_link()
    async def async_step_zeroconf(
        self, discovery_info: zeroconf.ZeroconfServiceInfo
    ) -> data_entry_flow.FlowResult:
        """Handle device found via zeroconf."""
        host = discovery_info.host
        if is_ipv6_address(host):
            return self.async_abort(reason="ipv6_not_supported")
        self._async_abort_entries_match({CONF_ADDRESS: host})
        service_type = discovery_info.type[:-1]  # Remove leading .
        name = discovery_info.name.replace(f".{service_type}.", "")
        properties = discovery_info.properties

        # Extract unique identifier from service
        unique_id = get_unique_id(service_type, name, properties)
        if unique_id is None:
            return self.async_abort(reason="unknown")

        if existing_unique_id := self._entry_unique_id_from_identifers({unique_id}):
            await self.async_set_unique_id(existing_unique_id)
            self._abort_if_unique_id_configured(updates={CONF_ADDRESS: host})
Esempio n. 5
0
def test_is_ipv6_address():
    """Test if strings are IPv6 addresses."""
    assert network_util.is_ipv6_address("::1") is True
    assert network_util.is_ipv6_address("8.8.8.8") is False
    assert network_util.is_ipv6_address("8.8.8.8") is False