mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 08:47:57 +00:00
Add support for ISY994 Variables as Sensors (#35453)
* Update tests, add missing constant * ISY994 Add support for ISY Variables as sensors
This commit is contained in:
parent
f302c6fd65
commit
799cdbe64d
@ -20,19 +20,22 @@ from .const import (
|
||||
CONF_RESTORE_LIGHT_STATE,
|
||||
CONF_SENSOR_STRING,
|
||||
CONF_TLS_VER,
|
||||
CONF_VAR_SENSOR_STRING,
|
||||
DEFAULT_IGNORE_STRING,
|
||||
DEFAULT_RESTORE_LIGHT_STATE,
|
||||
DEFAULT_SENSOR_STRING,
|
||||
DEFAULT_VAR_SENSOR_STRING,
|
||||
DOMAIN,
|
||||
ISY994_ISY,
|
||||
ISY994_NODES,
|
||||
ISY994_PROGRAMS,
|
||||
ISY994_VARIABLES,
|
||||
MANUFACTURER,
|
||||
SUPPORTED_PLATFORMS,
|
||||
SUPPORTED_PROGRAM_PLATFORMS,
|
||||
UNDO_UPDATE_LISTENER,
|
||||
)
|
||||
from .helpers import _categorize_nodes, _categorize_programs
|
||||
from .helpers import _categorize_nodes, _categorize_programs, _categorize_variables
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema(
|
||||
{
|
||||
@ -48,6 +51,9 @@ CONFIG_SCHEMA = vol.Schema(
|
||||
vol.Optional(
|
||||
CONF_SENSOR_STRING, default=DEFAULT_SENSOR_STRING
|
||||
): cv.string,
|
||||
vol.Optional(
|
||||
CONF_VAR_SENSOR_STRING, default=DEFAULT_VAR_SENSOR_STRING
|
||||
): cv.string,
|
||||
vol.Required(
|
||||
CONF_RESTORE_LIGHT_STATE, default=DEFAULT_RESTORE_LIGHT_STATE
|
||||
): bool,
|
||||
@ -111,6 +117,8 @@ async def async_setup_entry(
|
||||
for platform in SUPPORTED_PROGRAM_PLATFORMS:
|
||||
hass_isy_data[ISY994_PROGRAMS][platform] = []
|
||||
|
||||
hass_isy_data[ISY994_VARIABLES] = []
|
||||
|
||||
isy_config = entry.data
|
||||
isy_options = entry.options
|
||||
|
||||
@ -123,6 +131,9 @@ async def async_setup_entry(
|
||||
tls_version = isy_config.get(CONF_TLS_VER)
|
||||
ignore_identifier = isy_options.get(CONF_IGNORE_STRING, DEFAULT_IGNORE_STRING)
|
||||
sensor_identifier = isy_options.get(CONF_SENSOR_STRING, DEFAULT_SENSOR_STRING)
|
||||
variable_identifier = isy_options.get(
|
||||
CONF_VAR_SENSOR_STRING, DEFAULT_VAR_SENSOR_STRING
|
||||
)
|
||||
|
||||
if host.scheme == "http":
|
||||
https = False
|
||||
@ -153,6 +164,7 @@ async def async_setup_entry(
|
||||
|
||||
_categorize_nodes(hass_isy_data, isy.nodes, ignore_identifier, sensor_identifier)
|
||||
_categorize_programs(hass_isy_data, isy.programs)
|
||||
_categorize_variables(hass_isy_data, isy.variables, variable_identifier)
|
||||
|
||||
# Dump ISY Clock Information. Future: Add ISY as sensor to Hass with attrs
|
||||
_LOGGER.info(repr(isy.clock))
|
||||
|
@ -15,10 +15,12 @@ from .const import (
|
||||
CONF_RESTORE_LIGHT_STATE,
|
||||
CONF_SENSOR_STRING,
|
||||
CONF_TLS_VER,
|
||||
CONF_VAR_SENSOR_STRING,
|
||||
DEFAULT_IGNORE_STRING,
|
||||
DEFAULT_RESTORE_LIGHT_STATE,
|
||||
DEFAULT_SENSOR_STRING,
|
||||
DEFAULT_TLS_VERSION,
|
||||
DEFAULT_VAR_SENSOR_STRING,
|
||||
)
|
||||
from .const import DOMAIN # pylint:disable=unused-import
|
||||
|
||||
@ -154,11 +156,15 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
|
||||
)
|
||||
ignore_string = options.get(CONF_IGNORE_STRING, DEFAULT_IGNORE_STRING)
|
||||
sensor_string = options.get(CONF_SENSOR_STRING, DEFAULT_SENSOR_STRING)
|
||||
var_sensor_string = options.get(
|
||||
CONF_VAR_SENSOR_STRING, DEFAULT_VAR_SENSOR_STRING
|
||||
)
|
||||
|
||||
options_schema = vol.Schema(
|
||||
{
|
||||
vol.Optional(CONF_IGNORE_STRING, default=ignore_string): str,
|
||||
vol.Optional(CONF_SENSOR_STRING, default=sensor_string): str,
|
||||
vol.Optional(CONF_VAR_SENSOR_STRING, default=var_sensor_string): str,
|
||||
vol.Required(
|
||||
CONF_RESTORE_LIGHT_STATE, default=restore_light_state
|
||||
): bool,
|
||||
|
@ -98,6 +98,7 @@ MANUFACTURER = "Universal Devices, Inc"
|
||||
|
||||
CONF_IGNORE_STRING = "ignore_string"
|
||||
CONF_SENSOR_STRING = "sensor_string"
|
||||
CONF_VAR_SENSOR_STRING = "variable_sensor_string"
|
||||
CONF_TLS_VER = "tls"
|
||||
CONF_RESTORE_LIGHT_STATE = "restore_light_state"
|
||||
|
||||
@ -106,6 +107,7 @@ DEFAULT_SENSOR_STRING = "sensor"
|
||||
DEFAULT_RESTORE_LIGHT_STATE = False
|
||||
DEFAULT_TLS_VERSION = 1.1
|
||||
DEFAULT_PROGRAM_STRING = "HA."
|
||||
DEFAULT_VAR_SENSOR_STRING = "HA."
|
||||
|
||||
KEY_ACTIONS = "actions"
|
||||
KEY_STATUS = "status"
|
||||
@ -122,6 +124,7 @@ ISY_GROUP_PLATFORM = SWITCH
|
||||
ISY994_ISY = "isy"
|
||||
ISY994_NODES = "isy994_nodes"
|
||||
ISY994_PROGRAMS = "isy994_programs"
|
||||
ISY994_VARIABLES = "isy994_variables"
|
||||
|
||||
FILTER_UOM = "uom"
|
||||
FILTER_STATES = "states"
|
||||
|
@ -10,6 +10,7 @@ from pyisy.constants import (
|
||||
)
|
||||
from pyisy.nodes import Group, Node, Nodes
|
||||
from pyisy.programs import Programs
|
||||
from pyisy.variables import Variables
|
||||
|
||||
from homeassistant.components.binary_sensor import DOMAIN as BINARY_SENSOR
|
||||
from homeassistant.components.climate.const import DOMAIN as CLIMATE
|
||||
@ -31,6 +32,7 @@ from .const import (
|
||||
FILTER_ZWAVE_CAT,
|
||||
ISY994_NODES,
|
||||
ISY994_PROGRAMS,
|
||||
ISY994_VARIABLES,
|
||||
ISY_GROUP_PLATFORM,
|
||||
KEY_ACTIONS,
|
||||
KEY_STATUS,
|
||||
@ -345,6 +347,23 @@ def _categorize_programs(hass_isy_data: dict, programs: Programs) -> None:
|
||||
hass_isy_data[ISY994_PROGRAMS][platform].append(entity)
|
||||
|
||||
|
||||
def _categorize_variables(
|
||||
hass_isy_data: dict, variables: Variables, identifier: str
|
||||
) -> None:
|
||||
"""Gather the ISY994 Variables to be added as sensors."""
|
||||
try:
|
||||
var_to_add = [
|
||||
(vtype, vname, vid)
|
||||
for (vtype, vname, vid) in variables.children
|
||||
if identifier in vname
|
||||
]
|
||||
except KeyError as err:
|
||||
_LOGGER.error("Error adding ISY Variables: %s", err)
|
||||
return
|
||||
for vtype, vname, vid in var_to_add:
|
||||
hass_isy_data[ISY994_VARIABLES].append((vname, variables[vtype][vid]))
|
||||
|
||||
|
||||
async def migrate_old_unique_ids(
|
||||
hass: HomeAssistantType, platform: str, devices: Optional[List[Any]]
|
||||
) -> None:
|
||||
|
@ -1,5 +1,5 @@
|
||||
"""Support for ISY994 sensors."""
|
||||
from typing import Callable
|
||||
from typing import Callable, Dict
|
||||
|
||||
from pyisy.constants import ISY_VALUE_UNKNOWN
|
||||
|
||||
@ -12,10 +12,11 @@ from .const import (
|
||||
_LOGGER,
|
||||
DOMAIN as ISY994_DOMAIN,
|
||||
ISY994_NODES,
|
||||
ISY994_VARIABLES,
|
||||
UOM_FRIENDLY_NAME,
|
||||
UOM_TO_STATES,
|
||||
)
|
||||
from .entity import ISYNodeEntity
|
||||
from .entity import ISYEntity, ISYNodeEntity
|
||||
from .helpers import migrate_old_unique_ids
|
||||
|
||||
|
||||
@ -32,6 +33,9 @@ async def async_setup_entry(
|
||||
_LOGGER.debug("Loading %s", node.name)
|
||||
devices.append(ISYSensorEntity(node))
|
||||
|
||||
for vname, vobj in hass_isy_data[ISY994_VARIABLES]:
|
||||
devices.append(ISYSensorVariableEntity(vname, vobj))
|
||||
|
||||
await migrate_old_unique_ids(hass, SENSOR, devices)
|
||||
async_add_entities(devices)
|
||||
|
||||
@ -84,3 +88,27 @@ class ISYSensorEntity(ISYNodeEntity):
|
||||
if raw_units in (TEMP_FAHRENHEIT, TEMP_CELSIUS):
|
||||
return self.hass.config.units.temperature_unit
|
||||
return raw_units
|
||||
|
||||
|
||||
class ISYSensorVariableEntity(ISYEntity):
|
||||
"""Representation of an ISY994 variable as a sensor device."""
|
||||
|
||||
def __init__(self, vname: str, vobj: object) -> None:
|
||||
"""Initialize the ISY994 binary sensor program."""
|
||||
super().__init__(vobj)
|
||||
self._name = vname
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
"""Return the state of the variable."""
|
||||
return self.value
|
||||
|
||||
@property
|
||||
def device_state_attributes(self) -> Dict:
|
||||
"""Get the state attributes for the device."""
|
||||
return {"init_value": int(self._node.init)}
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
"""Return the icon."""
|
||||
return "mdi:counter"
|
||||
|
@ -27,10 +27,11 @@
|
||||
"step": {
|
||||
"init": {
|
||||
"title": "ISY994 Options",
|
||||
"description": "Set the options for the ISY Integration: \n • Node Sensor String: Any device or folder that contains 'Node Sensor String' in the name will be treated as a sensor or binary sensor. \n • Ignore String: Any device with 'Ignore String' in the name will be ignored. \n • Restore Light Brightness: If enabled, the previous brightness will be restored when turning on a light instead of the device's built-in On-Level.",
|
||||
"description": "Set the options for the ISY Integration: \n • Node Sensor String: Any device or folder that contains 'Node Sensor String' in the name will be treated as a sensor or binary sensor. \n • Ignore String: Any device with 'Ignore String' in the name will be ignored. \n • Variable Sensor String: Any variable that contains 'Variable Sensor String' will be added as a sensor. \n • Restore Light Brightness: If enabled, the previous brightness will be restored when turning on a light instead of the device's built-in On-Level.",
|
||||
"data": {
|
||||
"sensor_string": "Node Sensor String",
|
||||
"ignore_string": "Ignore String",
|
||||
"variable_sensor_string": "Variable Sensor String",
|
||||
"restore_light_state": "Restore Light Brightness"
|
||||
}
|
||||
}
|
||||
|
@ -27,10 +27,11 @@
|
||||
"step": {
|
||||
"init": {
|
||||
"title": "ISY994 Options",
|
||||
"description": "Set the options for the ISY Integration: \n • Node Sensor String: Any device or folder that contains 'Node Sensor String' in the name will be treated as a sensor or binary sensor. \n • Ignore String: Any device with 'Ignore String' in the name will be ignored. \n • Restore Light Brightness: If enabled, the previous brightness will be restored when turning on a light instead of the device's built-in On-Level.",
|
||||
"description": "Set the options for the ISY Integration: \n • Node Sensor String: Any device or folder that contains 'Node Sensor String' in the name will be treated as a sensor or binary sensor. \n • Ignore String: Any device with 'Ignore String' in the name will be ignored. \n • Variable Sensor String: Any variable that contains 'Variable Sensor String' will be added as a sensor. \n • Restore Light Brightness: If enabled, the previous brightness will be restored when turning on a light instead of the device's built-in On-Level.",
|
||||
"data": {
|
||||
"sensor_string": "Node Sensor String",
|
||||
"ignore_string": "Ignore String",
|
||||
"variable_sensor_string" : "Variable Sensor String",
|
||||
"restore_light_state": "Restore Light Brightness"
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ from homeassistant.components.isy994.const import (
|
||||
CONF_RESTORE_LIGHT_STATE,
|
||||
CONF_SENSOR_STRING,
|
||||
CONF_TLS_VER,
|
||||
CONF_VAR_SENSOR_STRING,
|
||||
DOMAIN,
|
||||
)
|
||||
from homeassistant.config_entries import SOURCE_IMPORT
|
||||
@ -25,6 +26,7 @@ MOCK_TLS_VERSION = 1.2
|
||||
MOCK_IGNORE_STRING = "{IGNOREME}"
|
||||
MOCK_RESTORE_LIGHT_STATE = True
|
||||
MOCK_SENSOR_STRING = "IMASENSOR"
|
||||
MOCK_VARIABLE_SENSOR_STRING = "HomeAssistant."
|
||||
|
||||
MOCK_USER_INPUT = {
|
||||
"host": f"http://{MOCK_HOSTNAME}",
|
||||
@ -45,6 +47,7 @@ MOCK_IMPORT_FULL_CONFIG = {
|
||||
CONF_RESTORE_LIGHT_STATE: MOCK_RESTORE_LIGHT_STATE,
|
||||
CONF_SENSOR_STRING: MOCK_SENSOR_STRING,
|
||||
CONF_TLS_VER: MOCK_TLS_VERSION,
|
||||
CONF_VAR_SENSOR_STRING: MOCK_VARIABLE_SENSOR_STRING,
|
||||
}
|
||||
|
||||
MOCK_DEVICE_NAME = "Name of the device"
|
||||
@ -203,4 +206,5 @@ async def test_import_flow_all_fields(hass: HomeAssistantType) -> None:
|
||||
assert result["data"][CONF_IGNORE_STRING] == MOCK_IGNORE_STRING
|
||||
assert result["data"][CONF_RESTORE_LIGHT_STATE] == MOCK_RESTORE_LIGHT_STATE
|
||||
assert result["data"][CONF_SENSOR_STRING] == MOCK_SENSOR_STRING
|
||||
assert result["data"][CONF_VAR_SENSOR_STRING] == MOCK_VARIABLE_SENSOR_STRING
|
||||
assert result["data"][CONF_TLS_VER] == MOCK_TLS_VERSION
|
||||
|
Loading…
x
Reference in New Issue
Block a user