mirror of
https://github.com/home-assistant/core.git
synced 2026-10-06 14:29:21 -04:00
Add operation status sensor to MELCloud Home (#183770)
This commit is contained in:
@@ -6,7 +6,7 @@ from datetime import datetime
|
||||
from itertools import chain
|
||||
from typing import override
|
||||
|
||||
from aiomelcloudhome import ATAUnit, ATWUnit
|
||||
from aiomelcloudhome import ATAUnit, ATWOperationMode, ATWUnit
|
||||
|
||||
from homeassistant.components.sensor import (
|
||||
SensorDeviceClass,
|
||||
@@ -44,6 +44,14 @@ ENERGY_CONSUMED_DESCRIPTION = SensorEntityDescription(
|
||||
suggested_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
)
|
||||
|
||||
ATW_OPERATION_STATUS: dict[ATWOperationMode, str] = {
|
||||
ATWOperationMode.STOP: "idle",
|
||||
ATWOperationMode.HOT_WATER: "heating_water",
|
||||
ATWOperationMode.HEAT: "heating_zones",
|
||||
ATWOperationMode.HEAT_ZONES: "heating_zones",
|
||||
ATWOperationMode.COOL: "cooling",
|
||||
}
|
||||
|
||||
OUTDOOR_TEMPERATURE_DESCRIPTION = SensorEntityDescription(
|
||||
key="outdoor_temperature",
|
||||
translation_key="outdoor_temperature",
|
||||
@@ -126,6 +134,15 @@ ATW_SENSORS: tuple[MelCloudHomeSensorEntityDescription[ATWUnit], ...] = (
|
||||
suggested_display_precision=1,
|
||||
value_fn=lambda unit, _: unit.tank_water_temperature,
|
||||
),
|
||||
MelCloudHomeSensorEntityDescription(
|
||||
key="operation_status",
|
||||
translation_key="operation_status",
|
||||
device_class=SensorDeviceClass.ENUM,
|
||||
options=list(dict.fromkeys(ATW_OPERATION_STATUS.values())),
|
||||
value_fn=lambda unit, _: (
|
||||
ATW_OPERATION_STATUS[unit.operation_mode] if unit.operation_mode else None
|
||||
),
|
||||
),
|
||||
*_common_sensor_descriptions(ATWUnit),
|
||||
)
|
||||
|
||||
|
||||
@@ -127,6 +127,15 @@
|
||||
"energy_consumed": {
|
||||
"name": "Energy consumed (monthly)"
|
||||
},
|
||||
"operation_status": {
|
||||
"name": "Operation status",
|
||||
"state": {
|
||||
"cooling": "Cooling",
|
||||
"heating_water": "Heating water",
|
||||
"heating_zones": "Heating zones",
|
||||
"idle": "[%key:common::state::idle%]"
|
||||
}
|
||||
},
|
||||
"outdoor_temperature": {
|
||||
"name": "Outdoor temperature"
|
||||
},
|
||||
|
||||
@@ -61,6 +61,70 @@
|
||||
'state': '0.4505',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.heat_pump_operation_status-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': list([
|
||||
None,
|
||||
]),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
<SensorEntityCapabilityAttribute.OPTIONS: 'options'>: list([
|
||||
'idle',
|
||||
'heating_water',
|
||||
'heating_zones',
|
||||
'cooling',
|
||||
]),
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.heat_pump_operation_status',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Operation status',
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.ENUM: 'enum'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Operation status',
|
||||
'platform': 'melcloud_home',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'operation_status',
|
||||
'unique_id': 'atw-unit-uuid-1_operation_status',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.heat_pump_operation_status-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'enum',
|
||||
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Heat Pump Operation status',
|
||||
<SensorEntityCapabilityAttribute.OPTIONS: 'options'>: list([
|
||||
'idle',
|
||||
'heating_water',
|
||||
'heating_zones',
|
||||
'cooling',
|
||||
]),
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.heat_pump_operation_status',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'heating_zones',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.heat_pump_signal_strength-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': list([
|
||||
|
||||
@@ -1,17 +1,25 @@
|
||||
"""Tests for the MELCloud Home sensor platform."""
|
||||
|
||||
from unittest.mock import patch
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
from aiomelcloudhome import UserContext
|
||||
import pytest
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
|
||||
from homeassistant.const import Platform
|
||||
from homeassistant.components.melcloud_home.const import DOMAIN
|
||||
from homeassistant.const import STATE_UNKNOWN, Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
|
||||
from . import setup_integration
|
||||
|
||||
from tests.common import MockConfigEntry, snapshot_platform
|
||||
from tests.common import (
|
||||
MockConfigEntry,
|
||||
async_load_json_object_fixture,
|
||||
snapshot_platform,
|
||||
)
|
||||
|
||||
OPERATION_STATUS_ENTITY_ID = "sensor.heat_pump_operation_status"
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
@@ -36,3 +44,36 @@ async def test_all_entities(
|
||||
await snapshot_platform(
|
||||
hass, entity_registry, snapshot, mock_config_entry.entry_id
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("operation_mode", "expected_state"),
|
||||
[
|
||||
pytest.param("Stop", "idle", id="idle"),
|
||||
pytest.param("HotWater", "heating_water", id="heating_water"),
|
||||
pytest.param("Heat", "heating_zones", id="heat"),
|
||||
pytest.param("HeatZones", "heating_zones", id="heating_zones"),
|
||||
pytest.param("Cool", "cooling", id="cooling"),
|
||||
pytest.param("Defrost", STATE_UNKNOWN, id="unsupported_mode"),
|
||||
],
|
||||
)
|
||||
async def test_operation_status(
|
||||
hass: HomeAssistant,
|
||||
mock_melcloud_client: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
operation_mode: str,
|
||||
expected_state: str,
|
||||
) -> None:
|
||||
"""Test the operation status follows the unit's operation mode."""
|
||||
context = await async_load_json_object_fixture(hass, "context.json", DOMAIN)
|
||||
settings = {
|
||||
unit_setting["name"]: unit_setting
|
||||
for unit_setting in context["buildings"][0]["airToWaterUnits"][0]["settings"]
|
||||
}
|
||||
settings["OperationMode"]["value"] = operation_mode
|
||||
mock_melcloud_client.get_context.return_value = UserContext.model_validate(context)
|
||||
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
assert (state := hass.states.get(OPERATION_STATUS_ENTITY_ID))
|
||||
assert state.state == expected_state
|
||||
|
||||
Reference in New Issue
Block a user