Update ISY994 integration to be model agnostic (#85017)

This commit is contained in:
shbatm 2023-01-02 18:22:40 -06:00 committed by GitHub
parent 5d6ca6dd44
commit 240e1fd8f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 111 additions and 103 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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."""

View File

@ -1,4 +1,4 @@
"""Constants for the ISY994 Platform."""
"""Constants for the ISY Platform."""
import logging
from homeassistant.components.binary_sensor import BinarySensorDeviceClass

View File

@ -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")

View File

@ -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

View File

@ -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")

View File

@ -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)

View File

@ -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:

View File

@ -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")

View File

@ -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"]

View File

@ -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

View File

@ -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))

View File

@ -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.

View File

@ -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")

View File

@ -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"

View File

@ -1 +1 @@
"""Tests for the Universal Devices ISY994 integration."""
"""Tests for the Universal Devices ISY/IoX integration."""

View File

@ -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

View File

@ -1,4 +1,4 @@
"""Test ISY994 system health."""
"""Test ISY system health."""
import asyncio
from unittest.mock import Mock