Move common Uptime Robot new device check logic to helper (#153094)

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Abílio Costa
2025-10-02 10:52:22 +01:00
committed by GitHub
parent a0356328c3
commit 3a89b3152f
4 changed files with 94 additions and 67 deletions

View File

@@ -2,6 +2,8 @@
from __future__ import annotations
from pyuptimerobot import UptimeRobotMonitor
from homeassistant.components.binary_sensor import (
BinarySensorDeviceClass,
BinarySensorEntity,
@@ -12,6 +14,7 @@ from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from .coordinator import UptimeRobotConfigEntry
from .entity import UptimeRobotEntity
from .utils import new_device_listener
# Coordinator is used to centralize the data updates
PARALLEL_UPDATES = 0
@@ -25,29 +28,23 @@ async def async_setup_entry(
"""Set up the UptimeRobot binary_sensors."""
coordinator = entry.runtime_data
known_devices: set[int] = set()
def _check_device() -> None:
entities: list[UptimeRobotBinarySensor] = []
for monitor in coordinator.data:
if monitor.id in known_devices:
continue
known_devices.add(monitor.id)
entities.append(
UptimeRobotBinarySensor(
coordinator,
BinarySensorEntityDescription(
key=str(monitor.id),
device_class=BinarySensorDeviceClass.CONNECTIVITY,
),
monitor=monitor,
)
def _add_new_entities(new_monitors: list[UptimeRobotMonitor]) -> None:
"""Add entities for new monitors."""
entities = [
UptimeRobotBinarySensor(
coordinator,
BinarySensorEntityDescription(
key=str(monitor.id),
device_class=BinarySensorDeviceClass.CONNECTIVITY,
),
monitor=monitor,
)
for monitor in new_monitors
]
if entities:
async_add_entities(entities)
_check_device()
entry.async_on_unload(coordinator.async_add_listener(_check_device))
entry.async_on_unload(new_device_listener(coordinator, _add_new_entities))
class UptimeRobotBinarySensor(UptimeRobotEntity, BinarySensorEntity):

View File

@@ -2,6 +2,8 @@
from __future__ import annotations
from pyuptimerobot import UptimeRobotMonitor
from homeassistant.components.sensor import (
SensorDeviceClass,
SensorEntity,
@@ -13,6 +15,7 @@ from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from .coordinator import UptimeRobotConfigEntry
from .entity import UptimeRobotEntity
from .utils import new_device_listener
SENSORS_INFO = {
0: "pause",
@@ -34,38 +37,32 @@ async def async_setup_entry(
"""Set up the UptimeRobot sensors."""
coordinator = entry.runtime_data
known_devices: set[int] = set()
def _check_device() -> None:
entities: list[UptimeRobotSensor] = []
for monitor in coordinator.data:
if monitor.id in known_devices:
continue
known_devices.add(monitor.id)
entities.append(
UptimeRobotSensor(
coordinator,
SensorEntityDescription(
key=str(monitor.id),
entity_category=EntityCategory.DIAGNOSTIC,
device_class=SensorDeviceClass.ENUM,
options=[
"down",
"not_checked_yet",
"pause",
"seems_down",
"up",
],
translation_key="monitor_status",
),
monitor=monitor,
)
def _add_new_entities(new_monitors: list[UptimeRobotMonitor]) -> None:
"""Add entities for new monitors."""
entities = [
UptimeRobotSensor(
coordinator,
SensorEntityDescription(
key=str(monitor.id),
entity_category=EntityCategory.DIAGNOSTIC,
device_class=SensorDeviceClass.ENUM,
options=[
"down",
"not_checked_yet",
"pause",
"seems_down",
"up",
],
translation_key="monitor_status",
),
monitor=monitor,
)
for monitor in new_monitors
]
if entities:
async_add_entities(entities)
_check_device()
entry.async_on_unload(coordinator.async_add_listener(_check_device))
entry.async_on_unload(new_device_listener(coordinator, _add_new_entities))
class UptimeRobotSensor(UptimeRobotEntity, SensorEntity):

View File

@@ -4,7 +4,11 @@ from __future__ import annotations
from typing import Any
from pyuptimerobot import UptimeRobotAuthenticationException, UptimeRobotException
from pyuptimerobot import (
UptimeRobotAuthenticationException,
UptimeRobotException,
UptimeRobotMonitor,
)
from homeassistant.components.switch import (
SwitchDeviceClass,
@@ -18,6 +22,7 @@ from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from .const import API_ATTR_OK, DOMAIN
from .coordinator import UptimeRobotConfigEntry
from .entity import UptimeRobotEntity
from .utils import new_device_listener
# Limit the number of parallel updates to 1
PARALLEL_UPDATES = 1
@@ -31,29 +36,23 @@ async def async_setup_entry(
"""Set up the UptimeRobot switches."""
coordinator = entry.runtime_data
known_devices: set[int] = set()
def _check_device() -> None:
entities: list[UptimeRobotSwitch] = []
for monitor in coordinator.data:
if monitor.id in known_devices:
continue
known_devices.add(monitor.id)
entities.append(
UptimeRobotSwitch(
coordinator,
SwitchEntityDescription(
key=str(monitor.id),
device_class=SwitchDeviceClass.SWITCH,
),
monitor=monitor,
)
def _add_new_entities(new_monitors: list[UptimeRobotMonitor]) -> None:
"""Add entities for new monitors."""
entities = [
UptimeRobotSwitch(
coordinator,
SwitchEntityDescription(
key=str(monitor.id),
device_class=SwitchDeviceClass.SWITCH,
),
monitor=monitor,
)
for monitor in new_monitors
]
if entities:
async_add_entities(entities)
_check_device()
entry.async_on_unload(coordinator.async_add_listener(_check_device))
entry.async_on_unload(new_device_listener(coordinator, _add_new_entities))
class UptimeRobotSwitch(UptimeRobotEntity, SwitchEntity):

View File

@@ -0,0 +1,34 @@
"""Utility functions for the UptimeRobot integration."""
from collections.abc import Callable
from pyuptimerobot import UptimeRobotMonitor
from .coordinator import UptimeRobotDataUpdateCoordinator
def new_device_listener(
coordinator: UptimeRobotDataUpdateCoordinator,
new_devices_callback: Callable[[list[UptimeRobotMonitor]], None],
) -> Callable[[], None]:
"""Subscribe to coordinator updates to check for new devices."""
known_devices: set[int] = set()
def _check_devices() -> None:
"""Check for new devices and call callback with any new monitors."""
if not coordinator.data:
return
new_monitors: list[UptimeRobotMonitor] = []
for monitor in coordinator.data:
if monitor.id not in known_devices:
known_devices.add(monitor.id)
new_monitors.append(monitor)
if new_monitors:
new_devices_callback(new_monitors)
# Check for devices immediately
_check_devices()
return coordinator.async_add_listener(_check_devices)