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
This commit is contained in:
BigMoby 2022-05-30 08:26:05 +02:00 committed by GitHub
parent 75669dba6e
commit 6e355e1074
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 32 additions and 57 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -5,6 +5,7 @@
},
"error": {
"cannot_connect": "Failed to connect",
"timeout": "Timeout establishing connection",
"unknown": "Unexpected error"
},
"step": {

View file

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

View file

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

View file

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

View file

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