From 6e355e1074b3c72f88008ea74ccd8e93571e1bbd Mon Sep 17 00:00:00 2001 From: BigMoby Date: Mon, 30 May 2022 08:26:05 +0200 Subject: [PATCH] iAlarm XR integration refinements (#72616) * fixing after MartinHjelmare review * fixing after MartinHjelmare review conversion alarm state to hass state * fixing after MartinHjelmare review conversion alarm state to hass state * manage the status in the alarm control * simplyfing return function --- .../components/ialarm_xr/__init__.py | 6 ++--- .../ialarm_xr/alarm_control_panel.py | 22 ++++++++++++++++--- .../components/ialarm_xr/config_flow.py | 4 ++-- homeassistant/components/ialarm_xr/const.py | 15 ------------- .../components/ialarm_xr/manifest.json | 4 ++-- .../components/ialarm_xr/strings.json | 1 + .../components/ialarm_xr/translations/en.json | 1 + requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- .../components/ialarm_xr/test_config_flow.py | 22 ++----------------- tests/components/ialarm_xr/test_init.py | 10 --------- 11 files changed, 32 insertions(+), 57 deletions(-) diff --git a/homeassistant/components/ialarm_xr/__init__.py b/homeassistant/components/ialarm_xr/__init__.py index 9a41b5ebab7..193bbe4fffc 100644 --- a/homeassistant/components/ialarm_xr/__init__.py +++ b/homeassistant/components/ialarm_xr/__init__.py @@ -24,7 +24,7 @@ from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryNotReady from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed -from .const import DOMAIN, IALARMXR_TO_HASS +from .const import DOMAIN from .utils import async_get_ialarmxr_mac PLATFORMS = [Platform.ALARM_CONTROL_PANEL] @@ -74,7 +74,7 @@ class IAlarmXRDataUpdateCoordinator(DataUpdateCoordinator): def __init__(self, hass: HomeAssistant, ialarmxr: IAlarmXR, mac: str) -> None: """Initialize global iAlarm data updater.""" self.ialarmxr: IAlarmXR = ialarmxr - self.state: str | None = None + self.state: int | None = None self.host: str = ialarmxr.host self.mac: str = mac @@ -90,7 +90,7 @@ class IAlarmXRDataUpdateCoordinator(DataUpdateCoordinator): status: int = self.ialarmxr.get_status() _LOGGER.debug("iAlarmXR status: %s", status) - self.state = IALARMXR_TO_HASS.get(status) + self.state = status async def _async_update_data(self) -> None: """Fetch data from iAlarmXR.""" diff --git a/homeassistant/components/ialarm_xr/alarm_control_panel.py b/homeassistant/components/ialarm_xr/alarm_control_panel.py index 7b47ce3d7fa..b64edb74391 100644 --- a/homeassistant/components/ialarm_xr/alarm_control_panel.py +++ b/homeassistant/components/ialarm_xr/alarm_control_panel.py @@ -1,11 +1,19 @@ """Interfaces with iAlarmXR control panels.""" from __future__ import annotations +from pyialarmxr import IAlarmXR + from homeassistant.components.alarm_control_panel import ( AlarmControlPanelEntity, AlarmControlPanelEntityFeature, ) from homeassistant.config_entries import ConfigEntry +from homeassistant.const import ( + STATE_ALARM_ARMED_AWAY, + STATE_ALARM_ARMED_HOME, + STATE_ALARM_DISARMED, + STATE_ALARM_TRIGGERED, +) from homeassistant.core import HomeAssistant from homeassistant.helpers import device_registry from homeassistant.helpers.entity import DeviceInfo @@ -15,6 +23,13 @@ from homeassistant.helpers.update_coordinator import CoordinatorEntity from . import IAlarmXRDataUpdateCoordinator from .const import DOMAIN +IALARMXR_TO_HASS = { + IAlarmXR.ARMED_AWAY: STATE_ALARM_ARMED_AWAY, + IAlarmXR.ARMED_STAY: STATE_ALARM_ARMED_HOME, + IAlarmXR.DISARMED: STATE_ALARM_DISARMED, + IAlarmXR.TRIGGERED: STATE_ALARM_TRIGGERED, +} + async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback @@ -24,7 +39,9 @@ async def async_setup_entry( async_add_entities([IAlarmXRPanel(coordinator)]) -class IAlarmXRPanel(CoordinatorEntity, AlarmControlPanelEntity): +class IAlarmXRPanel( + CoordinatorEntity[IAlarmXRDataUpdateCoordinator], AlarmControlPanelEntity +): """Representation of an iAlarmXR device.""" _attr_supported_features = ( @@ -37,7 +54,6 @@ class IAlarmXRPanel(CoordinatorEntity, AlarmControlPanelEntity): def __init__(self, coordinator: IAlarmXRDataUpdateCoordinator) -> None: """Initialize the alarm panel.""" super().__init__(coordinator) - self.coordinator: IAlarmXRDataUpdateCoordinator = coordinator self._attr_unique_id = coordinator.mac self._attr_device_info = DeviceInfo( manufacturer="Antifurto365 - Meian", @@ -48,7 +64,7 @@ class IAlarmXRPanel(CoordinatorEntity, AlarmControlPanelEntity): @property def state(self) -> str | None: """Return the state of the device.""" - return self.coordinator.state + return IALARMXR_TO_HASS.get(self.coordinator.state) def alarm_disarm(self, code: str | None = None) -> None: """Send disarm command.""" diff --git a/homeassistant/components/ialarm_xr/config_flow.py b/homeassistant/components/ialarm_xr/config_flow.py index 06509a82eb5..2a9cc406733 100644 --- a/homeassistant/components/ialarm_xr/config_flow.py +++ b/homeassistant/components/ialarm_xr/config_flow.py @@ -72,13 +72,13 @@ class IAlarmConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): "IAlarmXRGenericException with message: [ %s ]", ialarmxr_exception.message, ) - errors["base"] = "unknown" + errors["base"] = "cannot_connect" except IAlarmXRSocketTimeoutException as ialarmxr_socket_timeout_exception: _LOGGER.debug( "IAlarmXRSocketTimeoutException with message: [ %s ]", ialarmxr_socket_timeout_exception.message, ) - errors["base"] = "unknown" + errors["base"] = "timeout" except Exception: # pylint: disable=broad-except _LOGGER.exception("Unexpected exception") errors["base"] = "unknown" diff --git a/homeassistant/components/ialarm_xr/const.py b/homeassistant/components/ialarm_xr/const.py index a208f5290b6..12122277340 100644 --- a/homeassistant/components/ialarm_xr/const.py +++ b/homeassistant/components/ialarm_xr/const.py @@ -1,18 +1,3 @@ """Constants for the iAlarmXR integration.""" -from pyialarmxr import IAlarmXR - -from homeassistant.const import ( - STATE_ALARM_ARMED_AWAY, - STATE_ALARM_ARMED_HOME, - STATE_ALARM_DISARMED, - STATE_ALARM_TRIGGERED, -) DOMAIN = "ialarm_xr" - -IALARMXR_TO_HASS = { - IAlarmXR.ARMED_AWAY: STATE_ALARM_ARMED_AWAY, - IAlarmXR.ARMED_STAY: STATE_ALARM_ARMED_HOME, - IAlarmXR.DISARMED: STATE_ALARM_DISARMED, - IAlarmXR.TRIGGERED: STATE_ALARM_TRIGGERED, -} diff --git a/homeassistant/components/ialarm_xr/manifest.json b/homeassistant/components/ialarm_xr/manifest.json index 4861e9c901f..f863f360242 100644 --- a/homeassistant/components/ialarm_xr/manifest.json +++ b/homeassistant/components/ialarm_xr/manifest.json @@ -1,8 +1,8 @@ { "domain": "ialarm_xr", "name": "Antifurto365 iAlarmXR", - "documentation": "https://www.home-assistant.io/integrations/ialarmxr", - "requirements": ["pyialarmxr==1.0.13"], + "documentation": "https://www.home-assistant.io/integrations/ialarm_xr", + "requirements": ["pyialarmxr==1.0.18"], "codeowners": ["@bigmoby"], "config_flow": true, "iot_class": "cloud_polling", diff --git a/homeassistant/components/ialarm_xr/strings.json b/homeassistant/components/ialarm_xr/strings.json index 1650ae28c84..ea4f91fdbb9 100644 --- a/homeassistant/components/ialarm_xr/strings.json +++ b/homeassistant/components/ialarm_xr/strings.json @@ -12,6 +12,7 @@ }, "error": { "cannot_connect": "[%key:common::config_flow::error::cannot_connect%]", + "timeout": "[%key:common::config_flow::error::timeout_connect%]", "unknown": "[%key:common::config_flow::error::unknown%]" }, "abort": { diff --git a/homeassistant/components/ialarm_xr/translations/en.json b/homeassistant/components/ialarm_xr/translations/en.json index bf2bf989dcd..be59a5a1dc4 100644 --- a/homeassistant/components/ialarm_xr/translations/en.json +++ b/homeassistant/components/ialarm_xr/translations/en.json @@ -5,6 +5,7 @@ }, "error": { "cannot_connect": "Failed to connect", + "timeout": "Timeout establishing connection", "unknown": "Unexpected error" }, "step": { diff --git a/requirements_all.txt b/requirements_all.txt index 53e6e28788e..c28967caa33 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1550,7 +1550,7 @@ pyhomeworks==0.0.6 pyialarm==1.9.0 # homeassistant.components.ialarm_xr -pyialarmxr==1.0.13 +pyialarmxr==1.0.18 # homeassistant.components.icloud pyicloud==1.0.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 2688d1aa5c1..3025404fc62 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1038,7 +1038,7 @@ pyhomematic==0.1.77 pyialarm==1.9.0 # homeassistant.components.ialarm_xr -pyialarmxr==1.0.13 +pyialarmxr==1.0.18 # homeassistant.components.icloud pyicloud==1.0.0 diff --git a/tests/components/ialarm_xr/test_config_flow.py b/tests/components/ialarm_xr/test_config_flow.py index 22a70bda067..804249dd5cb 100644 --- a/tests/components/ialarm_xr/test_config_flow.py +++ b/tests/components/ialarm_xr/test_config_flow.py @@ -56,24 +56,6 @@ async def test_form(hass): assert len(mock_setup_entry.mock_calls) == 1 -async def test_form_cannot_connect(hass): - """Test we handle cannot connect error.""" - result = await hass.config_entries.flow.async_init( - DOMAIN, context={"source": config_entries.SOURCE_USER} - ) - - with patch( - "homeassistant.components.ialarm_xr.config_flow.IAlarmXR.get_mac", - side_effect=ConnectionError, - ): - result2 = await hass.config_entries.flow.async_configure( - result["flow_id"], TEST_DATA - ) - - assert result2["type"] == data_entry_flow.RESULT_TYPE_FORM - assert result2["errors"] == {"base": "cannot_connect"} - - async def test_form_exception(hass): """Test we handle unknown exception.""" result = await hass.config_entries.flow.async_init( @@ -125,7 +107,7 @@ async def test_form_cannot_connect_throwing_socket_timeout_exception(hass): ) assert result2["type"] == data_entry_flow.RESULT_TYPE_FORM - assert result2["errors"] == {"base": "unknown"} + assert result2["errors"] == {"base": "timeout"} async def test_form_cannot_connect_throwing_generic_exception(hass): @@ -143,7 +125,7 @@ async def test_form_cannot_connect_throwing_generic_exception(hass): ) assert result2["type"] == data_entry_flow.RESULT_TYPE_FORM - assert result2["errors"] == {"base": "unknown"} + assert result2["errors"] == {"base": "cannot_connect"} async def test_form_already_exists(hass): diff --git a/tests/components/ialarm_xr/test_init.py b/tests/components/ialarm_xr/test_init.py index 8486b7049e6..0898b6bebf8 100644 --- a/tests/components/ialarm_xr/test_init.py +++ b/tests/components/ialarm_xr/test_init.py @@ -48,16 +48,6 @@ async def test_setup_entry(hass, ialarmxr_api, mock_config_entry): assert mock_config_entry.state is ConfigEntryState.LOADED -async def test_setup_not_ready(hass, ialarmxr_api, mock_config_entry): - """Test setup failed because we can't connect to the alarm system.""" - ialarmxr_api.return_value.get_mac = Mock(side_effect=ConnectionError) - - mock_config_entry.add_to_hass(hass) - assert not await hass.config_entries.async_setup(mock_config_entry.entry_id) - await hass.async_block_till_done() - assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY - - async def test_unload_entry(hass, ialarmxr_api, mock_config_entry): """Test being able to unload an entry.""" ialarmxr_api.return_value.get_mac = Mock(return_value="00:00:54:12:34:56")