Ejemplo n.º 1
0
async def validate_input(
    hass: core.HomeAssistant, host: str, data: dict[str, Any]
) -> dict[str, Any]:
    """Validate the user input allows us to connect.

    Data has the keys from DATA_SCHEMA with values provided by the user.
    """

    options = aioshelly.ConnectionOptions(
        host, data.get(CONF_USERNAME), data.get(CONF_PASSWORD)
    )
    coap_context = await get_coap_context(hass)

    async with async_timeout.timeout(AIOSHELLY_DEVICE_TIMEOUT_SEC):
        device = await aioshelly.Device.create(
            aiohttp_client.async_get_clientsession(hass),
            coap_context,
            options,
        )

    device.shutdown()

    # Return info that you want to store in the config entry.
    return {
        "title": device.settings["name"],
        "hostname": device.settings["device"]["hostname"],
        "sleep_period": get_device_sleep_period(device.settings),
        "model": device.settings["device"]["type"],
    }
Ejemplo n.º 2
0
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
    """Set up Shelly from a config entry."""
    temperature_unit = "C" if hass.config.units.is_metric else "F"
    options = aioshelly.ConnectionOptions(
        entry.data[CONF_HOST],
        entry.data.get(CONF_USERNAME),
        entry.data.get(CONF_PASSWORD),
        temperature_unit,
    )
    try:
        async with async_timeout.timeout(5):
            device = await aioshelly.Device.create(
                aiohttp_client.async_get_clientsession(hass),
                options,
            )
    except (asyncio.TimeoutError, OSError) as err:
        raise ConfigEntryNotReady from err

    wrapper = hass.data[DOMAIN][entry.entry_id] = ShellyDeviceWrapper(
        hass, entry, device)
    await wrapper.async_setup()

    for component in PLATFORMS:
        hass.async_create_task(
            hass.config_entries.async_forward_entry_setup(entry, component))

    return True
Ejemplo n.º 3
0
async def validate_input(hass: core.HomeAssistant, host, data):
    """Validate the user input allows us to connect.

    Data has the keys from DATA_SCHEMA with values provided by the user.
    """
    ip_address = await hass.async_add_executor_job(gethostbyname, host)

    options = aioshelly.ConnectionOptions(ip_address, data.get(CONF_USERNAME),
                                          data.get(CONF_PASSWORD))
    coap_context = await get_coap_context(hass)

    async with async_timeout.timeout(5):
        device = await aioshelly.Device.create(
            aiohttp_client.async_get_clientsession(hass),
            coap_context,
            options,
        )

    device.shutdown()

    # Return info that you want to store in the config entry.
    return {
        "title": device.settings["name"],
        "hostname": device.settings["device"]["hostname"],
    }
Ejemplo n.º 4
0
async def validate_input(hass: core.HomeAssistant, host, data):
    """Validate the user input allows us to connect.

    Data has the keys from DATA_SCHEMA with values provided by the user.
    """
    options = aioshelly.ConnectionOptions(
        host, data.get(CONF_USERNAME), data.get(CONF_PASSWORD)
    )
    async with async_timeout.timeout(5):
        device = await aioshelly.Device.create(
            aiohttp_client.async_get_clientsession(hass),
            options,
        )

    await device.shutdown()

    # Return info that you want to store in the config entry.
    return {"title": device.settings["name"], "mac": device.settings["device"]["mac"]}
Ejemplo n.º 5
0
async def test_single(ip, username, password, init, timeout):
    options = aioshelly.ConnectionOptions(ip, username, password)

    async with aiohttp.ClientSession() as aiohttp_session, aioshelly.COAP(
    ) as coap_context:
        try:
            device = await asyncio.wait_for(
                aioshelly.Device.create(aiohttp_session, coap_context, options,
                                        init),
                timeout,
            )
        except asyncio.TimeoutError:
            print("Timeout connecting to", ip)
            return

        print_device(device)

        device.subscribe_updates(device_updated)

        while True:
            await asyncio.sleep(0.1)
