Skip to content

Commit

Permalink
iAlarm XR integration refinements (home-assistant#72616)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
bigmoby authored May 30, 2022
1 parent 75669db commit 6e355e1
Show file tree
Hide file tree
Showing 11 changed files with 32 additions and 57 deletions.
6 changes: 3 additions & 3 deletions homeassistant/components/ialarm_xr/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
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]
Expand Down Expand Up @@ -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

Expand All @@ -90,7 +90,7 @@ def _update_data(self) -> None:
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."""
Expand Down
22 changes: 19 additions & 3 deletions homeassistant/components/ialarm_xr/alarm_control_panel.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -15,6 +23,13 @@
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
Expand All @@ -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 = (
Expand All @@ -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",
Expand All @@ -48,7 +64,7 @@ def __init__(self, coordinator: IAlarmXRDataUpdateCoordinator) -> None:
@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."""
Expand Down
4 changes: 2 additions & 2 deletions homeassistant/components/ialarm_xr/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,13 @@ async def async_step_user(
"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"
Expand Down
15 changes: 0 additions & 15 deletions homeassistant/components/ialarm_xr/const.py
Original file line number Diff line number Diff line change
@@ -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,
}
4 changes: 2 additions & 2 deletions homeassistant/components/ialarm_xr/manifest.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
1 change: 1 addition & 0 deletions homeassistant/components/ialarm_xr/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
1 change: 1 addition & 0 deletions homeassistant/components/ialarm_xr/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
},
"error": {
"cannot_connect": "Failed to connect",
"timeout": "Timeout establishing connection",
"unknown": "Unexpected error"
},
"step": {
Expand Down
2 changes: 1 addition & 1 deletion requirements_all.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion requirements_test_all.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
22 changes: 2 additions & 20 deletions tests/components/ialarm_xr/test_config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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):
Expand All @@ -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):
Expand Down
10 changes: 0 additions & 10 deletions tests/components/ialarm_xr/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down

0 comments on commit 6e355e1

Please sign in to comment.