예제 #1
0
async def validate_input(data):
    """Validate the user input allows us to connect.

    Data has the keys from DATA_SCHEMA with values provided by the user.
    """
    userid = data.get(CONF_USERNAME)
    password = data.get(CONF_PASSWORD)

    prefix = data[CONF_PREFIX]
    url = _make_url_from_data(data)
    requires_password = url.startswith("elks://")

    if requires_password and (not userid or not password):
        raise InvalidAuth

    elk = elkm1.Elk(
        {"url": url, "userid": userid, "password": password, "element_list": ["panel"]}
    )
    elk.connect()

    if not await async_wait_for_elk_to_sync(elk, VALIDATE_TIMEOUT, url):
        raise InvalidAuth

    device_name = data[CONF_PREFIX] if data[CONF_PREFIX] else "ElkM1"
    # Return info that you want to store in the config entry.
    return {"title": device_name, CONF_HOST: url, CONF_PREFIX: slugify(prefix)}
예제 #2
0
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
    """Set up Elk-M1 Control from a config entry."""

    conf = entry.data

    _LOGGER.debug("Setting up elkm1 %s", conf["host"])

    config = {"temperature_unit": conf[CONF_TEMPERATURE_UNIT]}

    if not conf[CONF_AUTO_CONFIGURE]:
        # With elkm1-lib==0.7.16 and later auto configure is available
        config["panel"] = {"enabled": True, "included": [True]}
        for item, max_ in ELK_ELEMENTS.items():
            config[item] = {
                "enabled": conf[item][CONF_ENABLED],
                "included": [not conf[item]["include"]] * max_,
            }
            try:
                _included(conf[item]["include"], True,
                          config[item]["included"])
                _included(conf[item]["exclude"], False,
                          config[item]["included"])
            except (ValueError, vol.Invalid) as err:
                _LOGGER.error("Config item: %s; %s", item, err)
                return False

    elk = elkm1.Elk({
        "url": conf[CONF_HOST],
        "userid": conf[CONF_USERNAME],
        "password": conf[CONF_PASSWORD],
    })
    elk.connect()

    if not await async_wait_for_elk_to_sync(elk, SYNC_TIMEOUT):
        _LOGGER.error(
            "Timed out after %d seconds while trying to sync with ElkM1 at %s",
            SYNC_TIMEOUT,
            conf[CONF_HOST],
        )
        elk.disconnect()
        raise ConfigEntryNotReady

    if elk.invalid_auth:
        _LOGGER.error("Authentication failed for ElkM1")
        return False

    hass.data[DOMAIN][entry.entry_id] = {
        "elk": elk,
        "prefix": conf[CONF_PREFIX],
        "auto_configure": conf[CONF_AUTO_CONFIGURE],
        "config": config,
        "keypads": {},
    }

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

    return True
예제 #3
0
async def async_setup(hass: HomeAssistant, hass_config: ConfigType) -> bool:
    """Set up the Elk M1 platform."""
    from elkm1_lib.const import Max
    import elkm1_lib as elkm1

    configs = {
        CONF_AREA: Max.AREAS.value,
        CONF_COUNTER: Max.COUNTERS.value,
        CONF_KEYPAD: Max.KEYPADS.value,
        CONF_OUTPUT: Max.OUTPUTS.value,
        CONF_PLC: Max.LIGHTS.value,
        CONF_SETTING: Max.SETTINGS.value,
        CONF_TASK: Max.TASKS.value,
        CONF_THERMOSTAT: Max.THERMOSTATS.value,
        CONF_ZONE: Max.ZONES.value,
    }

    def _included(ranges, set_to, values):
        for rng in ranges:
            if not rng[0] <= rng[1] <= len(values):
                raise vol.Invalid("Invalid range {}".format(rng))
            values[rng[0] - 1:rng[1]] = [set_to] * (rng[1] - rng[0] + 1)

    conf = hass_config[DOMAIN]
    config = {'temperature_unit': conf[CONF_TEMPERATURE_UNIT]}
    config['panel'] = {'enabled': True, 'included': [True]}

    for item, max_ in configs.items():
        config[item] = {
            'enabled': conf[item][CONF_ENABLED],
            'included': [not conf[item]['include']] * max_
        }
        try:
            _included(conf[item]['include'], True, config[item]['included'])
            _included(conf[item]['exclude'], False, config[item]['included'])
        except (ValueError, vol.Invalid) as err:
            _LOGGER.error("Config item: %s; %s", item, err)
            return False

    elk = elkm1.Elk({
        'url': conf[CONF_HOST],
        'userid': conf[CONF_USERNAME],
        'password': conf[CONF_PASSWORD]
    })
    elk.connect()

    _create_elk_services(hass, elk)

    hass.data[DOMAIN] = {'elk': elk, 'config': config, 'keypads': {}}
    for component in SUPPORTED_DOMAINS:
        hass.async_create_task(
            discovery.async_load_platform(hass, component, DOMAIN, {},
                                          hass_config))

    return True
