mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 05:07:41 +00:00
Fix Shelly Air lamp life sensor (#140799)
This commit is contained in:
parent
18bd8b561a
commit
9b57a831f7
@ -39,7 +39,7 @@ from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
|||||||
from homeassistant.helpers.entity_registry import RegistryEntry
|
from homeassistant.helpers.entity_registry import RegistryEntry
|
||||||
from homeassistant.helpers.typing import StateType
|
from homeassistant.helpers.typing import StateType
|
||||||
|
|
||||||
from .const import CONF_SLEEP_PERIOD, ROLE_TO_DEVICE_CLASS_MAP, SHAIR_MAX_WORK_HOURS
|
from .const import CONF_SLEEP_PERIOD, ROLE_TO_DEVICE_CLASS_MAP
|
||||||
from .coordinator import ShellyBlockCoordinator, ShellyConfigEntry, ShellyRpcCoordinator
|
from .coordinator import ShellyBlockCoordinator, ShellyConfigEntry, ShellyRpcCoordinator
|
||||||
from .entity import (
|
from .entity import (
|
||||||
BlockEntityDescription,
|
BlockEntityDescription,
|
||||||
@ -58,6 +58,7 @@ from .utils import (
|
|||||||
async_remove_orphaned_entities,
|
async_remove_orphaned_entities,
|
||||||
get_device_entry_gen,
|
get_device_entry_gen,
|
||||||
get_device_uptime,
|
get_device_uptime,
|
||||||
|
get_shelly_air_lamp_life,
|
||||||
get_virtual_component_ids,
|
get_virtual_component_ids,
|
||||||
is_rpc_wifi_stations_disabled,
|
is_rpc_wifi_stations_disabled,
|
||||||
)
|
)
|
||||||
@ -355,7 +356,7 @@ SENSORS: dict[tuple[str, str], BlockSensorDescription] = {
|
|||||||
name="Lamp life",
|
name="Lamp life",
|
||||||
native_unit_of_measurement=PERCENTAGE,
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
translation_key="lamp_life",
|
translation_key="lamp_life",
|
||||||
value=lambda value: 100 - (value / 3600 / SHAIR_MAX_WORK_HOURS),
|
value=get_shelly_air_lamp_life,
|
||||||
suggested_display_precision=1,
|
suggested_display_precision=1,
|
||||||
extra_state_attributes=lambda block: {
|
extra_state_attributes=lambda block: {
|
||||||
"Operational hours": round(cast(int, block.totalWorkTime) / 3600, 1)
|
"Operational hours": round(cast(int, block.totalWorkTime) / 3600, 1)
|
||||||
|
@ -59,6 +59,7 @@ from .const import (
|
|||||||
GEN2_RELEASE_URL,
|
GEN2_RELEASE_URL,
|
||||||
LOGGER,
|
LOGGER,
|
||||||
RPC_INPUTS_EVENTS_TYPES,
|
RPC_INPUTS_EVENTS_TYPES,
|
||||||
|
SHAIR_MAX_WORK_HOURS,
|
||||||
SHBTN_INPUTS_EVENTS_TYPES,
|
SHBTN_INPUTS_EVENTS_TYPES,
|
||||||
SHBTN_MODELS,
|
SHBTN_MODELS,
|
||||||
SHELLY_EMIT_EVENT_PATTERN,
|
SHELLY_EMIT_EVENT_PATTERN,
|
||||||
@ -655,3 +656,11 @@ def is_rpc_exclude_from_relay(
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
return is_rpc_channel_type_light(settings, ch)
|
return is_rpc_channel_type_light(settings, ch)
|
||||||
|
|
||||||
|
|
||||||
|
def get_shelly_air_lamp_life(lamp_seconds: int) -> float:
|
||||||
|
"""Return Shelly Air lamp life in percentage."""
|
||||||
|
lamp_hours = lamp_seconds / 3600
|
||||||
|
if lamp_hours >= SHAIR_MAX_WORK_HOURS:
|
||||||
|
return 0.0
|
||||||
|
return 100 * (1 - lamp_hours / SHAIR_MAX_WORK_HOURS)
|
||||||
|
@ -102,12 +102,14 @@ MOCK_BLOCKS = [
|
|||||||
"power": 53.4,
|
"power": 53.4,
|
||||||
"energy": 1234567.89,
|
"energy": 1234567.89,
|
||||||
"output": True,
|
"output": True,
|
||||||
|
"totalWorkTime": 3600,
|
||||||
},
|
},
|
||||||
channel="0",
|
channel="0",
|
||||||
type="relay",
|
type="relay",
|
||||||
overpower=0,
|
overpower=0,
|
||||||
power=53.4,
|
power=53.4,
|
||||||
energy=1234567.89,
|
energy=1234567.89,
|
||||||
|
totalWorkTime=3600,
|
||||||
description="relay_0",
|
description="relay_0",
|
||||||
set_state=AsyncMock(side_effect=lambda turn: {"ison": turn == "on"}),
|
set_state=AsyncMock(side_effect=lambda turn: {"ison": turn == "on"}),
|
||||||
),
|
),
|
||||||
|
@ -374,6 +374,33 @@ async def test_block_sensor_unknown_value(
|
|||||||
assert hass.states.get(entity_id).state == STATE_UNKNOWN
|
assert hass.states.get(entity_id).state == STATE_UNKNOWN
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("lamp_life_seconds", "percentage"),
|
||||||
|
[
|
||||||
|
(0 * 3600, "100.0"), # 0 hours, 100% remaining
|
||||||
|
(16 * 3600, "99.8222222222222"),
|
||||||
|
(4500 * 3600, "50.0"), # 4500 hours, 50% remaining
|
||||||
|
(9000 * 3600, "0.0"), # 9000 hours, 0% remaining
|
||||||
|
(10000 * 3600, "0.0"), # > 9000 hours, 0% remaining
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_block_shelly_air_lamp_life(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_block_device: Mock,
|
||||||
|
monkeypatch: pytest.MonkeyPatch,
|
||||||
|
lamp_life_seconds: int,
|
||||||
|
percentage: float,
|
||||||
|
) -> None:
|
||||||
|
"""Test block Shelly Air lamp life percentage sensor."""
|
||||||
|
entity_id = f"{SENSOR_DOMAIN}.{'test_name_channel_1_lamp_life'}"
|
||||||
|
monkeypatch.setattr(
|
||||||
|
mock_block_device.blocks[RELAY_BLOCK_ID], "totalWorkTime", lamp_life_seconds
|
||||||
|
)
|
||||||
|
await init_integration(hass, 1)
|
||||||
|
|
||||||
|
assert hass.states.get(entity_id).state == percentage
|
||||||
|
|
||||||
|
|
||||||
async def test_rpc_sensor(
|
async def test_rpc_sensor(
|
||||||
hass: HomeAssistant, mock_rpc_device: Mock, monkeypatch: pytest.MonkeyPatch
|
hass: HomeAssistant, mock_rpc_device: Mock, monkeypatch: pytest.MonkeyPatch
|
||||||
) -> None:
|
) -> None:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user