Ejemplo n.º 6
0
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
    """Set up Shelly from a config entry."""
    temperature_unit = "C" if hass.config.units.is_metric else "F"

    ip_address = await hass.async_add_executor_job(gethostbyname,
                                                   entry.data[CONF_HOST])

    options = aioshelly.ConnectionOptions(
        ip_address,
        entry.data.get(CONF_USERNAME),
        entry.data.get(CONF_PASSWORD),
        temperature_unit,
    )

    coap_context = await get_coap_context(hass)

    try:
        async with async_timeout.timeout(AIOSHELLY_DEVICE_TIMEOUT_SEC):
            device = await aioshelly.Device.create(
                aiohttp_client.async_get_clientsession(hass),
                coap_context,
                options,
            )
    except (asyncio.TimeoutError, OSError) as err:
        raise ConfigEntryNotReady from err

    hass.data[DOMAIN][DATA_CONFIG_ENTRY][entry.entry_id] = {}
    coap_wrapper = hass.data[DOMAIN][DATA_CONFIG_ENTRY][
        entry.entry_id][COAP] = ShellyDeviceWrapper(hass, entry, device)
    await coap_wrapper.async_setup()

    hass.data[DOMAIN][DATA_CONFIG_ENTRY][
        entry.entry_id][REST] = ShellyDeviceRestWrapper(hass, device)

    for component in PLATFORMS:
        hass.async_create_task(
            hass.config_entries.async_forward_entry_setup(entry, component))

    return True
Ejemplo n.º 7
0
async def test_devices(init, timeout):
    device_options = []
    with open("devices.json") as fp:
        for line in fp:
            device_options.append(
                aioshelly.ConnectionOptions(**json.loads(line)))

    async with aiohttp.ClientSession() as aiohttp_session, aioshelly.COAP(
    ) as coap_context:
        results = await asyncio.gather(
            *[
                asyncio.wait_for(
                    connect_and_print_device(aiohttp_session, coap_context,
                                             options, init),
                    timeout,
                ) for options in device_options
            ],
            return_exceptions=True,
        )

        for options, result in zip(device_options, results):
            if not isinstance(result, Exception):
                continue

            print()
            print(f"Error printing device @ {options.ip_address}")

            if isinstance(result, asyncio.TimeoutError):
                print("Timeout connecting to device")
            else:
                print()
                traceback.print_tb(result.__traceback__)
                print(result)

        while True:
            await asyncio.sleep(0.1)
Ejemplo n.º 8
0
async def async_setup_entry(opp: OpenPeerPower, entry: ConfigEntry):
    """Set up Shelly from a config entry."""
    # The custom component for Shelly devices uses shelly domain as well as core
    # integration. If the user removes the custom component but doesn't remove the
    # config entry, core integration will try to configure that config entry with an
    # error. The config entry data for this custom component doesn't contain host
    # value, so if host isn't present, config entry will not be configured.
    if not entry.data.get(CONF_HOST):
        _LOGGER.warning(
            "The config entry %s probably comes from a custom integration, please remove it if you want to use core Shelly integration",
            entry.title,
        )
        return False

    opp.data[DOMAIN][DATA_CONFIG_ENTRY][entry.entry_id] = {}
    opp.data[DOMAIN][DATA_CONFIG_ENTRY][entry.entry_id][DEVICE] = None

    temperature_unit = "C" if opp.config.units.is_metric else "F"

    options = aioshelly.ConnectionOptions(
        entry.data[CONF_HOST],
        entry.data.get(CONF_USERNAME),
        entry.data.get(CONF_PASSWORD),
        temperature_unit,
    )

    coap_context = await get_coap_context(opp)

    device = await aioshelly.Device.create(
        aiohttp_client.async_get_clientsession(opp),
        coap_context,
        options,
        False,
    )

    dev_reg = await device_registry.async_get_registry(opp)
    device_entry = None
    if entry.unique_id is not None:
        device_entry = dev_reg.async_get_device(identifiers={
            (DOMAIN, entry.unique_id)
        },
                                                connections=set())
    if device_entry and entry.entry_id not in device_entry.config_entries:
        device_entry = None

    sleep_period = entry.data.get("sleep_period")

    @callback
    def _async_device_online(_):
        _LOGGER.debug("Device %s is online, resuming setup", entry.title)
        opp.data[DOMAIN][DATA_CONFIG_ENTRY][entry.entry_id][DEVICE] = None

        if sleep_period is None:
            data = {**entry.data}
            data["sleep_period"] = get_device_sleep_period(device.settings)
            data["model"] = device.settings["device"]["type"]
            opp.config_entries.async_update_entry(entry, data=data)

        opp.async_create_task(async_device_setup(opp, entry, device))

    if sleep_period == 0:
        # Not a sleeping device, finish setup
        _LOGGER.debug("Setting up online device %s", entry.title)
        try:
            async with async_timeout.timeout(AIOSHELLY_DEVICE_TIMEOUT_SEC):
                await device.initialize(True)
        except (asyncio.TimeoutError, OSError) as err:
            raise ConfigEntryNotReady from err

        await async_device_setup(opp, entry, device)
    elif sleep_period is None or device_entry is None:
        # Need to get sleep info or first time sleeping device setup, wait for device
        opp.data[DOMAIN][DATA_CONFIG_ENTRY][entry.entry_id][DEVICE] = device
        _LOGGER.debug("Setup for device %s will resume when device is online",
                      entry.title)
        device.subscribe_updates(_async_device_online)
        await device.coap_request("s")
    else:
        # Restore sensors for sleeping device
        _LOGGER.debug("Setting up offline device %s", entry.title)
        await async_device_setup(opp, entry, device)

    return True
