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)}
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
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
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], }, )
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)}
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], },
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
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