示例#1
0
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
    """Set up Smappee from a zeroconf or config entry."""
    if CONF_IP_ADDRESS in entry.data:
        if helper.is_smappee_genius(entry.data[CONF_SERIALNUMBER]):
            # next generation: local mqtt broker
            smappee_mqtt = mqtt.SmappeeLocalMqtt(
                serial_number=entry.data[CONF_SERIALNUMBER])
            await hass.async_add_executor_job(
                smappee_mqtt.start_and_wait_for_config)
            smappee = Smappee(api=smappee_mqtt,
                              serialnumber=entry.data[CONF_SERIALNUMBER])
        else:
            # legacy devices through local api
            smappee_api = api.api.SmappeeLocalApi(
                ip=entry.data[CONF_IP_ADDRESS])
            smappee = Smappee(api=smappee_api,
                              serialnumber=entry.data[CONF_SERIALNUMBER])
        await hass.async_add_executor_job(smappee.load_local_service_location)
    else:
        implementation = (
            await
            config_entry_oauth2_flow.async_get_config_entry_implementation(
                hass, entry))

        smappee_api = api.ConfigEntrySmappeeApi(hass, entry, implementation)

        smappee = Smappee(api=smappee_api)
        await hass.async_add_executor_job(smappee.load_service_locations)

    hass.data[DOMAIN][entry.entry_id] = SmappeeBase(hass, smappee)

    hass.config_entries.async_setup_platforms(entry, PLATFORMS)

    return True
示例#2
0
    async def async_step_local(self, user_input=None):
        """Handle local flow."""
        if user_input is None:
            return self.async_show_form(
                step_id="local",
                data_schema=vol.Schema({vol.Required(CONF_HOST): str}),
                errors={},
            )
        # In a LOCAL setup we still need to resolve the host to serial number
        ip_address = user_input["host"]
        serial_number = None

        # Attempt 1: try to use the local api (older generation) to resolve host to serialnumber
        smappee_api = api.api.SmappeeLocalApi(ip=ip_address)
        logon = await self.opp.async_add_executor_job(smappee_api.logon)
        if logon is not None:
            advanced_config = await self.opp.async_add_executor_job(
                smappee_api.load_advanced_config)
            for config_item in advanced_config:
                if config_item["key"] == "mdnsHostName":
                    serial_number = config_item["value"]
        else:
            # Attempt 2: try to use the local mqtt broker (newer generation) to resolve host to serialnumber
            smappee_mqtt = mqtt.SmappeeLocalMqtt()
            connect = await self.opp.async_add_executor_job(
                smappee_mqtt.start_attempt)
            if not connect:
                return self.async_abort(reason="cannot_connect")

            serial_number = await self.opp.async_add_executor_job(
                smappee_mqtt.start_and_wait_for_config)
            await self.opp.async_add_executor_job(smappee_mqtt.stop)
            if serial_number is None:
                return self.async_abort(reason="cannot_connect")

        if serial_number is None or not serial_number.startswith(
                SUPPORTED_LOCAL_DEVICES):
            return self.async_abort(reason="invalid_mdns")

        serial_number = serial_number.replace("Smappee", "")

        # Check if already configured (local)
        await self.async_set_unique_id(serial_number, raise_on_progress=False)
        self._abort_if_unique_id_configured()

        return self.async_create_entry(
            title=f"{DOMAIN}{serial_number}",
            data={
                CONF_IP_ADDRESS: ip_address,
                CONF_SERIALNUMBER: serial_number
            },
        )
示例#3
0
    async def async_step_zeroconf_confirm(self, user_input=None):
        """Confirm zeroconf flow."""
        errors = {}

        # Check if already configured (cloud)
        if self.is_cloud_device_already_added():
            return self.async_abort(reason="already_configured_device")

        if user_input is None:
            serialnumber = self.context.get(CONF_SERIALNUMBER)
            return self.async_show_form(
                step_id="zeroconf_confirm",
                description_placeholders={"serialnumber": serialnumber},
                errors=errors,
            )

        ip_address = self.context.get(CONF_IP_ADDRESS)
        serial_number = self.context.get(CONF_SERIALNUMBER)

        # Attempt to make a connection to the local device
        if helper.is_smappee_genius(serial_number):
            # next generation device, attempt connect to the local mqtt broker
            smappee_mqtt = mqtt.SmappeeLocalMqtt(serial_number=serial_number)
            connect = await self.opp.async_add_executor_job(
                smappee_mqtt.start_attempt)
            if not connect:
                return self.async_abort(reason="cannot_connect")
        else:
            # legacy devices, without local mqtt broker, try api access
            smappee_api = api.api.SmappeeLocalApi(ip=ip_address)
            logon = await self.opp.async_add_executor_job(smappee_api.logon)
            if logon is None:
                return self.async_abort(reason="cannot_connect")

        return self.async_create_entry(
            title=f"{DOMAIN}{serial_number}",
            data={
                CONF_IP_ADDRESS: ip_address,
                CONF_SERIALNUMBER: serial_number
            },
        )