예제 #4
0
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
    """Set up Elk-M1 Control from a config entry."""
    conf: MappingProxyType[str, Any] = entry.data

    _LOGGER.debug("Setting up elkm1 %s", conf["host"])

    temperature_unit = TEMP_FAHRENHEIT
    if conf[CONF_TEMPERATURE_UNIT] in (BARE_TEMP_CELSIUS, TEMP_CELSIUS):
        temperature_unit = TEMP_CELSIUS

    config: dict[str, Any] = {"temperature_unit": temperature_unit}

    if not conf[CONF_AUTO_CONFIGURE]:
        # With elkm1-lib==0.7.16 and later auto configure is available
        config["panel"] = {"enabled": True, "included": [True]}
        for item, max_ in ELK_ELEMENTS.items():
            config[item] = {
                "enabled": conf[item][CONF_ENABLED],
                "included": [not conf[item]["include"]] * max_,
            }
            try:
                _included(conf[item]["include"], True,
                          config[item]["included"])
                _included(conf[item]["exclude"], False,
                          config[item]["included"])
            except (ValueError, vol.Invalid) as err:
                _LOGGER.error("Config item: %s; %s", item, err)
                return False

    elk = elkm1.Elk({
        "url": conf[CONF_HOST],
        "userid": conf[CONF_USERNAME],
        "password": conf[CONF_PASSWORD],
    })
    elk.connect()

    def _element_changed(element, changeset):
        if (keypress := changeset.get("last_keypress")) is None:
            return

        hass.bus.async_fire(
            EVENT_ELKM1_KEYPAD_KEY_PRESSED,
            {
                ATTR_KEYPAD_ID: element.index + 1,
                ATTR_KEY_NAME: keypress[0],
                ATTR_KEY: keypress[1],
            },
        )
예제 #5
0
async def validate_input(data: dict[str, str],
                         mac: str | None) -> dict[str, str]:
    """Validate the user input allows us to connect.

    Data has the keys from DATA_SCHEMA with values provided by the user.
    """
    userid = data.get(CONF_USERNAME)
    password = data.get(CONF_PASSWORD)

    prefix = data[CONF_PREFIX]
    url = _make_url_from_data(data)
    requires_password = url.startswith("elks://") or url.startswith("elksv1_2")

    if requires_password and (not userid or not password):
        raise InvalidAuth

    elk = elkm1.Elk({
        "url": url,
        "userid": userid,
        "password": password,
        "element_list": ["panel"]
    })
    elk.connect()

    try:
        if not await async_wait_for_elk_to_sync(elk, LOGIN_TIMEOUT,
                                                VALIDATE_TIMEOUT):
            raise InvalidAuth
    finally:
        elk.disconnect()

    short_mac = _short_mac(mac) if mac else None
    if prefix and prefix != short_mac:
        device_name = prefix
    elif mac:
        device_name = f"ElkM1 {short_mac}"
    else:
        device_name = "ElkM1"
    return {"title": device_name, CONF_HOST: url, CONF_PREFIX: slugify(prefix)}