Ejemplo n.º 9
0
 def device(self):
     device = aioshelly.Device(Mock(), None,
                               aioshelly.ConnectionOptions("mock-ip"))
     device._update_d(self.cit_d)
     device._update_s(self.cit_s)
     return device
Ejemplo n.º 10
0
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
    """Set up Shelly from a config entry."""
    hass.data[DOMAIN][DATA_CONFIG_ENTRY][entry.entry_id] = {}
    hass.data[DOMAIN][DATA_CONFIG_ENTRY][entry.entry_id][DEVICE] = None

    temperature_unit = "C" if hass.config.units.is_metric else "F"

    options = aioshelly.ConnectionOptions(
        entry.data[CONF_HOST],
        entry.data.get(CONF_USERNAME),
        entry.data.get(CONF_PASSWORD),
        temperature_unit,
    )

    coap_context = await get_coap_context(hass)

    device = await aioshelly.Device.create(
        aiohttp_client.async_get_clientsession(hass),
        coap_context,
        options,
        False,
    )

    dev_reg = await device_registry.async_get_registry(hass)
    device_entry = None
    if entry.unique_id is not None:
        device_entry = dev_reg.async_get_device(identifiers={
            (DOMAIN, entry.unique_id)
        },
                                                connections=set())
    if device_entry and entry.entry_id not in device_entry.config_entries:
        device_entry = None

    sleep_period = entry.data.get("sleep_period")

    @callback
    def _async_device_online(_):
        _LOGGER.debug("Device %s is online, resuming setup", entry.title)
        hass.data[DOMAIN][DATA_CONFIG_ENTRY][entry.entry_id][DEVICE] = None

        if sleep_period is None:
            data = {**entry.data}
            data["sleep_period"] = get_device_sleep_period(device.settings)
            data["model"] = device.settings["device"]["type"]
            hass.config_entries.async_update_entry(entry, data=data)

        hass.async_create_task(async_device_setup(hass, entry, device))

    if sleep_period == 0:
        # Not a sleeping device, finish setup
        _LOGGER.debug("Setting up online device %s", entry.title)
        try:
            async with async_timeout.timeout(AIOSHELLY_DEVICE_TIMEOUT_SEC):
                await device.initialize(True)
        except (asyncio.TimeoutError, OSError) as err:
            raise ConfigEntryNotReady from err

        await async_device_setup(hass, entry, device)
    elif sleep_period is None or device_entry is None:
        # Need to get sleep info or first time sleeping device setup, wait for device
        hass.data[DOMAIN][DATA_CONFIG_ENTRY][entry.entry_id][DEVICE] = device
        _LOGGER.debug("Setup for device %s will resume when device is online",
                      entry.title)
        device.subscribe_updates(_async_device_online)
        await device.coap_request("s")
    else:
        # Restore sensors for sleeping device
        _LOGGER.debug("Setting up offline device %s", entry.title)
        await async_device_setup(hass, entry, device)

    return True