Compare commits

...

2 Commits

Author SHA1 Message Date
Paul Bottein b0f98ed98d Rename to cover 2026-05-05 18:55:25 +02:00
Paul Bottein 40e797ca6d Migrate Freebox to has_entity_name and key-based unique IDs 2026-05-05 18:31:20 +02:00
17 changed files with 247 additions and 86 deletions
+47 -3
View File
@@ -1,19 +1,61 @@
"""Support for Freebox devices (Freebox v6 and Freebox mini 4K)."""
from datetime import timedelta
import logging
from freebox_api.exceptions import HttpRequestError
from homeassistant.const import CONF_HOST, CONF_PORT, EVENT_HOMEASSISTANT_STOP
from homeassistant.core import Event, HomeAssistant
from homeassistant.const import CONF_HOST, CONF_PORT, EVENT_HOMEASSISTANT_STOP, Platform
from homeassistant.core import Event, HomeAssistant, callback
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers import entity_registry as er
from homeassistant.helpers.event import async_track_time_interval
from .const import PLATFORMS
from .const import DOMAIN, PLATFORMS
from .router import FreeboxConfigEntry, FreeboxRouter, get_api
_LOGGER = logging.getLogger(__name__)
SCAN_INTERVAL = timedelta(seconds=30)
# Old entity name suffixes that need rewriting to the entity description key.
# Format: (platform, old name suffix, new key)
_STATIC_UNIQUE_ID_MIGRATIONS: tuple[tuple[Platform, str, str], ...] = (
(Platform.SENSOR, "Freebox download speed", "rate_down"),
(Platform.SENSOR, "Freebox upload speed", "rate_up"),
(Platform.SENSOR, "Freebox missed calls", "missed"),
(Platform.BUTTON, "Reboot Freebox", "reboot"),
(Platform.BUTTON, "Mark calls as read", "mark_calls_as_read"),
(Platform.SWITCH, "Freebox WiFi", "wifi"),
)
@callback
def _migrate_unique_ids(hass: HomeAssistant, router: FreeboxRouter) -> None:
"""Migrate name-based unique ids to key-based ones."""
entity_registry = er.async_get(hass)
mac = router.mac
for platform, old_suffix, new_key in _STATIC_UNIQUE_ID_MIGRATIONS:
old_uid = f"{mac} {old_suffix}"
new_uid = f"{mac} {new_key}"
if entity_id := entity_registry.async_get_entity_id(platform, DOMAIN, old_uid):
_LOGGER.debug(
"Migrating %s unique_id from %s to %s", entity_id, old_uid, new_uid
)
entity_registry.async_update_entity(entity_id, new_unique_id=new_uid)
for sensor_id, sensor_name in router.sensors_temperature_names.items():
old_uid = f"{mac} Freebox {sensor_name}"
new_uid = f"{mac} {sensor_id}"
if entity_id := entity_registry.async_get_entity_id(
Platform.SENSOR, DOMAIN, old_uid
):
_LOGGER.debug(
"Migrating %s unique_id from %s to %s", entity_id, old_uid, new_uid
)
entity_registry.async_update_entity(entity_id, new_unique_id=new_uid)
async def async_setup_entry(hass: HomeAssistant, entry: FreeboxConfigEntry) -> bool:
"""Set up Freebox entry."""
@@ -31,6 +73,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: FreeboxConfigEntry) -> b
async_track_time_interval(hass, router.update_all, SCAN_INTERVAL)
)
_migrate_unique_ids(hass, router)
entry.runtime_data = router
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
@@ -48,6 +48,7 @@ class FreeboxAlarm(FreeboxHomeEntity, AlarmControlPanelEntity):
"""Representation of a Freebox alarm."""
_attr_code_arm_required = False
_attr_name = None
def __init__(self, router: FreeboxRouter, node: dict[str, Any]) -> None:
"""Initialize an alarm."""
@@ -23,7 +23,7 @@ _LOGGER = logging.getLogger(__name__)
RAID_SENSORS: tuple[BinarySensorEntityDescription, ...] = (
BinarySensorEntityDescription(
key="raid_degraded",
name="degraded",
translation_key="raid_degraded",
device_class=BinarySensorDeviceClass.PROBLEM,
entity_category=EntityCategory.DIAGNOSTIC,
),
@@ -68,7 +68,7 @@ async def async_setup_entry(
class FreeboxHomeBinarySensor(FreeboxHomeEntity, BinarySensorEntity):
"""Representation of a Freebox binary sensor."""
_sensor_name = "trigger"
_endpoint_name = "trigger"
def __init__(
self,
@@ -79,9 +79,11 @@ class FreeboxHomeBinarySensor(FreeboxHomeEntity, BinarySensorEntity):
"""Initialize a Freebox binary sensor."""
super().__init__(router, node, sub_node)
self._command_id = self.get_command_id(
node["type"]["endpoints"], "signal", self._sensor_name
node["type"]["endpoints"], "signal", self._endpoint_name
)
self._attr_is_on = self._edit_state(
self.get_value("signal", self._endpoint_name)
)
self._attr_is_on = self._edit_state(self.get_value("signal", self._sensor_name))
async def async_update_signal(self) -> None:
"""Update name & state."""
@@ -91,10 +93,10 @@ class FreeboxHomeBinarySensor(FreeboxHomeEntity, BinarySensorEntity):
await FreeboxHomeEntity.async_update_signal(self)
def _edit_state(self, state: bool | None) -> bool | None:
"""Edit state depending on sensor name."""
"""Edit state depending on endpoint name."""
if state is None:
return None
if self._sensor_name == "trigger":
if self._endpoint_name == "trigger":
return not state
return state
@@ -103,12 +105,14 @@ class FreeboxPirSensor(FreeboxHomeBinarySensor):
"""Representation of a Freebox motion binary sensor."""
_attr_device_class = BinarySensorDeviceClass.MOTION
_attr_name = None
class FreeboxDwsSensor(FreeboxHomeBinarySensor):
"""Representation of a Freebox door opener binary sensor."""
_attr_device_class = BinarySensorDeviceClass.DOOR
_attr_name = None
class FreeboxCoverSensor(FreeboxHomeBinarySensor):
@@ -117,14 +121,15 @@ class FreeboxCoverSensor(FreeboxHomeBinarySensor):
_attr_device_class = BinarySensorDeviceClass.SAFETY
_attr_entity_category = EntityCategory.DIAGNOSTIC
_attr_entity_registry_enabled_default = False
_attr_translation_key = "cover"
_sensor_name = "cover"
_endpoint_name = "cover"
def __init__(self, router: FreeboxRouter, node: dict[str, Any]) -> None:
"""Initialize a cover for another device."""
cover_node = next(
filter(
lambda x: x["name"] == self._sensor_name and x["ep_type"] == "signal",
lambda x: x["name"] == self._endpoint_name and x["ep_type"] == "signal",
node["type"]["endpoints"],
),
None,
@@ -149,7 +154,7 @@ class FreeboxRaidDegradedSensor(BinarySensorEntity):
self._router = router
self._attr_device_info = router.device_info
self._raid = raid
self._attr_name = f"Raid array {raid['id']} {description.name}"
self._attr_translation_placeholders = {"id": str(raid["id"])}
self._attr_unique_id = (
f"{router.mac} {description.key} {raid['name']} {raid['id']}"
)
+4 -3
View File
@@ -25,14 +25,14 @@ class FreeboxButtonEntityDescription(ButtonEntityDescription):
BUTTON_DESCRIPTIONS: tuple[FreeboxButtonEntityDescription, ...] = (
FreeboxButtonEntityDescription(
key="reboot",
name="Reboot Freebox",
translation_key="reboot",
device_class=ButtonDeviceClass.RESTART,
entity_category=EntityCategory.CONFIG,
async_press=lambda router: router.reboot(),
),
FreeboxButtonEntityDescription(
key="mark_calls_as_read",
name="Mark calls as read",
translation_key="mark_calls_as_read",
entity_category=EntityCategory.DIAGNOSTIC,
async_press=lambda router: router.call.mark_calls_log_as_read(),
),
@@ -55,6 +55,7 @@ async def async_setup_entry(
class FreeboxButton(ButtonEntity):
"""Representation of a Freebox button."""
_attr_has_entity_name = True
entity_description: FreeboxButtonEntityDescription
def __init__(
@@ -64,7 +65,7 @@ class FreeboxButton(ButtonEntity):
self.entity_description = description
self._router = router
self._attr_device_info = router.device_info
self._attr_unique_id = f"{router.mac} {description.name}"
self._attr_unique_id = f"{router.mac} {description.key}"
async def async_press(self) -> None:
"""Press the button."""
+12 -2
View File
@@ -66,6 +66,8 @@ def add_entities(
class FreeboxCamera(FreeboxHomeEntity, FFmpegCamera):
"""Representation of a Freebox camera."""
_attr_name = None
def __init__(
self, hass: HomeAssistant, router: FreeboxRouter, node: dict[str, Any]
) -> None:
@@ -89,6 +91,16 @@ class FreeboxCamera(FreeboxHomeEntity, FFmpegCamera):
self._attr_extra_state_attributes = {}
self.update_node(node)
@property
def name(self) -> str | None: # type: ignore[override]
"""Return None so the device name is used as entity name.
FFmpegCamera defines its own `name` property that takes precedence
over the base Entity class's name resolution (which would use
`_attr_name`). Override here to honor `_attr_name = None`.
"""
return self._attr_name
async def async_enable_motion_detection(self) -> None:
"""Enable motion detection in the camera."""
if await self.set_home_endpoint_value(self._command_motion_detection, True):
@@ -106,8 +118,6 @@ class FreeboxCamera(FreeboxHomeEntity, FFmpegCamera):
def update_node(self, node: dict[str, Any]) -> None:
"""Update params."""
self._name = node["label"].strip()
# Get status
if self._node["status"] == "active":
self._attr_is_streaming = True
@@ -55,6 +55,7 @@ def add_entities(
class FreeboxDevice(ScannerEntity):
"""Representation of a Freebox device."""
_attr_has_entity_name = True
_attr_should_poll = False
def __init__(self, router: FreeboxRouter, device: dict[str, Any]) -> None:
+3 -11
View File
@@ -16,6 +16,8 @@ _LOGGER = logging.getLogger(__name__)
class FreeboxHomeEntity(Entity):
"""Representation of a Freebox base entity."""
_attr_has_entity_name = True
def __init__(
self,
router: FreeboxRouter,
@@ -27,12 +29,9 @@ class FreeboxHomeEntity(Entity):
self._node = node
self._sub_node = sub_node
self._id = node["id"]
self._attr_name = node["label"].strip()
self._device_name = self._attr_name
self._attr_unique_id = f"{self._router.mac}-node_{self._id}"
if sub_node is not None:
self._attr_name += " " + sub_node["label"].strip()
self._attr_unique_id += "-" + sub_node["name"].strip()
self._available = True
@@ -52,7 +51,7 @@ class FreeboxHomeEntity(Entity):
identifiers={(DOMAIN, self._id)},
manufacturer=self._manufacturer,
model=self._model,
name=self._device_name,
name=node["label"].strip(),
sw_version=self._firmware,
via_device=(DOMAIN, router.mac),
)
@@ -60,13 +59,6 @@ class FreeboxHomeEntity(Entity):
async def async_update_signal(self) -> None:
"""Update signal."""
self._node = self._router.home_devices[self._id]
# Update name
if self._sub_node is None:
self._attr_name = self._node["label"].strip()
else:
self._attr_name = (
self._node["label"].strip() + " " + self._sub_node["label"].strip()
)
self.async_write_ha_state()
async def set_home_endpoint_value(
+22 -3
View File
@@ -1,7 +1,26 @@
{
"services": {
"reboot": {
"service": "mdi:restart"
"entity": {
"sensor": {
"missed": {
"default": "mdi:phone-missed"
},
"partition_free_space": {
"default": "mdi:harddisk"
},
"rate_down": {
"default": "mdi:download-network"
},
"rate_up": {
"default": "mdi:upload-network"
}
},
"switch": {
"wifi": {
"default": "mdi:wifi",
"state": {
"off": "mdi:wifi-off"
}
}
}
}
}
+6 -1
View File
@@ -125,6 +125,7 @@ class FreeboxRouter:
self.supports_raid = True
self.raids: dict[int, dict[str, Any]] = {}
self.sensors_temperature: dict[str, int] = {}
self.sensors_temperature_names: dict[str, str] = {}
self.sensors_connection: dict[str, float] = {}
self.call_list: list[dict[str, Any]] = []
self.home_granted = True
@@ -183,7 +184,11 @@ class FreeboxRouter:
# According to the doc `syst_datas["sensors"]` is temperature sensors in celsius degree.
# Name and id of sensors may vary under Freebox devices.
for sensor in syst_datas["sensors"]:
self.sensors_temperature[sensor["name"]] = sensor.get("value")
sensor_id = sensor["id"]
self.sensors_temperature[sensor_id] = sensor.get("value")
# Names are static per-device; only populate once.
if sensor_id not in self.sensors_temperature_names:
self.sensors_temperature_names[sensor_id] = sensor["name"]
# Connection sensors
connection_datas: dict[str, Any] = await self._api.connection.get_status()
+12 -13
View File
@@ -25,36 +25,34 @@ _LOGGER = logging.getLogger(__name__)
CONNECTION_SENSORS: tuple[SensorEntityDescription, ...] = (
SensorEntityDescription(
key="rate_down",
name="Freebox download speed",
translation_key="rate_down",
device_class=SensorDeviceClass.DATA_RATE,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfDataRate.KILOBYTES_PER_SECOND,
icon="mdi:download-network",
),
SensorEntityDescription(
key="rate_up",
name="Freebox upload speed",
translation_key="rate_up",
device_class=SensorDeviceClass.DATA_RATE,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfDataRate.KILOBYTES_PER_SECOND,
icon="mdi:upload-network",
),
)
CALL_SENSORS: tuple[SensorEntityDescription, ...] = (
SensorEntityDescription(
key="missed",
name="Freebox missed calls",
icon="mdi:phone-missed",
translation_key="missed",
native_unit_of_measurement="calls",
state_class=SensorStateClass.MEASUREMENT,
),
)
DISK_PARTITION_SENSORS: tuple[SensorEntityDescription, ...] = (
SensorEntityDescription(
key="partition_free_space",
name="free space",
translation_key="partition_free_space",
native_unit_of_measurement=PERCENTAGE,
icon="mdi:harddisk",
),
)
@@ -77,14 +75,14 @@ async def async_setup_entry(
FreeboxSensor(
router,
SensorEntityDescription(
key=sensor_name,
name=f"Freebox {sensor_name}",
key=sensor_id,
name=sensor_name,
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
device_class=SensorDeviceClass.TEMPERATURE,
state_class=SensorStateClass.MEASUREMENT,
),
)
for sensor_name in router.sensors_temperature
for sensor_id, sensor_name in router.sensors_temperature_names.items()
]
entities.extend(
@@ -121,6 +119,7 @@ class FreeboxSensor(SensorEntity):
"""Representation of a Freebox sensor."""
_attr_should_poll = False
_attr_has_entity_name = True
def __init__(
self, router: FreeboxRouter, description: SensorEntityDescription
@@ -128,7 +127,7 @@ class FreeboxSensor(SensorEntity):
"""Initialize a Freebox sensor."""
self.entity_description = description
self._router = router
self._attr_unique_id = f"{router.mac} {description.name}"
self._attr_unique_id = f"{router.mac} {description.key}"
self._attr_device_info = router.device_info
@callback
@@ -204,7 +203,7 @@ class FreeboxDiskSensor(FreeboxSensor):
super().__init__(router, description)
self._disk_id = disk["id"]
self._partition_id = partition["id"]
self._attr_name = f"{partition['label']} {description.name}"
self._attr_translation_placeholders = {"partition": partition["label"]}
self._attr_unique_id = (
f"{router.mac} {description.key} {disk['id']} {partition['id']}"
)
@@ -1,3 +0,0 @@
# Freebox service entries description.
reboot:
+35 -4
View File
@@ -25,10 +25,41 @@
}
}
},
"services": {
"reboot": {
"description": "Reboots the Freebox.",
"name": "Reboot"
"entity": {
"binary_sensor": {
"cover": {
"name": "Cover"
},
"raid_degraded": {
"name": "RAID array {id} degraded"
}
},
"button": {
"mark_calls_as_read": {
"name": "Mark calls as read"
},
"reboot": {
"name": "Reboot"
}
},
"sensor": {
"missed": {
"name": "Missed calls"
},
"partition_free_space": {
"name": "{partition} free space"
},
"rate_down": {
"name": "Download speed"
},
"rate_up": {
"name": "Upload speed"
}
},
"switch": {
"wifi": {
"name": "Wi-Fi"
}
}
}
}
+4 -2
View File
@@ -18,7 +18,7 @@ _LOGGER = logging.getLogger(__name__)
SWITCH_DESCRIPTIONS = [
SwitchEntityDescription(
key="wifi",
name="Freebox WiFi",
translation_key="wifi",
entity_category=EntityCategory.CONFIG,
)
]
@@ -41,6 +41,8 @@ async def async_setup_entry(
class FreeboxSwitch(SwitchEntity):
"""Representation of a freebox switch."""
_attr_has_entity_name = True
def __init__(
self, router: FreeboxRouter, entity_description: SwitchEntityDescription
) -> None:
@@ -48,7 +50,7 @@ class FreeboxSwitch(SwitchEntity):
self.entity_description = entity_description
self._router = router
self._attr_device_info = router.device_info
self._attr_unique_id = f"{router.mac} {entity_description.name}"
self._attr_unique_id = f"{router.mac} {entity_description.key}"
async def _async_set_state(self, enabled: bool) -> None:
"""Turn the switch on or off."""
@@ -63,7 +63,7 @@ async def test_home(
== BinarySensorDeviceClass.DOOR
)
assert (
hass.states.get("binary_sensor.ouverture_porte_couvercle").attributes[
hass.states.get("binary_sensor.ouverture_porte_cover").attributes[
ATTR_DEVICE_CLASS
]
== BinarySensorDeviceClass.SAFETY
@@ -71,9 +71,9 @@ async def test_home(
# Initial state
assert hass.states.get("binary_sensor.detecteur").state == "on"
assert hass.states.get("binary_sensor.detecteur_couvercle").state == "off"
assert hass.states.get("binary_sensor.detecteur_cover").state == "off"
assert hass.states.get("binary_sensor.ouverture_porte").state == "unknown"
assert hass.states.get("binary_sensor.ouverture_porte_couvercle").state == "off"
assert hass.states.get("binary_sensor.ouverture_porte_cover").state == "off"
# Now simulate a changed status
data_home_get_values_changed = deepcopy(DATA_HOME_PIR_GET_VALUE)
@@ -86,6 +86,6 @@ async def test_home(
await hass.async_block_till_done()
assert hass.states.get("binary_sensor.detecteur").state == "off"
assert hass.states.get("binary_sensor.detecteur_couvercle").state == "on"
assert hass.states.get("binary_sensor.detecteur_cover").state == "on"
assert hass.states.get("binary_sensor.ouverture_porte").state == "off"
assert hass.states.get("binary_sensor.ouverture_porte_couvercle").state == "on"
assert hass.states.get("binary_sensor.ouverture_porte_cover").state == "on"
+1 -1
View File
@@ -28,7 +28,7 @@ async def test_reboot(hass: HomeAssistant, router: Mock) -> None:
BUTTON_DOMAIN,
SERVICE_PRESS,
service_data={
ATTR_ENTITY_ID: "button.freebox_server_r2_reboot_freebox",
ATTR_ENTITY_ID: "button.freebox_server_r2_reboot",
},
blocking=True,
)
+58 -2
View File
@@ -2,8 +2,10 @@
from unittest.mock import ANY, Mock
import pytest
from pytest_unordered import unordered
from homeassistant.components.button import DOMAIN as BUTTON_DOMAIN
from homeassistant.components.device_tracker import DOMAIN as DT_DOMAIN
from homeassistant.components.freebox.const import DOMAIN
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
@@ -11,12 +13,15 @@ from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
from homeassistant.config_entries import ConfigEntryState
from homeassistant.const import CONF_HOST, CONF_PORT, STATE_UNAVAILABLE
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from homeassistant.setup import async_setup_component
from .const import MOCK_HOST, MOCK_PORT
from tests.common import MockConfigEntry
MOCK_MAC = "68:A3:78:00:00:00"
async def test_setup(hass: HomeAssistant, router: Mock) -> None:
"""Test setup of integration."""
@@ -56,8 +61,8 @@ async def test_setup_import(hass: HomeAssistant, router: Mock) -> None:
async def test_unload_remove(hass: HomeAssistant, router: Mock) -> None:
"""Test unload and remove of integration."""
entity_id_dt = f"{DT_DOMAIN}.freebox_server_r2"
entity_id_sensor = f"{SENSOR_DOMAIN}.freebox_server_r2_freebox_download_speed"
entity_id_switch = f"{SWITCH_DOMAIN}.freebox_server_r2_freebox_wifi"
entity_id_sensor = f"{SENSOR_DOMAIN}.freebox_server_r2_download_speed"
entity_id_switch = f"{SWITCH_DOMAIN}.freebox_server_r2_wi_fi"
entry = MockConfigEntry(
domain=DOMAIN,
@@ -103,3 +108,54 @@ async def test_unload_remove(hass: HomeAssistant, router: Mock) -> None:
assert state_sensor is None
state_switch = hass.states.get(entity_id_switch)
assert state_switch is None
@pytest.mark.parametrize(
("platform", "old_suffix", "new_key"),
[
(SENSOR_DOMAIN, "Freebox download speed", "rate_down"),
(SENSOR_DOMAIN, "Freebox upload speed", "rate_up"),
(SENSOR_DOMAIN, "Freebox missed calls", "missed"),
(SENSOR_DOMAIN, "Freebox Disque dur", "temp_hdd"),
(SENSOR_DOMAIN, "Freebox Disque dur 2", "temp_hdd2"),
(SENSOR_DOMAIN, "Freebox Température Switch", "temp_sw"),
(SENSOR_DOMAIN, "Freebox Température CPU M", "temp_cpum"),
(SENSOR_DOMAIN, "Freebox Température CPU B", "temp_cpub"),
(BUTTON_DOMAIN, "Reboot Freebox", "reboot"),
(BUTTON_DOMAIN, "Mark calls as read", "mark_calls_as_read"),
(SWITCH_DOMAIN, "Freebox WiFi", "wifi"),
],
)
async def test_unique_id_migration(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
router: Mock,
platform: str,
old_suffix: str,
new_key: str,
) -> None:
"""Test migration of name-based unique ids to key-based ones."""
old_unique_id = f"{MOCK_MAC} {old_suffix}"
new_unique_id = f"{MOCK_MAC} {new_key}"
entry = MockConfigEntry(
domain=DOMAIN,
data={CONF_HOST: MOCK_HOST, CONF_PORT: MOCK_PORT},
unique_id=MOCK_HOST,
)
entry.add_to_hass(hass)
entity_registry.async_get_or_create(
platform,
DOMAIN,
old_unique_id,
config_entry=entry,
)
assert await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done()
assert entity_registry.async_get_entity_id(platform, DOMAIN, old_unique_id) is None
assert (
entity_registry.async_get_entity_id(platform, DOMAIN, new_unique_id) is not None
)
+22 -24
View File
@@ -25,14 +25,8 @@ async def test_network_speed(
"""Test missed call sensor."""
await setup_platform(hass, SENSOR_DOMAIN)
assert (
hass.states.get("sensor.freebox_server_r2_freebox_download_speed").state
== "198.9"
)
assert (
hass.states.get("sensor.freebox_server_r2_freebox_upload_speed").state
== "1440.0"
)
assert hass.states.get("sensor.freebox_server_r2_download_speed").state == "198.9"
assert hass.states.get("sensor.freebox_server_r2_upload_speed").state == "1440.0"
# Simulate a changed speed
data_connection_get_status_changed = deepcopy(DATA_CONNECTION_GET_STATUS)
@@ -44,14 +38,8 @@ async def test_network_speed(
async_fire_time_changed(hass)
# To execute the save
await hass.async_block_till_done()
assert (
hass.states.get("sensor.freebox_server_r2_freebox_download_speed").state
== "123.4"
)
assert (
hass.states.get("sensor.freebox_server_r2_freebox_upload_speed").state
== "432.1"
)
assert hass.states.get("sensor.freebox_server_r2_download_speed").state == "123.4"
assert hass.states.get("sensor.freebox_server_r2_upload_speed").state == "432.1"
async def test_call(
@@ -60,7 +48,7 @@ async def test_call(
"""Test missed call sensor."""
await setup_platform(hass, SENSOR_DOMAIN)
assert hass.states.get("sensor.freebox_server_r2_freebox_missed_calls").state == "3"
assert hass.states.get("sensor.freebox_server_r2_missed_calls").state == "3"
# Simulate we marked calls as read
data_call_get_calls_marked_as_read = []
@@ -70,7 +58,7 @@ async def test_call(
async_fire_time_changed(hass)
# To execute the save
await hass.async_block_till_done()
assert hass.states.get("sensor.freebox_server_r2_freebox_missed_calls").state == "0"
assert hass.states.get("sensor.freebox_server_r2_missed_calls").state == "0"
async def test_disk(
@@ -104,15 +92,25 @@ async def test_disk(
assert hass.states.get("sensor.disk_3000_freebox_free_space").state == "44.9"
async def test_temperature(hass: HomeAssistant, router: Mock) -> None:
"""Test temperature sensors expose API names and values."""
await setup_platform(hass, SENSOR_DOMAIN)
assert hass.states.get("sensor.freebox_server_r2_disque_dur").state == "40"
assert hass.states.get("sensor.freebox_server_r2_temperature_switch").state == "50"
assert hass.states.get("sensor.freebox_server_r2_temperature_cpu_m").state == "60"
assert hass.states.get("sensor.freebox_server_r2_temperature_cpu_b").state == "56"
async def test_battery(
hass: HomeAssistant, freezer: FrozenDateTimeFactory, router: Mock
) -> None:
"""Test battery sensor."""
await setup_platform(hass, SENSOR_DOMAIN)
assert hass.states.get("sensor.telecommande_niveau_de_batterie").state == "100"
assert hass.states.get("sensor.ouverture_porte_niveau_de_batterie").state == "100"
assert hass.states.get("sensor.detecteur_niveau_de_batterie").state == "100"
assert hass.states.get("sensor.telecommande_battery").state == "100"
assert hass.states.get("sensor.ouverture_porte_battery").state == "100"
assert hass.states.get("sensor.detecteur_battery").state == "100"
# Simulate a changed battery
data_home_get_nodes_changed = deepcopy(DATA_HOME_GET_NODES)
@@ -125,6 +123,6 @@ async def test_battery(
async_fire_time_changed(hass)
# To execute the save
await hass.async_block_till_done()
assert hass.states.get("sensor.telecommande_niveau_de_batterie").state == "25"
assert hass.states.get("sensor.ouverture_porte_niveau_de_batterie").state == "50"
assert hass.states.get("sensor.detecteur_niveau_de_batterie").state == "75"
assert hass.states.get("sensor.telecommande_battery").state == "25"
assert hass.states.get("sensor.ouverture_porte_battery").state == "50"
assert hass.states.get("sensor.detecteur_battery").state == "75"