mirror of
https://github.com/home-assistant/core.git
synced 2026-02-15 07:36:16 +00:00
Add uptime ratio and avg. response time sensors to Uptime Kuma (#162785)
This commit is contained in:
@@ -1,6 +1,15 @@
|
||||
{
|
||||
"entity": {
|
||||
"sensor": {
|
||||
"avg_response_time_1d": {
|
||||
"default": "mdi:timeline-clock-outline"
|
||||
},
|
||||
"avg_response_time_30d": {
|
||||
"default": "mdi:timeline-clock-outline"
|
||||
},
|
||||
"avg_response_time_365d": {
|
||||
"default": "mdi:timeline-clock-outline"
|
||||
},
|
||||
"cert_days_remaining": {
|
||||
"default": "mdi:certificate"
|
||||
},
|
||||
@@ -24,6 +33,15 @@
|
||||
"type": {
|
||||
"default": "mdi:protocol"
|
||||
},
|
||||
"uptime_1d": {
|
||||
"default": "mdi:history"
|
||||
},
|
||||
"uptime_30d": {
|
||||
"default": "mdi:history"
|
||||
},
|
||||
"uptime_365d": {
|
||||
"default": "mdi:history"
|
||||
},
|
||||
"url": {
|
||||
"default": "mdi:web"
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ from homeassistant.components.sensor import (
|
||||
SensorEntity,
|
||||
SensorEntityDescription,
|
||||
)
|
||||
from homeassistant.const import CONF_URL, EntityCategory, UnitOfTime
|
||||
from homeassistant.const import CONF_URL, PERCENTAGE, EntityCategory, UnitOfTime
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
@@ -37,6 +37,12 @@ class UptimeKumaSensor(StrEnum):
|
||||
URL = "url"
|
||||
HOSTNAME = "hostname"
|
||||
PORT = "port"
|
||||
UPTIME_RATIO_1D = "uptime_1d"
|
||||
UPTIME_RATIO_30D = "uptime_30d"
|
||||
UPTIME_RATIO_365D = "uptime_365d"
|
||||
AVG_RESPONSE_TIME_1D = "avg_response_time_1d"
|
||||
AVG_RESPONSE_TIME_30D = "avg_response_time_30d"
|
||||
AVG_RESPONSE_TIME_365D = "avg_response_time_365d"
|
||||
|
||||
|
||||
@dataclass(kw_only=True, frozen=True)
|
||||
@@ -104,6 +110,76 @@ SENSOR_DESCRIPTIONS: tuple[UptimeKumaSensorEntityDescription, ...] = (
|
||||
value_fn=lambda m: m.monitor_port,
|
||||
create_entity=lambda t: t in HAS_PORT,
|
||||
),
|
||||
UptimeKumaSensorEntityDescription(
|
||||
key=UptimeKumaSensor.PORT,
|
||||
translation_key=UptimeKumaSensor.PORT,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
value_fn=lambda m: m.monitor_port,
|
||||
create_entity=lambda t: t in HAS_PORT,
|
||||
),
|
||||
UptimeKumaSensorEntityDescription(
|
||||
key=UptimeKumaSensor.UPTIME_RATIO_1D,
|
||||
translation_key=UptimeKumaSensor.UPTIME_RATIO_1D,
|
||||
value_fn=lambda m: (
|
||||
m.monitor_uptime_ratio_1d * 100
|
||||
if m.monitor_uptime_ratio_1d is not None
|
||||
else None
|
||||
),
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
suggested_display_precision=2,
|
||||
create_entity=lambda t: True,
|
||||
),
|
||||
UptimeKumaSensorEntityDescription(
|
||||
key=UptimeKumaSensor.UPTIME_RATIO_30D,
|
||||
translation_key=UptimeKumaSensor.UPTIME_RATIO_30D,
|
||||
value_fn=lambda m: (
|
||||
m.monitor_uptime_ratio_30d * 100
|
||||
if m.monitor_uptime_ratio_30d is not None
|
||||
else None
|
||||
),
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
suggested_display_precision=2,
|
||||
create_entity=lambda t: True,
|
||||
),
|
||||
UptimeKumaSensorEntityDescription(
|
||||
key=UptimeKumaSensor.UPTIME_RATIO_365D,
|
||||
translation_key=UptimeKumaSensor.UPTIME_RATIO_365D,
|
||||
value_fn=lambda m: (
|
||||
m.monitor_uptime_ratio_365d * 100
|
||||
if m.monitor_uptime_ratio_365d is not None
|
||||
else None
|
||||
),
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
suggested_display_precision=2,
|
||||
create_entity=lambda t: True,
|
||||
),
|
||||
UptimeKumaSensorEntityDescription(
|
||||
key=UptimeKumaSensor.AVG_RESPONSE_TIME_1D,
|
||||
translation_key=UptimeKumaSensor.AVG_RESPONSE_TIME_1D,
|
||||
value_fn=lambda m: m.monitor_response_time_seconds_1d,
|
||||
device_class=SensorDeviceClass.DURATION,
|
||||
native_unit_of_measurement=UnitOfTime.SECONDS,
|
||||
suggested_unit_of_measurement=UnitOfTime.MILLISECONDS,
|
||||
create_entity=lambda t: True,
|
||||
),
|
||||
UptimeKumaSensorEntityDescription(
|
||||
key=UptimeKumaSensor.AVG_RESPONSE_TIME_30D,
|
||||
translation_key=UptimeKumaSensor.AVG_RESPONSE_TIME_30D,
|
||||
value_fn=lambda m: m.monitor_response_time_seconds_30d,
|
||||
device_class=SensorDeviceClass.DURATION,
|
||||
native_unit_of_measurement=UnitOfTime.SECONDS,
|
||||
suggested_unit_of_measurement=UnitOfTime.MILLISECONDS,
|
||||
create_entity=lambda t: True,
|
||||
),
|
||||
UptimeKumaSensorEntityDescription(
|
||||
key=UptimeKumaSensor.AVG_RESPONSE_TIME_365D,
|
||||
translation_key=UptimeKumaSensor.AVG_RESPONSE_TIME_365D,
|
||||
value_fn=lambda m: m.monitor_response_time_seconds_365d,
|
||||
device_class=SensorDeviceClass.DURATION,
|
||||
native_unit_of_measurement=UnitOfTime.SECONDS,
|
||||
suggested_unit_of_measurement=UnitOfTime.MILLISECONDS,
|
||||
create_entity=lambda t: True,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -61,6 +61,15 @@
|
||||
},
|
||||
"entity": {
|
||||
"sensor": {
|
||||
"avg_response_time_1d": {
|
||||
"name": "Response time Ø (1 day)"
|
||||
},
|
||||
"avg_response_time_30d": {
|
||||
"name": "Response time Ø (30 days)"
|
||||
},
|
||||
"avg_response_time_365d": {
|
||||
"name": "Response time Ø (365 days)"
|
||||
},
|
||||
"cert_days_remaining": {
|
||||
"name": "Certificate expiry"
|
||||
},
|
||||
@@ -117,6 +126,15 @@
|
||||
"websocket_upgrade": "WebSocket-Upgrade"
|
||||
}
|
||||
},
|
||||
"uptime_1d": {
|
||||
"name": "Uptime (1 day)"
|
||||
},
|
||||
"uptime_30d": {
|
||||
"name": "Uptime (30 days)"
|
||||
},
|
||||
"uptime_365d": {
|
||||
"name": "Uptime (365 days)"
|
||||
},
|
||||
"url": {
|
||||
"name": "Monitored URL"
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ def mock_pythonkuma() -> Generator[AsyncMock]:
|
||||
monitor_1 = UptimeKumaMonitor(
|
||||
monitor_id=1,
|
||||
monitor_cert_days_remaining=90,
|
||||
monitor_cert_is_valid=1,
|
||||
monitor_cert_is_valid=True,
|
||||
monitor_hostname=None,
|
||||
monitor_name="Monitor 1",
|
||||
monitor_port=None,
|
||||
@@ -64,11 +64,17 @@ def mock_pythonkuma() -> Generator[AsyncMock]:
|
||||
monitor_status=MonitorStatus.UP,
|
||||
monitor_type=MonitorType.HTTP,
|
||||
monitor_url="https://example.org",
|
||||
monitor_uptime_ratio_1d=1,
|
||||
monitor_uptime_ratio_30d=0.9993369956431142,
|
||||
monitor_uptime_ratio_365d=0.9941977428851816,
|
||||
monitor_response_time_seconds_1d=0.10920649819494585,
|
||||
monitor_response_time_seconds_30d=0.0993296843901052,
|
||||
monitor_response_time_seconds_365d=0.1043971646081903,
|
||||
)
|
||||
monitor_2 = UptimeKumaMonitor(
|
||||
monitor_id=2,
|
||||
monitor_cert_days_remaining=0,
|
||||
monitor_cert_is_valid=0,
|
||||
monitor_cert_is_valid=False,
|
||||
monitor_hostname=None,
|
||||
monitor_name="Monitor 2",
|
||||
monitor_port=None,
|
||||
@@ -76,11 +82,17 @@ def mock_pythonkuma() -> Generator[AsyncMock]:
|
||||
monitor_status=MonitorStatus.UP,
|
||||
monitor_type=MonitorType.PORT,
|
||||
monitor_url=None,
|
||||
monitor_uptime_ratio_1d=0.9992223950233281,
|
||||
monitor_uptime_ratio_30d=0.9990979870869731,
|
||||
monitor_uptime_ratio_365d=0.9994612200915926,
|
||||
monitor_response_time_seconds_1d=0.16390272373540857,
|
||||
monitor_response_time_seconds_30d=0.3371273224043715,
|
||||
monitor_response_time_seconds_365d=0.34270098747886596,
|
||||
)
|
||||
monitor_3 = UptimeKumaMonitor(
|
||||
monitor_id=3,
|
||||
monitor_cert_days_remaining=90,
|
||||
monitor_cert_is_valid=1,
|
||||
monitor_cert_is_valid=True,
|
||||
monitor_hostname=None,
|
||||
monitor_name="Monitor 3",
|
||||
monitor_port=None,
|
||||
@@ -88,6 +100,12 @@ def mock_pythonkuma() -> Generator[AsyncMock]:
|
||||
monitor_status=MonitorStatus.DOWN,
|
||||
monitor_type=MonitorType.JSON_QUERY,
|
||||
monitor_url="https://down.example.org",
|
||||
monitor_uptime_ratio_1d=None,
|
||||
monitor_uptime_ratio_30d=None,
|
||||
monitor_uptime_ratio_365d=None,
|
||||
monitor_response_time_seconds_1d=None,
|
||||
monitor_response_time_seconds_30d=None,
|
||||
monitor_response_time_seconds_365d=None,
|
||||
)
|
||||
|
||||
with (
|
||||
|
||||
@@ -3,43 +3,43 @@
|
||||
dict({
|
||||
'1': dict({
|
||||
'monitor_cert_days_remaining': 90,
|
||||
'monitor_cert_is_valid': 1,
|
||||
'monitor_cert_is_valid': True,
|
||||
'monitor_hostname': None,
|
||||
'monitor_id': 1,
|
||||
'monitor_name': 'Monitor 1',
|
||||
'monitor_port': None,
|
||||
'monitor_response_time': 120,
|
||||
'monitor_response_time_seconds_1d': None,
|
||||
'monitor_response_time_seconds_30d': None,
|
||||
'monitor_response_time_seconds_365d': None,
|
||||
'monitor_response_time_seconds_1d': 0.10920649819494585,
|
||||
'monitor_response_time_seconds_30d': 0.0993296843901052,
|
||||
'monitor_response_time_seconds_365d': 0.1043971646081903,
|
||||
'monitor_status': 1,
|
||||
'monitor_type': 'http',
|
||||
'monitor_uptime_ratio_1d': None,
|
||||
'monitor_uptime_ratio_30d': None,
|
||||
'monitor_uptime_ratio_365d': None,
|
||||
'monitor_uptime_ratio_1d': 1,
|
||||
'monitor_uptime_ratio_30d': 0.9993369956431142,
|
||||
'monitor_uptime_ratio_365d': 0.9941977428851816,
|
||||
'monitor_url': '**REDACTED**',
|
||||
}),
|
||||
'2': dict({
|
||||
'monitor_cert_days_remaining': 0,
|
||||
'monitor_cert_is_valid': 0,
|
||||
'monitor_cert_is_valid': False,
|
||||
'monitor_hostname': None,
|
||||
'monitor_id': 2,
|
||||
'monitor_name': 'Monitor 2',
|
||||
'monitor_port': None,
|
||||
'monitor_response_time': 28,
|
||||
'monitor_response_time_seconds_1d': None,
|
||||
'monitor_response_time_seconds_30d': None,
|
||||
'monitor_response_time_seconds_365d': None,
|
||||
'monitor_response_time_seconds_1d': 0.16390272373540857,
|
||||
'monitor_response_time_seconds_30d': 0.3371273224043715,
|
||||
'monitor_response_time_seconds_365d': 0.34270098747886596,
|
||||
'monitor_status': 1,
|
||||
'monitor_type': 'port',
|
||||
'monitor_uptime_ratio_1d': None,
|
||||
'monitor_uptime_ratio_30d': None,
|
||||
'monitor_uptime_ratio_365d': None,
|
||||
'monitor_uptime_ratio_1d': 0.9992223950233281,
|
||||
'monitor_uptime_ratio_30d': 0.9990979870869731,
|
||||
'monitor_uptime_ratio_365d': 0.9994612200915926,
|
||||
'monitor_url': None,
|
||||
}),
|
||||
'3': dict({
|
||||
'monitor_cert_days_remaining': 90,
|
||||
'monitor_cert_is_valid': 1,
|
||||
'monitor_cert_is_valid': True,
|
||||
'monitor_hostname': None,
|
||||
'monitor_id': 3,
|
||||
'monitor_name': 'Monitor 3',
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user