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:
parent
75669dba6e
commit
6e355e1074
11 changed files with 32 additions and 57 deletions
|
@ -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."""
|
||||
|
|
|
@ -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."""
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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": {
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
},
|
||||
"error": {
|
||||
"cannot_connect": "Failed to connect",
|
||||
"timeout": "Timeout establishing connection",
|
||||
"unknown": "Unexpected error"
|
||||
},
|
||||
"step": {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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")
|
||||
|
|
Loading…
Add table
Reference in a new issue