2019-02-13 20:21:14 +00:00
|
|
|
"""Support the ElkM1 Gold and ElkM1 EZ8 alarm/integration panels."""
|
2020-03-27 20:38:35 +00:00
|
|
|
import asyncio
|
2018-10-07 19:45:36 +00:00
|
|
|
import logging
|
|
|
|
import re
|
|
|
|
|
2020-03-27 20:38:35 +00:00
|
|
|
import async_timeout
|
2019-10-20 21:37:52 +00:00
|
|
|
import elkm1_lib as elkm1
|
2018-10-07 19:45:36 +00:00
|
|
|
import voluptuous as vol
|
2019-10-20 21:37:52 +00:00
|
|
|
|
2020-03-27 20:38:35 +00:00
|
|
|
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
|
2018-10-07 19:45:36 +00:00
|
|
|
from homeassistant.const import (
|
2019-07-31 19:25:30 +00:00
|
|
|
CONF_EXCLUDE,
|
|
|
|
CONF_HOST,
|
|
|
|
CONF_INCLUDE,
|
|
|
|
CONF_PASSWORD,
|
2021-02-09 19:20:20 +00:00
|
|
|
CONF_PREFIX,
|
2019-07-31 19:25:30 +00:00
|
|
|
CONF_TEMPERATURE_UNIT,
|
|
|
|
CONF_USERNAME,
|
2020-04-16 22:18:41 +00:00
|
|
|
TEMP_CELSIUS,
|
|
|
|
TEMP_FAHRENHEIT,
|
2019-07-31 19:25:30 +00:00
|
|
|
)
|
2019-11-16 09:22:07 +00:00
|
|
|
from homeassistant.core import HomeAssistant, callback
|
2020-10-15 22:05:07 +00:00
|
|
|
from homeassistant.exceptions import ConfigEntryNotReady, HomeAssistantError
|
2020-03-27 20:38:35 +00:00
|
|
|
from homeassistant.helpers import config_validation as cv
|
2018-10-07 19:45:36 +00:00
|
|
|
from homeassistant.helpers.entity import Entity
|
2019-11-16 09:22:07 +00:00
|
|
|
from homeassistant.helpers.typing import ConfigType
|
2020-10-15 22:05:07 +00:00
|
|
|
import homeassistant.util.dt as dt_util
|
2018-10-07 19:45:36 +00:00
|
|
|
|
2020-03-27 20:38:35 +00:00
|
|
|
from .const import (
|
2020-10-15 22:05:07 +00:00
|
|
|
ATTR_KEY,
|
|
|
|
ATTR_KEY_NAME,
|
|
|
|
ATTR_KEYPAD_ID,
|
2020-04-16 22:18:41 +00:00
|
|
|
BARE_TEMP_CELSIUS,
|
|
|
|
BARE_TEMP_FAHRENHEIT,
|
2020-03-27 20:38:35 +00:00
|
|
|
CONF_AREA,
|
|
|
|
CONF_AUTO_CONFIGURE,
|
|
|
|
CONF_COUNTER,
|
|
|
|
CONF_ENABLED,
|
|
|
|
CONF_KEYPAD,
|
|
|
|
CONF_OUTPUT,
|
|
|
|
CONF_PLC,
|
|
|
|
CONF_SETTING,
|
|
|
|
CONF_TASK,
|
|
|
|
CONF_THERMOSTAT,
|
|
|
|
CONF_ZONE,
|
|
|
|
DOMAIN,
|
|
|
|
ELK_ELEMENTS,
|
2020-10-15 22:05:07 +00:00
|
|
|
EVENT_ELKM1_KEYPAD_KEY_PRESSED,
|
2020-03-27 20:38:35 +00:00
|
|
|
)
|
2019-02-13 20:21:14 +00:00
|
|
|
|
2020-04-13 23:16:17 +00:00
|
|
|
SYNC_TIMEOUT = 120
|
2018-10-07 19:45:36 +00:00
|
|
|
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
2021-03-02 20:43:59 +00:00
|
|
|
PLATFORMS = [
|
2019-07-31 19:25:30 +00:00
|
|
|
"alarm_control_panel",
|
|
|
|
"climate",
|
|
|
|
"light",
|
|
|
|
"scene",
|
|
|
|
"sensor",
|
|
|
|
"switch",
|
|
|
|
]
|
|
|
|
|
|
|
|
SPEAK_SERVICE_SCHEMA = vol.Schema(
|
|
|
|
{
|
|
|
|
vol.Required("number"): vol.All(vol.Coerce(int), vol.Range(min=0, max=999)),
|
|
|
|
vol.Optional("prefix", default=""): cv.string,
|
|
|
|
}
|
|
|
|
)
|
2018-10-07 19:45:36 +00:00
|
|
|
|
2020-10-15 22:05:07 +00:00
|
|
|
SET_TIME_SERVICE_SCHEMA = vol.Schema(
|
|
|
|
{
|
|
|
|
vol.Optional("prefix", default=""): cv.string,
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
2018-10-07 19:45:36 +00:00
|
|
|
|
|
|
|
def _host_validator(config):
|
|
|
|
"""Validate that a host is properly configured."""
|
2019-07-31 19:25:30 +00:00
|
|
|
if config[CONF_HOST].startswith("elks://"):
|
2018-10-07 19:45:36 +00:00
|
|
|
if CONF_USERNAME not in config or CONF_PASSWORD not in config:
|
|
|
|
raise vol.Invalid("Specify username and password for elks://")
|
2019-07-31 19:25:30 +00:00
|
|
|
elif not config[CONF_HOST].startswith("elk://") and not config[
|
|
|
|
CONF_HOST
|
|
|
|
].startswith("serial://"):
|
2018-10-07 19:45:36 +00:00
|
|
|
raise vol.Invalid("Invalid host URL")
|
|
|
|
return config
|
|
|
|
|
|
|
|
|
|
|
|
def _elk_range_validator(rng):
|
|
|
|
def _housecode_to_int(val):
|
2019-07-31 19:25:30 +00:00
|
|
|
match = re.search(r"^([a-p])(0[1-9]|1[0-6]|[1-9])$", val.lower())
|
2018-10-07 19:45:36 +00:00
|
|
|
if match:
|
2019-07-31 19:25:30 +00:00
|
|
|
return (ord(match.group(1)) - ord("a")) * 16 + int(match.group(2))
|
2018-10-07 19:45:36 +00:00
|
|
|
raise vol.Invalid("Invalid range")
|
|
|
|
|
|
|
|
def _elk_value(val):
|
|
|
|
return int(val) if val.isdigit() else _housecode_to_int(val)
|
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
vals = [s.strip() for s in str(rng).split("-")]
|
2018-10-07 19:45:36 +00:00
|
|
|
start = _elk_value(vals[0])
|
|
|
|
end = start if len(vals) == 1 else _elk_value(vals[1])
|
|
|
|
return (start, end)
|
|
|
|
|
|
|
|
|
Support multiple Elk instances (#23839)
* Support multiple Elk instances
* Allow more than one Elk M1 alarm system to be integrated into a single hass instance.
* Introduces new "devices" schema at the top level, each of which has
the prior configuration schema.
* Requires new version of elkm1, 0.7.14, that gwww and I just updated (thanks Glen!)
QUESTION: Should the "devices" section be optional to avoid breaking
old configuration files? I chose not to do that for simplicity and
because I was following the doorbird code which requires the "devices"
section for all configurations even with only one device.
* Fixed a bunch of hound-raised issues
Fixed issues raised by hound -- there was clearly
a tool I was supposed to run to get those warnings
before submitting the PR. Sorry!
Updated REQUIREMENTS.
* Fixed whitespace and line-length mistakes
Also fixed unused prefix local variable lint warning.
* Fixed missing blank line
* Fixed more lint warnings.
Not sure if I missed these on the first pass or if the linter stopped
after a certain number of warnings or something else.
Switched logging to use %d and %s instead of string concatenation (per
lint request and because I imagine it migth be better performing
in some (oldish, I presume) implementations of python.
* Fixed typo in last commit.
* Eliminate devices subsection in config schema
This eliminates the breaking change for configurations wanting a
singleton elk m1 instance (the majority of users, no doubt). I did
not do it like this before because I was following the lead of the
doorbird component which introduced a devices: section when moving
to support multiple doorbells. But Rohan Kapoor kindly pointed me
at the zoneminder component which sets the other (IMO) preferable
precedent. Will update the docs change shortly.
* Call async_add_entities once for all the elk controllers.
Just move async_add_entities() outside of the loops across the elk m1
controllers, so it's called once for each platform.
* Call async_add_entities only once per platform.
Move it to after the loop, so it's called only once
per platform even when there are multiple elk m1 controllers.
* Various improvements to be more idiomatic python + bug fixes
Thanks to Martin Hjelmare for the careful review and suggestions.
(All mistaken improvements and new bugs are my own.)
* Removed semicolon that lint caught.
* Idiomatic python improvements
Use dict.values() (instead of making it easier to add local looping variable
on the keys by using _, bar = ...items())
Use [] when the key is known to exist.
* Support multiple Elk instances
* Allow more than one Elk M1 alarm system to be integrated into a single hass instance.
* Introduces new "devices" schema at the top level, each of which has
the prior configuration schema.
* Requires new version of elkm1, 0.7.14, that gwww and I just updated (thanks Glen!)
QUESTION: Should the "devices" section be optional to avoid breaking
old configuration files? I chose not to do that for simplicity and
because I was following the doorbird code which requires the "devices"
section for all configurations even with only one device.
* Fixed a bunch of hound-raised issues
Fixed issues raised by hound -- there was clearly
a tool I was supposed to run to get those warnings
before submitting the PR. Sorry!
Updated REQUIREMENTS.
* Fixed whitespace and line-length mistakes
Also fixed unused prefix local variable lint warning.
* Fixed missing blank line
* Fixed more lint warnings.
Not sure if I missed these on the first pass or if the linter stopped
after a certain number of warnings or something else.
Switched logging to use %d and %s instead of string concatenation (per
lint request and because I imagine it migth be better performing
in some (oldish, I presume) implementations of python.
* Fixed typo in last commit.
* Eliminate devices subsection in config schema
This eliminates the breaking change for configurations wanting a
singleton elk m1 instance (the majority of users, no doubt). I did
not do it like this before because I was following the lead of the
doorbird component which introduced a devices: section when moving
to support multiple doorbells. But Rohan Kapoor kindly pointed me
at the zoneminder component which sets the other (IMO) preferable
precedent. Will update the docs change shortly.
* Call async_add_entities once for all the elk controllers.
Just move async_add_entities() outside of the loops across the elk m1
controllers, so it's called once for each platform.
* Call async_add_entities only once per platform.
Move it to after the loop, so it's called only once
per platform even when there are multiple elk m1 controllers.
* Various improvements to be more idiomatic python + bug fixes
Thanks to Martin Hjelmare for the careful review and suggestions.
(All mistaken improvements and new bugs are my own.)
* Removed semicolon that lint caught.
* Idiomatic python improvements
Use dict.values() (instead of making it easier to add local looping variable
on the keys by using _, bar = ...items())
Use [] when the key is known to exist.
* Use dict[key] instead of .get (incl. fixing typo). Use .values() instead of .items() when ignoring keys.
* Gotta use devices.get(prefix) since we use no prefix for the singleton elk instance
* fix requirement to use newer elkm1 that supports my changes for multiple elk devices
* Removed spurious + between a string broken between two lines for formatting; was failing a lint check about logging needing to use %s
* Remove REQUIREMENTS and DEPENDENCIES since those are now taken care of by the manifest.json file.
* Add configuration check that the prefixes are all unique
* Use new dependency 'getmac' to get mac address of Elk M1 controllers and use that for uniqueid if possible, else use None. Also removed some procedural checking of unique prefix since that's now handled at schema check time.
* Whitespace changes to make style checker happy and code more consistent
* Removed unused variable, added blank line
* Make getmac a requirement not dependency
I should've RTFM.
* ws only change; I really need to get Emacs to understand these style guidelines
* Ran script/gen_requirements_all.py; script/setup needed to be run so that was failing.
* More style check fixes and one bug fix.
* Incomplete set of changes from last push
* More conform-to-hass-style changes: use caps to start log message (and do not use function name even for debug message. And do not use string concatenation; prefer new-style .format.
* Style fixes.
* Switch back to using the prefix config field for setting the unique_id since the mac address approach has numerous shortcomings including: 1) new dependency; 2) lack of reliability; 3) doesn't work for serial connections; 4) breaks when a layer 4+ networking entity intermediates the elk m1 connection.
* Reran to update (removing getmac dependency)
* Skipped trailing ','; keep forgetting which languages are forgiving about this practical nicety of allowing trailing commas without changing the semantics.
* Validate uniqueness on lowercase versions of the prefix since we're gonna use .lower() on creating the entity id that has to be unique; do the _has_all_unique_prefixes check last so we get errors from the device schema before complaining about the uniqueness problem, if any
* Use vol.Lower to convert to lowercase instead of the map. Also fixed a pair of bugs for the alarm control panel display message service -- since data templates always generate strings, the values subject to range/set restrictions need to be coerced to their proper type before the check
* Fix some flake8 warnings.
* Fixed typo; it's Coerce not coerce.
* Use elkm1m_ string to start unique_id when and only when there is a non-empty prefix given; this enables backward compatibility to avoid a breaking change by letting the elkm1_ start to unique_id keep working exactly as it used to.
* minor comment tweak to force automation tests to run again since they failed for unrelated reasons last time
* There's actually been a 0.7.15 release which was meta-information and tidying only so we might as well depend on it
* Forgot to update this with gen_requirements_all.py
2019-07-27 08:36:09 +00:00
|
|
|
def _has_all_unique_prefixes(value):
|
|
|
|
"""Validate that each m1 configured has a unique prefix.
|
|
|
|
|
|
|
|
Uniqueness is determined case-independently.
|
|
|
|
"""
|
|
|
|
prefixes = [device[CONF_PREFIX] for device in value]
|
|
|
|
schema = vol.Schema(vol.Unique())
|
|
|
|
schema(prefixes)
|
|
|
|
return value
|
|
|
|
|
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
DEVICE_SCHEMA_SUBDOMAIN = vol.Schema(
|
|
|
|
{
|
|
|
|
vol.Optional(CONF_ENABLED, default=True): cv.boolean,
|
|
|
|
vol.Optional(CONF_INCLUDE, default=[]): [_elk_range_validator],
|
|
|
|
vol.Optional(CONF_EXCLUDE, default=[]): [_elk_range_validator],
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
|
|
|
DEVICE_SCHEMA = vol.Schema(
|
|
|
|
{
|
|
|
|
vol.Required(CONF_HOST): cv.string,
|
|
|
|
vol.Optional(CONF_PREFIX, default=""): vol.All(cv.string, vol.Lower),
|
|
|
|
vol.Optional(CONF_USERNAME, default=""): cv.string,
|
|
|
|
vol.Optional(CONF_PASSWORD, default=""): cv.string,
|
2020-03-27 20:38:35 +00:00
|
|
|
vol.Optional(CONF_AUTO_CONFIGURE, default=False): cv.boolean,
|
2020-04-16 22:18:41 +00:00
|
|
|
# cv.temperature_unit will mutate 'C' -> '°C' and 'F' -> '°F'
|
|
|
|
vol.Optional(
|
|
|
|
CONF_TEMPERATURE_UNIT, default=BARE_TEMP_FAHRENHEIT
|
|
|
|
): cv.temperature_unit,
|
2019-07-31 19:25:30 +00:00
|
|
|
vol.Optional(CONF_AREA, default={}): DEVICE_SCHEMA_SUBDOMAIN,
|
|
|
|
vol.Optional(CONF_COUNTER, default={}): DEVICE_SCHEMA_SUBDOMAIN,
|
|
|
|
vol.Optional(CONF_KEYPAD, default={}): DEVICE_SCHEMA_SUBDOMAIN,
|
|
|
|
vol.Optional(CONF_OUTPUT, default={}): DEVICE_SCHEMA_SUBDOMAIN,
|
|
|
|
vol.Optional(CONF_PLC, default={}): DEVICE_SCHEMA_SUBDOMAIN,
|
|
|
|
vol.Optional(CONF_SETTING, default={}): DEVICE_SCHEMA_SUBDOMAIN,
|
|
|
|
vol.Optional(CONF_TASK, default={}): DEVICE_SCHEMA_SUBDOMAIN,
|
|
|
|
vol.Optional(CONF_THERMOSTAT, default={}): DEVICE_SCHEMA_SUBDOMAIN,
|
|
|
|
vol.Optional(CONF_ZONE, default={}): DEVICE_SCHEMA_SUBDOMAIN,
|
|
|
|
},
|
|
|
|
_host_validator,
|
|
|
|
)
|
|
|
|
|
|
|
|
CONFIG_SCHEMA = vol.Schema(
|
|
|
|
{DOMAIN: vol.All(cv.ensure_list, [DEVICE_SCHEMA], _has_all_unique_prefixes)},
|
|
|
|
extra=vol.ALLOW_EXTRA,
|
|
|
|
)
|
2018-10-07 19:45:36 +00:00
|
|
|
|
|
|
|
|
|
|
|
async def async_setup(hass: HomeAssistant, hass_config: ConfigType) -> bool:
|
|
|
|
"""Set up the Elk M1 platform."""
|
2020-03-27 20:38:35 +00:00
|
|
|
hass.data.setdefault(DOMAIN, {})
|
|
|
|
_create_elk_services(hass)
|
2018-10-07 19:45:36 +00:00
|
|
|
|
2020-03-27 20:38:35 +00:00
|
|
|
if DOMAIN not in hass_config:
|
|
|
|
return True
|
2018-10-07 19:45:36 +00:00
|
|
|
|
Support multiple Elk instances (#23839)
* Support multiple Elk instances
* Allow more than one Elk M1 alarm system to be integrated into a single hass instance.
* Introduces new "devices" schema at the top level, each of which has
the prior configuration schema.
* Requires new version of elkm1, 0.7.14, that gwww and I just updated (thanks Glen!)
QUESTION: Should the "devices" section be optional to avoid breaking
old configuration files? I chose not to do that for simplicity and
because I was following the doorbird code which requires the "devices"
section for all configurations even with only one device.
* Fixed a bunch of hound-raised issues
Fixed issues raised by hound -- there was clearly
a tool I was supposed to run to get those warnings
before submitting the PR. Sorry!
Updated REQUIREMENTS.
* Fixed whitespace and line-length mistakes
Also fixed unused prefix local variable lint warning.
* Fixed missing blank line
* Fixed more lint warnings.
Not sure if I missed these on the first pass or if the linter stopped
after a certain number of warnings or something else.
Switched logging to use %d and %s instead of string concatenation (per
lint request and because I imagine it migth be better performing
in some (oldish, I presume) implementations of python.
* Fixed typo in last commit.
* Eliminate devices subsection in config schema
This eliminates the breaking change for configurations wanting a
singleton elk m1 instance (the majority of users, no doubt). I did
not do it like this before because I was following the lead of the
doorbird component which introduced a devices: section when moving
to support multiple doorbells. But Rohan Kapoor kindly pointed me
at the zoneminder component which sets the other (IMO) preferable
precedent. Will update the docs change shortly.
* Call async_add_entities once for all the elk controllers.
Just move async_add_entities() outside of the loops across the elk m1
controllers, so it's called once for each platform.
* Call async_add_entities only once per platform.
Move it to after the loop, so it's called only once
per platform even when there are multiple elk m1 controllers.
* Various improvements to be more idiomatic python + bug fixes
Thanks to Martin Hjelmare for the careful review and suggestions.
(All mistaken improvements and new bugs are my own.)
* Removed semicolon that lint caught.
* Idiomatic python improvements
Use dict.values() (instead of making it easier to add local looping variable
on the keys by using _, bar = ...items())
Use [] when the key is known to exist.
* Support multiple Elk instances
* Allow more than one Elk M1 alarm system to be integrated into a single hass instance.
* Introduces new "devices" schema at the top level, each of which has
the prior configuration schema.
* Requires new version of elkm1, 0.7.14, that gwww and I just updated (thanks Glen!)
QUESTION: Should the "devices" section be optional to avoid breaking
old configuration files? I chose not to do that for simplicity and
because I was following the doorbird code which requires the "devices"
section for all configurations even with only one device.
* Fixed a bunch of hound-raised issues
Fixed issues raised by hound -- there was clearly
a tool I was supposed to run to get those warnings
before submitting the PR. Sorry!
Updated REQUIREMENTS.
* Fixed whitespace and line-length mistakes
Also fixed unused prefix local variable lint warning.
* Fixed missing blank line
* Fixed more lint warnings.
Not sure if I missed these on the first pass or if the linter stopped
after a certain number of warnings or something else.
Switched logging to use %d and %s instead of string concatenation (per
lint request and because I imagine it migth be better performing
in some (oldish, I presume) implementations of python.
* Fixed typo in last commit.
* Eliminate devices subsection in config schema
This eliminates the breaking change for configurations wanting a
singleton elk m1 instance (the majority of users, no doubt). I did
not do it like this before because I was following the lead of the
doorbird component which introduced a devices: section when moving
to support multiple doorbells. But Rohan Kapoor kindly pointed me
at the zoneminder component which sets the other (IMO) preferable
precedent. Will update the docs change shortly.
* Call async_add_entities once for all the elk controllers.
Just move async_add_entities() outside of the loops across the elk m1
controllers, so it's called once for each platform.
* Call async_add_entities only once per platform.
Move it to after the loop, so it's called only once
per platform even when there are multiple elk m1 controllers.
* Various improvements to be more idiomatic python + bug fixes
Thanks to Martin Hjelmare for the careful review and suggestions.
(All mistaken improvements and new bugs are my own.)
* Removed semicolon that lint caught.
* Idiomatic python improvements
Use dict.values() (instead of making it easier to add local looping variable
on the keys by using _, bar = ...items())
Use [] when the key is known to exist.
* Use dict[key] instead of .get (incl. fixing typo). Use .values() instead of .items() when ignoring keys.
* Gotta use devices.get(prefix) since we use no prefix for the singleton elk instance
* fix requirement to use newer elkm1 that supports my changes for multiple elk devices
* Removed spurious + between a string broken between two lines for formatting; was failing a lint check about logging needing to use %s
* Remove REQUIREMENTS and DEPENDENCIES since those are now taken care of by the manifest.json file.
* Add configuration check that the prefixes are all unique
* Use new dependency 'getmac' to get mac address of Elk M1 controllers and use that for uniqueid if possible, else use None. Also removed some procedural checking of unique prefix since that's now handled at schema check time.
* Whitespace changes to make style checker happy and code more consistent
* Removed unused variable, added blank line
* Make getmac a requirement not dependency
I should've RTFM.
* ws only change; I really need to get Emacs to understand these style guidelines
* Ran script/gen_requirements_all.py; script/setup needed to be run so that was failing.
* More style check fixes and one bug fix.
* Incomplete set of changes from last push
* More conform-to-hass-style changes: use caps to start log message (and do not use function name even for debug message. And do not use string concatenation; prefer new-style .format.
* Style fixes.
* Switch back to using the prefix config field for setting the unique_id since the mac address approach has numerous shortcomings including: 1) new dependency; 2) lack of reliability; 3) doesn't work for serial connections; 4) breaks when a layer 4+ networking entity intermediates the elk m1 connection.
* Reran to update (removing getmac dependency)
* Skipped trailing ','; keep forgetting which languages are forgiving about this practical nicety of allowing trailing commas without changing the semantics.
* Validate uniqueness on lowercase versions of the prefix since we're gonna use .lower() on creating the entity id that has to be unique; do the _has_all_unique_prefixes check last so we get errors from the device schema before complaining about the uniqueness problem, if any
* Use vol.Lower to convert to lowercase instead of the map. Also fixed a pair of bugs for the alarm control panel display message service -- since data templates always generate strings, the values subject to range/set restrictions need to be coerced to their proper type before the check
* Fix some flake8 warnings.
* Fixed typo; it's Coerce not coerce.
* Use elkm1m_ string to start unique_id when and only when there is a non-empty prefix given; this enables backward compatibility to avoid a breaking change by letting the elkm1_ start to unique_id keep working exactly as it used to.
* minor comment tweak to force automation tests to run again since they failed for unrelated reasons last time
* There's actually been a 0.7.15 release which was meta-information and tidying only so we might as well depend on it
* Forgot to update this with gen_requirements_all.py
2019-07-27 08:36:09 +00:00
|
|
|
for index, conf in enumerate(hass_config[DOMAIN]):
|
2020-03-27 20:38:35 +00:00
|
|
|
_LOGGER.debug("Importing elkm1 #%d - %s", index, conf[CONF_HOST])
|
2020-03-28 16:23:39 +00:00
|
|
|
|
|
|
|
# The update of the config entry is done in async_setup
|
|
|
|
# to ensure the entry if updated before async_setup_entry
|
|
|
|
# is called to avoid a situation where the user has to restart
|
|
|
|
# twice for the changes to take effect
|
2020-03-27 20:38:35 +00:00
|
|
|
current_config_entry = _async_find_matching_config_entry(
|
|
|
|
hass, conf[CONF_PREFIX]
|
|
|
|
)
|
|
|
|
if current_config_entry:
|
|
|
|
# If they alter the yaml config we import the changes
|
|
|
|
# since there currently is no practical way to do an options flow
|
|
|
|
# with the large amount of include/exclude/enabled options that elkm1 has.
|
|
|
|
hass.config_entries.async_update_entry(current_config_entry, data=conf)
|
|
|
|
continue
|
Support multiple Elk instances (#23839)
* Support multiple Elk instances
* Allow more than one Elk M1 alarm system to be integrated into a single hass instance.
* Introduces new "devices" schema at the top level, each of which has
the prior configuration schema.
* Requires new version of elkm1, 0.7.14, that gwww and I just updated (thanks Glen!)
QUESTION: Should the "devices" section be optional to avoid breaking
old configuration files? I chose not to do that for simplicity and
because I was following the doorbird code which requires the "devices"
section for all configurations even with only one device.
* Fixed a bunch of hound-raised issues
Fixed issues raised by hound -- there was clearly
a tool I was supposed to run to get those warnings
before submitting the PR. Sorry!
Updated REQUIREMENTS.
* Fixed whitespace and line-length mistakes
Also fixed unused prefix local variable lint warning.
* Fixed missing blank line
* Fixed more lint warnings.
Not sure if I missed these on the first pass or if the linter stopped
after a certain number of warnings or something else.
Switched logging to use %d and %s instead of string concatenation (per
lint request and because I imagine it migth be better performing
in some (oldish, I presume) implementations of python.
* Fixed typo in last commit.
* Eliminate devices subsection in config schema
This eliminates the breaking change for configurations wanting a
singleton elk m1 instance (the majority of users, no doubt). I did
not do it like this before because I was following the lead of the
doorbird component which introduced a devices: section when moving
to support multiple doorbells. But Rohan Kapoor kindly pointed me
at the zoneminder component which sets the other (IMO) preferable
precedent. Will update the docs change shortly.
* Call async_add_entities once for all the elk controllers.
Just move async_add_entities() outside of the loops across the elk m1
controllers, so it's called once for each platform.
* Call async_add_entities only once per platform.
Move it to after the loop, so it's called only once
per platform even when there are multiple elk m1 controllers.
* Various improvements to be more idiomatic python + bug fixes
Thanks to Martin Hjelmare for the careful review and suggestions.
(All mistaken improvements and new bugs are my own.)
* Removed semicolon that lint caught.
* Idiomatic python improvements
Use dict.values() (instead of making it easier to add local looping variable
on the keys by using _, bar = ...items())
Use [] when the key is known to exist.
* Support multiple Elk instances
* Allow more than one Elk M1 alarm system to be integrated into a single hass instance.
* Introduces new "devices" schema at the top level, each of which has
the prior configuration schema.
* Requires new version of elkm1, 0.7.14, that gwww and I just updated (thanks Glen!)
QUESTION: Should the "devices" section be optional to avoid breaking
old configuration files? I chose not to do that for simplicity and
because I was following the doorbird code which requires the "devices"
section for all configurations even with only one device.
* Fixed a bunch of hound-raised issues
Fixed issues raised by hound -- there was clearly
a tool I was supposed to run to get those warnings
before submitting the PR. Sorry!
Updated REQUIREMENTS.
* Fixed whitespace and line-length mistakes
Also fixed unused prefix local variable lint warning.
* Fixed missing blank line
* Fixed more lint warnings.
Not sure if I missed these on the first pass or if the linter stopped
after a certain number of warnings or something else.
Switched logging to use %d and %s instead of string concatenation (per
lint request and because I imagine it migth be better performing
in some (oldish, I presume) implementations of python.
* Fixed typo in last commit.
* Eliminate devices subsection in config schema
This eliminates the breaking change for configurations wanting a
singleton elk m1 instance (the majority of users, no doubt). I did
not do it like this before because I was following the lead of the
doorbird component which introduced a devices: section when moving
to support multiple doorbells. But Rohan Kapoor kindly pointed me
at the zoneminder component which sets the other (IMO) preferable
precedent. Will update the docs change shortly.
* Call async_add_entities once for all the elk controllers.
Just move async_add_entities() outside of the loops across the elk m1
controllers, so it's called once for each platform.
* Call async_add_entities only once per platform.
Move it to after the loop, so it's called only once
per platform even when there are multiple elk m1 controllers.
* Various improvements to be more idiomatic python + bug fixes
Thanks to Martin Hjelmare for the careful review and suggestions.
(All mistaken improvements and new bugs are my own.)
* Removed semicolon that lint caught.
* Idiomatic python improvements
Use dict.values() (instead of making it easier to add local looping variable
on the keys by using _, bar = ...items())
Use [] when the key is known to exist.
* Use dict[key] instead of .get (incl. fixing typo). Use .values() instead of .items() when ignoring keys.
* Gotta use devices.get(prefix) since we use no prefix for the singleton elk instance
* fix requirement to use newer elkm1 that supports my changes for multiple elk devices
* Removed spurious + between a string broken between two lines for formatting; was failing a lint check about logging needing to use %s
* Remove REQUIREMENTS and DEPENDENCIES since those are now taken care of by the manifest.json file.
* Add configuration check that the prefixes are all unique
* Use new dependency 'getmac' to get mac address of Elk M1 controllers and use that for uniqueid if possible, else use None. Also removed some procedural checking of unique prefix since that's now handled at schema check time.
* Whitespace changes to make style checker happy and code more consistent
* Removed unused variable, added blank line
* Make getmac a requirement not dependency
I should've RTFM.
* ws only change; I really need to get Emacs to understand these style guidelines
* Ran script/gen_requirements_all.py; script/setup needed to be run so that was failing.
* More style check fixes and one bug fix.
* Incomplete set of changes from last push
* More conform-to-hass-style changes: use caps to start log message (and do not use function name even for debug message. And do not use string concatenation; prefer new-style .format.
* Style fixes.
* Switch back to using the prefix config field for setting the unique_id since the mac address approach has numerous shortcomings including: 1) new dependency; 2) lack of reliability; 3) doesn't work for serial connections; 4) breaks when a layer 4+ networking entity intermediates the elk m1 connection.
* Reran to update (removing getmac dependency)
* Skipped trailing ','; keep forgetting which languages are forgiving about this practical nicety of allowing trailing commas without changing the semantics.
* Validate uniqueness on lowercase versions of the prefix since we're gonna use .lower() on creating the entity id that has to be unique; do the _has_all_unique_prefixes check last so we get errors from the device schema before complaining about the uniqueness problem, if any
* Use vol.Lower to convert to lowercase instead of the map. Also fixed a pair of bugs for the alarm control panel display message service -- since data templates always generate strings, the values subject to range/set restrictions need to be coerced to their proper type before the check
* Fix some flake8 warnings.
* Fixed typo; it's Coerce not coerce.
* Use elkm1m_ string to start unique_id when and only when there is a non-empty prefix given; this enables backward compatibility to avoid a breaking change by letting the elkm1_ start to unique_id keep working exactly as it used to.
* minor comment tweak to force automation tests to run again since they failed for unrelated reasons last time
* There's actually been a 0.7.15 release which was meta-information and tidying only so we might as well depend on it
* Forgot to update this with gen_requirements_all.py
2019-07-27 08:36:09 +00:00
|
|
|
|
2020-03-27 20:38:35 +00:00
|
|
|
hass.async_create_task(
|
|
|
|
hass.config_entries.flow.async_init(
|
2020-08-27 11:56:20 +00:00
|
|
|
DOMAIN,
|
|
|
|
context={"source": SOURCE_IMPORT},
|
|
|
|
data=conf,
|
2020-03-27 20:38:35 +00:00
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
@callback
|
|
|
|
def _async_find_matching_config_entry(hass, prefix):
|
|
|
|
for entry in hass.config_entries.async_entries(DOMAIN):
|
|
|
|
if entry.unique_id == prefix:
|
|
|
|
return entry
|
|
|
|
|
|
|
|
|
2021-05-27 15:39:06 +00:00
|
|
|
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
2020-03-27 20:38:35 +00:00
|
|
|
"""Set up Elk-M1 Control from a config entry."""
|
|
|
|
conf = entry.data
|
Support multiple Elk instances (#23839)
* Support multiple Elk instances
* Allow more than one Elk M1 alarm system to be integrated into a single hass instance.
* Introduces new "devices" schema at the top level, each of which has
the prior configuration schema.
* Requires new version of elkm1, 0.7.14, that gwww and I just updated (thanks Glen!)
QUESTION: Should the "devices" section be optional to avoid breaking
old configuration files? I chose not to do that for simplicity and
because I was following the doorbird code which requires the "devices"
section for all configurations even with only one device.
* Fixed a bunch of hound-raised issues
Fixed issues raised by hound -- there was clearly
a tool I was supposed to run to get those warnings
before submitting the PR. Sorry!
Updated REQUIREMENTS.
* Fixed whitespace and line-length mistakes
Also fixed unused prefix local variable lint warning.
* Fixed missing blank line
* Fixed more lint warnings.
Not sure if I missed these on the first pass or if the linter stopped
after a certain number of warnings or something else.
Switched logging to use %d and %s instead of string concatenation (per
lint request and because I imagine it migth be better performing
in some (oldish, I presume) implementations of python.
* Fixed typo in last commit.
* Eliminate devices subsection in config schema
This eliminates the breaking change for configurations wanting a
singleton elk m1 instance (the majority of users, no doubt). I did
not do it like this before because I was following the lead of the
doorbird component which introduced a devices: section when moving
to support multiple doorbells. But Rohan Kapoor kindly pointed me
at the zoneminder component which sets the other (IMO) preferable
precedent. Will update the docs change shortly.
* Call async_add_entities once for all the elk controllers.
Just move async_add_entities() outside of the loops across the elk m1
controllers, so it's called once for each platform.
* Call async_add_entities only once per platform.
Move it to after the loop, so it's called only once
per platform even when there are multiple elk m1 controllers.
* Various improvements to be more idiomatic python + bug fixes
Thanks to Martin Hjelmare for the careful review and suggestions.
(All mistaken improvements and new bugs are my own.)
* Removed semicolon that lint caught.
* Idiomatic python improvements
Use dict.values() (instead of making it easier to add local looping variable
on the keys by using _, bar = ...items())
Use [] when the key is known to exist.
* Support multiple Elk instances
* Allow more than one Elk M1 alarm system to be integrated into a single hass instance.
* Introduces new "devices" schema at the top level, each of which has
the prior configuration schema.
* Requires new version of elkm1, 0.7.14, that gwww and I just updated (thanks Glen!)
QUESTION: Should the "devices" section be optional to avoid breaking
old configuration files? I chose not to do that for simplicity and
because I was following the doorbird code which requires the "devices"
section for all configurations even with only one device.
* Fixed a bunch of hound-raised issues
Fixed issues raised by hound -- there was clearly
a tool I was supposed to run to get those warnings
before submitting the PR. Sorry!
Updated REQUIREMENTS.
* Fixed whitespace and line-length mistakes
Also fixed unused prefix local variable lint warning.
* Fixed missing blank line
* Fixed more lint warnings.
Not sure if I missed these on the first pass or if the linter stopped
after a certain number of warnings or something else.
Switched logging to use %d and %s instead of string concatenation (per
lint request and because I imagine it migth be better performing
in some (oldish, I presume) implementations of python.
* Fixed typo in last commit.
* Eliminate devices subsection in config schema
This eliminates the breaking change for configurations wanting a
singleton elk m1 instance (the majority of users, no doubt). I did
not do it like this before because I was following the lead of the
doorbird component which introduced a devices: section when moving
to support multiple doorbells. But Rohan Kapoor kindly pointed me
at the zoneminder component which sets the other (IMO) preferable
precedent. Will update the docs change shortly.
* Call async_add_entities once for all the elk controllers.
Just move async_add_entities() outside of the loops across the elk m1
controllers, so it's called once for each platform.
* Call async_add_entities only once per platform.
Move it to after the loop, so it's called only once
per platform even when there are multiple elk m1 controllers.
* Various improvements to be more idiomatic python + bug fixes
Thanks to Martin Hjelmare for the careful review and suggestions.
(All mistaken improvements and new bugs are my own.)
* Removed semicolon that lint caught.
* Idiomatic python improvements
Use dict.values() (instead of making it easier to add local looping variable
on the keys by using _, bar = ...items())
Use [] when the key is known to exist.
* Use dict[key] instead of .get (incl. fixing typo). Use .values() instead of .items() when ignoring keys.
* Gotta use devices.get(prefix) since we use no prefix for the singleton elk instance
* fix requirement to use newer elkm1 that supports my changes for multiple elk devices
* Removed spurious + between a string broken between two lines for formatting; was failing a lint check about logging needing to use %s
* Remove REQUIREMENTS and DEPENDENCIES since those are now taken care of by the manifest.json file.
* Add configuration check that the prefixes are all unique
* Use new dependency 'getmac' to get mac address of Elk M1 controllers and use that for uniqueid if possible, else use None. Also removed some procedural checking of unique prefix since that's now handled at schema check time.
* Whitespace changes to make style checker happy and code more consistent
* Removed unused variable, added blank line
* Make getmac a requirement not dependency
I should've RTFM.
* ws only change; I really need to get Emacs to understand these style guidelines
* Ran script/gen_requirements_all.py; script/setup needed to be run so that was failing.
* More style check fixes and one bug fix.
* Incomplete set of changes from last push
* More conform-to-hass-style changes: use caps to start log message (and do not use function name even for debug message. And do not use string concatenation; prefer new-style .format.
* Style fixes.
* Switch back to using the prefix config field for setting the unique_id since the mac address approach has numerous shortcomings including: 1) new dependency; 2) lack of reliability; 3) doesn't work for serial connections; 4) breaks when a layer 4+ networking entity intermediates the elk m1 connection.
* Reran to update (removing getmac dependency)
* Skipped trailing ','; keep forgetting which languages are forgiving about this practical nicety of allowing trailing commas without changing the semantics.
* Validate uniqueness on lowercase versions of the prefix since we're gonna use .lower() on creating the entity id that has to be unique; do the _has_all_unique_prefixes check last so we get errors from the device schema before complaining about the uniqueness problem, if any
* Use vol.Lower to convert to lowercase instead of the map. Also fixed a pair of bugs for the alarm control panel display message service -- since data templates always generate strings, the values subject to range/set restrictions need to be coerced to their proper type before the check
* Fix some flake8 warnings.
* Fixed typo; it's Coerce not coerce.
* Use elkm1m_ string to start unique_id when and only when there is a non-empty prefix given; this enables backward compatibility to avoid a breaking change by letting the elkm1_ start to unique_id keep working exactly as it used to.
* minor comment tweak to force automation tests to run again since they failed for unrelated reasons last time
* There's actually been a 0.7.15 release which was meta-information and tidying only so we might as well depend on it
* Forgot to update this with gen_requirements_all.py
2019-07-27 08:36:09 +00:00
|
|
|
|
2020-03-27 20:38:35 +00:00
|
|
|
_LOGGER.debug("Setting up elkm1 %s", conf["host"])
|
|
|
|
|
2020-04-16 22:18:41 +00:00
|
|
|
temperature_unit = TEMP_FAHRENHEIT
|
|
|
|
if conf[CONF_TEMPERATURE_UNIT] in (BARE_TEMP_CELSIUS, TEMP_CELSIUS):
|
|
|
|
temperature_unit = TEMP_CELSIUS
|
|
|
|
|
|
|
|
config = {"temperature_unit": temperature_unit}
|
2020-03-27 20:38:35 +00:00
|
|
|
|
|
|
|
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():
|
2019-07-31 19:25:30 +00:00
|
|
|
config[item] = {
|
|
|
|
"enabled": conf[item][CONF_ENABLED],
|
|
|
|
"included": [not conf[item]["include"]] * max_,
|
|
|
|
}
|
Support multiple Elk instances (#23839)
* Support multiple Elk instances
* Allow more than one Elk M1 alarm system to be integrated into a single hass instance.
* Introduces new "devices" schema at the top level, each of which has
the prior configuration schema.
* Requires new version of elkm1, 0.7.14, that gwww and I just updated (thanks Glen!)
QUESTION: Should the "devices" section be optional to avoid breaking
old configuration files? I chose not to do that for simplicity and
because I was following the doorbird code which requires the "devices"
section for all configurations even with only one device.
* Fixed a bunch of hound-raised issues
Fixed issues raised by hound -- there was clearly
a tool I was supposed to run to get those warnings
before submitting the PR. Sorry!
Updated REQUIREMENTS.
* Fixed whitespace and line-length mistakes
Also fixed unused prefix local variable lint warning.
* Fixed missing blank line
* Fixed more lint warnings.
Not sure if I missed these on the first pass or if the linter stopped
after a certain number of warnings or something else.
Switched logging to use %d and %s instead of string concatenation (per
lint request and because I imagine it migth be better performing
in some (oldish, I presume) implementations of python.
* Fixed typo in last commit.
* Eliminate devices subsection in config schema
This eliminates the breaking change for configurations wanting a
singleton elk m1 instance (the majority of users, no doubt). I did
not do it like this before because I was following the lead of the
doorbird component which introduced a devices: section when moving
to support multiple doorbells. But Rohan Kapoor kindly pointed me
at the zoneminder component which sets the other (IMO) preferable
precedent. Will update the docs change shortly.
* Call async_add_entities once for all the elk controllers.
Just move async_add_entities() outside of the loops across the elk m1
controllers, so it's called once for each platform.
* Call async_add_entities only once per platform.
Move it to after the loop, so it's called only once
per platform even when there are multiple elk m1 controllers.
* Various improvements to be more idiomatic python + bug fixes
Thanks to Martin Hjelmare for the careful review and suggestions.
(All mistaken improvements and new bugs are my own.)
* Removed semicolon that lint caught.
* Idiomatic python improvements
Use dict.values() (instead of making it easier to add local looping variable
on the keys by using _, bar = ...items())
Use [] when the key is known to exist.
* Support multiple Elk instances
* Allow more than one Elk M1 alarm system to be integrated into a single hass instance.
* Introduces new "devices" schema at the top level, each of which has
the prior configuration schema.
* Requires new version of elkm1, 0.7.14, that gwww and I just updated (thanks Glen!)
QUESTION: Should the "devices" section be optional to avoid breaking
old configuration files? I chose not to do that for simplicity and
because I was following the doorbird code which requires the "devices"
section for all configurations even with only one device.
* Fixed a bunch of hound-raised issues
Fixed issues raised by hound -- there was clearly
a tool I was supposed to run to get those warnings
before submitting the PR. Sorry!
Updated REQUIREMENTS.
* Fixed whitespace and line-length mistakes
Also fixed unused prefix local variable lint warning.
* Fixed missing blank line
* Fixed more lint warnings.
Not sure if I missed these on the first pass or if the linter stopped
after a certain number of warnings or something else.
Switched logging to use %d and %s instead of string concatenation (per
lint request and because I imagine it migth be better performing
in some (oldish, I presume) implementations of python.
* Fixed typo in last commit.
* Eliminate devices subsection in config schema
This eliminates the breaking change for configurations wanting a
singleton elk m1 instance (the majority of users, no doubt). I did
not do it like this before because I was following the lead of the
doorbird component which introduced a devices: section when moving
to support multiple doorbells. But Rohan Kapoor kindly pointed me
at the zoneminder component which sets the other (IMO) preferable
precedent. Will update the docs change shortly.
* Call async_add_entities once for all the elk controllers.
Just move async_add_entities() outside of the loops across the elk m1
controllers, so it's called once for each platform.
* Call async_add_entities only once per platform.
Move it to after the loop, so it's called only once
per platform even when there are multiple elk m1 controllers.
* Various improvements to be more idiomatic python + bug fixes
Thanks to Martin Hjelmare for the careful review and suggestions.
(All mistaken improvements and new bugs are my own.)
* Removed semicolon that lint caught.
* Idiomatic python improvements
Use dict.values() (instead of making it easier to add local looping variable
on the keys by using _, bar = ...items())
Use [] when the key is known to exist.
* Use dict[key] instead of .get (incl. fixing typo). Use .values() instead of .items() when ignoring keys.
* Gotta use devices.get(prefix) since we use no prefix for the singleton elk instance
* fix requirement to use newer elkm1 that supports my changes for multiple elk devices
* Removed spurious + between a string broken between two lines for formatting; was failing a lint check about logging needing to use %s
* Remove REQUIREMENTS and DEPENDENCIES since those are now taken care of by the manifest.json file.
* Add configuration check that the prefixes are all unique
* Use new dependency 'getmac' to get mac address of Elk M1 controllers and use that for uniqueid if possible, else use None. Also removed some procedural checking of unique prefix since that's now handled at schema check time.
* Whitespace changes to make style checker happy and code more consistent
* Removed unused variable, added blank line
* Make getmac a requirement not dependency
I should've RTFM.
* ws only change; I really need to get Emacs to understand these style guidelines
* Ran script/gen_requirements_all.py; script/setup needed to be run so that was failing.
* More style check fixes and one bug fix.
* Incomplete set of changes from last push
* More conform-to-hass-style changes: use caps to start log message (and do not use function name even for debug message. And do not use string concatenation; prefer new-style .format.
* Style fixes.
* Switch back to using the prefix config field for setting the unique_id since the mac address approach has numerous shortcomings including: 1) new dependency; 2) lack of reliability; 3) doesn't work for serial connections; 4) breaks when a layer 4+ networking entity intermediates the elk m1 connection.
* Reran to update (removing getmac dependency)
* Skipped trailing ','; keep forgetting which languages are forgiving about this practical nicety of allowing trailing commas without changing the semantics.
* Validate uniqueness on lowercase versions of the prefix since we're gonna use .lower() on creating the entity id that has to be unique; do the _has_all_unique_prefixes check last so we get errors from the device schema before complaining about the uniqueness problem, if any
* Use vol.Lower to convert to lowercase instead of the map. Also fixed a pair of bugs for the alarm control panel display message service -- since data templates always generate strings, the values subject to range/set restrictions need to be coerced to their proper type before the check
* Fix some flake8 warnings.
* Fixed typo; it's Coerce not coerce.
* Use elkm1m_ string to start unique_id when and only when there is a non-empty prefix given; this enables backward compatibility to avoid a breaking change by letting the elkm1_ start to unique_id keep working exactly as it used to.
* minor comment tweak to force automation tests to run again since they failed for unrelated reasons last time
* There's actually been a 0.7.15 release which was meta-information and tidying only so we might as well depend on it
* Forgot to update this with gen_requirements_all.py
2019-07-27 08:36:09 +00:00
|
|
|
try:
|
2019-07-31 19:25:30 +00:00
|
|
|
_included(conf[item]["include"], True, config[item]["included"])
|
|
|
|
_included(conf[item]["exclude"], False, config[item]["included"])
|
Support multiple Elk instances (#23839)
* Support multiple Elk instances
* Allow more than one Elk M1 alarm system to be integrated into a single hass instance.
* Introduces new "devices" schema at the top level, each of which has
the prior configuration schema.
* Requires new version of elkm1, 0.7.14, that gwww and I just updated (thanks Glen!)
QUESTION: Should the "devices" section be optional to avoid breaking
old configuration files? I chose not to do that for simplicity and
because I was following the doorbird code which requires the "devices"
section for all configurations even with only one device.
* Fixed a bunch of hound-raised issues
Fixed issues raised by hound -- there was clearly
a tool I was supposed to run to get those warnings
before submitting the PR. Sorry!
Updated REQUIREMENTS.
* Fixed whitespace and line-length mistakes
Also fixed unused prefix local variable lint warning.
* Fixed missing blank line
* Fixed more lint warnings.
Not sure if I missed these on the first pass or if the linter stopped
after a certain number of warnings or something else.
Switched logging to use %d and %s instead of string concatenation (per
lint request and because I imagine it migth be better performing
in some (oldish, I presume) implementations of python.
* Fixed typo in last commit.
* Eliminate devices subsection in config schema
This eliminates the breaking change for configurations wanting a
singleton elk m1 instance (the majority of users, no doubt). I did
not do it like this before because I was following the lead of the
doorbird component which introduced a devices: section when moving
to support multiple doorbells. But Rohan Kapoor kindly pointed me
at the zoneminder component which sets the other (IMO) preferable
precedent. Will update the docs change shortly.
* Call async_add_entities once for all the elk controllers.
Just move async_add_entities() outside of the loops across the elk m1
controllers, so it's called once for each platform.
* Call async_add_entities only once per platform.
Move it to after the loop, so it's called only once
per platform even when there are multiple elk m1 controllers.
* Various improvements to be more idiomatic python + bug fixes
Thanks to Martin Hjelmare for the careful review and suggestions.
(All mistaken improvements and new bugs are my own.)
* Removed semicolon that lint caught.
* Idiomatic python improvements
Use dict.values() (instead of making it easier to add local looping variable
on the keys by using _, bar = ...items())
Use [] when the key is known to exist.
* Support multiple Elk instances
* Allow more than one Elk M1 alarm system to be integrated into a single hass instance.
* Introduces new "devices" schema at the top level, each of which has
the prior configuration schema.
* Requires new version of elkm1, 0.7.14, that gwww and I just updated (thanks Glen!)
QUESTION: Should the "devices" section be optional to avoid breaking
old configuration files? I chose not to do that for simplicity and
because I was following the doorbird code which requires the "devices"
section for all configurations even with only one device.
* Fixed a bunch of hound-raised issues
Fixed issues raised by hound -- there was clearly
a tool I was supposed to run to get those warnings
before submitting the PR. Sorry!
Updated REQUIREMENTS.
* Fixed whitespace and line-length mistakes
Also fixed unused prefix local variable lint warning.
* Fixed missing blank line
* Fixed more lint warnings.
Not sure if I missed these on the first pass or if the linter stopped
after a certain number of warnings or something else.
Switched logging to use %d and %s instead of string concatenation (per
lint request and because I imagine it migth be better performing
in some (oldish, I presume) implementations of python.
* Fixed typo in last commit.
* Eliminate devices subsection in config schema
This eliminates the breaking change for configurations wanting a
singleton elk m1 instance (the majority of users, no doubt). I did
not do it like this before because I was following the lead of the
doorbird component which introduced a devices: section when moving
to support multiple doorbells. But Rohan Kapoor kindly pointed me
at the zoneminder component which sets the other (IMO) preferable
precedent. Will update the docs change shortly.
* Call async_add_entities once for all the elk controllers.
Just move async_add_entities() outside of the loops across the elk m1
controllers, so it's called once for each platform.
* Call async_add_entities only once per platform.
Move it to after the loop, so it's called only once
per platform even when there are multiple elk m1 controllers.
* Various improvements to be more idiomatic python + bug fixes
Thanks to Martin Hjelmare for the careful review and suggestions.
(All mistaken improvements and new bugs are my own.)
* Removed semicolon that lint caught.
* Idiomatic python improvements
Use dict.values() (instead of making it easier to add local looping variable
on the keys by using _, bar = ...items())
Use [] when the key is known to exist.
* Use dict[key] instead of .get (incl. fixing typo). Use .values() instead of .items() when ignoring keys.
* Gotta use devices.get(prefix) since we use no prefix for the singleton elk instance
* fix requirement to use newer elkm1 that supports my changes for multiple elk devices
* Removed spurious + between a string broken between two lines for formatting; was failing a lint check about logging needing to use %s
* Remove REQUIREMENTS and DEPENDENCIES since those are now taken care of by the manifest.json file.
* Add configuration check that the prefixes are all unique
* Use new dependency 'getmac' to get mac address of Elk M1 controllers and use that for uniqueid if possible, else use None. Also removed some procedural checking of unique prefix since that's now handled at schema check time.
* Whitespace changes to make style checker happy and code more consistent
* Removed unused variable, added blank line
* Make getmac a requirement not dependency
I should've RTFM.
* ws only change; I really need to get Emacs to understand these style guidelines
* Ran script/gen_requirements_all.py; script/setup needed to be run so that was failing.
* More style check fixes and one bug fix.
* Incomplete set of changes from last push
* More conform-to-hass-style changes: use caps to start log message (and do not use function name even for debug message. And do not use string concatenation; prefer new-style .format.
* Style fixes.
* Switch back to using the prefix config field for setting the unique_id since the mac address approach has numerous shortcomings including: 1) new dependency; 2) lack of reliability; 3) doesn't work for serial connections; 4) breaks when a layer 4+ networking entity intermediates the elk m1 connection.
* Reran to update (removing getmac dependency)
* Skipped trailing ','; keep forgetting which languages are forgiving about this practical nicety of allowing trailing commas without changing the semantics.
* Validate uniqueness on lowercase versions of the prefix since we're gonna use .lower() on creating the entity id that has to be unique; do the _has_all_unique_prefixes check last so we get errors from the device schema before complaining about the uniqueness problem, if any
* Use vol.Lower to convert to lowercase instead of the map. Also fixed a pair of bugs for the alarm control panel display message service -- since data templates always generate strings, the values subject to range/set restrictions need to be coerced to their proper type before the check
* Fix some flake8 warnings.
* Fixed typo; it's Coerce not coerce.
* Use elkm1m_ string to start unique_id when and only when there is a non-empty prefix given; this enables backward compatibility to avoid a breaking change by letting the elkm1_ start to unique_id keep working exactly as it used to.
* minor comment tweak to force automation tests to run again since they failed for unrelated reasons last time
* There's actually been a 0.7.15 release which was meta-information and tidying only so we might as well depend on it
* Forgot to update this with gen_requirements_all.py
2019-07-27 08:36:09 +00:00
|
|
|
except (ValueError, vol.Invalid) as err:
|
|
|
|
_LOGGER.error("Config item: %s; %s", item, err)
|
|
|
|
return False
|
|
|
|
|
2020-03-27 20:38:35 +00:00
|
|
|
elk = elkm1.Elk(
|
|
|
|
{
|
|
|
|
"url": conf[CONF_HOST],
|
|
|
|
"userid": conf[CONF_USERNAME],
|
|
|
|
"password": conf[CONF_PASSWORD],
|
2019-07-31 19:25:30 +00:00
|
|
|
}
|
2020-03-27 20:38:35 +00:00
|
|
|
)
|
|
|
|
elk.connect()
|
Support multiple Elk instances (#23839)
* Support multiple Elk instances
* Allow more than one Elk M1 alarm system to be integrated into a single hass instance.
* Introduces new "devices" schema at the top level, each of which has
the prior configuration schema.
* Requires new version of elkm1, 0.7.14, that gwww and I just updated (thanks Glen!)
QUESTION: Should the "devices" section be optional to avoid breaking
old configuration files? I chose not to do that for simplicity and
because I was following the doorbird code which requires the "devices"
section for all configurations even with only one device.
* Fixed a bunch of hound-raised issues
Fixed issues raised by hound -- there was clearly
a tool I was supposed to run to get those warnings
before submitting the PR. Sorry!
Updated REQUIREMENTS.
* Fixed whitespace and line-length mistakes
Also fixed unused prefix local variable lint warning.
* Fixed missing blank line
* Fixed more lint warnings.
Not sure if I missed these on the first pass or if the linter stopped
after a certain number of warnings or something else.
Switched logging to use %d and %s instead of string concatenation (per
lint request and because I imagine it migth be better performing
in some (oldish, I presume) implementations of python.
* Fixed typo in last commit.
* Eliminate devices subsection in config schema
This eliminates the breaking change for configurations wanting a
singleton elk m1 instance (the majority of users, no doubt). I did
not do it like this before because I was following the lead of the
doorbird component which introduced a devices: section when moving
to support multiple doorbells. But Rohan Kapoor kindly pointed me
at the zoneminder component which sets the other (IMO) preferable
precedent. Will update the docs change shortly.
* Call async_add_entities once for all the elk controllers.
Just move async_add_entities() outside of the loops across the elk m1
controllers, so it's called once for each platform.
* Call async_add_entities only once per platform.
Move it to after the loop, so it's called only once
per platform even when there are multiple elk m1 controllers.
* Various improvements to be more idiomatic python + bug fixes
Thanks to Martin Hjelmare for the careful review and suggestions.
(All mistaken improvements and new bugs are my own.)
* Removed semicolon that lint caught.
* Idiomatic python improvements
Use dict.values() (instead of making it easier to add local looping variable
on the keys by using _, bar = ...items())
Use [] when the key is known to exist.
* Support multiple Elk instances
* Allow more than one Elk M1 alarm system to be integrated into a single hass instance.
* Introduces new "devices" schema at the top level, each of which has
the prior configuration schema.
* Requires new version of elkm1, 0.7.14, that gwww and I just updated (thanks Glen!)
QUESTION: Should the "devices" section be optional to avoid breaking
old configuration files? I chose not to do that for simplicity and
because I was following the doorbird code which requires the "devices"
section for all configurations even with only one device.
* Fixed a bunch of hound-raised issues
Fixed issues raised by hound -- there was clearly
a tool I was supposed to run to get those warnings
before submitting the PR. Sorry!
Updated REQUIREMENTS.
* Fixed whitespace and line-length mistakes
Also fixed unused prefix local variable lint warning.
* Fixed missing blank line
* Fixed more lint warnings.
Not sure if I missed these on the first pass or if the linter stopped
after a certain number of warnings or something else.
Switched logging to use %d and %s instead of string concatenation (per
lint request and because I imagine it migth be better performing
in some (oldish, I presume) implementations of python.
* Fixed typo in last commit.
* Eliminate devices subsection in config schema
This eliminates the breaking change for configurations wanting a
singleton elk m1 instance (the majority of users, no doubt). I did
not do it like this before because I was following the lead of the
doorbird component which introduced a devices: section when moving
to support multiple doorbells. But Rohan Kapoor kindly pointed me
at the zoneminder component which sets the other (IMO) preferable
precedent. Will update the docs change shortly.
* Call async_add_entities once for all the elk controllers.
Just move async_add_entities() outside of the loops across the elk m1
controllers, so it's called once for each platform.
* Call async_add_entities only once per platform.
Move it to after the loop, so it's called only once
per platform even when there are multiple elk m1 controllers.
* Various improvements to be more idiomatic python + bug fixes
Thanks to Martin Hjelmare for the careful review and suggestions.
(All mistaken improvements and new bugs are my own.)
* Removed semicolon that lint caught.
* Idiomatic python improvements
Use dict.values() (instead of making it easier to add local looping variable
on the keys by using _, bar = ...items())
Use [] when the key is known to exist.
* Use dict[key] instead of .get (incl. fixing typo). Use .values() instead of .items() when ignoring keys.
* Gotta use devices.get(prefix) since we use no prefix for the singleton elk instance
* fix requirement to use newer elkm1 that supports my changes for multiple elk devices
* Removed spurious + between a string broken between two lines for formatting; was failing a lint check about logging needing to use %s
* Remove REQUIREMENTS and DEPENDENCIES since those are now taken care of by the manifest.json file.
* Add configuration check that the prefixes are all unique
* Use new dependency 'getmac' to get mac address of Elk M1 controllers and use that for uniqueid if possible, else use None. Also removed some procedural checking of unique prefix since that's now handled at schema check time.
* Whitespace changes to make style checker happy and code more consistent
* Removed unused variable, added blank line
* Make getmac a requirement not dependency
I should've RTFM.
* ws only change; I really need to get Emacs to understand these style guidelines
* Ran script/gen_requirements_all.py; script/setup needed to be run so that was failing.
* More style check fixes and one bug fix.
* Incomplete set of changes from last push
* More conform-to-hass-style changes: use caps to start log message (and do not use function name even for debug message. And do not use string concatenation; prefer new-style .format.
* Style fixes.
* Switch back to using the prefix config field for setting the unique_id since the mac address approach has numerous shortcomings including: 1) new dependency; 2) lack of reliability; 3) doesn't work for serial connections; 4) breaks when a layer 4+ networking entity intermediates the elk m1 connection.
* Reran to update (removing getmac dependency)
* Skipped trailing ','; keep forgetting which languages are forgiving about this practical nicety of allowing trailing commas without changing the semantics.
* Validate uniqueness on lowercase versions of the prefix since we're gonna use .lower() on creating the entity id that has to be unique; do the _has_all_unique_prefixes check last so we get errors from the device schema before complaining about the uniqueness problem, if any
* Use vol.Lower to convert to lowercase instead of the map. Also fixed a pair of bugs for the alarm control panel display message service -- since data templates always generate strings, the values subject to range/set restrictions need to be coerced to their proper type before the check
* Fix some flake8 warnings.
* Fixed typo; it's Coerce not coerce.
* Use elkm1m_ string to start unique_id when and only when there is a non-empty prefix given; this enables backward compatibility to avoid a breaking change by letting the elkm1_ start to unique_id keep working exactly as it used to.
* minor comment tweak to force automation tests to run again since they failed for unrelated reasons last time
* There's actually been a 0.7.15 release which was meta-information and tidying only so we might as well depend on it
* Forgot to update this with gen_requirements_all.py
2019-07-27 08:36:09 +00:00
|
|
|
|
2020-10-15 22:05:07 +00:00
|
|
|
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)
|
|
|
|
|
2020-10-25 04:46:22 +00:00
|
|
|
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
|
2020-03-27 20:38:35 +00:00
|
|
|
|
|
|
|
hass.data[DOMAIN][entry.entry_id] = {
|
|
|
|
"elk": elk,
|
|
|
|
"prefix": conf[CONF_PREFIX],
|
|
|
|
"auto_configure": conf[CONF_AUTO_CONFIGURE],
|
|
|
|
"config": config,
|
|
|
|
"keypads": {},
|
|
|
|
}
|
Support multiple Elk instances (#23839)
* Support multiple Elk instances
* Allow more than one Elk M1 alarm system to be integrated into a single hass instance.
* Introduces new "devices" schema at the top level, each of which has
the prior configuration schema.
* Requires new version of elkm1, 0.7.14, that gwww and I just updated (thanks Glen!)
QUESTION: Should the "devices" section be optional to avoid breaking
old configuration files? I chose not to do that for simplicity and
because I was following the doorbird code which requires the "devices"
section for all configurations even with only one device.
* Fixed a bunch of hound-raised issues
Fixed issues raised by hound -- there was clearly
a tool I was supposed to run to get those warnings
before submitting the PR. Sorry!
Updated REQUIREMENTS.
* Fixed whitespace and line-length mistakes
Also fixed unused prefix local variable lint warning.
* Fixed missing blank line
* Fixed more lint warnings.
Not sure if I missed these on the first pass or if the linter stopped
after a certain number of warnings or something else.
Switched logging to use %d and %s instead of string concatenation (per
lint request and because I imagine it migth be better performing
in some (oldish, I presume) implementations of python.
* Fixed typo in last commit.
* Eliminate devices subsection in config schema
This eliminates the breaking change for configurations wanting a
singleton elk m1 instance (the majority of users, no doubt). I did
not do it like this before because I was following the lead of the
doorbird component which introduced a devices: section when moving
to support multiple doorbells. But Rohan Kapoor kindly pointed me
at the zoneminder component which sets the other (IMO) preferable
precedent. Will update the docs change shortly.
* Call async_add_entities once for all the elk controllers.
Just move async_add_entities() outside of the loops across the elk m1
controllers, so it's called once for each platform.
* Call async_add_entities only once per platform.
Move it to after the loop, so it's called only once
per platform even when there are multiple elk m1 controllers.
* Various improvements to be more idiomatic python + bug fixes
Thanks to Martin Hjelmare for the careful review and suggestions.
(All mistaken improvements and new bugs are my own.)
* Removed semicolon that lint caught.
* Idiomatic python improvements
Use dict.values() (instead of making it easier to add local looping variable
on the keys by using _, bar = ...items())
Use [] when the key is known to exist.
* Support multiple Elk instances
* Allow more than one Elk M1 alarm system to be integrated into a single hass instance.
* Introduces new "devices" schema at the top level, each of which has
the prior configuration schema.
* Requires new version of elkm1, 0.7.14, that gwww and I just updated (thanks Glen!)
QUESTION: Should the "devices" section be optional to avoid breaking
old configuration files? I chose not to do that for simplicity and
because I was following the doorbird code which requires the "devices"
section for all configurations even with only one device.
* Fixed a bunch of hound-raised issues
Fixed issues raised by hound -- there was clearly
a tool I was supposed to run to get those warnings
before submitting the PR. Sorry!
Updated REQUIREMENTS.
* Fixed whitespace and line-length mistakes
Also fixed unused prefix local variable lint warning.
* Fixed missing blank line
* Fixed more lint warnings.
Not sure if I missed these on the first pass or if the linter stopped
after a certain number of warnings or something else.
Switched logging to use %d and %s instead of string concatenation (per
lint request and because I imagine it migth be better performing
in some (oldish, I presume) implementations of python.
* Fixed typo in last commit.
* Eliminate devices subsection in config schema
This eliminates the breaking change for configurations wanting a
singleton elk m1 instance (the majority of users, no doubt). I did
not do it like this before because I was following the lead of the
doorbird component which introduced a devices: section when moving
to support multiple doorbells. But Rohan Kapoor kindly pointed me
at the zoneminder component which sets the other (IMO) preferable
precedent. Will update the docs change shortly.
* Call async_add_entities once for all the elk controllers.
Just move async_add_entities() outside of the loops across the elk m1
controllers, so it's called once for each platform.
* Call async_add_entities only once per platform.
Move it to after the loop, so it's called only once
per platform even when there are multiple elk m1 controllers.
* Various improvements to be more idiomatic python + bug fixes
Thanks to Martin Hjelmare for the careful review and suggestions.
(All mistaken improvements and new bugs are my own.)
* Removed semicolon that lint caught.
* Idiomatic python improvements
Use dict.values() (instead of making it easier to add local looping variable
on the keys by using _, bar = ...items())
Use [] when the key is known to exist.
* Use dict[key] instead of .get (incl. fixing typo). Use .values() instead of .items() when ignoring keys.
* Gotta use devices.get(prefix) since we use no prefix for the singleton elk instance
* fix requirement to use newer elkm1 that supports my changes for multiple elk devices
* Removed spurious + between a string broken between two lines for formatting; was failing a lint check about logging needing to use %s
* Remove REQUIREMENTS and DEPENDENCIES since those are now taken care of by the manifest.json file.
* Add configuration check that the prefixes are all unique
* Use new dependency 'getmac' to get mac address of Elk M1 controllers and use that for uniqueid if possible, else use None. Also removed some procedural checking of unique prefix since that's now handled at schema check time.
* Whitespace changes to make style checker happy and code more consistent
* Removed unused variable, added blank line
* Make getmac a requirement not dependency
I should've RTFM.
* ws only change; I really need to get Emacs to understand these style guidelines
* Ran script/gen_requirements_all.py; script/setup needed to be run so that was failing.
* More style check fixes and one bug fix.
* Incomplete set of changes from last push
* More conform-to-hass-style changes: use caps to start log message (and do not use function name even for debug message. And do not use string concatenation; prefer new-style .format.
* Style fixes.
* Switch back to using the prefix config field for setting the unique_id since the mac address approach has numerous shortcomings including: 1) new dependency; 2) lack of reliability; 3) doesn't work for serial connections; 4) breaks when a layer 4+ networking entity intermediates the elk m1 connection.
* Reran to update (removing getmac dependency)
* Skipped trailing ','; keep forgetting which languages are forgiving about this practical nicety of allowing trailing commas without changing the semantics.
* Validate uniqueness on lowercase versions of the prefix since we're gonna use .lower() on creating the entity id that has to be unique; do the _has_all_unique_prefixes check last so we get errors from the device schema before complaining about the uniqueness problem, if any
* Use vol.Lower to convert to lowercase instead of the map. Also fixed a pair of bugs for the alarm control panel display message service -- since data templates always generate strings, the values subject to range/set restrictions need to be coerced to their proper type before the check
* Fix some flake8 warnings.
* Fixed typo; it's Coerce not coerce.
* Use elkm1m_ string to start unique_id when and only when there is a non-empty prefix given; this enables backward compatibility to avoid a breaking change by letting the elkm1_ start to unique_id keep working exactly as it used to.
* minor comment tweak to force automation tests to run again since they failed for unrelated reasons last time
* There's actually been a 0.7.15 release which was meta-information and tidying only so we might as well depend on it
* Forgot to update this with gen_requirements_all.py
2019-07-27 08:36:09 +00:00
|
|
|
|
2021-04-27 06:46:49 +00:00
|
|
|
hass.config_entries.async_setup_platforms(entry, PLATFORMS)
|
2018-10-07 19:45:36 +00:00
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
2020-03-27 20:38:35 +00:00
|
|
|
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)
|
|
|
|
|
|
|
|
|
|
|
|
def _find_elk_by_prefix(hass, prefix):
|
|
|
|
"""Search all config entries for a given prefix."""
|
|
|
|
for entry_id in hass.data[DOMAIN]:
|
|
|
|
if hass.data[DOMAIN][entry_id]["prefix"] == prefix:
|
|
|
|
return hass.data[DOMAIN][entry_id]["elk"]
|
|
|
|
|
|
|
|
|
|
|
|
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry):
|
|
|
|
"""Unload a config entry."""
|
2021-04-27 06:46:49 +00:00
|
|
|
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
2020-03-27 20:38:35 +00:00
|
|
|
|
|
|
|
# disconnect cleanly
|
|
|
|
hass.data[DOMAIN][entry.entry_id]["elk"].disconnect()
|
|
|
|
|
|
|
|
if unload_ok:
|
|
|
|
hass.data[DOMAIN].pop(entry.entry_id)
|
|
|
|
|
|
|
|
return unload_ok
|
|
|
|
|
|
|
|
|
2020-10-25 04:46:22 +00:00
|
|
|
async def async_wait_for_elk_to_sync(elk, timeout, conf_host):
|
|
|
|
"""Wait until the elk has finished sync. Can fail login or timeout."""
|
|
|
|
|
|
|
|
def login_status(succeeded):
|
|
|
|
nonlocal success
|
|
|
|
|
|
|
|
success = succeeded
|
|
|
|
if succeeded:
|
2020-10-26 09:36:28 +00:00
|
|
|
_LOGGER.debug("ElkM1 login succeeded")
|
2020-10-25 04:46:22 +00:00
|
|
|
else:
|
|
|
|
elk.disconnect()
|
2020-10-26 09:36:28 +00:00
|
|
|
_LOGGER.error("ElkM1 login failed; invalid username or password")
|
2020-10-25 04:46:22 +00:00
|
|
|
event.set()
|
|
|
|
|
|
|
|
def sync_complete():
|
|
|
|
event.set()
|
|
|
|
|
|
|
|
success = True
|
|
|
|
event = asyncio.Event()
|
|
|
|
elk.add_handler("login", login_status)
|
|
|
|
elk.add_handler("sync_complete", sync_complete)
|
2020-03-27 20:38:35 +00:00
|
|
|
try:
|
|
|
|
with async_timeout.timeout(timeout):
|
2020-10-25 04:46:22 +00:00
|
|
|
await event.wait()
|
2020-03-27 20:38:35 +00:00
|
|
|
except asyncio.TimeoutError:
|
2020-10-25 04:46:22 +00:00
|
|
|
_LOGGER.error(
|
|
|
|
"Timed out after %d seconds while trying to sync with ElkM1 at %s",
|
2020-10-26 09:36:28 +00:00
|
|
|
timeout,
|
2020-10-25 04:46:22 +00:00
|
|
|
conf_host,
|
|
|
|
)
|
2020-03-27 20:38:35 +00:00
|
|
|
elk.disconnect()
|
2020-10-25 04:46:22 +00:00
|
|
|
raise
|
2020-03-27 20:38:35 +00:00
|
|
|
|
2020-10-25 04:46:22 +00:00
|
|
|
return success
|
2020-03-27 20:38:35 +00:00
|
|
|
|
|
|
|
|
|
|
|
def _create_elk_services(hass):
|
2020-10-15 22:05:07 +00:00
|
|
|
def _getelk(service):
|
2019-07-31 19:25:30 +00:00
|
|
|
prefix = service.data["prefix"]
|
2020-03-27 20:38:35 +00:00
|
|
|
elk = _find_elk_by_prefix(hass, prefix)
|
Support multiple Elk instances (#23839)
* Support multiple Elk instances
* Allow more than one Elk M1 alarm system to be integrated into a single hass instance.
* Introduces new "devices" schema at the top level, each of which has
the prior configuration schema.
* Requires new version of elkm1, 0.7.14, that gwww and I just updated (thanks Glen!)
QUESTION: Should the "devices" section be optional to avoid breaking
old configuration files? I chose not to do that for simplicity and
because I was following the doorbird code which requires the "devices"
section for all configurations even with only one device.
* Fixed a bunch of hound-raised issues
Fixed issues raised by hound -- there was clearly
a tool I was supposed to run to get those warnings
before submitting the PR. Sorry!
Updated REQUIREMENTS.
* Fixed whitespace and line-length mistakes
Also fixed unused prefix local variable lint warning.
* Fixed missing blank line
* Fixed more lint warnings.
Not sure if I missed these on the first pass or if the linter stopped
after a certain number of warnings or something else.
Switched logging to use %d and %s instead of string concatenation (per
lint request and because I imagine it migth be better performing
in some (oldish, I presume) implementations of python.
* Fixed typo in last commit.
* Eliminate devices subsection in config schema
This eliminates the breaking change for configurations wanting a
singleton elk m1 instance (the majority of users, no doubt). I did
not do it like this before because I was following the lead of the
doorbird component which introduced a devices: section when moving
to support multiple doorbells. But Rohan Kapoor kindly pointed me
at the zoneminder component which sets the other (IMO) preferable
precedent. Will update the docs change shortly.
* Call async_add_entities once for all the elk controllers.
Just move async_add_entities() outside of the loops across the elk m1
controllers, so it's called once for each platform.
* Call async_add_entities only once per platform.
Move it to after the loop, so it's called only once
per platform even when there are multiple elk m1 controllers.
* Various improvements to be more idiomatic python + bug fixes
Thanks to Martin Hjelmare for the careful review and suggestions.
(All mistaken improvements and new bugs are my own.)
* Removed semicolon that lint caught.
* Idiomatic python improvements
Use dict.values() (instead of making it easier to add local looping variable
on the keys by using _, bar = ...items())
Use [] when the key is known to exist.
* Support multiple Elk instances
* Allow more than one Elk M1 alarm system to be integrated into a single hass instance.
* Introduces new "devices" schema at the top level, each of which has
the prior configuration schema.
* Requires new version of elkm1, 0.7.14, that gwww and I just updated (thanks Glen!)
QUESTION: Should the "devices" section be optional to avoid breaking
old configuration files? I chose not to do that for simplicity and
because I was following the doorbird code which requires the "devices"
section for all configurations even with only one device.
* Fixed a bunch of hound-raised issues
Fixed issues raised by hound -- there was clearly
a tool I was supposed to run to get those warnings
before submitting the PR. Sorry!
Updated REQUIREMENTS.
* Fixed whitespace and line-length mistakes
Also fixed unused prefix local variable lint warning.
* Fixed missing blank line
* Fixed more lint warnings.
Not sure if I missed these on the first pass or if the linter stopped
after a certain number of warnings or something else.
Switched logging to use %d and %s instead of string concatenation (per
lint request and because I imagine it migth be better performing
in some (oldish, I presume) implementations of python.
* Fixed typo in last commit.
* Eliminate devices subsection in config schema
This eliminates the breaking change for configurations wanting a
singleton elk m1 instance (the majority of users, no doubt). I did
not do it like this before because I was following the lead of the
doorbird component which introduced a devices: section when moving
to support multiple doorbells. But Rohan Kapoor kindly pointed me
at the zoneminder component which sets the other (IMO) preferable
precedent. Will update the docs change shortly.
* Call async_add_entities once for all the elk controllers.
Just move async_add_entities() outside of the loops across the elk m1
controllers, so it's called once for each platform.
* Call async_add_entities only once per platform.
Move it to after the loop, so it's called only once
per platform even when there are multiple elk m1 controllers.
* Various improvements to be more idiomatic python + bug fixes
Thanks to Martin Hjelmare for the careful review and suggestions.
(All mistaken improvements and new bugs are my own.)
* Removed semicolon that lint caught.
* Idiomatic python improvements
Use dict.values() (instead of making it easier to add local looping variable
on the keys by using _, bar = ...items())
Use [] when the key is known to exist.
* Use dict[key] instead of .get (incl. fixing typo). Use .values() instead of .items() when ignoring keys.
* Gotta use devices.get(prefix) since we use no prefix for the singleton elk instance
* fix requirement to use newer elkm1 that supports my changes for multiple elk devices
* Removed spurious + between a string broken between two lines for formatting; was failing a lint check about logging needing to use %s
* Remove REQUIREMENTS and DEPENDENCIES since those are now taken care of by the manifest.json file.
* Add configuration check that the prefixes are all unique
* Use new dependency 'getmac' to get mac address of Elk M1 controllers and use that for uniqueid if possible, else use None. Also removed some procedural checking of unique prefix since that's now handled at schema check time.
* Whitespace changes to make style checker happy and code more consistent
* Removed unused variable, added blank line
* Make getmac a requirement not dependency
I should've RTFM.
* ws only change; I really need to get Emacs to understand these style guidelines
* Ran script/gen_requirements_all.py; script/setup needed to be run so that was failing.
* More style check fixes and one bug fix.
* Incomplete set of changes from last push
* More conform-to-hass-style changes: use caps to start log message (and do not use function name even for debug message. And do not use string concatenation; prefer new-style .format.
* Style fixes.
* Switch back to using the prefix config field for setting the unique_id since the mac address approach has numerous shortcomings including: 1) new dependency; 2) lack of reliability; 3) doesn't work for serial connections; 4) breaks when a layer 4+ networking entity intermediates the elk m1 connection.
* Reran to update (removing getmac dependency)
* Skipped trailing ','; keep forgetting which languages are forgiving about this practical nicety of allowing trailing commas without changing the semantics.
* Validate uniqueness on lowercase versions of the prefix since we're gonna use .lower() on creating the entity id that has to be unique; do the _has_all_unique_prefixes check last so we get errors from the device schema before complaining about the uniqueness problem, if any
* Use vol.Lower to convert to lowercase instead of the map. Also fixed a pair of bugs for the alarm control panel display message service -- since data templates always generate strings, the values subject to range/set restrictions need to be coerced to their proper type before the check
* Fix some flake8 warnings.
* Fixed typo; it's Coerce not coerce.
* Use elkm1m_ string to start unique_id when and only when there is a non-empty prefix given; this enables backward compatibility to avoid a breaking change by letting the elkm1_ start to unique_id keep working exactly as it used to.
* minor comment tweak to force automation tests to run again since they failed for unrelated reasons last time
* There's actually been a 0.7.15 release which was meta-information and tidying only so we might as well depend on it
* Forgot to update this with gen_requirements_all.py
2019-07-27 08:36:09 +00:00
|
|
|
if elk is None:
|
2020-10-15 22:05:07 +00:00
|
|
|
raise HomeAssistantError(f"No ElkM1 with prefix '{prefix}' found")
|
|
|
|
return elk
|
|
|
|
|
|
|
|
def _speak_word_service(service):
|
|
|
|
_getelk(service).panel.speak_word(service.data["number"])
|
2018-10-19 21:41:04 +00:00
|
|
|
|
|
|
|
def _speak_phrase_service(service):
|
2020-10-15 22:05:07 +00:00
|
|
|
_getelk(service).panel.speak_phrase(service.data["number"])
|
|
|
|
|
|
|
|
def _set_time_service(service):
|
|
|
|
_getelk(service).panel.set_time(dt_util.now())
|
2018-10-19 21:41:04 +00:00
|
|
|
|
|
|
|
hass.services.async_register(
|
2019-07-31 19:25:30 +00:00
|
|
|
DOMAIN, "speak_word", _speak_word_service, SPEAK_SERVICE_SCHEMA
|
|
|
|
)
|
2018-10-19 21:41:04 +00:00
|
|
|
hass.services.async_register(
|
2019-07-31 19:25:30 +00:00
|
|
|
DOMAIN, "speak_phrase", _speak_phrase_service, SPEAK_SERVICE_SCHEMA
|
|
|
|
)
|
2020-10-15 22:05:07 +00:00
|
|
|
hass.services.async_register(
|
|
|
|
DOMAIN, "set_time", _set_time_service, SET_TIME_SERVICE_SCHEMA
|
|
|
|
)
|
2018-10-19 21:41:04 +00:00
|
|
|
|
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
def create_elk_entities(elk_data, elk_elements, element_type, class_, entities):
|
2018-10-07 19:45:36 +00:00
|
|
|
"""Create the ElkM1 devices of a particular class."""
|
2020-03-27 20:38:35 +00:00
|
|
|
auto_configure = elk_data["auto_configure"]
|
|
|
|
|
|
|
|
if not auto_configure and not elk_data["config"][element_type]["enabled"]:
|
|
|
|
return
|
|
|
|
|
|
|
|
elk = elk_data["elk"]
|
|
|
|
_LOGGER.debug("Creating elk entities for %s", elk)
|
|
|
|
|
|
|
|
for element in elk_elements:
|
|
|
|
if auto_configure:
|
|
|
|
if not element.configured:
|
|
|
|
continue
|
|
|
|
# Only check the included list if auto configure is not
|
|
|
|
elif not elk_data["config"][element_type]["included"][element.index]:
|
|
|
|
continue
|
|
|
|
|
|
|
|
entities.append(class_(element, elk, elk_data))
|
2018-10-07 19:45:36 +00:00
|
|
|
return entities
|
|
|
|
|
|
|
|
|
|
|
|
class ElkEntity(Entity):
|
|
|
|
"""Base class for all Elk entities."""
|
|
|
|
|
2018-10-10 17:05:19 +00:00
|
|
|
def __init__(self, element, elk, elk_data):
|
2018-10-07 19:45:36 +00:00
|
|
|
"""Initialize the base of all Elk devices."""
|
|
|
|
self._elk = elk
|
|
|
|
self._element = element
|
2019-07-31 19:25:30 +00:00
|
|
|
self._prefix = elk_data["prefix"]
|
|
|
|
self._temperature_unit = elk_data["config"]["temperature_unit"]
|
Support multiple Elk instances (#23839)
* Support multiple Elk instances
* Allow more than one Elk M1 alarm system to be integrated into a single hass instance.
* Introduces new "devices" schema at the top level, each of which has
the prior configuration schema.
* Requires new version of elkm1, 0.7.14, that gwww and I just updated (thanks Glen!)
QUESTION: Should the "devices" section be optional to avoid breaking
old configuration files? I chose not to do that for simplicity and
because I was following the doorbird code which requires the "devices"
section for all configurations even with only one device.
* Fixed a bunch of hound-raised issues
Fixed issues raised by hound -- there was clearly
a tool I was supposed to run to get those warnings
before submitting the PR. Sorry!
Updated REQUIREMENTS.
* Fixed whitespace and line-length mistakes
Also fixed unused prefix local variable lint warning.
* Fixed missing blank line
* Fixed more lint warnings.
Not sure if I missed these on the first pass or if the linter stopped
after a certain number of warnings or something else.
Switched logging to use %d and %s instead of string concatenation (per
lint request and because I imagine it migth be better performing
in some (oldish, I presume) implementations of python.
* Fixed typo in last commit.
* Eliminate devices subsection in config schema
This eliminates the breaking change for configurations wanting a
singleton elk m1 instance (the majority of users, no doubt). I did
not do it like this before because I was following the lead of the
doorbird component which introduced a devices: section when moving
to support multiple doorbells. But Rohan Kapoor kindly pointed me
at the zoneminder component which sets the other (IMO) preferable
precedent. Will update the docs change shortly.
* Call async_add_entities once for all the elk controllers.
Just move async_add_entities() outside of the loops across the elk m1
controllers, so it's called once for each platform.
* Call async_add_entities only once per platform.
Move it to after the loop, so it's called only once
per platform even when there are multiple elk m1 controllers.
* Various improvements to be more idiomatic python + bug fixes
Thanks to Martin Hjelmare for the careful review and suggestions.
(All mistaken improvements and new bugs are my own.)
* Removed semicolon that lint caught.
* Idiomatic python improvements
Use dict.values() (instead of making it easier to add local looping variable
on the keys by using _, bar = ...items())
Use [] when the key is known to exist.
* Support multiple Elk instances
* Allow more than one Elk M1 alarm system to be integrated into a single hass instance.
* Introduces new "devices" schema at the top level, each of which has
the prior configuration schema.
* Requires new version of elkm1, 0.7.14, that gwww and I just updated (thanks Glen!)
QUESTION: Should the "devices" section be optional to avoid breaking
old configuration files? I chose not to do that for simplicity and
because I was following the doorbird code which requires the "devices"
section for all configurations even with only one device.
* Fixed a bunch of hound-raised issues
Fixed issues raised by hound -- there was clearly
a tool I was supposed to run to get those warnings
before submitting the PR. Sorry!
Updated REQUIREMENTS.
* Fixed whitespace and line-length mistakes
Also fixed unused prefix local variable lint warning.
* Fixed missing blank line
* Fixed more lint warnings.
Not sure if I missed these on the first pass or if the linter stopped
after a certain number of warnings or something else.
Switched logging to use %d and %s instead of string concatenation (per
lint request and because I imagine it migth be better performing
in some (oldish, I presume) implementations of python.
* Fixed typo in last commit.
* Eliminate devices subsection in config schema
This eliminates the breaking change for configurations wanting a
singleton elk m1 instance (the majority of users, no doubt). I did
not do it like this before because I was following the lead of the
doorbird component which introduced a devices: section when moving
to support multiple doorbells. But Rohan Kapoor kindly pointed me
at the zoneminder component which sets the other (IMO) preferable
precedent. Will update the docs change shortly.
* Call async_add_entities once for all the elk controllers.
Just move async_add_entities() outside of the loops across the elk m1
controllers, so it's called once for each platform.
* Call async_add_entities only once per platform.
Move it to after the loop, so it's called only once
per platform even when there are multiple elk m1 controllers.
* Various improvements to be more idiomatic python + bug fixes
Thanks to Martin Hjelmare for the careful review and suggestions.
(All mistaken improvements and new bugs are my own.)
* Removed semicolon that lint caught.
* Idiomatic python improvements
Use dict.values() (instead of making it easier to add local looping variable
on the keys by using _, bar = ...items())
Use [] when the key is known to exist.
* Use dict[key] instead of .get (incl. fixing typo). Use .values() instead of .items() when ignoring keys.
* Gotta use devices.get(prefix) since we use no prefix for the singleton elk instance
* fix requirement to use newer elkm1 that supports my changes for multiple elk devices
* Removed spurious + between a string broken between two lines for formatting; was failing a lint check about logging needing to use %s
* Remove REQUIREMENTS and DEPENDENCIES since those are now taken care of by the manifest.json file.
* Add configuration check that the prefixes are all unique
* Use new dependency 'getmac' to get mac address of Elk M1 controllers and use that for uniqueid if possible, else use None. Also removed some procedural checking of unique prefix since that's now handled at schema check time.
* Whitespace changes to make style checker happy and code more consistent
* Removed unused variable, added blank line
* Make getmac a requirement not dependency
I should've RTFM.
* ws only change; I really need to get Emacs to understand these style guidelines
* Ran script/gen_requirements_all.py; script/setup needed to be run so that was failing.
* More style check fixes and one bug fix.
* Incomplete set of changes from last push
* More conform-to-hass-style changes: use caps to start log message (and do not use function name even for debug message. And do not use string concatenation; prefer new-style .format.
* Style fixes.
* Switch back to using the prefix config field for setting the unique_id since the mac address approach has numerous shortcomings including: 1) new dependency; 2) lack of reliability; 3) doesn't work for serial connections; 4) breaks when a layer 4+ networking entity intermediates the elk m1 connection.
* Reran to update (removing getmac dependency)
* Skipped trailing ','; keep forgetting which languages are forgiving about this practical nicety of allowing trailing commas without changing the semantics.
* Validate uniqueness on lowercase versions of the prefix since we're gonna use .lower() on creating the entity id that has to be unique; do the _has_all_unique_prefixes check last so we get errors from the device schema before complaining about the uniqueness problem, if any
* Use vol.Lower to convert to lowercase instead of the map. Also fixed a pair of bugs for the alarm control panel display message service -- since data templates always generate strings, the values subject to range/set restrictions need to be coerced to their proper type before the check
* Fix some flake8 warnings.
* Fixed typo; it's Coerce not coerce.
* Use elkm1m_ string to start unique_id when and only when there is a non-empty prefix given; this enables backward compatibility to avoid a breaking change by letting the elkm1_ start to unique_id keep working exactly as it used to.
* minor comment tweak to force automation tests to run again since they failed for unrelated reasons last time
* There's actually been a 0.7.15 release which was meta-information and tidying only so we might as well depend on it
* Forgot to update this with gen_requirements_all.py
2019-07-27 08:36:09 +00:00
|
|
|
# unique_id starts with elkm1_ iff there is no prefix
|
|
|
|
# it starts with elkm1m_{prefix} iff there is a prefix
|
|
|
|
# this is to avoid a conflict between
|
|
|
|
# prefix=foo, name=bar (which would be elkm1_foo_bar)
|
|
|
|
# - and -
|
|
|
|
# prefix="", name="foo bar" (which would be elkm1_foo_bar also)
|
|
|
|
# we could have used elkm1__foo_bar for the latter, but that
|
|
|
|
# would have been a breaking change
|
|
|
|
if self._prefix != "":
|
2019-09-03 15:10:56 +00:00
|
|
|
uid_start = f"elkm1m_{self._prefix}"
|
Support multiple Elk instances (#23839)
* Support multiple Elk instances
* Allow more than one Elk M1 alarm system to be integrated into a single hass instance.
* Introduces new "devices" schema at the top level, each of which has
the prior configuration schema.
* Requires new version of elkm1, 0.7.14, that gwww and I just updated (thanks Glen!)
QUESTION: Should the "devices" section be optional to avoid breaking
old configuration files? I chose not to do that for simplicity and
because I was following the doorbird code which requires the "devices"
section for all configurations even with only one device.
* Fixed a bunch of hound-raised issues
Fixed issues raised by hound -- there was clearly
a tool I was supposed to run to get those warnings
before submitting the PR. Sorry!
Updated REQUIREMENTS.
* Fixed whitespace and line-length mistakes
Also fixed unused prefix local variable lint warning.
* Fixed missing blank line
* Fixed more lint warnings.
Not sure if I missed these on the first pass or if the linter stopped
after a certain number of warnings or something else.
Switched logging to use %d and %s instead of string concatenation (per
lint request and because I imagine it migth be better performing
in some (oldish, I presume) implementations of python.
* Fixed typo in last commit.
* Eliminate devices subsection in config schema
This eliminates the breaking change for configurations wanting a
singleton elk m1 instance (the majority of users, no doubt). I did
not do it like this before because I was following the lead of the
doorbird component which introduced a devices: section when moving
to support multiple doorbells. But Rohan Kapoor kindly pointed me
at the zoneminder component which sets the other (IMO) preferable
precedent. Will update the docs change shortly.
* Call async_add_entities once for all the elk controllers.
Just move async_add_entities() outside of the loops across the elk m1
controllers, so it's called once for each platform.
* Call async_add_entities only once per platform.
Move it to after the loop, so it's called only once
per platform even when there are multiple elk m1 controllers.
* Various improvements to be more idiomatic python + bug fixes
Thanks to Martin Hjelmare for the careful review and suggestions.
(All mistaken improvements and new bugs are my own.)
* Removed semicolon that lint caught.
* Idiomatic python improvements
Use dict.values() (instead of making it easier to add local looping variable
on the keys by using _, bar = ...items())
Use [] when the key is known to exist.
* Support multiple Elk instances
* Allow more than one Elk M1 alarm system to be integrated into a single hass instance.
* Introduces new "devices" schema at the top level, each of which has
the prior configuration schema.
* Requires new version of elkm1, 0.7.14, that gwww and I just updated (thanks Glen!)
QUESTION: Should the "devices" section be optional to avoid breaking
old configuration files? I chose not to do that for simplicity and
because I was following the doorbird code which requires the "devices"
section for all configurations even with only one device.
* Fixed a bunch of hound-raised issues
Fixed issues raised by hound -- there was clearly
a tool I was supposed to run to get those warnings
before submitting the PR. Sorry!
Updated REQUIREMENTS.
* Fixed whitespace and line-length mistakes
Also fixed unused prefix local variable lint warning.
* Fixed missing blank line
* Fixed more lint warnings.
Not sure if I missed these on the first pass or if the linter stopped
after a certain number of warnings or something else.
Switched logging to use %d and %s instead of string concatenation (per
lint request and because I imagine it migth be better performing
in some (oldish, I presume) implementations of python.
* Fixed typo in last commit.
* Eliminate devices subsection in config schema
This eliminates the breaking change for configurations wanting a
singleton elk m1 instance (the majority of users, no doubt). I did
not do it like this before because I was following the lead of the
doorbird component which introduced a devices: section when moving
to support multiple doorbells. But Rohan Kapoor kindly pointed me
at the zoneminder component which sets the other (IMO) preferable
precedent. Will update the docs change shortly.
* Call async_add_entities once for all the elk controllers.
Just move async_add_entities() outside of the loops across the elk m1
controllers, so it's called once for each platform.
* Call async_add_entities only once per platform.
Move it to after the loop, so it's called only once
per platform even when there are multiple elk m1 controllers.
* Various improvements to be more idiomatic python + bug fixes
Thanks to Martin Hjelmare for the careful review and suggestions.
(All mistaken improvements and new bugs are my own.)
* Removed semicolon that lint caught.
* Idiomatic python improvements
Use dict.values() (instead of making it easier to add local looping variable
on the keys by using _, bar = ...items())
Use [] when the key is known to exist.
* Use dict[key] instead of .get (incl. fixing typo). Use .values() instead of .items() when ignoring keys.
* Gotta use devices.get(prefix) since we use no prefix for the singleton elk instance
* fix requirement to use newer elkm1 that supports my changes for multiple elk devices
* Removed spurious + between a string broken between two lines for formatting; was failing a lint check about logging needing to use %s
* Remove REQUIREMENTS and DEPENDENCIES since those are now taken care of by the manifest.json file.
* Add configuration check that the prefixes are all unique
* Use new dependency 'getmac' to get mac address of Elk M1 controllers and use that for uniqueid if possible, else use None. Also removed some procedural checking of unique prefix since that's now handled at schema check time.
* Whitespace changes to make style checker happy and code more consistent
* Removed unused variable, added blank line
* Make getmac a requirement not dependency
I should've RTFM.
* ws only change; I really need to get Emacs to understand these style guidelines
* Ran script/gen_requirements_all.py; script/setup needed to be run so that was failing.
* More style check fixes and one bug fix.
* Incomplete set of changes from last push
* More conform-to-hass-style changes: use caps to start log message (and do not use function name even for debug message. And do not use string concatenation; prefer new-style .format.
* Style fixes.
* Switch back to using the prefix config field for setting the unique_id since the mac address approach has numerous shortcomings including: 1) new dependency; 2) lack of reliability; 3) doesn't work for serial connections; 4) breaks when a layer 4+ networking entity intermediates the elk m1 connection.
* Reran to update (removing getmac dependency)
* Skipped trailing ','; keep forgetting which languages are forgiving about this practical nicety of allowing trailing commas without changing the semantics.
* Validate uniqueness on lowercase versions of the prefix since we're gonna use .lower() on creating the entity id that has to be unique; do the _has_all_unique_prefixes check last so we get errors from the device schema before complaining about the uniqueness problem, if any
* Use vol.Lower to convert to lowercase instead of the map. Also fixed a pair of bugs for the alarm control panel display message service -- since data templates always generate strings, the values subject to range/set restrictions need to be coerced to their proper type before the check
* Fix some flake8 warnings.
* Fixed typo; it's Coerce not coerce.
* Use elkm1m_ string to start unique_id when and only when there is a non-empty prefix given; this enables backward compatibility to avoid a breaking change by letting the elkm1_ start to unique_id keep working exactly as it used to.
* minor comment tweak to force automation tests to run again since they failed for unrelated reasons last time
* There's actually been a 0.7.15 release which was meta-information and tidying only so we might as well depend on it
* Forgot to update this with gen_requirements_all.py
2019-07-27 08:36:09 +00:00
|
|
|
else:
|
2019-07-31 19:25:30 +00:00
|
|
|
uid_start = "elkm1"
|
2020-02-24 16:47:52 +00:00
|
|
|
self._unique_id = f"{uid_start}_{self._element.default_name('_')}".lower()
|
2018-10-07 19:45:36 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def name(self):
|
|
|
|
"""Name of the element."""
|
2019-09-03 15:10:56 +00:00
|
|
|
return f"{self._prefix}{self._element.name}"
|
2018-10-07 19:45:36 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def unique_id(self):
|
|
|
|
"""Return unique id of the element."""
|
|
|
|
return self._unique_id
|
|
|
|
|
|
|
|
@property
|
|
|
|
def should_poll(self) -> bool:
|
|
|
|
"""Don't poll this device."""
|
|
|
|
return False
|
|
|
|
|
|
|
|
@property
|
2021-03-11 15:51:03 +00:00
|
|
|
def extra_state_attributes(self):
|
2018-10-07 19:45:36 +00:00
|
|
|
"""Return the default attributes of the element."""
|
|
|
|
return {**self._element.as_dict(), **self.initial_attrs()}
|
|
|
|
|
|
|
|
@property
|
|
|
|
def available(self):
|
|
|
|
"""Is the entity available to be updated."""
|
|
|
|
return self._elk.is_connected()
|
|
|
|
|
|
|
|
def initial_attrs(self):
|
|
|
|
"""Return the underlying element's attributes as a dict."""
|
|
|
|
attrs = {}
|
2019-07-31 19:25:30 +00:00
|
|
|
attrs["index"] = self._element.index + 1
|
2018-10-07 19:45:36 +00:00
|
|
|
return attrs
|
|
|
|
|
|
|
|
def _element_changed(self, element, changeset):
|
2018-10-10 17:05:19 +00:00
|
|
|
pass
|
2018-10-07 19:45:36 +00:00
|
|
|
|
|
|
|
@callback
|
|
|
|
def _element_callback(self, element, changeset):
|
|
|
|
"""Handle callback from an Elk element that has changed."""
|
|
|
|
self._element_changed(element, changeset)
|
2020-03-27 20:38:35 +00:00
|
|
|
self.async_write_ha_state()
|
2018-10-07 19:45:36 +00:00
|
|
|
|
|
|
|
async def async_added_to_hass(self):
|
|
|
|
"""Register callback for ElkM1 changes and update entity state."""
|
|
|
|
self._element.add_callback(self._element_callback)
|
|
|
|
self._element_callback(self._element, {})
|
2020-03-27 20:38:35 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def device_info(self):
|
|
|
|
"""Device info connecting via the ElkM1 system."""
|
|
|
|
return {
|
|
|
|
"via_device": (DOMAIN, f"{self._prefix}_system"),
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
class ElkAttachedEntity(ElkEntity):
|
|
|
|
"""An elk entity that is attached to the elk system."""
|
|
|
|
|
|
|
|
@property
|
|
|
|
def device_info(self):
|
|
|
|
"""Device info for the underlying ElkM1 system."""
|
|
|
|
device_name = "ElkM1"
|
|
|
|
if self._prefix:
|
|
|
|
device_name += f" {self._prefix}"
|
|
|
|
return {
|
|
|
|
"name": device_name,
|
|
|
|
"identifiers": {(DOMAIN, f"{self._prefix}_system")},
|
|
|
|
"sw_version": self._elk.panel.elkm1_version,
|
|
|
|
"manufacturer": "ELK Products, Inc.",
|
|
|
|
"model": "M1",
|
|
|
|
}
|