Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions homeassistant/components/shelly/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,6 @@
BLOCK_WRONG_SLEEP_PERIOD = 21600
BLOCK_EXPECTED_SLEEP_PERIOD = 43200

UPTIME_DEVIATION: Final = 60

# Time to wait before reloading entry upon device config change
ENTRY_RELOAD_COOLDOWN = 60

Expand Down
11 changes: 6 additions & 5 deletions homeassistant/components/shelly/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from __future__ import annotations

from dataclasses import dataclass
from datetime import timedelta
from typing import Final, cast

from aioshelly.block_device import Block
Expand Down Expand Up @@ -41,6 +42,7 @@
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from homeassistant.helpers.entity_registry import RegistryEntry
from homeassistant.helpers.typing import StateType
from homeassistant.util.dt import utcnow

from .const import CONF_SLEEP_PERIOD, ROLE_GENERIC
from .coordinator import ShellyBlockCoordinator, ShellyConfigEntry, ShellyRpcCoordinator
Expand All @@ -62,7 +64,6 @@
async_remove_orphaned_entities,
get_blu_trv_device_info,
get_device_entry_gen,
get_device_uptime,
get_shelly_air_lamp_life,
get_virtual_component_unit,
is_rpc_wifi_stations_disabled,
Expand Down Expand Up @@ -467,8 +468,8 @@ def __init__(
"uptime": RestSensorDescription(
key="uptime",
translation_key="last_restart",
value=lambda status, last: get_device_uptime(status["uptime"], last),
device_class=SensorDeviceClass.TIMESTAMP,
value=lambda status, _: utcnow() - timedelta(seconds=status["uptime"]),
device_class=SensorDeviceClass.UPTIME,
entity_registry_enabled_default=False,
entity_category=EntityCategory.DIAGNOSTIC,
),
Expand Down Expand Up @@ -1243,8 +1244,8 @@ def __init__(
key="sys",
sub_key="uptime",
translation_key="last_restart",
value=get_device_uptime,
device_class=SensorDeviceClass.TIMESTAMP,
device_class=SensorDeviceClass.UPTIME,
value=lambda status, _: utcnow() - timedelta(seconds=status),
entity_registry_enabled_default=False,
entity_category=EntityCategory.DIAGNOSTIC,
use_polling_coordinator=True,
Expand Down
26 changes: 0 additions & 26 deletions homeassistant/components/shelly/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from __future__ import annotations

from collections.abc import Iterable, Mapping
from datetime import datetime, timedelta
from ipaddress import IPv4Address, IPv6Address, ip_address
from typing import TYPE_CHECKING, Any, cast

Expand Down Expand Up @@ -51,7 +50,6 @@
DeviceInfo,
)
from homeassistant.helpers.network import NoURLAvailableError, get_url
from homeassistant.util.dt import utcnow

from .const import (
API_WS_URL,
Expand All @@ -78,7 +76,6 @@
SHELLY_EMIT_EVENT_PATTERN,
SHELLY_WALL_DISPLAY_MODELS,
SHIX3_1_INPUTS_EVENTS_TYPES,
UPTIME_DEVIATION,
VIRTUAL_COMPONENTS,
VIRTUAL_COMPONENTS_MAP,
WALL_DISPLAY_RELEASE_URL,
Expand Down Expand Up @@ -194,29 +191,6 @@ def is_block_exclude_from_relay(settings: dict[str, Any], block: Block) -> bool:
return is_block_channel_type_light(settings, block)


def get_device_uptime(uptime: float, last_uptime: datetime | None) -> datetime:
"""Return device uptime string, tolerate up to 5 seconds deviation."""
delta_uptime = utcnow() - timedelta(seconds=uptime)

if (
not last_uptime
or (diff := abs((delta_uptime - last_uptime).total_seconds()))
> UPTIME_DEVIATION
):
if last_uptime:
LOGGER.debug(
"Time deviation %s > %s: uptime=%s, last_uptime=%s, delta_uptime=%s",
diff,
UPTIME_DEVIATION,
uptime,
last_uptime,
delta_uptime,
)
return delta_uptime

return last_uptime


def get_block_input_triggers(
device: BlockDevice, block: Block
) -> list[tuple[str, str]]:
Expand Down
32 changes: 16 additions & 16 deletions tests/components/shelly/snapshots/test_devices.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@
'object_id_base': 'Last restart',
'options': dict({
}),
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
'original_device_class': <SensorDeviceClass.UPTIME: 'uptime'>,
'original_icon': None,
'original_name': 'Last restart',
'platform': 'shelly',
Expand All @@ -483,7 +483,7 @@
# name: test_device[cury_gen4][sensor.test_name_last_restart-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'timestamp',
'device_class': 'uptime',
'friendly_name': 'Test name Last restart',
}),
'context': <ANY>,
Expand Down Expand Up @@ -1379,7 +1379,7 @@
'object_id_base': 'Last restart',
'options': dict({
}),
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
'original_device_class': <SensorDeviceClass.UPTIME: 'uptime'>,
'original_icon': None,
'original_name': 'Last restart',
'platform': 'shelly',
Expand All @@ -1394,7 +1394,7 @@
# name: test_device[duo_bulb_gen3][sensor.test_name_last_restart-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'timestamp',
'device_class': 'uptime',
'friendly_name': 'Test name Last restart',
}),
'context': <ANY>,
Expand Down Expand Up @@ -3588,7 +3588,7 @@
'object_id_base': 'Last restart',
'options': dict({
}),
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
'original_device_class': <SensorDeviceClass.UPTIME: 'uptime'>,
'original_icon': None,
'original_name': 'Last restart',
'platform': 'shelly',
Expand All @@ -3603,7 +3603,7 @@
# name: test_device[power_strip_gen4][sensor.test_name_last_restart-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'timestamp',
'device_class': 'uptime',
'friendly_name': 'Test name Last restart',
}),
'context': <ANY>,
Expand Down Expand Up @@ -5168,7 +5168,7 @@
'object_id_base': 'Last restart',
'options': dict({
}),
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
'original_device_class': <SensorDeviceClass.UPTIME: 'uptime'>,
'original_icon': None,
'original_name': 'Last restart',
'platform': 'shelly',
Expand All @@ -5183,7 +5183,7 @@
# name: test_device[presence_gen4][sensor.test_name_last_restart-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'timestamp',
'device_class': 'uptime',
'friendly_name': 'Test name Last restart',
}),
'context': <ANY>,
Expand Down Expand Up @@ -6275,7 +6275,7 @@
'object_id_base': 'Last restart',
'options': dict({
}),
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
'original_device_class': <SensorDeviceClass.UPTIME: 'uptime'>,
'original_icon': None,
'original_name': 'Last restart',
'platform': 'shelly',
Expand All @@ -6290,7 +6290,7 @@
# name: test_device[wall_display_xl][sensor.test_name_last_restart-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'timestamp',
'device_class': 'uptime',
'friendly_name': 'Test name Last restart',
}),
'context': <ANY>,
Expand Down Expand Up @@ -7304,7 +7304,7 @@
'object_id_base': 'Last restart',
'options': dict({
}),
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
'original_device_class': <SensorDeviceClass.UPTIME: 'uptime'>,
'original_icon': None,
'original_name': 'Last restart',
'platform': 'shelly',
Expand All @@ -7319,7 +7319,7 @@
# name: test_shelly_2pm_gen3_cover[sensor.test_name_last_restart-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'timestamp',
'device_class': 'uptime',
'friendly_name': 'Test name Last restart',
}),
'context': <ANY>,
Expand Down Expand Up @@ -8373,7 +8373,7 @@
'object_id_base': 'Last restart',
'options': dict({
}),
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
'original_device_class': <SensorDeviceClass.UPTIME: 'uptime'>,
'original_icon': None,
'original_name': 'Last restart',
'platform': 'shelly',
Expand All @@ -8388,7 +8388,7 @@
# name: test_shelly_2pm_gen3_no_relay_names[sensor.test_name_last_restart-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'timestamp',
'device_class': 'uptime',
'friendly_name': 'Test name Last restart',
}),
'context': <ANY>,
Expand Down Expand Up @@ -10042,7 +10042,7 @@
'object_id_base': 'Last restart',
'options': dict({
}),
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
'original_device_class': <SensorDeviceClass.UPTIME: 'uptime'>,
'original_icon': None,
'original_name': 'Last restart',
'platform': 'shelly',
Expand All @@ -10057,7 +10057,7 @@
# name: test_shelly_pro_3em[sensor.test_name_last_restart-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'timestamp',
'device_class': 'uptime',
'friendly_name': 'Test name Last restart',
}),
'context': <ANY>,
Expand Down
16 changes: 0 additions & 16 deletions tests/components/shelly/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,13 @@
GEN1_RELEASE_URL,
GEN2_BETA_RELEASE_URL,
GEN2_RELEASE_URL,
UPTIME_DEVIATION,
WALL_DISPLAY_RELEASE_URL,
)
from homeassistant.components.shelly.utils import (
ShellyReceiver,
get_block_device_sleep_period,
get_block_input_triggers,
get_block_number_of_channels,
get_device_uptime,
get_host,
get_release_url,
get_rpc_channel_name,
Expand All @@ -39,7 +37,6 @@
is_block_momentary_input,
mac_address_from_name,
)
from homeassistant.util import dt as dt_util

DEVICE_BLOCK_ID = 4

Expand Down Expand Up @@ -149,19 +146,6 @@ async def test_get_block_device_sleep_period(
assert get_block_device_sleep_period(settings) == sleep_period


@pytest.mark.freeze_time("2019-01-10 18:43:00+00:00")
async def test_get_device_uptime() -> None:
"""Test block test get device uptime."""
assert get_device_uptime(
55, dt_util.as_utc(dt_util.parse_datetime("2019-01-10 18:42:00+00:00"))
) == dt_util.as_utc(dt_util.parse_datetime("2019-01-10 18:42:00+00:00"))

assert get_device_uptime(
55 - UPTIME_DEVIATION,
dt_util.as_utc(dt_util.parse_datetime("2019-01-10 18:42:00+00:00")),
) == dt_util.as_utc(dt_util.parse_datetime("2019-01-10 18:43:05+00:00"))


async def test_get_block_input_triggers(
mock_block_device: Mock, monkeypatch: pytest.MonkeyPatch
) -> None:
Expand Down