예제 #6
0
            config[item] = {
                "enabled": conf[item][CONF_ENABLED],
                "included": [not conf[item]["include"]] * max_,
            }
            try:
                _included(conf[item]["include"], True,
                          config[item]["included"])
                _included(conf[item]["exclude"], False,
                          config[item]["included"])
            except (ValueError, vol.Invalid) as err:
                _LOGGER.error("Config item: %s; %s", item, err)
                return False

    elk = elkm1.Elk({
        "url": conf[CONF_HOST],
        "userid": conf[CONF_USERNAME],
        "password": conf[CONF_PASSWORD],
    })
    elk.connect()

    def _element_changed(element, changeset):
        if (keypress := changeset.get("last_keypress")) is None:
            return

        hass.bus.async_fire(
            EVENT_ELKM1_KEYPAD_KEY_PRESSED,
            {
                ATTR_KEYPAD_ID: element.index + 1,
                ATTR_KEY_NAME: keypress[0],
                ATTR_KEY: keypress[1],
            },
예제 #7
0
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
    """Set up Elk-M1 Control from a config entry."""
    conf = entry.data

    _LOGGER.debug("Setting up elkm1 %s", conf["host"])

    temperature_unit = TEMP_FAHRENHEIT
    if conf[CONF_TEMPERATURE_UNIT] in (BARE_TEMP_CELSIUS, TEMP_CELSIUS):
        temperature_unit = TEMP_CELSIUS

    config = {"temperature_unit": temperature_unit}

    if not conf[CONF_AUTO_CONFIGURE]:
        # With elkm1-lib==0.7.16 and later auto configure is available
        config["panel"] = {"enabled": True, "included": [True]}
        for item, max_ in ELK_ELEMENTS.items():
            config[item] = {
                "enabled": conf[item][CONF_ENABLED],
                "included": [not conf[item]["include"]] * max_,
            }
            try:
                _included(conf[item]["include"], True,
                          config[item]["included"])
                _included(conf[item]["exclude"], False,
                          config[item]["included"])
            except (ValueError, vol.Invalid) as err:
                _LOGGER.error("Config item: %s; %s", item, err)
                return False

    elk = elkm1.Elk({
        "url": conf[CONF_HOST],
        "userid": conf[CONF_USERNAME],
        "password": conf[CONF_PASSWORD],
    })
    elk.connect()

    def _element_changed(element, changeset):
        keypress = changeset.get("last_keypress")
        if keypress is None:
            return

        hass.bus.async_fire(
            EVENT_ELKM1_KEYPAD_KEY_PRESSED,
            {
                ATTR_KEYPAD_ID: element.index + 1,
                ATTR_KEY_NAME: keypress[0],
                ATTR_KEY: keypress[1],
            },
        )

    for keypad in elk.keypads:  # pylint: disable=no-member
        keypad.add_callback(_element_changed)

    try:
        if not await async_wait_for_elk_to_sync(elk, SYNC_TIMEOUT,
                                                conf[CONF_HOST]):
            return False
    except asyncio.TimeoutError as exc:
        raise ConfigEntryNotReady from exc

    hass.data[DOMAIN][entry.entry_id] = {
        "elk": elk,
        "prefix": conf[CONF_PREFIX],
        "auto_configure": conf[CONF_AUTO_CONFIGURE],
        "config": config,
        "keypads": {},
    }

    hass.config_entries.async_setup_platforms(entry, PLATFORMS)

    return True
예제 #8
0
async def async_setup(hass: HomeAssistant, hass_config: ConfigType) -> bool:
    """Set up the Elk M1 platform."""
    devices = {}
    elk_datas = {}

    configs = {
        CONF_AREA: Max.AREAS.value,
        CONF_COUNTER: Max.COUNTERS.value,
        CONF_KEYPAD: Max.KEYPADS.value,
        CONF_OUTPUT: Max.OUTPUTS.value,
        CONF_PLC: Max.LIGHTS.value,
        CONF_SETTING: Max.SETTINGS.value,
        CONF_TASK: Max.TASKS.value,
        CONF_THERMOSTAT: Max.THERMOSTATS.value,
        CONF_ZONE: Max.ZONES.value,
    }

    def _included(ranges, set_to, values):
        for rng in ranges:
            if not rng[0] <= rng[1] <= len(values):
                raise vol.Invalid(f"Invalid range {rng}")
            values[rng[0] - 1:rng[1]] = [set_to] * (rng[1] - rng[0] + 1)

    for index, conf in enumerate(hass_config[DOMAIN]):
        _LOGGER.debug("Setting up elkm1 #%d - %s", index, conf["host"])

        config = {"temperature_unit": conf[CONF_TEMPERATURE_UNIT]}
        config["panel"] = {"enabled": True, "included": [True]}

        for item, max_ in configs.items():
            config[item] = {
                "enabled": conf[item][CONF_ENABLED],
                "included": [not conf[item]["include"]] * max_,
            }
            try:
                _included(conf[item]["include"], True,
                          config[item]["included"])
                _included(conf[item]["exclude"], False,
                          config[item]["included"])
            except (ValueError, vol.Invalid) as err:
                _LOGGER.error("Config item: %s; %s", item, err)
                return False

        prefix = conf[CONF_PREFIX]
        elk = elkm1.Elk({
            "url": conf[CONF_HOST],
            "userid": conf[CONF_USERNAME],
            "password": conf[CONF_PASSWORD],
        })
        elk.connect()

        devices[prefix] = elk
        elk_datas[prefix] = {
            "elk": elk,
            "prefix": prefix,
            "config": config,
            "keypads": {},
        }

    _create_elk_services(hass, devices)

    hass.data[DOMAIN] = elk_datas
    for component in SUPPORTED_DOMAINS:
        hass.async_create_task(
            discovery.async_load_platform(hass, component, DOMAIN, {},
                                          hass_config))

    return True