Fix Freebox Home alarm & improve platform tests (#103475)
* Fix Freebox Home alarm * Add trigger feature test & fix * FreeboxCallSensor: Add test for missing coverage of new call * Use generator Co-authored-by: Martin Hjelmare <marhje52@gmail.com> * Add test for arm_home feature (questions about the check) * Stay focus on alam tests * can_arm_home ==> if _command_arm_home * Use one liner for supported_features * Add idle state * Fix rebase --------- Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
parent
6d7df5ae13
commit
923c13907c
12 changed files with 186 additions and 151 deletions
|
@ -1,5 +1,4 @@
|
||||||
"""Support for Freebox alarms."""
|
"""Support for Freebox alarms."""
|
||||||
import logging
|
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from homeassistant.components.alarm_control_panel import (
|
from homeassistant.components.alarm_control_panel import (
|
||||||
|
@ -9,7 +8,7 @@ from homeassistant.components.alarm_control_panel import (
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
STATE_ALARM_ARMED_AWAY,
|
STATE_ALARM_ARMED_AWAY,
|
||||||
STATE_ALARM_ARMED_NIGHT,
|
STATE_ALARM_ARMED_HOME,
|
||||||
STATE_ALARM_ARMING,
|
STATE_ALARM_ARMING,
|
||||||
STATE_ALARM_DISARMED,
|
STATE_ALARM_DISARMED,
|
||||||
STATE_ALARM_TRIGGERED,
|
STATE_ALARM_TRIGGERED,
|
||||||
|
@ -25,16 +24,14 @@ FREEBOX_TO_STATUS = {
|
||||||
"alarm1_arming": STATE_ALARM_ARMING,
|
"alarm1_arming": STATE_ALARM_ARMING,
|
||||||
"alarm2_arming": STATE_ALARM_ARMING,
|
"alarm2_arming": STATE_ALARM_ARMING,
|
||||||
"alarm1_armed": STATE_ALARM_ARMED_AWAY,
|
"alarm1_armed": STATE_ALARM_ARMED_AWAY,
|
||||||
"alarm2_armed": STATE_ALARM_ARMED_NIGHT,
|
"alarm2_armed": STATE_ALARM_ARMED_HOME,
|
||||||
"alarm1_alert_timer": STATE_ALARM_TRIGGERED,
|
"alarm1_alert_timer": STATE_ALARM_TRIGGERED,
|
||||||
"alarm2_alert_timer": STATE_ALARM_TRIGGERED,
|
"alarm2_alert_timer": STATE_ALARM_TRIGGERED,
|
||||||
"alert": STATE_ALARM_TRIGGERED,
|
"alert": STATE_ALARM_TRIGGERED,
|
||||||
|
"idle": STATE_ALARM_DISARMED,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(
|
async def async_setup_entry(
|
||||||
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
||||||
) -> None:
|
) -> None:
|
||||||
|
@ -76,63 +73,33 @@ class FreeboxAlarm(FreeboxHomeEntity, AlarmControlPanelEntity):
|
||||||
self._command_state = self.get_command_id(
|
self._command_state = self.get_command_id(
|
||||||
node["type"]["endpoints"], "signal", "state"
|
node["type"]["endpoints"], "signal", "state"
|
||||||
)
|
)
|
||||||
self._set_features(self._router.home_devices[self._id])
|
|
||||||
|
self._attr_supported_features = (
|
||||||
|
AlarmControlPanelEntityFeature.ARM_AWAY
|
||||||
|
| (AlarmControlPanelEntityFeature.ARM_HOME if self._command_arm_home else 0)
|
||||||
|
| AlarmControlPanelEntityFeature.TRIGGER
|
||||||
|
)
|
||||||
|
|
||||||
async def async_alarm_disarm(self, code: str | None = None) -> None:
|
async def async_alarm_disarm(self, code: str | None = None) -> None:
|
||||||
"""Send disarm command."""
|
"""Send disarm command."""
|
||||||
if await self.set_home_endpoint_value(self._command_disarm):
|
await self.set_home_endpoint_value(self._command_disarm)
|
||||||
self._set_state(STATE_ALARM_DISARMED)
|
|
||||||
|
|
||||||
async def async_alarm_arm_away(self, code: str | None = None) -> None:
|
async def async_alarm_arm_away(self, code: str | None = None) -> None:
|
||||||
"""Send arm away command."""
|
"""Send arm away command."""
|
||||||
if await self.set_home_endpoint_value(self._command_arm_away):
|
await self.set_home_endpoint_value(self._command_arm_away)
|
||||||
self._set_state(STATE_ALARM_ARMING)
|
|
||||||
|
|
||||||
async def async_alarm_arm_home(self, code: str | None = None) -> None:
|
async def async_alarm_arm_home(self, code: str | None = None) -> None:
|
||||||
"""Send arm home command."""
|
"""Send arm home command."""
|
||||||
if await self.set_home_endpoint_value(self._command_arm_home):
|
await self.set_home_endpoint_value(self._command_arm_home)
|
||||||
self._set_state(STATE_ALARM_ARMING)
|
|
||||||
|
|
||||||
async def async_alarm_trigger(self, code: str | None = None) -> None:
|
async def async_alarm_trigger(self, code: str | None = None) -> None:
|
||||||
"""Send alarm trigger command."""
|
"""Send alarm trigger command."""
|
||||||
if await self.set_home_endpoint_value(self._command_trigger):
|
await self.set_home_endpoint_value(self._command_trigger)
|
||||||
self._set_state(STATE_ALARM_TRIGGERED)
|
|
||||||
|
|
||||||
async def async_update_signal(self):
|
async def async_update(self) -> None:
|
||||||
"""Update signal."""
|
|
||||||
state = await self.get_home_endpoint_value(self._command_state)
|
|
||||||
if state:
|
|
||||||
self._set_state(state)
|
|
||||||
|
|
||||||
def _set_features(self, node: dict[str, Any]) -> None:
|
|
||||||
"""Add alarm features."""
|
|
||||||
# Search if the arm home feature is present => has an "alarm2" endpoint
|
|
||||||
can_arm_home = False
|
|
||||||
for nodeid, local_node in self._router.home_devices.items():
|
|
||||||
if nodeid == local_node["id"]:
|
|
||||||
alarm2 = next(
|
|
||||||
filter(
|
|
||||||
lambda x: (x["name"] == "alarm2" and x["ep_type"] == "signal"),
|
|
||||||
local_node["show_endpoints"],
|
|
||||||
),
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
if alarm2:
|
|
||||||
can_arm_home = alarm2["value"]
|
|
||||||
break
|
|
||||||
|
|
||||||
if can_arm_home:
|
|
||||||
self._attr_supported_features = (
|
|
||||||
AlarmControlPanelEntityFeature.ARM_AWAY
|
|
||||||
| AlarmControlPanelEntityFeature.ARM_HOME
|
|
||||||
)
|
|
||||||
|
|
||||||
else:
|
|
||||||
self._attr_supported_features = AlarmControlPanelEntityFeature.ARM_AWAY
|
|
||||||
|
|
||||||
def _set_state(self, state: str) -> None:
|
|
||||||
"""Update state."""
|
"""Update state."""
|
||||||
self._attr_state = FREEBOX_TO_STATUS.get(state)
|
state: str | None = await self.get_home_endpoint_value(self._command_state)
|
||||||
if not self._attr_state:
|
if state:
|
||||||
self._attr_state = STATE_ALARM_DISARMED
|
self._attr_state = FREEBOX_TO_STATUS.get(state)
|
||||||
self.async_write_ha_state()
|
else:
|
||||||
|
self._attr_state = None
|
||||||
|
|
|
@ -131,13 +131,14 @@ class FreeboxHomeEntity(Entity):
|
||||||
def get_value(self, ep_type: str, name: str):
|
def get_value(self, ep_type: str, name: str):
|
||||||
"""Get the value."""
|
"""Get the value."""
|
||||||
node = next(
|
node = next(
|
||||||
filter(
|
(
|
||||||
lambda x: (x["name"] == name and x["ep_type"] == ep_type),
|
endpoint
|
||||||
self._node["show_endpoints"],
|
for endpoint in self._node["show_endpoints"]
|
||||||
|
if endpoint["name"] == name and endpoint["ep_type"] == ep_type
|
||||||
),
|
),
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
if not node:
|
if node is None:
|
||||||
_LOGGER.warning(
|
_LOGGER.warning(
|
||||||
"The Freebox Home device has no node value for: %s/%s", ep_type, name
|
"The Freebox Home device has no node value for: %s/%s", ep_type, name
|
||||||
)
|
)
|
||||||
|
|
|
@ -12,13 +12,14 @@ from .const import (
|
||||||
DATA_CALL_GET_CALLS_LOG,
|
DATA_CALL_GET_CALLS_LOG,
|
||||||
DATA_CONNECTION_GET_STATUS,
|
DATA_CONNECTION_GET_STATUS,
|
||||||
DATA_HOME_GET_NODES,
|
DATA_HOME_GET_NODES,
|
||||||
DATA_HOME_PIR_GET_VALUES,
|
DATA_HOME_PIR_GET_VALUE,
|
||||||
|
DATA_HOME_SET_VALUE,
|
||||||
DATA_LAN_GET_HOSTS_LIST,
|
DATA_LAN_GET_HOSTS_LIST,
|
||||||
DATA_LAN_GET_HOSTS_LIST_MODE_BRIDGE,
|
DATA_LAN_GET_HOSTS_LIST_MODE_BRIDGE,
|
||||||
DATA_STORAGE_GET_DISKS,
|
DATA_STORAGE_GET_DISKS,
|
||||||
DATA_STORAGE_GET_RAIDS,
|
DATA_STORAGE_GET_RAIDS,
|
||||||
DATA_SYSTEM_GET_CONFIG,
|
DATA_SYSTEM_GET_CONFIG,
|
||||||
WIFI_GET_GLOBAL_CONFIG,
|
DATA_WIFI_GET_GLOBAL_CONFIG,
|
||||||
)
|
)
|
||||||
|
|
||||||
from tests.common import MockConfigEntry
|
from tests.common import MockConfigEntry
|
||||||
|
@ -84,11 +85,16 @@ def mock_router(mock_device_registry_devices):
|
||||||
return_value=DATA_CONNECTION_GET_STATUS
|
return_value=DATA_CONNECTION_GET_STATUS
|
||||||
)
|
)
|
||||||
# switch
|
# switch
|
||||||
instance.wifi.get_global_config = AsyncMock(return_value=WIFI_GET_GLOBAL_CONFIG)
|
instance.wifi.get_global_config = AsyncMock(
|
||||||
|
return_value=DATA_WIFI_GET_GLOBAL_CONFIG
|
||||||
|
)
|
||||||
# home devices
|
# home devices
|
||||||
instance.home.get_home_nodes = AsyncMock(return_value=DATA_HOME_GET_NODES)
|
instance.home.get_home_nodes = AsyncMock(return_value=DATA_HOME_GET_NODES)
|
||||||
instance.home.get_home_endpoint_value = AsyncMock(
|
instance.home.get_home_endpoint_value = AsyncMock(
|
||||||
return_value=DATA_HOME_PIR_GET_VALUES
|
return_value=DATA_HOME_PIR_GET_VALUE
|
||||||
|
)
|
||||||
|
instance.home.set_home_endpoint_value = AsyncMock(
|
||||||
|
return_value=DATA_HOME_SET_VALUE
|
||||||
)
|
)
|
||||||
instance.close = AsyncMock()
|
instance.close = AsyncMock()
|
||||||
yield service_mock
|
yield service_mock
|
||||||
|
|
|
@ -21,7 +21,9 @@ DATA_STORAGE_GET_DISKS = load_json_array_fixture("freebox/storage_get_disks.json
|
||||||
DATA_STORAGE_GET_RAIDS = load_json_array_fixture("freebox/storage_get_raids.json")
|
DATA_STORAGE_GET_RAIDS = load_json_array_fixture("freebox/storage_get_raids.json")
|
||||||
|
|
||||||
# switch
|
# switch
|
||||||
WIFI_GET_GLOBAL_CONFIG = load_json_object_fixture("freebox/wifi_get_global_config.json")
|
DATA_WIFI_GET_GLOBAL_CONFIG = load_json_object_fixture(
|
||||||
|
"freebox/wifi_get_global_config.json"
|
||||||
|
)
|
||||||
|
|
||||||
# device_tracker
|
# device_tracker
|
||||||
DATA_LAN_GET_HOSTS_LIST = load_json_array_fixture("freebox/lan_get_hosts_list.json")
|
DATA_LAN_GET_HOSTS_LIST = load_json_array_fixture("freebox/lan_get_hosts_list.json")
|
||||||
|
@ -35,10 +37,14 @@ DATA_HOME_GET_NODES = load_json_array_fixture("freebox/home_get_nodes.json")
|
||||||
|
|
||||||
# Home
|
# Home
|
||||||
# PIR node id 26, endpoint id 6
|
# PIR node id 26, endpoint id 6
|
||||||
DATA_HOME_PIR_GET_VALUES = load_json_object_fixture("freebox/home_pir_get_values.json")
|
DATA_HOME_PIR_GET_VALUE = load_json_object_fixture("freebox/home_pir_get_value.json")
|
||||||
|
|
||||||
# Home
|
# Home
|
||||||
# ALARM node id 7, endpoint id 11
|
# ALARM node id 7, endpoint id 11
|
||||||
DATA_HOME_ALARM_GET_VALUES = load_json_object_fixture(
|
DATA_HOME_ALARM_GET_VALUE = load_json_object_fixture(
|
||||||
"freebox/home_alarm_get_values.json"
|
"freebox/home_alarm_get_value.json"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Home
|
||||||
|
# Set a node value with success
|
||||||
|
DATA_HOME_SET_VALUE = load_json_object_fixture("freebox/home_set_value.json")
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"refresh": 2000,
|
"refresh": 2000,
|
||||||
"value": "alarm2_armed",
|
"value": "alarm1_armed",
|
||||||
"value_type": "string"
|
"value_type": "string"
|
||||||
}
|
}
|
3
tests/components/freebox/fixtures/home_set_value.json
Normal file
3
tests/components/freebox/fixtures/home_set_value.json
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"success": true
|
||||||
|
}
|
|
@ -1,57 +1,68 @@
|
||||||
"""Tests for the Freebox sensors."""
|
"""Tests for the Freebox alarms."""
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
from unittest.mock import Mock
|
from unittest.mock import Mock
|
||||||
|
|
||||||
from freezegun.api import FrozenDateTimeFactory
|
from freezegun.api import FrozenDateTimeFactory
|
||||||
import pytest
|
|
||||||
|
|
||||||
from homeassistant.components.alarm_control_panel import (
|
from homeassistant.components.alarm_control_panel import (
|
||||||
DOMAIN as ALARM_CONTROL_PANEL,
|
DOMAIN as ALARM_CONTROL_PANEL_DOMAIN,
|
||||||
AlarmControlPanelEntityFeature,
|
AlarmControlPanelEntityFeature,
|
||||||
)
|
)
|
||||||
from homeassistant.components.freebox import SCAN_INTERVAL
|
from homeassistant.components.freebox import SCAN_INTERVAL
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
|
ATTR_ENTITY_ID,
|
||||||
SERVICE_ALARM_ARM_AWAY,
|
SERVICE_ALARM_ARM_AWAY,
|
||||||
SERVICE_ALARM_ARM_CUSTOM_BYPASS,
|
|
||||||
SERVICE_ALARM_ARM_HOME,
|
SERVICE_ALARM_ARM_HOME,
|
||||||
SERVICE_ALARM_ARM_NIGHT,
|
|
||||||
SERVICE_ALARM_ARM_VACATION,
|
|
||||||
SERVICE_ALARM_DISARM,
|
SERVICE_ALARM_DISARM,
|
||||||
SERVICE_ALARM_TRIGGER,
|
SERVICE_ALARM_TRIGGER,
|
||||||
STATE_ALARM_ARMED_AWAY,
|
STATE_ALARM_ARMED_AWAY,
|
||||||
STATE_ALARM_ARMED_CUSTOM_BYPASS,
|
|
||||||
STATE_ALARM_ARMED_HOME,
|
STATE_ALARM_ARMED_HOME,
|
||||||
STATE_ALARM_ARMED_NIGHT,
|
STATE_ALARM_ARMING,
|
||||||
STATE_ALARM_ARMED_VACATION,
|
|
||||||
STATE_ALARM_DISARMED,
|
STATE_ALARM_DISARMED,
|
||||||
STATE_ALARM_TRIGGERED,
|
STATE_ALARM_TRIGGERED,
|
||||||
|
STATE_UNKNOWN,
|
||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant, State
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.state import async_reproduce_state
|
|
||||||
|
|
||||||
from .common import setup_platform
|
from .common import setup_platform
|
||||||
from .const import DATA_HOME_ALARM_GET_VALUES
|
from .const import DATA_HOME_ALARM_GET_VALUE, DATA_HOME_GET_NODES
|
||||||
|
|
||||||
from tests.common import async_fire_time_changed, async_mock_service
|
from tests.common import async_fire_time_changed
|
||||||
|
|
||||||
|
|
||||||
async def test_panel(
|
async def test_alarm_changed_from_external(
|
||||||
hass: HomeAssistant, freezer: FrozenDateTimeFactory, router: Mock
|
hass: HomeAssistant, freezer: FrozenDateTimeFactory, router: Mock
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test home binary sensors."""
|
"""Test Freebox Home alarm which state depends on external changes."""
|
||||||
await setup_platform(hass, ALARM_CONTROL_PANEL)
|
data_get_home_nodes = deepcopy(DATA_HOME_GET_NODES)
|
||||||
|
data_get_home_endpoint_value = deepcopy(DATA_HOME_ALARM_GET_VALUE)
|
||||||
|
|
||||||
|
# Add remove arm_home feature
|
||||||
|
ALARM_NODE_ID = 7
|
||||||
|
ALARM_HOME_ENDPOINT_ID = 2
|
||||||
|
del data_get_home_nodes[ALARM_NODE_ID]["type"]["endpoints"][ALARM_HOME_ENDPOINT_ID]
|
||||||
|
router().home.get_home_nodes.return_value = data_get_home_nodes
|
||||||
|
|
||||||
|
data_get_home_endpoint_value["value"] = "alarm1_arming"
|
||||||
|
router().home.get_home_endpoint_value.return_value = data_get_home_endpoint_value
|
||||||
|
|
||||||
|
await setup_platform(hass, ALARM_CONTROL_PANEL_DOMAIN)
|
||||||
|
|
||||||
|
# Attributes
|
||||||
|
assert hass.states.get("alarm_control_panel.systeme_d_alarme").attributes[
|
||||||
|
"supported_features"
|
||||||
|
] == (
|
||||||
|
AlarmControlPanelEntityFeature.ARM_AWAY | AlarmControlPanelEntityFeature.TRIGGER
|
||||||
|
)
|
||||||
|
|
||||||
# Initial state
|
# Initial state
|
||||||
assert hass.states.get("alarm_control_panel.systeme_d_alarme").state == "unknown"
|
|
||||||
assert (
|
assert (
|
||||||
hass.states.get("alarm_control_panel.systeme_d_alarme").attributes[
|
hass.states.get("alarm_control_panel.systeme_d_alarme").state
|
||||||
"supported_features"
|
== STATE_ALARM_ARMING
|
||||||
]
|
|
||||||
== AlarmControlPanelEntityFeature.ARM_AWAY
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Now simulate a changed status
|
# Now simulate a changed status
|
||||||
data_get_home_endpoint_value = deepcopy(DATA_HOME_ALARM_GET_VALUES)
|
data_get_home_endpoint_value["value"] = "alarm1_armed"
|
||||||
router().home.get_home_endpoint_value.return_value = data_get_home_endpoint_value
|
router().home.get_home_endpoint_value.return_value = data_get_home_endpoint_value
|
||||||
|
|
||||||
# Simulate an update
|
# Simulate an update
|
||||||
|
@ -60,64 +71,105 @@ async def test_panel(
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert (
|
assert (
|
||||||
hass.states.get("alarm_control_panel.systeme_d_alarme").state == "armed_night"
|
hass.states.get("alarm_control_panel.systeme_d_alarme").state
|
||||||
)
|
== STATE_ALARM_ARMED_AWAY
|
||||||
# Fake that the entity is triggered.
|
|
||||||
hass.states.async_set("alarm_control_panel.systeme_d_alarme", STATE_ALARM_DISARMED)
|
|
||||||
assert hass.states.get("alarm_control_panel.systeme_d_alarme").state == "disarmed"
|
|
||||||
|
|
||||||
|
|
||||||
async def test_reproducing_states(
|
|
||||||
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
|
|
||||||
) -> None:
|
|
||||||
"""Test reproducing Alarm control panel states."""
|
|
||||||
hass.states.async_set(
|
|
||||||
"alarm_control_panel.entity_armed_away", STATE_ALARM_ARMED_AWAY, {}
|
|
||||||
)
|
|
||||||
hass.states.async_set(
|
|
||||||
"alarm_control_panel.entity_armed_custom_bypass",
|
|
||||||
STATE_ALARM_ARMED_CUSTOM_BYPASS,
|
|
||||||
{},
|
|
||||||
)
|
|
||||||
hass.states.async_set(
|
|
||||||
"alarm_control_panel.entity_armed_home", STATE_ALARM_ARMED_HOME, {}
|
|
||||||
)
|
|
||||||
hass.states.async_set(
|
|
||||||
"alarm_control_panel.entity_armed_night", STATE_ALARM_ARMED_NIGHT, {}
|
|
||||||
)
|
|
||||||
hass.states.async_set(
|
|
||||||
"alarm_control_panel.entity_armed_vacation", STATE_ALARM_ARMED_VACATION, {}
|
|
||||||
)
|
|
||||||
hass.states.async_set(
|
|
||||||
"alarm_control_panel.entity_disarmed", STATE_ALARM_DISARMED, {}
|
|
||||||
)
|
|
||||||
hass.states.async_set(
|
|
||||||
"alarm_control_panel.entity_triggered", STATE_ALARM_TRIGGERED, {}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
async_mock_service(hass, "alarm_control_panel", SERVICE_ALARM_ARM_AWAY)
|
|
||||||
async_mock_service(hass, "alarm_control_panel", SERVICE_ALARM_ARM_CUSTOM_BYPASS)
|
|
||||||
async_mock_service(hass, "alarm_control_panel", SERVICE_ALARM_ARM_HOME)
|
|
||||||
async_mock_service(hass, "alarm_control_panel", SERVICE_ALARM_ARM_NIGHT)
|
|
||||||
async_mock_service(hass, "alarm_control_panel", SERVICE_ALARM_ARM_VACATION)
|
|
||||||
async_mock_service(hass, "alarm_control_panel", SERVICE_ALARM_DISARM)
|
|
||||||
async_mock_service(hass, "alarm_control_panel", SERVICE_ALARM_TRIGGER)
|
|
||||||
|
|
||||||
# These calls should do nothing as entities already in desired state
|
async def test_alarm_changed_from_hass(hass: HomeAssistant, router: Mock) -> None:
|
||||||
await async_reproduce_state(
|
"""Test Freebox Home alarm which state depends on HA."""
|
||||||
hass,
|
data_get_home_endpoint_value = deepcopy(DATA_HOME_ALARM_GET_VALUE)
|
||||||
[
|
|
||||||
State("alarm_control_panel.entity_armed_away", STATE_ALARM_ARMED_AWAY),
|
data_get_home_endpoint_value["value"] = "alarm1_armed"
|
||||||
State(
|
router().home.get_home_endpoint_value.return_value = data_get_home_endpoint_value
|
||||||
"alarm_control_panel.entity_armed_custom_bypass",
|
|
||||||
STATE_ALARM_ARMED_CUSTOM_BYPASS,
|
await setup_platform(hass, ALARM_CONTROL_PANEL_DOMAIN)
|
||||||
),
|
|
||||||
State("alarm_control_panel.entity_armed_home", STATE_ALARM_ARMED_HOME),
|
# Attributes
|
||||||
State("alarm_control_panel.entity_armed_night", STATE_ALARM_ARMED_NIGHT),
|
assert hass.states.get("alarm_control_panel.systeme_d_alarme").attributes[
|
||||||
State(
|
"supported_features"
|
||||||
"alarm_control_panel.entity_armed_vacation", STATE_ALARM_ARMED_VACATION
|
] == (
|
||||||
),
|
AlarmControlPanelEntityFeature.ARM_AWAY
|
||||||
State("alarm_control_panel.entity_disarmed", STATE_ALARM_DISARMED),
|
| AlarmControlPanelEntityFeature.ARM_HOME
|
||||||
State("alarm_control_panel.entity_triggered", STATE_ALARM_TRIGGERED),
|
| AlarmControlPanelEntityFeature.TRIGGER
|
||||||
],
|
)
|
||||||
|
|
||||||
|
# Initial state: arm_away
|
||||||
|
assert (
|
||||||
|
hass.states.get("alarm_control_panel.systeme_d_alarme").state
|
||||||
|
== STATE_ALARM_ARMED_AWAY
|
||||||
|
)
|
||||||
|
|
||||||
|
# Now call for a change -> disarmed
|
||||||
|
data_get_home_endpoint_value["value"] = "idle"
|
||||||
|
router().home.get_home_endpoint_value.return_value = data_get_home_endpoint_value
|
||||||
|
await hass.services.async_call(
|
||||||
|
ALARM_CONTROL_PANEL_DOMAIN,
|
||||||
|
SERVICE_ALARM_DISARM,
|
||||||
|
{ATTR_ENTITY_ID: ["alarm_control_panel.systeme_d_alarme"]},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert (
|
||||||
|
hass.states.get("alarm_control_panel.systeme_d_alarme").state
|
||||||
|
== STATE_ALARM_DISARMED
|
||||||
|
)
|
||||||
|
|
||||||
|
# Now call for a change -> arm_away
|
||||||
|
data_get_home_endpoint_value["value"] = "alarm1_arming"
|
||||||
|
router().home.get_home_endpoint_value.return_value = data_get_home_endpoint_value
|
||||||
|
await hass.services.async_call(
|
||||||
|
ALARM_CONTROL_PANEL_DOMAIN,
|
||||||
|
SERVICE_ALARM_ARM_AWAY,
|
||||||
|
{ATTR_ENTITY_ID: ["alarm_control_panel.systeme_d_alarme"]},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert (
|
||||||
|
hass.states.get("alarm_control_panel.systeme_d_alarme").state
|
||||||
|
== STATE_ALARM_ARMING
|
||||||
|
)
|
||||||
|
|
||||||
|
# Now call for a change -> arm_home
|
||||||
|
data_get_home_endpoint_value["value"] = "alarm2_armed"
|
||||||
|
# in reality: alarm2_arming then alarm2_armed
|
||||||
|
router().home.get_home_endpoint_value.return_value = data_get_home_endpoint_value
|
||||||
|
await hass.services.async_call(
|
||||||
|
ALARM_CONTROL_PANEL_DOMAIN,
|
||||||
|
SERVICE_ALARM_ARM_HOME,
|
||||||
|
{ATTR_ENTITY_ID: ["alarm_control_panel.systeme_d_alarme"]},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert (
|
||||||
|
hass.states.get("alarm_control_panel.systeme_d_alarme").state
|
||||||
|
== STATE_ALARM_ARMED_HOME
|
||||||
|
)
|
||||||
|
|
||||||
|
# Now call for a change -> trigger
|
||||||
|
data_get_home_endpoint_value["value"] = "alarm1_alert_timer"
|
||||||
|
router().home.get_home_endpoint_value.return_value = data_get_home_endpoint_value
|
||||||
|
await hass.services.async_call(
|
||||||
|
ALARM_CONTROL_PANEL_DOMAIN,
|
||||||
|
SERVICE_ALARM_TRIGGER,
|
||||||
|
{ATTR_ENTITY_ID: ["alarm_control_panel.systeme_d_alarme"]},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert (
|
||||||
|
hass.states.get("alarm_control_panel.systeme_d_alarme").state
|
||||||
|
== STATE_ALARM_TRIGGERED
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def test_alarm_undefined_fetch_status(hass: HomeAssistant, router: Mock) -> None:
|
||||||
|
"""Test Freebox Home alarm which state is undefined or null."""
|
||||||
|
data_get_home_endpoint_value = deepcopy(DATA_HOME_ALARM_GET_VALUE)
|
||||||
|
data_get_home_endpoint_value["value"] = None
|
||||||
|
router().home.get_home_endpoint_value.return_value = data_get_home_endpoint_value
|
||||||
|
|
||||||
|
await setup_platform(hass, ALARM_CONTROL_PANEL_DOMAIN)
|
||||||
|
|
||||||
|
assert (
|
||||||
|
hass.states.get("alarm_control_panel.systeme_d_alarme").state == STATE_UNKNOWN
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
"""Tests for the Freebox sensors."""
|
"""Tests for the Freebox binary sensors."""
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
from unittest.mock import Mock
|
from unittest.mock import Mock
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ from homeassistant.const import ATTR_DEVICE_CLASS
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
from .common import setup_platform
|
from .common import setup_platform
|
||||||
from .const import DATA_HOME_PIR_GET_VALUES, DATA_STORAGE_GET_RAIDS
|
from .const import DATA_HOME_PIR_GET_VALUE, DATA_STORAGE_GET_RAIDS
|
||||||
|
|
||||||
from tests.common import async_fire_time_changed
|
from tests.common import async_fire_time_changed
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ async def test_home(
|
||||||
assert hass.states.get("binary_sensor.ouverture_porte_couvercle").state == "off"
|
assert hass.states.get("binary_sensor.ouverture_porte_couvercle").state == "off"
|
||||||
|
|
||||||
# Now simulate a changed status
|
# Now simulate a changed status
|
||||||
data_home_get_values_changed = deepcopy(DATA_HOME_PIR_GET_VALUES)
|
data_home_get_values_changed = deepcopy(DATA_HOME_PIR_GET_VALUE)
|
||||||
data_home_get_values_changed["value"] = True
|
data_home_get_values_changed["value"] = True
|
||||||
router().home.get_home_endpoint_value.return_value = data_home_get_values_changed
|
router().home.get_home_endpoint_value.return_value = data_home_get_values_changed
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
"""Tests for the Freebox config flow."""
|
"""Tests for the Freebox buttons."""
|
||||||
from unittest.mock import ANY, AsyncMock, Mock, patch
|
from unittest.mock import ANY, AsyncMock, Mock, patch
|
||||||
|
|
||||||
from pytest_unordered import unordered
|
from pytest_unordered import unordered
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
"""Tests for the Freebox config flow."""
|
"""Tests for the Freebox init."""
|
||||||
from unittest.mock import ANY, Mock, patch
|
from unittest.mock import ANY, Mock, patch
|
||||||
|
|
||||||
from pytest_unordered import unordered
|
from pytest_unordered import unordered
|
||||||
|
|
|
@ -3,7 +3,7 @@ import json
|
||||||
|
|
||||||
from homeassistant.components.freebox.router import is_json
|
from homeassistant.components.freebox.router import is_json
|
||||||
|
|
||||||
from .const import DATA_LAN_GET_HOSTS_LIST_MODE_BRIDGE, WIFI_GET_GLOBAL_CONFIG
|
from .const import DATA_LAN_GET_HOSTS_LIST_MODE_BRIDGE, DATA_WIFI_GET_GLOBAL_CONFIG
|
||||||
|
|
||||||
|
|
||||||
async def test_is_json() -> None:
|
async def test_is_json() -> None:
|
||||||
|
@ -12,7 +12,7 @@ async def test_is_json() -> None:
|
||||||
# Valid JSON values
|
# Valid JSON values
|
||||||
assert is_json("{}")
|
assert is_json("{}")
|
||||||
assert is_json('{ "simple":"json" }')
|
assert is_json('{ "simple":"json" }')
|
||||||
assert is_json(json.dumps(WIFI_GET_GLOBAL_CONFIG))
|
assert is_json(json.dumps(DATA_WIFI_GET_GLOBAL_CONFIG))
|
||||||
assert is_json(json.dumps(DATA_LAN_GET_HOSTS_LIST_MODE_BRIDGE))
|
assert is_json(json.dumps(DATA_LAN_GET_HOSTS_LIST_MODE_BRIDGE))
|
||||||
|
|
||||||
# Not valid JSON values
|
# Not valid JSON values
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue