mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 08:47:57 +00:00
Update ISY994 integration to be model agnostic (#85017)
This commit is contained in:
parent
5d6ca6dd44
commit
240e1fd8f3
@ -1,4 +1,4 @@
|
||||
"""Support the ISY-994 controllers."""
|
||||
"""Support the Universal Devices ISY/IoX controllers."""
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
@ -159,7 +159,7 @@ async def async_setup_entry(
|
||||
port = host.port or 443
|
||||
session = aiohttp_client.async_get_clientsession(hass)
|
||||
else:
|
||||
_LOGGER.error("The isy994 host value in configuration is invalid")
|
||||
_LOGGER.error("The ISY/IoX host value in configuration is invalid")
|
||||
return False
|
||||
|
||||
# Connect to ISY controller.
|
||||
@ -310,7 +310,7 @@ async def async_remove_config_entry_device(
|
||||
config_entry: config_entries.ConfigEntry,
|
||||
device_entry: dr.DeviceEntry,
|
||||
) -> bool:
|
||||
"""Remove isy994 config entry from a device."""
|
||||
"""Remove ISY config entry from a device."""
|
||||
return not device_entry.identifiers.intersection(
|
||||
(DOMAIN, unique_id)
|
||||
for unique_id in unique_ids_for_config_entry_id(hass, config_entry.entry_id)
|
||||
|
@ -1,4 +1,4 @@
|
||||
"""Support for ISY994 binary sensors."""
|
||||
"""Support for ISY binary sensors."""
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
@ -56,7 +56,7 @@ DEVICE_PARENT_REQUIRED = [
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
||||
) -> None:
|
||||
"""Set up the ISY994 binary sensor platform."""
|
||||
"""Set up the ISY binary sensor platform."""
|
||||
entities: list[
|
||||
ISYInsteonBinarySensorEntity
|
||||
| ISYBinarySensorEntity
|
||||
@ -219,7 +219,7 @@ def _detect_device_type_and_class(
|
||||
|
||||
|
||||
class ISYBinarySensorEntity(ISYNodeEntity, BinarySensorEntity):
|
||||
"""Representation of a basic ISY994 binary sensor device."""
|
||||
"""Representation of a basic ISY binary sensor device."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@ -227,13 +227,13 @@ class ISYBinarySensorEntity(ISYNodeEntity, BinarySensorEntity):
|
||||
force_device_class: BinarySensorDeviceClass | None = None,
|
||||
unknown_state: bool | None = None,
|
||||
) -> None:
|
||||
"""Initialize the ISY994 binary sensor device."""
|
||||
"""Initialize the ISY binary sensor device."""
|
||||
super().__init__(node)
|
||||
self._device_class = force_device_class
|
||||
|
||||
@property
|
||||
def is_on(self) -> bool | None:
|
||||
"""Get whether the ISY994 binary sensor device is on."""
|
||||
"""Get whether the ISY binary sensor device is on."""
|
||||
if self._node.status == ISY_VALUE_UNKNOWN:
|
||||
return None
|
||||
return bool(self._node.status)
|
||||
@ -248,7 +248,7 @@ class ISYBinarySensorEntity(ISYNodeEntity, BinarySensorEntity):
|
||||
|
||||
|
||||
class ISYInsteonBinarySensorEntity(ISYBinarySensorEntity):
|
||||
"""Representation of an ISY994 Insteon binary sensor device.
|
||||
"""Representation of an ISY Insteon binary sensor device.
|
||||
|
||||
Often times, a single device is represented by multiple nodes in the ISY,
|
||||
allowing for different nuances in how those devices report their on and
|
||||
@ -262,7 +262,7 @@ class ISYInsteonBinarySensorEntity(ISYBinarySensorEntity):
|
||||
force_device_class: BinarySensorDeviceClass | None = None,
|
||||
unknown_state: bool | None = None,
|
||||
) -> None:
|
||||
"""Initialize the ISY994 binary sensor device."""
|
||||
"""Initialize the ISY binary sensor device."""
|
||||
super().__init__(node, force_device_class)
|
||||
self._negative_node: Node | None = None
|
||||
self._heartbeat_device: ISYBinarySensorHeartbeat | None = None
|
||||
@ -374,7 +374,7 @@ class ISYInsteonBinarySensorEntity(ISYBinarySensorEntity):
|
||||
|
||||
@property
|
||||
def is_on(self) -> bool | None:
|
||||
"""Get whether the ISY994 binary sensor device is on.
|
||||
"""Get whether the ISY binary sensor device is on.
|
||||
|
||||
Insteon leak sensors set their primary node to On when the state is
|
||||
DRY, not WET, so we invert the binary state if the user indicates
|
||||
@ -391,7 +391,7 @@ class ISYInsteonBinarySensorEntity(ISYBinarySensorEntity):
|
||||
|
||||
|
||||
class ISYBinarySensorHeartbeat(ISYNodeEntity, BinarySensorEntity):
|
||||
"""Representation of the battery state of an ISY994 sensor."""
|
||||
"""Representation of the battery state of an ISY sensor."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@ -401,7 +401,7 @@ class ISYBinarySensorHeartbeat(ISYNodeEntity, BinarySensorEntity):
|
||||
| ISYBinarySensorHeartbeat
|
||||
| ISYBinarySensorProgramEntity,
|
||||
) -> None:
|
||||
"""Initialize the ISY994 binary sensor device.
|
||||
"""Initialize the ISY binary sensor device.
|
||||
|
||||
Computed state is set to UNKNOWN unless the ISY provided a valid
|
||||
state. See notes above regarding ISY Sensor status on ISY restart.
|
||||
@ -479,7 +479,7 @@ class ISYBinarySensorHeartbeat(ISYNodeEntity, BinarySensorEntity):
|
||||
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""Get whether the ISY994 binary sensor device is on.
|
||||
"""Get whether the ISY binary sensor device is on.
|
||||
|
||||
Note: This method will return false if the current state is UNKNOWN
|
||||
which occurs after a restart until the first heartbeat or control
|
||||
@ -501,7 +501,7 @@ class ISYBinarySensorHeartbeat(ISYNodeEntity, BinarySensorEntity):
|
||||
|
||||
|
||||
class ISYBinarySensorProgramEntity(ISYProgramEntity, BinarySensorEntity):
|
||||
"""Representation of an ISY994 binary sensor program.
|
||||
"""Representation of an ISY binary sensor program.
|
||||
|
||||
This does not need all of the subnode logic in the device version of binary
|
||||
sensors.
|
||||
@ -509,5 +509,5 @@ class ISYBinarySensorProgramEntity(ISYProgramEntity, BinarySensorEntity):
|
||||
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""Get whether the ISY994 binary sensor device is on."""
|
||||
"""Get whether the ISY binary sensor device is on."""
|
||||
return bool(self._node.status)
|
||||
|
@ -1,4 +1,4 @@
|
||||
"""Support for Insteon Thermostats via ISY994 Platform."""
|
||||
"""Support for Insteon Thermostats via ISY Platform."""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
@ -56,7 +56,7 @@ from .helpers import convert_isy_value_to_hass, migrate_old_unique_ids
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
||||
) -> None:
|
||||
"""Set up the ISY994 thermostat platform."""
|
||||
"""Set up the ISY thermostat platform."""
|
||||
entities = []
|
||||
|
||||
hass_isy_data = hass.data[ISY994_DOMAIN][entry.entry_id]
|
||||
@ -68,7 +68,7 @@ async def async_setup_entry(
|
||||
|
||||
|
||||
class ISYThermostatEntity(ISYNodeEntity, ClimateEntity):
|
||||
"""Representation of an ISY994 thermostat entity."""
|
||||
"""Representation of an ISY thermostat entity."""
|
||||
|
||||
_attr_hvac_modes = ISY_HVAC_MODES
|
||||
_attr_precision = PRECISION_TENTHS
|
||||
|
@ -1,4 +1,4 @@
|
||||
"""Config flow for Universal Devices ISY994 integration."""
|
||||
"""Config flow for Universal Devices ISY/IoX integration."""
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Mapping
|
||||
@ -79,7 +79,7 @@ async def validate_input(
|
||||
port = host.port or HTTPS_PORT
|
||||
session = aiohttp_client.async_get_clientsession(hass)
|
||||
else:
|
||||
_LOGGER.error("The isy994 host value in configuration is invalid")
|
||||
_LOGGER.error("The ISY/IoX host value in configuration is invalid")
|
||||
raise InvalidHost
|
||||
|
||||
# Connect to ISY controller.
|
||||
@ -114,12 +114,12 @@ async def validate_input(
|
||||
|
||||
|
||||
class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
"""Handle a config flow for Universal Devices ISY994."""
|
||||
"""Handle a config flow for Universal Devices ISY/IoX."""
|
||||
|
||||
VERSION = 1
|
||||
|
||||
def __init__(self) -> None:
|
||||
"""Initialize the isy994 config flow."""
|
||||
"""Initialize the ISY/IoX config flow."""
|
||||
self.discovered_conf: dict[str, str] = {}
|
||||
self._existing_entry: config_entries.ConfigEntry | None = None
|
||||
|
||||
@ -200,7 +200,7 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
raise AbortFlow("already_configured")
|
||||
|
||||
async def async_step_dhcp(self, discovery_info: dhcp.DhcpServiceInfo) -> FlowResult:
|
||||
"""Handle a discovered isy994 via dhcp."""
|
||||
"""Handle a discovered ISY/IoX device via dhcp."""
|
||||
friendly_name = discovery_info.hostname
|
||||
if friendly_name.startswith("polisy"):
|
||||
url = f"http://{discovery_info.ip}:8080"
|
||||
@ -221,7 +221,7 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
return await self.async_step_user()
|
||||
|
||||
async def async_step_ssdp(self, discovery_info: ssdp.SsdpServiceInfo) -> FlowResult:
|
||||
"""Handle a discovered isy994."""
|
||||
"""Handle a discovered ISY/IoX Device."""
|
||||
friendly_name = discovery_info.upnp[ssdp.ATTR_UPNP_FRIENDLY_NAME]
|
||||
url = discovery_info.ssdp_location
|
||||
assert isinstance(url, str)
|
||||
@ -300,7 +300,7 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
|
||||
|
||||
class OptionsFlowHandler(config_entries.OptionsFlow):
|
||||
"""Handle a option flow for isy994."""
|
||||
"""Handle a option flow for ISY/IoX."""
|
||||
|
||||
def __init__(self, config_entry: config_entries.ConfigEntry) -> None:
|
||||
"""Initialize options flow."""
|
||||
|
@ -1,4 +1,4 @@
|
||||
"""Constants for the ISY994 Platform."""
|
||||
"""Constants for the ISY Platform."""
|
||||
import logging
|
||||
|
||||
from homeassistant.components.binary_sensor import BinarySensorDeviceClass
|
||||
|
@ -1,4 +1,4 @@
|
||||
"""Support for ISY994 covers."""
|
||||
"""Support for ISY covers."""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any, cast
|
||||
@ -30,7 +30,7 @@ from .helpers import migrate_old_unique_ids
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
||||
) -> None:
|
||||
"""Set up the ISY994 cover platform."""
|
||||
"""Set up the ISY cover platform."""
|
||||
hass_isy_data = hass.data[ISY994_DOMAIN][entry.entry_id]
|
||||
entities: list[ISYCoverEntity | ISYCoverProgramEntity] = []
|
||||
for node in hass_isy_data[ISY994_NODES][COVER]:
|
||||
@ -44,7 +44,7 @@ async def async_setup_entry(
|
||||
|
||||
|
||||
class ISYCoverEntity(ISYNodeEntity, CoverEntity):
|
||||
"""Representation of an ISY994 cover device."""
|
||||
"""Representation of an ISY cover device."""
|
||||
|
||||
_attr_supported_features = (
|
||||
CoverEntityFeature.OPEN
|
||||
@ -63,19 +63,19 @@ class ISYCoverEntity(ISYNodeEntity, CoverEntity):
|
||||
|
||||
@property
|
||||
def is_closed(self) -> bool | None:
|
||||
"""Get whether the ISY994 cover device is closed."""
|
||||
"""Get whether the ISY cover device is closed."""
|
||||
if self._node.status == ISY_VALUE_UNKNOWN:
|
||||
return None
|
||||
return bool(self._node.status == 0)
|
||||
|
||||
async def async_open_cover(self, **kwargs: Any) -> None:
|
||||
"""Send the open cover command to the ISY994 cover device."""
|
||||
"""Send the open cover command to the ISY cover device."""
|
||||
val = 100 if self._node.uom == UOM_BARRIER else None
|
||||
if not await self._node.turn_on(val=val):
|
||||
_LOGGER.error("Unable to open the cover")
|
||||
|
||||
async def async_close_cover(self, **kwargs: Any) -> None:
|
||||
"""Send the close cover command to the ISY994 cover device."""
|
||||
"""Send the close cover command to the ISY cover device."""
|
||||
if not await self._node.turn_off():
|
||||
_LOGGER.error("Unable to close the cover")
|
||||
|
||||
@ -89,19 +89,19 @@ class ISYCoverEntity(ISYNodeEntity, CoverEntity):
|
||||
|
||||
|
||||
class ISYCoverProgramEntity(ISYProgramEntity, CoverEntity):
|
||||
"""Representation of an ISY994 cover program."""
|
||||
"""Representation of an ISY cover program."""
|
||||
|
||||
@property
|
||||
def is_closed(self) -> bool:
|
||||
"""Get whether the ISY994 cover program is closed."""
|
||||
"""Get whether the ISY cover program is closed."""
|
||||
return bool(self._node.status)
|
||||
|
||||
async def async_open_cover(self, **kwargs: Any) -> None:
|
||||
"""Send the open cover command to the ISY994 cover program."""
|
||||
"""Send the open cover command to the ISY cover program."""
|
||||
if not await self._actions.run_then():
|
||||
_LOGGER.error("Unable to open the cover")
|
||||
|
||||
async def async_close_cover(self, **kwargs: Any) -> None:
|
||||
"""Send the close cover command to the ISY994 cover program."""
|
||||
"""Send the close cover command to the ISY cover program."""
|
||||
if not await self._actions.run_else():
|
||||
_LOGGER.error("Unable to close the cover")
|
||||
|
@ -33,7 +33,7 @@ from .const import DOMAIN
|
||||
|
||||
|
||||
class ISYEntity(Entity):
|
||||
"""Representation of an ISY994 device."""
|
||||
"""Representation of an ISY device."""
|
||||
|
||||
_name: str | None = None
|
||||
_attr_should_poll = False
|
||||
@ -56,12 +56,12 @@ class ISYEntity(Entity):
|
||||
|
||||
@callback
|
||||
def async_on_update(self, event: NodeProperty) -> None:
|
||||
"""Handle the update event from the ISY994 Node."""
|
||||
"""Handle the update event from the ISY Node."""
|
||||
self.async_write_ha_state()
|
||||
|
||||
@callback
|
||||
def async_on_control(self, event: NodeProperty) -> None:
|
||||
"""Handle a control event from the ISY994 Node."""
|
||||
"""Handle a control event from the ISY Node."""
|
||||
event_data = {
|
||||
"entity_id": self.entity_id,
|
||||
"control": event.control,
|
||||
@ -239,10 +239,10 @@ class ISYNodeEntity(ISYEntity):
|
||||
|
||||
|
||||
class ISYProgramEntity(ISYEntity):
|
||||
"""Representation of an ISY994 program base."""
|
||||
"""Representation of an ISY program base."""
|
||||
|
||||
def __init__(self, name: str, status: Any | None, actions: Program = None) -> None:
|
||||
"""Initialize the ISY994 program-based entity."""
|
||||
"""Initialize the ISY program-based entity."""
|
||||
super().__init__(status)
|
||||
self._name = name
|
||||
self._actions = actions
|
||||
|
@ -1,4 +1,4 @@
|
||||
"""Support for ISY994 fans."""
|
||||
"""Support for ISY fans."""
|
||||
from __future__ import annotations
|
||||
|
||||
import math
|
||||
@ -26,7 +26,7 @@ SPEED_RANGE = (1, 255) # off is not included
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
||||
) -> None:
|
||||
"""Set up the ISY994 fan platform."""
|
||||
"""Set up the ISY fan platform."""
|
||||
hass_isy_data = hass.data[ISY994_DOMAIN][entry.entry_id]
|
||||
entities: list[ISYFanEntity | ISYFanProgramEntity] = []
|
||||
|
||||
@ -41,7 +41,7 @@ async def async_setup_entry(
|
||||
|
||||
|
||||
class ISYFanEntity(ISYNodeEntity, FanEntity):
|
||||
"""Representation of an ISY994 fan device."""
|
||||
"""Representation of an ISY fan device."""
|
||||
|
||||
_attr_supported_features = FanEntityFeature.SET_SPEED
|
||||
|
||||
@ -67,7 +67,7 @@ class ISYFanEntity(ISYNodeEntity, FanEntity):
|
||||
return bool(self._node.status != 0)
|
||||
|
||||
async def async_set_percentage(self, percentage: int) -> None:
|
||||
"""Set node to speed percentage for the ISY994 fan device."""
|
||||
"""Set node to speed percentage for the ISY fan device."""
|
||||
if percentage == 0:
|
||||
await self._node.turn_off()
|
||||
return
|
||||
@ -82,16 +82,16 @@ class ISYFanEntity(ISYNodeEntity, FanEntity):
|
||||
preset_mode: str | None = None,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
"""Send the turn on command to the ISY994 fan device."""
|
||||
"""Send the turn on command to the ISY fan device."""
|
||||
await self.async_set_percentage(percentage or 67)
|
||||
|
||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||
"""Send the turn off command to the ISY994 fan device."""
|
||||
"""Send the turn off command to the ISY fan device."""
|
||||
await self._node.turn_off()
|
||||
|
||||
|
||||
class ISYFanProgramEntity(ISYProgramEntity, FanEntity):
|
||||
"""Representation of an ISY994 fan program."""
|
||||
"""Representation of an ISY fan program."""
|
||||
|
||||
@property
|
||||
def percentage(self) -> int | None:
|
||||
@ -111,7 +111,7 @@ class ISYFanProgramEntity(ISYProgramEntity, FanEntity):
|
||||
return bool(self._node.status != 0)
|
||||
|
||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||
"""Send the turn on command to ISY994 fan program."""
|
||||
"""Send the turn on command to ISY fan program."""
|
||||
if not await self._actions.run_then():
|
||||
_LOGGER.error("Unable to turn off the fan")
|
||||
|
||||
@ -121,6 +121,6 @@ class ISYFanProgramEntity(ISYProgramEntity, FanEntity):
|
||||
preset_mode: str | None = None,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
"""Send the turn off command to ISY994 fan program."""
|
||||
"""Send the turn off command to ISY fan program."""
|
||||
if not await self._actions.run_else():
|
||||
_LOGGER.error("Unable to turn on the fan")
|
||||
|
@ -1,4 +1,4 @@
|
||||
"""Sorting helpers for ISY994 device classifications."""
|
||||
"""Sorting helpers for ISY device classifications."""
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Sequence
|
||||
@ -327,7 +327,7 @@ def _categorize_nodes(
|
||||
|
||||
|
||||
def _categorize_programs(hass_isy_data: dict, programs: Programs) -> None:
|
||||
"""Categorize the ISY994 programs."""
|
||||
"""Categorize the ISY programs."""
|
||||
for platform in PROGRAM_PLATFORMS:
|
||||
folder = programs.get_by_name(f"{DEFAULT_PROGRAM_STRING}{platform}")
|
||||
if not folder:
|
||||
@ -368,7 +368,7 @@ def _categorize_programs(hass_isy_data: dict, programs: Programs) -> None:
|
||||
def _categorize_variables(
|
||||
hass_isy_data: dict, variables: Variables, identifier: str
|
||||
) -> None:
|
||||
"""Gather the ISY994 Variables to be added as sensors."""
|
||||
"""Gather the ISY Variables to be added as sensors."""
|
||||
try:
|
||||
var_to_add = [
|
||||
(vtype, vname, vid)
|
||||
|
@ -1,4 +1,4 @@
|
||||
"""Support for ISY994 lights."""
|
||||
"""Support for ISY lights."""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any, cast
|
||||
@ -30,7 +30,7 @@ ATTR_LAST_BRIGHTNESS = "last_brightness"
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
||||
) -> None:
|
||||
"""Set up the ISY994 light platform."""
|
||||
"""Set up the ISY light platform."""
|
||||
hass_isy_data = hass.data[ISY994_DOMAIN][entry.entry_id]
|
||||
isy_options = entry.options
|
||||
restore_light_state = isy_options.get(CONF_RESTORE_LIGHT_STATE, False)
|
||||
@ -45,27 +45,27 @@ async def async_setup_entry(
|
||||
|
||||
|
||||
class ISYLightEntity(ISYNodeEntity, LightEntity, RestoreEntity):
|
||||
"""Representation of an ISY994 light device."""
|
||||
"""Representation of an ISY light device."""
|
||||
|
||||
_attr_color_mode = ColorMode.BRIGHTNESS
|
||||
_attr_supported_color_modes = {ColorMode.BRIGHTNESS}
|
||||
|
||||
def __init__(self, node: Node, restore_light_state: bool) -> None:
|
||||
"""Initialize the ISY994 light device."""
|
||||
"""Initialize the ISY light device."""
|
||||
super().__init__(node)
|
||||
self._last_brightness: int | None = None
|
||||
self._restore_light_state = restore_light_state
|
||||
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""Get whether the ISY994 light is on."""
|
||||
"""Get whether the ISY light is on."""
|
||||
if self._node.status == ISY_VALUE_UNKNOWN:
|
||||
return False
|
||||
return int(self._node.status) != 0
|
||||
|
||||
@property
|
||||
def brightness(self) -> int | None:
|
||||
"""Get the brightness of the ISY994 light."""
|
||||
"""Get the brightness of the ISY light."""
|
||||
if self._node.status == ISY_VALUE_UNKNOWN:
|
||||
return None
|
||||
# Special Case for ISY Z-Wave Devices using % instead of 0-255:
|
||||
@ -74,14 +74,14 @@ class ISYLightEntity(ISYNodeEntity, LightEntity, RestoreEntity):
|
||||
return int(self._node.status)
|
||||
|
||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||
"""Send the turn off command to the ISY994 light device."""
|
||||
"""Send the turn off command to the ISY light device."""
|
||||
self._last_brightness = self.brightness
|
||||
if not await self._node.turn_off():
|
||||
_LOGGER.debug("Unable to turn off light")
|
||||
|
||||
@callback
|
||||
def async_on_update(self, event: NodeProperty) -> None:
|
||||
"""Save brightness in the update event from the ISY994 Node."""
|
||||
"""Save brightness in the update event from the ISY Node."""
|
||||
if self._node.status not in (0, ISY_VALUE_UNKNOWN):
|
||||
self._last_brightness = self._node.status
|
||||
if self._node.uom == UOM_PERCENTAGE:
|
||||
@ -91,7 +91,7 @@ class ISYLightEntity(ISYNodeEntity, LightEntity, RestoreEntity):
|
||||
super().async_on_update(event)
|
||||
|
||||
async def async_turn_on(self, brightness: int | None = None, **kwargs: Any) -> None:
|
||||
"""Send the turn on command to the ISY994 light device."""
|
||||
"""Send the turn on command to the ISY light device."""
|
||||
if self._restore_light_state and brightness is None and self._last_brightness:
|
||||
brightness = self._last_brightness
|
||||
# Special Case for ISY Z-Wave Devices using % instead of 0-255:
|
||||
|
@ -1,4 +1,4 @@
|
||||
"""Support for ISY994 locks."""
|
||||
"""Support for ISY locks."""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
@ -20,7 +20,7 @@ VALUE_TO_STATE = {0: False, 100: True}
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
||||
) -> None:
|
||||
"""Set up the ISY994 lock platform."""
|
||||
"""Set up the ISY lock platform."""
|
||||
hass_isy_data = hass.data[ISY994_DOMAIN][entry.entry_id]
|
||||
entities: list[ISYLockEntity | ISYLockProgramEntity] = []
|
||||
for node in hass_isy_data[ISY994_NODES][LOCK]:
|
||||
@ -34,7 +34,7 @@ async def async_setup_entry(
|
||||
|
||||
|
||||
class ISYLockEntity(ISYNodeEntity, LockEntity):
|
||||
"""Representation of an ISY994 lock device."""
|
||||
"""Representation of an ISY lock device."""
|
||||
|
||||
@property
|
||||
def is_locked(self) -> bool | None:
|
||||
@ -44,12 +44,12 @@ class ISYLockEntity(ISYNodeEntity, LockEntity):
|
||||
return VALUE_TO_STATE.get(self._node.status)
|
||||
|
||||
async def async_lock(self, **kwargs: Any) -> None:
|
||||
"""Send the lock command to the ISY994 device."""
|
||||
"""Send the lock command to the ISY device."""
|
||||
if not await self._node.secure_lock():
|
||||
_LOGGER.error("Unable to lock device")
|
||||
|
||||
async def async_unlock(self, **kwargs: Any) -> None:
|
||||
"""Send the unlock command to the ISY994 device."""
|
||||
"""Send the unlock command to the ISY device."""
|
||||
if not await self._node.secure_unlock():
|
||||
_LOGGER.error("Unable to lock device")
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"domain": "isy994",
|
||||
"name": "Universal Devices ISY994",
|
||||
"name": "Universal Devices ISY/IoX",
|
||||
"integration_type": "hub",
|
||||
"documentation": "https://www.home-assistant.io/integrations/isy994",
|
||||
"requirements": ["pyisy==3.0.10"],
|
||||
@ -13,9 +13,17 @@
|
||||
}
|
||||
],
|
||||
"dhcp": [
|
||||
{ "registered_devices": true },
|
||||
{ "hostname": "isy*", "macaddress": "0021B9*" },
|
||||
{ "hostname": "polisy*", "macaddress": "000DB9*" }
|
||||
{
|
||||
"registered_devices": true
|
||||
},
|
||||
{
|
||||
"hostname": "isy*",
|
||||
"macaddress": "0021B9*"
|
||||
},
|
||||
{
|
||||
"hostname": "polisy*",
|
||||
"macaddress": "000DB9*"
|
||||
}
|
||||
],
|
||||
"iot_class": "local_push",
|
||||
"loggers": ["pyisy"]
|
||||
|
@ -1,4 +1,4 @@
|
||||
"""Support for ISY994 sensors."""
|
||||
"""Support for ISY sensors."""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any, cast
|
||||
@ -81,7 +81,7 @@ ISY_CONTROL_TO_ENTITY_CATEGORY = {
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
||||
) -> None:
|
||||
"""Set up the ISY994 sensor platform."""
|
||||
"""Set up the ISY sensor platform."""
|
||||
hass_isy_data = hass.data[ISY994_DOMAIN][entry.entry_id]
|
||||
entities: list[ISYSensorEntity | ISYSensorVariableEntity] = []
|
||||
|
||||
@ -112,7 +112,7 @@ async def async_setup_entry(
|
||||
|
||||
|
||||
class ISYSensorEntity(ISYNodeEntity, SensorEntity):
|
||||
"""Representation of an ISY994 sensor device."""
|
||||
"""Representation of an ISY sensor device."""
|
||||
|
||||
@property
|
||||
def target(self) -> Node | NodeProperty | None:
|
||||
@ -126,7 +126,7 @@ class ISYSensorEntity(ISYNodeEntity, SensorEntity):
|
||||
|
||||
@property
|
||||
def raw_unit_of_measurement(self) -> dict | str | None:
|
||||
"""Get the raw unit of measurement for the ISY994 sensor device."""
|
||||
"""Get the raw unit of measurement for the ISY sensor device."""
|
||||
if self.target is None:
|
||||
return None
|
||||
|
||||
@ -148,7 +148,7 @@ class ISYSensorEntity(ISYNodeEntity, SensorEntity):
|
||||
|
||||
@property
|
||||
def native_value(self) -> float | int | str | None:
|
||||
"""Get the state of the ISY994 sensor device."""
|
||||
"""Get the state of the ISY sensor device."""
|
||||
if self.target is None:
|
||||
return None
|
||||
|
||||
@ -199,10 +199,10 @@ class ISYSensorEntity(ISYNodeEntity, SensorEntity):
|
||||
|
||||
|
||||
class ISYAuxSensorEntity(ISYSensorEntity):
|
||||
"""Representation of an ISY994 aux sensor device."""
|
||||
"""Representation of an ISY aux sensor device."""
|
||||
|
||||
def __init__(self, node: Node, control: str, enabled_default: bool) -> None:
|
||||
"""Initialize the ISY994 aux sensor."""
|
||||
"""Initialize the ISY aux sensor."""
|
||||
super().__init__(node)
|
||||
self._control = control
|
||||
self._attr_entity_registry_enabled_default = enabled_default
|
||||
@ -239,10 +239,10 @@ class ISYAuxSensorEntity(ISYSensorEntity):
|
||||
|
||||
|
||||
class ISYSensorVariableEntity(ISYEntity, SensorEntity):
|
||||
"""Representation of an ISY994 variable as a sensor device."""
|
||||
"""Representation of an ISY variable as a sensor device."""
|
||||
|
||||
def __init__(self, vname: str, vobj: object) -> None:
|
||||
"""Initialize the ISY994 binary sensor program."""
|
||||
"""Initialize the ISY binary sensor program."""
|
||||
super().__init__(vobj)
|
||||
self._name = vname
|
||||
|
||||
|
@ -300,7 +300,7 @@ def async_setup_services(hass: HomeAssistant) -> None: # noqa: C901
|
||||
|
||||
_LOGGER.debug(
|
||||
(
|
||||
"Cleaning up ISY994 Entities and devices: Config Entries: %s, Current"
|
||||
"Cleaning up ISY Entities and devices: Config Entries: %s, Current"
|
||||
" Entries: %s, Extra Entries Removed: %s"
|
||||
),
|
||||
len(config_ids),
|
||||
@ -309,7 +309,7 @@ def async_setup_services(hass: HomeAssistant) -> None: # noqa: C901
|
||||
)
|
||||
|
||||
async def async_reload_config_entries(service: ServiceCall) -> None:
|
||||
"""Trigger a reload of all ISY994 config entries."""
|
||||
"""Trigger a reload of all ISY config entries."""
|
||||
for config_entry_id in hass.data[DOMAIN]:
|
||||
hass.async_create_task(hass.config_entries.async_reload(config_entry_id))
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Describes the ISY994-specific services available
|
||||
# Describes the ISY-specific services available
|
||||
|
||||
# Note: controlling many entity_ids with one call is not recommended since it may result in
|
||||
# flooding the ISY with requests. To control multiple devices with a service call
|
||||
@ -119,9 +119,9 @@ set_zwave_parameter:
|
||||
- "2"
|
||||
- "4"
|
||||
rename_node:
|
||||
name: Rename Node on ISY994
|
||||
name: Rename Node on ISY
|
||||
description: >-
|
||||
Rename a node or group (scene) on the ISY994. Note: this will not automatically change the Home Assistant Entity Name or Entity ID to match.
|
||||
Rename a node or group (scene) on the ISY. Note: this will not automatically change the Home Assistant Entity Name or Entity ID to match.
|
||||
The entity name and ID will only be updated after calling `isy994.reload` or restarting Home Assistant, and ONLY IF you have not already customized the
|
||||
name within Home Assistant.
|
||||
target:
|
||||
@ -130,7 +130,7 @@ rename_node:
|
||||
fields:
|
||||
name:
|
||||
name: New Name
|
||||
description: The new name to use within the ISY994.
|
||||
description: The new name to use within the ISY.
|
||||
required: true
|
||||
example: "Front Door Light"
|
||||
selector:
|
||||
@ -291,7 +291,7 @@ run_network_resource:
|
||||
text:
|
||||
reload:
|
||||
name: Reload
|
||||
description: Reload the ISY994 connection(s) without restarting Home Assistant. Use to pick up new devices that have been added or changed on the ISY.
|
||||
description: Reload the ISY connection(s) without restarting Home Assistant. Use to pick up new devices that have been added or changed on the ISY.
|
||||
cleanup_entities:
|
||||
name: Cleanup entities
|
||||
description: Cleanup old entities and devices no longer used by the ISY994 integrations. Useful if you've removed devices from the ISY or changed the options in the configuration to exclude additional items.
|
||||
description: Cleanup old entities and devices no longer used by the ISY integration. Useful if you've removed devices from the ISY or changed the options in the configuration to exclude additional items.
|
||||
|
@ -1,4 +1,4 @@
|
||||
"""Support for ISY994 switches."""
|
||||
"""Support for ISY switches."""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
@ -18,7 +18,7 @@ from .helpers import migrate_old_unique_ids
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
||||
) -> None:
|
||||
"""Set up the ISY994 switch platform."""
|
||||
"""Set up the ISY switch platform."""
|
||||
hass_isy_data = hass.data[ISY994_DOMAIN][entry.entry_id]
|
||||
entities: list[ISYSwitchProgramEntity | ISYSwitchEntity] = []
|
||||
for node in hass_isy_data[ISY994_NODES][SWITCH]:
|
||||
@ -32,22 +32,22 @@ async def async_setup_entry(
|
||||
|
||||
|
||||
class ISYSwitchEntity(ISYNodeEntity, SwitchEntity):
|
||||
"""Representation of an ISY994 switch device."""
|
||||
"""Representation of an ISY switch device."""
|
||||
|
||||
@property
|
||||
def is_on(self) -> bool | None:
|
||||
"""Get whether the ISY994 device is in the on state."""
|
||||
"""Get whether the ISY device is in the on state."""
|
||||
if self._node.status == ISY_VALUE_UNKNOWN:
|
||||
return None
|
||||
return bool(self._node.status)
|
||||
|
||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||
"""Send the turn off command to the ISY994 switch."""
|
||||
"""Send the turn off command to the ISY switch."""
|
||||
if not await self._node.turn_off():
|
||||
_LOGGER.debug("Unable to turn off switch")
|
||||
|
||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||
"""Send the turn on command to the ISY994 switch."""
|
||||
"""Send the turn on command to the ISY switch."""
|
||||
if not await self._node.turn_on():
|
||||
_LOGGER.debug("Unable to turn on switch")
|
||||
|
||||
@ -60,20 +60,20 @@ class ISYSwitchEntity(ISYNodeEntity, SwitchEntity):
|
||||
|
||||
|
||||
class ISYSwitchProgramEntity(ISYProgramEntity, SwitchEntity):
|
||||
"""A representation of an ISY994 program switch."""
|
||||
"""A representation of an ISY program switch."""
|
||||
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""Get whether the ISY994 switch program is on."""
|
||||
"""Get whether the ISY switch program is on."""
|
||||
return bool(self._node.status)
|
||||
|
||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||
"""Send the turn on command to the ISY994 switch program."""
|
||||
"""Send the turn on command to the ISY switch program."""
|
||||
if not await self._actions.run_then():
|
||||
_LOGGER.error("Unable to turn on switch")
|
||||
|
||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||
"""Send the turn off command to the ISY994 switch program."""
|
||||
"""Send the turn off command to the ISY switch program."""
|
||||
if not await self._actions.run_else():
|
||||
_LOGGER.error("Unable to turn off switch")
|
||||
|
||||
|
@ -2543,7 +2543,7 @@
|
||||
"iot_class": "cloud_polling"
|
||||
},
|
||||
"isy994": {
|
||||
"name": "Universal Devices ISY994",
|
||||
"name": "Universal Devices ISY/IoX",
|
||||
"integration_type": "hub",
|
||||
"config_flow": true,
|
||||
"iot_class": "local_push"
|
||||
|
@ -1 +1 @@
|
||||
"""Tests for the Universal Devices ISY994 integration."""
|
||||
"""Tests for the Universal Devices ISY/IoX integration."""
|
||||
|
@ -1,4 +1,4 @@
|
||||
"""Test the Universal Devices ISY994 config flow."""
|
||||
"""Test the Universal Devices ISY/IoX config flow."""
|
||||
import re
|
||||
from unittest.mock import patch
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
"""Test ISY994 system health."""
|
||||
"""Test ISY system health."""
|
||||
import asyncio
|
||||
from unittest.mock import Mock
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user