Compare commits

..

1 Commits

Author SHA1 Message Date
Paul Bottein
df06a5878c Add windows 98 labs feature 2026-03-10 09:41:49 +01:00
24 changed files with 458 additions and 1311 deletions

View File

@@ -137,6 +137,7 @@ _EXPERIMENTAL_CONDITION_PLATFORMS = {
_EXPERIMENTAL_TRIGGER_PLATFORMS = {
"alarm_control_panel",
"assist_satellite",
"binary_sensor",
"button",
"climate",
"cover",

View File

@@ -174,5 +174,13 @@
"on": "mdi:window-open"
}
}
},
"triggers": {
"occupancy_cleared": {
"trigger": "mdi:home-outline"
},
"occupancy_detected": {
"trigger": "mdi:home"
}
}
}

View File

@@ -1,4 +1,8 @@
{
"common": {
"trigger_behavior_description_occupancy": "The behavior of the targeted occupancy sensors to trigger on.",
"trigger_behavior_name": "Behavior"
},
"device_automation": {
"condition_type": {
"is_bat_low": "{entity_name} battery is low",
@@ -317,5 +321,36 @@
}
}
},
"title": "Binary sensor"
"selector": {
"trigger_behavior": {
"options": {
"any": "Any",
"first": "First",
"last": "Last"
}
}
},
"title": "Binary sensor",
"triggers": {
"occupancy_cleared": {
"description": "Triggers after one or more occupancy sensors stop detecting occupancy.",
"fields": {
"behavior": {
"description": "[%key:component::binary_sensor::common::trigger_behavior_description_occupancy%]",
"name": "[%key:component::binary_sensor::common::trigger_behavior_name%]"
}
},
"name": "Occupancy cleared"
},
"occupancy_detected": {
"description": "Triggers after one or more occupancy sensors start detecting occupancy.",
"fields": {
"behavior": {
"description": "[%key:component::binary_sensor::common::trigger_behavior_description_occupancy%]",
"name": "[%key:component::binary_sensor::common::trigger_behavior_name%]"
}
},
"name": "Occupancy detected"
}
}
}

View File

@@ -0,0 +1,67 @@
"""Provides triggers for binary sensors."""
from homeassistant.const import STATE_OFF, STATE_ON
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.entity import get_device_class
from homeassistant.helpers.trigger import EntityTargetStateTriggerBase, Trigger
from homeassistant.helpers.typing import UNDEFINED, UndefinedType
from . import DOMAIN, BinarySensorDeviceClass
def get_device_class_or_undefined(
hass: HomeAssistant, entity_id: str
) -> str | None | UndefinedType:
"""Get the device class of an entity or UNDEFINED if not found."""
try:
return get_device_class(hass, entity_id)
except HomeAssistantError:
return UNDEFINED
class BinarySensorOnOffTrigger(EntityTargetStateTriggerBase):
"""Class for binary sensor on/off triggers."""
_device_class: BinarySensorDeviceClass | None
_domains = {DOMAIN}
def entity_filter(self, entities: set[str]) -> set[str]:
"""Filter entities of this domain."""
entities = super().entity_filter(entities)
return {
entity_id
for entity_id in entities
if get_device_class_or_undefined(self._hass, entity_id)
== self._device_class
}
def make_binary_sensor_trigger(
device_class: BinarySensorDeviceClass | None,
to_state: str,
) -> type[BinarySensorOnOffTrigger]:
"""Create an entity state trigger class."""
class CustomTrigger(BinarySensorOnOffTrigger):
"""Trigger for entity state changes."""
_device_class = device_class
_to_states = {to_state}
return CustomTrigger
TRIGGERS: dict[str, type[Trigger]] = {
"occupancy_detected": make_binary_sensor_trigger(
BinarySensorDeviceClass.OCCUPANCY, STATE_ON
),
"occupancy_cleared": make_binary_sensor_trigger(
BinarySensorDeviceClass.OCCUPANCY, STATE_OFF
),
}
async def async_get_triggers(hass: HomeAssistant) -> dict[str, type[Trigger]]:
"""Return the triggers for binary sensors."""
return TRIGGERS

View File

@@ -0,0 +1,25 @@
.trigger_common_fields: &trigger_common_fields
behavior:
required: true
default: any
selector:
select:
translation_key: trigger_behavior
options:
- first
- last
- any
occupancy_cleared:
fields: *trigger_common_fields
target:
entity:
domain: binary_sensor
device_class: occupancy
occupancy_detected:
fields: *trigger_common_fields
target:
entity:
domain: binary_sensor
device_class: occupancy

View File

@@ -19,7 +19,7 @@
],
"documentation": "https://www.home-assistant.io/integrations/frontend",
"integration_type": "system",
"preview_features": { "winter_mode": {} },
"preview_features": { "windows_98": {}, "winter_mode": {} },
"quality_scale": "internal",
"requirements": ["home-assistant-frontend==20260304.0"]
}

View File

@@ -1,5 +1,11 @@
{
"preview_features": {
"windows_98": {
"description": "Transforms your dashboard with a nostalgic Windows 98 look.",
"disable_confirmation": "Your dashboard will return to its normal look. You can re-enable this at any time in Labs settings.",
"enable_confirmation": "Your dashboard will be transformed with a Windows 98 theme. You can turn this off at any time in Labs settings.",
"name": "Windows 98"
},
"winter_mode": {
"description": "Adds falling snowflakes on your screen. Get your home ready for winter! ❄️\n\nIf you have animations disabled in your device accessibility settings, this feature will not work.",
"disable_confirmation": "Snowflakes will no longer fall on your screen. You can re-enable this at any time in Labs settings.",

View File

@@ -62,9 +62,7 @@ class LibreHardwareMonitorCoordinator(DataUpdateCoordinator[LibreHardwareMonitor
registry=dr.async_get(self.hass), config_entry_id=self._entry_id
)
self._previous_devices: dict[DeviceId, DeviceName] = {
DeviceId(
next(iter(device.identifiers))[1].removeprefix(f"{self._entry_id}_")
): DeviceName(device.name)
DeviceId(next(iter(device.identifiers))[1]): DeviceName(device.name)
for device in device_entries
if device.identifiers and device.name
}
@@ -111,6 +109,11 @@ class LibreHardwareMonitorCoordinator(DataUpdateCoordinator[LibreHardwareMonitor
self, detected_devices: dict[DeviceId, DeviceName]
) -> None:
"""Handle device changes by deleting devices from / adding devices to Home Assistant."""
detected_devices = {
DeviceId(f"{self.config_entry.entry_id}_{detected_id}"): device_name
for detected_id, device_name in detected_devices.items()
}
previous_device_ids = set(self._previous_devices.keys())
detected_device_ids = set(detected_devices.keys())
@@ -128,14 +131,25 @@ class LibreHardwareMonitorCoordinator(DataUpdateCoordinator[LibreHardwareMonitor
device_registry = dr.async_get(self.hass)
for device_id in orphaned_devices:
if device := device_registry.async_get_device(
identifiers={(DOMAIN, f"{self._entry_id}_{device_id}")}
identifiers={(DOMAIN, device_id)}
):
_LOGGER.debug(
"Removing device: %s", self._previous_devices[device_id]
)
device_registry.async_update_device(
device_id=device.id,
remove_config_entry_id=self._entry_id,
remove_config_entry_id=self.config_entry.entry_id,
)
if self.data is None:
# initial update during integration startup
self._previous_devices = detected_devices # type: ignore[unreachable]
return
if new_devices := detected_device_ids - previous_device_ids:
_LOGGER.warning(
"New Device(s) detected, reload integration to add them to Home Assistant: %s",
[detected_devices[DeviceId(device_id)] for device_id in new_devices],
)
self._previous_devices = detected_devices

View File

@@ -2,10 +2,9 @@
from __future__ import annotations
import logging
from typing import Any
from librehardwaremonitor_api.model import DeviceId, LibreHardwareMonitorSensorData
from librehardwaremonitor_api.model import LibreHardwareMonitorSensorData
from librehardwaremonitor_api.sensor_type import SensorType
from homeassistant.components.sensor import SensorEntity, SensorStateClass
@@ -17,8 +16,6 @@ from homeassistant.helpers.update_coordinator import CoordinatorEntity
from . import LibreHardwareMonitorConfigEntry, LibreHardwareMonitorCoordinator
from .const import DOMAIN
_LOGGER = logging.getLogger(__name__)
PARALLEL_UPDATES = 0
STATE_MIN_VALUE = "min_value"
@@ -33,28 +30,10 @@ async def async_setup_entry(
"""Set up the LibreHardwareMonitor platform."""
lhm_coordinator = config_entry.runtime_data
known_devices: set[DeviceId] = set()
def _check_device() -> None:
current_devices = set(lhm_coordinator.data.main_device_ids_and_names)
new_devices = current_devices - known_devices
if new_devices:
_LOGGER.debug("New Device(s) detected, adding: %s", new_devices)
known_devices.update(new_devices)
new_devices_sensor_data = [
sensor_data
for sensor_data in lhm_coordinator.data.sensor_data.values()
if sensor_data.device_id in new_devices
]
async_add_entities(
LibreHardwareMonitorSensor(
lhm_coordinator, config_entry.entry_id, sensor_data
)
for sensor_data in new_devices_sensor_data
)
_check_device()
config_entry.async_on_unload(lhm_coordinator.async_add_listener(_check_device))
async_add_entities(
LibreHardwareMonitorSensor(lhm_coordinator, config_entry.entry_id, sensor_data)
for sensor_data in lhm_coordinator.data.sensor_data.values()
)
class LibreHardwareMonitorSensor(

View File

@@ -10,5 +10,5 @@
"iot_class": "cloud_polling",
"loggers": ["onedrive_personal_sdk"],
"quality_scale": "platinum",
"requirements": ["onedrive-personal-sdk==0.1.6"]
"requirements": ["onedrive-personal-sdk==0.1.5"]
}

View File

@@ -10,5 +10,5 @@
"iot_class": "cloud_polling",
"loggers": ["onedrive_personal_sdk"],
"quality_scale": "platinum",
"requirements": ["onedrive-personal-sdk==0.1.6"]
"requirements": ["onedrive-personal-sdk==0.1.5"]
}

View File

@@ -19,6 +19,11 @@ LABS_PREVIEW_FEATURES = {
},
},
"frontend": {
"windows_98": {
"feedback_url": "",
"learn_more_url": "",
"report_issue_url": "",
},
"winter_mode": {
"feedback_url": "",
"learn_more_url": "",

2
requirements_all.txt generated
View File

@@ -1676,7 +1676,7 @@ ondilo==0.5.0
# homeassistant.components.onedrive
# homeassistant.components.onedrive_for_business
onedrive-personal-sdk==0.1.6
onedrive-personal-sdk==0.1.5
# homeassistant.components.onvif
onvif-zeep-async==4.0.4

View File

@@ -1462,7 +1462,7 @@ ondilo==0.5.0
# homeassistant.components.onedrive
# homeassistant.components.onedrive_for_business
onedrive-personal-sdk==0.1.6
onedrive-personal-sdk==0.1.5
# homeassistant.components.onvif
onvif-zeep-async==4.0.4

View File

@@ -0,0 +1,258 @@
"""Test binary sensor trigger."""
from typing import Any
import pytest
from homeassistant.const import (
ATTR_DEVICE_CLASS,
ATTR_LABEL_ID,
CONF_ENTITY_ID,
STATE_OFF,
STATE_ON,
)
from homeassistant.core import HomeAssistant, ServiceCall
from tests.components import (
TriggerStateDescription,
arm_trigger,
parametrize_target_entities,
parametrize_trigger_states,
set_or_remove_state,
target_entities,
)
@pytest.fixture
async def target_binary_sensors(hass: HomeAssistant) -> tuple[list[str], list[str]]:
"""Create multiple binary sensor entities associated with different targets."""
return await target_entities(hass, "binary_sensor")
@pytest.mark.parametrize(
"trigger_key",
[
"binary_sensor.occupancy_detected",
"binary_sensor.occupancy_cleared",
],
)
async def test_binary_sensor_triggers_gated_by_labs_flag(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture, trigger_key: str
) -> None:
"""Test the binary sensor triggers are gated by the labs flag."""
await arm_trigger(hass, trigger_key, None, {ATTR_LABEL_ID: "test_label"})
assert (
"Unnamed automation failed to setup triggers and has been disabled: Trigger "
f"'{trigger_key}' requires the experimental 'New triggers and conditions' "
"feature to be enabled in Home Assistant Labs settings (feature flag: "
"'new_triggers_conditions')"
) in caplog.text
@pytest.mark.usefixtures("enable_labs_preview_features")
@pytest.mark.parametrize(
("trigger_target_config", "entity_id", "entities_in_target"),
parametrize_target_entities("binary_sensor"),
)
@pytest.mark.parametrize(
("trigger", "trigger_options", "states"),
[
*parametrize_trigger_states(
trigger="binary_sensor.occupancy_detected",
target_states=[STATE_ON],
other_states=[STATE_OFF],
additional_attributes={ATTR_DEVICE_CLASS: "occupancy"},
trigger_from_none=False,
),
*parametrize_trigger_states(
trigger="binary_sensor.occupancy_cleared",
target_states=[STATE_OFF],
other_states=[STATE_ON],
additional_attributes={ATTR_DEVICE_CLASS: "occupancy"},
trigger_from_none=False,
),
],
)
async def test_binary_sensor_state_attribute_trigger_behavior_any(
hass: HomeAssistant,
service_calls: list[ServiceCall],
target_binary_sensors: dict[list[str], list[str]],
trigger_target_config: dict,
entity_id: str,
entities_in_target: int,
trigger: str,
trigger_options: dict[str, Any],
states: list[TriggerStateDescription],
) -> None:
"""Test that the binary sensor state trigger fires when any binary sensor state changes to a specific state."""
other_entity_ids = set(target_binary_sensors["included"]) - {entity_id}
excluded_entity_ids = set(target_binary_sensors["excluded"]) - {entity_id}
# Set all binary sensors, including the tested binary sensor, to the initial state
for eid in target_binary_sensors["included"]:
set_or_remove_state(hass, eid, states[0]["included"])
await hass.async_block_till_done()
for eid in excluded_entity_ids:
set_or_remove_state(hass, eid, states[0]["excluded"])
await hass.async_block_till_done()
await arm_trigger(hass, trigger, {}, trigger_target_config)
for state in states[1:]:
excluded_state = state["excluded"]
included_state = state["included"]
set_or_remove_state(hass, entity_id, included_state)
await hass.async_block_till_done()
assert len(service_calls) == state["count"]
for service_call in service_calls:
assert service_call.data[CONF_ENTITY_ID] == entity_id
service_calls.clear()
# Check if changing other binary sensors also triggers
for other_entity_id in other_entity_ids:
set_or_remove_state(hass, other_entity_id, included_state)
await hass.async_block_till_done()
for excluded_entity_id in excluded_entity_ids:
set_or_remove_state(hass, excluded_entity_id, excluded_state)
await hass.async_block_till_done()
assert len(service_calls) == (entities_in_target - 1) * state["count"]
service_calls.clear()
@pytest.mark.usefixtures("enable_labs_preview_features")
@pytest.mark.parametrize(
("trigger_target_config", "entity_id", "entities_in_target"),
parametrize_target_entities("binary_sensor"),
)
@pytest.mark.parametrize(
("trigger", "trigger_options", "states"),
[
*parametrize_trigger_states(
trigger="binary_sensor.occupancy_detected",
target_states=[STATE_ON],
other_states=[STATE_OFF],
additional_attributes={ATTR_DEVICE_CLASS: "occupancy"},
trigger_from_none=False,
),
*parametrize_trigger_states(
trigger="binary_sensor.occupancy_cleared",
target_states=[STATE_OFF],
other_states=[STATE_ON],
additional_attributes={ATTR_DEVICE_CLASS: "occupancy"},
trigger_from_none=False,
),
],
)
async def test_binary_sensor_state_attribute_trigger_behavior_first(
hass: HomeAssistant,
service_calls: list[ServiceCall],
target_binary_sensors: list[str],
trigger_target_config: dict,
entity_id: str,
entities_in_target: int,
trigger: str,
trigger_options: dict[str, Any],
states: list[TriggerStateDescription],
) -> None:
"""Test that the binary sensor state trigger fires when the first binary sensor state changes to a specific state."""
other_entity_ids = set(target_binary_sensors["included"]) - {entity_id}
excluded_entity_ids = set(target_binary_sensors["excluded"]) - {entity_id}
# Set all binary sensors, including the tested binary sensor, to the initial state
for eid in target_binary_sensors["included"]:
set_or_remove_state(hass, eid, states[0]["included"])
await hass.async_block_till_done()
for eid in excluded_entity_ids:
set_or_remove_state(hass, eid, states[0]["excluded"])
await hass.async_block_till_done()
await arm_trigger(hass, trigger, {"behavior": "first"}, trigger_target_config)
for state in states[1:]:
excluded_state = state["excluded"]
included_state = state["included"]
set_or_remove_state(hass, entity_id, included_state)
await hass.async_block_till_done()
assert len(service_calls) == state["count"]
for service_call in service_calls:
assert service_call.data[CONF_ENTITY_ID] == entity_id
service_calls.clear()
# Triggering other binary sensors should not cause the trigger to fire again
for other_entity_id in other_entity_ids:
set_or_remove_state(hass, other_entity_id, excluded_state)
await hass.async_block_till_done()
for excluded_entity_id in excluded_entity_ids:
set_or_remove_state(hass, excluded_entity_id, excluded_state)
await hass.async_block_till_done()
assert len(service_calls) == 0
@pytest.mark.usefixtures("enable_labs_preview_features")
@pytest.mark.parametrize(
("trigger_target_config", "entity_id", "entities_in_target"),
parametrize_target_entities("binary_sensor"),
)
@pytest.mark.parametrize(
("trigger", "trigger_options", "states"),
[
*parametrize_trigger_states(
trigger="binary_sensor.occupancy_detected",
target_states=[STATE_ON],
other_states=[STATE_OFF],
additional_attributes={ATTR_DEVICE_CLASS: "occupancy"},
trigger_from_none=False,
),
*parametrize_trigger_states(
trigger="binary_sensor.occupancy_cleared",
target_states=[STATE_OFF],
other_states=[STATE_ON],
additional_attributes={ATTR_DEVICE_CLASS: "occupancy"},
trigger_from_none=False,
),
],
)
async def test_binary_sensor_state_attribute_trigger_behavior_last(
hass: HomeAssistant,
service_calls: list[ServiceCall],
target_binary_sensors: list[str],
trigger_target_config: dict,
entity_id: str,
entities_in_target: int,
trigger: str,
trigger_options: dict[str, Any],
states: list[TriggerStateDescription],
) -> None:
"""Test that the binary sensor state trigger fires when the last binary sensor state changes to a specific state."""
other_entity_ids = set(target_binary_sensors["included"]) - {entity_id}
excluded_entity_ids = set(target_binary_sensors["excluded"]) - {entity_id}
# Set all binary sensors, including the tested binary sensor, to the initial state
for eid in target_binary_sensors["included"]:
set_or_remove_state(hass, eid, states[0]["included"])
await hass.async_block_till_done()
for eid in excluded_entity_ids:
set_or_remove_state(hass, eid, states[0]["excluded"])
await hass.async_block_till_done()
await arm_trigger(hass, trigger, {"behavior": "last"}, trigger_target_config)
for state in states[1:]:
excluded_state = state["excluded"]
included_state = state["included"]
for other_entity_id in other_entity_ids:
set_or_remove_state(hass, other_entity_id, excluded_state)
await hass.async_block_till_done()
assert len(service_calls) == 0
set_or_remove_state(hass, entity_id, included_state)
await hass.async_block_till_done()
assert len(service_calls) == state["count"]
for service_call in service_calls:
assert service_call.data[CONF_ENTITY_ID] == entity_id
service_calls.clear()
for excluded_entity_id in excluded_entity_ids:
set_or_remove_state(hass, excluded_entity_id, excluded_state)
await hass.async_block_till_done()
assert len(service_calls) == 0

View File

@@ -2,6 +2,7 @@
from dataclasses import replace
from datetime import timedelta
import logging
from types import MappingProxyType
from unittest.mock import AsyncMock
@@ -15,9 +16,7 @@ from librehardwaremonitor_api.model import (
DeviceId,
DeviceName,
LibreHardwareMonitorData,
LibreHardwareMonitorSensorData,
)
from librehardwaremonitor_api.sensor_type import SensorType
import pytest
from syrupy.assertion import SnapshotAssertion
@@ -58,6 +57,7 @@ async def test_sensors_are_created(
)
async def test_sensors_go_unavailable_in_case_of_error_and_recover_after_successful_retry(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
mock_lhm_client: AsyncMock,
mock_config_entry: MockConfigEntry,
freezer: FrozenDateTimeFactory,
@@ -288,66 +288,34 @@ async def _mock_orphaned_device(
)
async def test_integration_dynamically_adds_new_devices(
async def test_integration_does_not_log_new_devices_on_first_refresh(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
device_registry: dr.DeviceRegistry,
mock_lhm_client: AsyncMock,
mock_config_entry: MockConfigEntry,
freezer: FrozenDateTimeFactory,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test that new devices are created when detected."""
await init_integration(hass, mock_config_entry)
device_entries: list[DeviceEntry] = dr.async_entries_for_config_entry(
registry=device_registry, config_entry_id=mock_config_entry.entry_id
)
assert len(device_entries) == 3
mock_lhm_client.get_data.return_value = replace(
mock_lhm_client.get_data.return_value,
"""Test that initial data update does not cause warning about new devices."""
mock_lhm_client.get_data.return_value = LibreHardwareMonitorData(
computer_name=mock_lhm_client.get_data.return_value.computer_name,
main_device_ids_and_names=MappingProxyType(
{
**mock_lhm_client.get_data.return_value.main_device_ids_and_names,
DeviceId("generic-memory"): DeviceName("Generic Memory"),
}
),
sensor_data=MappingProxyType(
{
**mock_lhm_client.get_data.return_value.sensor_data,
"generic-memory-test-sensor": LibreHardwareMonitorSensorData(
name="Test sensor",
value="30",
type=SensorType.FACTOR,
min="12",
max="36",
unit=None,
device_id="generic-memory",
device_name="Generic Memory",
device_type="MEMORY",
sensor_id="generic-memory-test-sensor",
),
}
),
sensor_data=mock_lhm_client.get_data.return_value.sensor_data,
is_deprecated_version=False,
)
freezer.tick(timedelta(DEFAULT_SCAN_INTERVAL))
async_fire_time_changed(hass)
await hass.async_block_till_done()
with caplog.at_level(logging.WARNING):
await init_integration(hass, mock_config_entry)
device_entries: list[DeviceEntry] = dr.async_entries_for_config_entry(
registry=device_registry, config_entry_id=mock_config_entry.entry_id
)
assert len(device_entries) == 4
expected_device = next(entry for entry in device_entries if "Generic" in entry.name)
assert expected_device.name == "[GAMING-PC] Generic Memory"
entity_entries = er.async_entries_for_config_entry(
entity_registry, mock_config_entry.entry_id
)
assert "sensor.gaming_pc_generic_memory_test_sensor" in [
entry.entity_id for entry in entity_entries
]
libre_hardware_monitor_logs = [
record
for record in caplog.records
if record.name.startswith("homeassistant.components.libre_hardware_monitor")
]
assert len(libre_hardware_monitor_logs) == 0
async def test_non_deprecated_version_does_not_raise_issue(

View File

@@ -26,7 +26,6 @@ DEVICE_FIXTURES = [
"aq_sensor_3_ikea",
"aeotec_ms6",
"da_ac_air_000001",
"da_ac_air_01011",
"da_ac_airsensor_01001",
"da_ac_rac_000001",
"da_ac_rac_000003",

View File

@@ -1,532 +0,0 @@
{
"components": {
"main": {
"samsungce.unavailableCapabilities": {
"unavailableCommands": {
"value": [
"airConditionerFanMode.setFanMode",
"custom.periodicSensing.setPeriodicSensing"
],
"timestamp": "2026-02-28T01:15:36.299Z"
}
},
"samsungce.deviceIdentification": {
"micomAssayCode": {
"value": "10241841",
"timestamp": "2026-02-28T01:15:35.448Z"
},
"modelName": {
"value": null
},
"serialNumber": {
"value": null
},
"serialNumberExtra": {
"value": null
},
"releaseCountry": {
"value": null
},
"modelClassificationCode": {
"value": "70000629001610000D000800000A0000",
"timestamp": "2026-02-28T01:15:35.448Z"
},
"description": {
"value": "AVT-WW-TP1-22-TOUCHOTN",
"timestamp": "2026-02-28T01:15:35.448Z"
},
"releaseYear": {
"value": 22,
"timestamp": "2024-10-24T07:31:42.182Z"
},
"binaryId": {
"value": "AVT-WW-TP1-22-TOUCHOTN",
"timestamp": "2026-03-09T08:56:28.699Z"
}
},
"airQualitySensor": {
"airQuality": {
"value": 1,
"unit": "CAQI",
"timestamp": "2026-02-28T01:15:35.652Z"
}
},
"samsungce.airPurifierLighting": {
"lighting": {
"value": null
}
},
"switch": {
"switch": {
"value": "on",
"timestamp": "2026-03-09T20:25:52.124Z"
}
},
"samsungce.quickControl": {
"version": {
"value": null
}
},
"fineDustHealthConcern": {
"fineDustHealthConcern": {
"value": null
},
"supportedFineDustValues": {
"value": null
}
},
"ocf": {
"st": {
"value": null
},
"mndt": {
"value": null
},
"mnfv": {
"value": "AVT-WW-TP1-22-TOUCHOTN_12240702",
"timestamp": "2025-06-22T06:13:50.772Z"
},
"mnhw": {
"value": "Realtek",
"timestamp": "2025-06-22T06:13:50.772Z"
},
"di": {
"value": "a5662f73-57d5-ba89-bf44-8b0008b8b2f3",
"timestamp": "2025-06-22T06:13:50.772Z"
},
"mnsl": {
"value": "http://www.samsung.com",
"timestamp": "2025-06-22T06:13:50.772Z"
},
"dmv": {
"value": "res.1.1.0,sh.1.1.0",
"timestamp": "2025-06-22T06:13:50.772Z"
},
"n": {
"value": "[air purifier] Samsung",
"timestamp": "2025-06-22T06:13:50.772Z"
},
"mnmo": {
"value": "AVT-WW-TP1-22-TOUCHOTN|10241841|70000629001610000D000800000A0000",
"timestamp": "2025-06-22T06:13:50.772Z"
},
"vid": {
"value": "DA-AC-AIR-01011",
"timestamp": "2025-06-22T06:13:50.772Z"
},
"mnmn": {
"value": "Samsung Electronics",
"timestamp": "2025-06-22T06:13:50.772Z"
},
"mnml": {
"value": "http://www.samsung.com",
"timestamp": "2025-06-22T06:13:50.772Z"
},
"mnpv": {
"value": "DAWIT 2.0",
"timestamp": "2025-06-22T06:13:50.772Z"
},
"mnos": {
"value": "TizenRT 3.1",
"timestamp": "2025-06-22T06:13:50.772Z"
},
"pi": {
"value": "a5662f73-57d5-ba89-bf44-8b0008b8b2f3",
"timestamp": "2025-06-22T06:13:50.772Z"
},
"icv": {
"value": "core.1.1.0",
"timestamp": "2025-06-22T06:13:50.772Z"
}
},
"airConditionerFanMode": {
"fanMode": {
"value": "auto",
"timestamp": "2026-03-09T20:25:52.338Z"
},
"supportedAcFanModes": {
"value": ["auto", "low", "medium", "high", "sleep"],
"timestamp": "2026-02-28T01:15:35.705Z"
},
"availableAcFanModes": {
"value": [],
"timestamp": "2026-02-28T01:15:36.299Z"
}
},
"veryFineDustHealthConcern": {
"supportedVeryFineDustValues": {
"value": null
},
"veryFineDustHealthConcern": {
"value": null
}
},
"custom.disabledCapabilities": {
"disabledCapabilities": {
"value": [
"demandResponseLoadControl",
"samsungce.quickControl",
"odorSensor",
"dustSensor",
"dustHealthConcern",
"fineDustHealthConcern",
"veryFineDustSensor",
"veryFineDustHealthConcern",
"custom.virusDoctorMode",
"custom.welcomeCareMode",
"custom.periodicSensing",
"custom.doNotDisturbMode",
"samsungce.alwaysOnSensing",
"samsungce.airPurifierLighting"
],
"timestamp": "2025-06-12T19:57:13.156Z"
}
},
"samsungce.driverVersion": {
"versionNumber": {
"value": 25040102,
"timestamp": "2025-06-12T02:03:16.508Z"
}
},
"sec.diagnosticsInformation": {
"logType": {
"value": ["errCode", "dump"],
"timestamp": "2026-02-28T01:15:35.448Z"
},
"endpoint": {
"value": "SSM",
"timestamp": "2026-02-28T01:15:35.448Z"
},
"minVersion": {
"value": "1.0",
"timestamp": "2026-02-28T01:15:35.448Z"
},
"signinPermission": {
"value": null
},
"setupId": {
"value": "AP1",
"timestamp": "2026-02-28T01:15:35.448Z"
},
"protocolType": {
"value": "wifi_https",
"timestamp": "2026-02-28T01:15:35.448Z"
},
"tsId": {
"value": "DA01",
"timestamp": "2026-02-28T01:15:35.448Z"
},
"mnId": {
"value": "0AJT",
"timestamp": "2026-02-28T01:15:35.448Z"
},
"dumpType": {
"value": "file",
"timestamp": "2026-02-28T01:15:35.448Z"
}
},
"custom.hepaFilter": {
"hepaFilterCapacity": {
"value": 8760,
"unit": "Hour",
"timestamp": "2026-02-28T01:15:35.366Z"
},
"hepaFilterStatus": {
"value": "normal",
"timestamp": "2026-02-28T01:15:35.366Z"
},
"hepaFilterResetType": {
"value": ["replaceable"],
"timestamp": "2026-02-28T01:15:35.366Z"
},
"hepaFilterUsageStep": {
"value": 1,
"timestamp": "2026-02-28T01:15:35.366Z"
},
"hepaFilterUsage": {
"value": 32,
"timestamp": "2026-03-06T06:48:11.439Z"
},
"hepaFilterLastResetDate": {
"value": null
}
},
"dustSensor": {
"dustLevel": {
"value": null
},
"fineDustLevel": {
"value": null
}
},
"custom.deviceReportStateConfiguration": {
"reportStateRealtimePeriod": {
"value": "disabled",
"timestamp": "2026-02-28T01:15:35.602Z"
},
"reportStateRealtime": {
"value": {
"state": "disabled"
},
"timestamp": "2026-02-28T01:15:35.602Z"
},
"reportStatePeriod": {
"value": "enabled",
"timestamp": "2026-02-28T01:15:35.602Z"
}
},
"custom.periodicSensing": {
"automaticExecutionSetting": {
"value": null
},
"automaticExecutionMode": {
"value": null
},
"supportedAutomaticExecutionSetting": {
"value": null
},
"supportedAutomaticExecutionMode": {
"value": ["Off", "Airpurify", "Alarm"],
"timestamp": "2026-02-28T01:15:35.085Z"
},
"periodicSensing": {
"value": null
},
"periodicSensingInterval": {
"value": 600,
"timestamp": "2026-02-28T01:15:35.085Z"
},
"lastSensingTime": {
"value": "1773089160",
"unit": "second",
"timestamp": "2026-03-09T20:46:15.135Z"
},
"lastSensingLevel": {
"value": "Kr1",
"timestamp": "2026-03-09T20:46:15.135Z"
},
"periodicSensingStatus": {
"value": "nonprocessing",
"timestamp": "2026-02-28T01:15:35.085Z"
}
},
"custom.virusDoctorMode": {
"virusDoctorMode": {
"value": null
}
},
"dustHealthConcern": {
"supportedDustValues": {
"value": null
},
"dustHealthConcern": {
"value": null
}
},
"custom.lowerDevicePower": {
"powerState": {
"value": null
}
},
"demandResponseLoadControl": {
"drlcStatus": {
"value": null
}
},
"powerConsumptionReport": {
"powerConsumption": {
"value": {
"energy": 221878,
"deltaEnergy": 4,
"power": 0,
"powerEnergy": 0.0,
"persistedEnergy": 0,
"energySaved": 0,
"start": "2026-03-09T20:42:57Z",
"end": "2026-03-09T20:53:57Z"
},
"timestamp": "2026-03-09T20:53:57.809Z"
}
},
"samsungce.alwaysOnSensing": {
"origins": {
"value": null
},
"alwaysOn": {
"value": null
}
},
"refresh": {},
"execute": {
"data": {
"value": null
}
},
"sec.wifiConfiguration": {
"autoReconnection": {
"value": true,
"timestamp": "2026-02-28T01:15:36.415Z"
},
"minVersion": {
"value": "1.0",
"timestamp": "2026-02-28T01:15:36.415Z"
},
"supportedWiFiFreq": {
"value": ["2.4G"],
"timestamp": "2026-02-28T01:15:36.415Z"
},
"supportedAuthType": {
"value": ["OPEN", "WEP", "WPA-PSK", "WPA2-PSK", "SAE"],
"timestamp": "2026-02-28T01:15:36.415Z"
},
"protocolType": {
"value": ["helper_hotspot", "ble_ocf"],
"timestamp": "2026-02-28T01:15:36.415Z"
}
},
"samsungce.softwareVersion": {
"versions": {
"value": [
{
"id": "0",
"swType": "Software",
"versionNumber": "02425A240702",
"description": "Version"
},
{
"id": "1",
"swType": "Firmware",
"versionNumber": "22022301,ffffffff",
"description": "Version"
},
{
"id": "2",
"swType": "Firmware",
"versionNumber": "22020200",
"description": "Version"
}
],
"timestamp": "2026-02-28T01:15:35.448Z"
}
},
"odorSensor": {
"odorLevel": {
"value": null
}
},
"custom.deviceDependencyStatus": {
"subDeviceActive": {
"value": true,
"timestamp": "2022-11-10T21:26:29.123Z"
},
"dependencyStatus": {
"value": "single",
"timestamp": "2022-11-10T21:26:29.123Z"
},
"numberOfSubDevices": {
"value": 0,
"timestamp": "2022-11-10T21:26:30.131Z"
}
},
"custom.energyType": {
"energyType": {
"value": "2.0",
"timestamp": "2022-11-10T21:26:29.123Z"
},
"energySavingSupport": {
"value": false,
"timestamp": "2022-11-10T21:26:29.115Z"
},
"drMaxDuration": {
"value": null
},
"energySavingLevel": {
"value": null
},
"energySavingInfo": {
"value": null
},
"supportedEnergySavingLevels": {
"value": null
},
"energySavingOperation": {
"value": null
},
"notificationTemplateID": {
"value": null
},
"energySavingOperationSupport": {
"value": null
}
},
"samsungce.airQualityHealthConcern": {
"supportedAirQualityHealthConcerns": {
"value": ["good", "normal", "poor", "veryPoor"],
"timestamp": "2023-07-31T10:37:10.067Z"
},
"airQualityHealthConcern": {
"value": "good",
"timestamp": "2026-02-28T01:15:35.652Z"
}
},
"samsungce.softwareUpdate": {
"targetModule": {
"value": {},
"timestamp": "2026-02-28T01:15:35.562Z"
},
"otnDUID": {
"value": "2DCGCEMPL4HLK",
"timestamp": "2026-02-28T01:15:35.448Z"
},
"lastUpdatedDate": {
"value": null
},
"availableModules": {
"value": [],
"timestamp": "2022-11-10T21:26:30.407Z"
},
"newVersionAvailable": {
"value": false,
"timestamp": "2026-02-28T01:15:35.448Z"
},
"operatingState": {
"value": "none",
"timestamp": "2026-02-28T01:15:35.562Z"
},
"progress": {
"value": null
}
},
"custom.welcomeCareMode": {
"welcomeCareMode": {
"value": null
}
},
"veryFineDustSensor": {
"veryFineDustLevel": {
"value": null
}
},
"custom.doNotDisturbMode": {
"doNotDisturb": {
"value": "off",
"timestamp": "2026-02-28T01:15:35.085Z"
},
"startTime": {
"value": "0000",
"timestamp": "2026-02-28T01:15:35.085Z"
},
"endTime": {
"value": "0000",
"timestamp": "2026-02-28T01:15:35.085Z"
}
},
"custom.airQualityMaxLevel": {
"airQualityMaxLevel": {
"value": 4,
"timestamp": "2022-11-10T21:26:30.774Z"
}
}
}
}
}

View File

@@ -1,206 +0,0 @@
{
"items": [
{
"deviceId": "a5662f73-57d5-ba89-bf44-8b0008b8b2f3",
"name": "[air purifier] Samsung",
"label": "Air filter",
"manufacturerName": "Samsung Electronics",
"presentationId": "DA-AC-AIR-01011",
"deviceManufacturerCode": "Samsung Electronics",
"locationId": "0ab793d8-ef93-4c27-b1c5-602c5a90ba6a",
"ownerId": "862a9721-9b24-59f0-aac2-d56c6d76eaf2",
"roomId": "b1e67439-f25e-4c62-b27c-34787273a7c7",
"deviceTypeName": "Samsung OCF Air Purifier",
"components": [
{
"id": "main",
"label": "main",
"capabilities": [
{
"id": "ocf",
"version": 1
},
{
"id": "switch",
"version": 1
},
{
"id": "refresh",
"version": 1
},
{
"id": "execute",
"version": 1
},
{
"id": "airConditionerFanMode",
"version": 1
},
{
"id": "powerConsumptionReport",
"version": 1
},
{
"id": "airQualitySensor",
"version": 1
},
{
"id": "odorSensor",
"version": 1
},
{
"id": "dustSensor",
"version": 1
},
{
"id": "veryFineDustSensor",
"version": 1
},
{
"id": "dustHealthConcern",
"version": 1
},
{
"id": "fineDustHealthConcern",
"version": 1
},
{
"id": "veryFineDustHealthConcern",
"version": 1
},
{
"id": "demandResponseLoadControl",
"version": 1
},
{
"id": "custom.airQualityMaxLevel",
"version": 1
},
{
"id": "custom.welcomeCareMode",
"version": 1
},
{
"id": "custom.lowerDevicePower",
"version": 1
},
{
"id": "custom.deviceDependencyStatus",
"version": 1
},
{
"id": "custom.deviceReportStateConfiguration",
"version": 1
},
{
"id": "custom.hepaFilter",
"version": 1
},
{
"id": "custom.periodicSensing",
"version": 1
},
{
"id": "custom.doNotDisturbMode",
"version": 1
},
{
"id": "custom.disabledCapabilities",
"version": 1
},
{
"id": "custom.energyType",
"version": 1
},
{
"id": "custom.virusDoctorMode",
"version": 1
},
{
"id": "samsungce.airPurifierLighting",
"version": 1
},
{
"id": "samsungce.airQualityHealthConcern",
"version": 1
},
{
"id": "samsungce.alwaysOnSensing",
"version": 1
},
{
"id": "samsungce.deviceIdentification",
"version": 1
},
{
"id": "samsungce.softwareUpdate",
"version": 1
},
{
"id": "samsungce.softwareVersion",
"version": 1
},
{
"id": "samsungce.driverVersion",
"version": 1
},
{
"id": "samsungce.quickControl",
"version": 1
},
{
"id": "samsungce.unavailableCapabilities",
"version": 1
},
{
"id": "sec.diagnosticsInformation",
"version": 1
},
{
"id": "sec.wifiConfiguration",
"version": 1
}
],
"categories": [
{
"name": "AirPurifier",
"categoryType": "manufacturer"
},
{
"name": "AirPurifier",
"categoryType": "user"
}
],
"optional": false
}
],
"createTime": "2022-11-10T21:26:28.352Z",
"profile": {
"id": "75a9d6bf-25ea-347e-9439-adecda280b55"
},
"ocf": {
"ocfDeviceType": "oic.d.airpurifier",
"name": "[air purifier] Samsung",
"specVersion": "core.1.1.0",
"verticalDomainSpecVersion": "res.1.1.0,sh.1.1.0",
"manufacturerName": "Samsung Electronics",
"modelNumber": "AVT-WW-TP1-22-TOUCHOTN|10241841|70000629001610000D000800000A0000",
"platformVersion": "DAWIT 2.0",
"platformOS": "TizenRT 3.1",
"hwVersion": "Realtek",
"firmwareVersion": "AVT-WW-TP1-22-TOUCHOTN_12240702",
"vendorId": "DA-AC-AIR-01011",
"vendorResourceClientServerVersion": "Realtek Release 3.1.240221",
"lastSignupTime": "2022-11-10T21:26:20.091647Z",
"transferCandidate": false,
"additionalAuthCodeRequired": false
},
"type": "OCF",
"restrictionTier": 0,
"allowed": null,
"executionContext": "CLOUD",
"relationships": []
}
],
"_links": {}
}

View File

@@ -65,72 +65,6 @@
'state': 'on',
})
# ---
# name: test_all_entities[da_ac_air_01011][fan.air_filter-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'preset_modes': list([
'auto',
'low',
'medium',
'high',
'sleep',
]),
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'fan',
'entity_category': None,
'entity_id': 'fan.air_filter',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'object_id_base': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': None,
'platform': 'smartthings',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': <FanEntityFeature: 56>,
'translation_key': None,
'unique_id': 'a5662f73-57d5-ba89-bf44-8b0008b8b2f3_main',
'unit_of_measurement': None,
})
# ---
# name: test_all_entities[da_ac_air_01011][fan.air_filter-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Air filter',
'preset_mode': 'auto',
'preset_modes': list([
'auto',
'low',
'medium',
'high',
'sleep',
]),
'supported_features': <FanEntityFeature: 56>,
}),
'context': <ANY>,
'entity_id': 'fan.air_filter',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'on',
})
# ---
# name: test_all_entities[da_ks_hood_01001][fan.range_hood-entry]
EntityRegistryEntrySnapshot({
'aliases': set({

View File

@@ -374,37 +374,6 @@
'via_device_id': None,
})
# ---
# name: test_devices[da_ac_air_01011]
DeviceRegistryEntrySnapshot({
'area_id': None,
'config_entries': <ANY>,
'config_entries_subentries': <ANY>,
'configuration_url': 'https://account.smartthings.com',
'connections': set({
}),
'disabled_by': None,
'entry_type': None,
'hw_version': 'Realtek',
'id': <ANY>,
'identifiers': set({
tuple(
'smartthings',
'a5662f73-57d5-ba89-bf44-8b0008b8b2f3',
),
}),
'labels': set({
}),
'manufacturer': 'Samsung Electronics',
'model': 'AVT-WW-TP1-22-TOUCHOTN',
'model_id': None,
'name': 'Air filter',
'name_by_user': None,
'primary_config_entry': <ANY>,
'serial_number': None,
'sw_version': 'AVT-WW-TP1-22-TOUCHOTN_12240702',
'via_device_id': None,
})
# ---
# name: test_devices[da_ac_airsensor_01001]
DeviceRegistryEntrySnapshot({
'area_id': None,

View File

@@ -1676,346 +1676,6 @@
'state': 'good',
})
# ---
# name: test_all_entities[da_ac_air_01011][sensor.air_filter_air_quality-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'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.air_filter_air_quality',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'object_id_base': 'Air quality',
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Air quality',
'platform': 'smartthings',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'air_quality',
'unique_id': 'a5662f73-57d5-ba89-bf44-8b0008b8b2f3_main_airQualitySensor_airQuality_airQuality',
'unit_of_measurement': 'CAQI',
})
# ---
# name: test_all_entities[da_ac_air_01011][sensor.air_filter_air_quality-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Air filter Air quality',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': 'CAQI',
}),
'context': <ANY>,
'entity_id': 'sensor.air_filter_air_quality',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '1',
})
# ---
# name: test_all_entities[da_ac_air_01011][sensor.air_filter_energy-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
}),
'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.air_filter_energy',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'object_id_base': 'Energy',
'options': dict({
'sensor': dict({
'suggested_display_precision': 2,
}),
}),
'original_device_class': <SensorDeviceClass.ENERGY: 'energy'>,
'original_icon': None,
'original_name': 'Energy',
'platform': 'smartthings',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': None,
'unique_id': 'a5662f73-57d5-ba89-bf44-8b0008b8b2f3_main_powerConsumptionReport_powerConsumption_energy_meter',
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
})
# ---
# name: test_all_entities[da_ac_air_01011][sensor.air_filter_energy-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'energy',
'friendly_name': 'Air filter Energy',
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
}),
'context': <ANY>,
'entity_id': 'sensor.air_filter_energy',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '221.878',
})
# ---
# name: test_all_entities[da_ac_air_01011][sensor.air_filter_energy_difference-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.TOTAL: 'total'>,
}),
'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.air_filter_energy_difference',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'object_id_base': 'Energy difference',
'options': dict({
'sensor': dict({
'suggested_display_precision': 2,
}),
}),
'original_device_class': <SensorDeviceClass.ENERGY: 'energy'>,
'original_icon': None,
'original_name': 'Energy difference',
'platform': 'smartthings',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'energy_difference',
'unique_id': 'a5662f73-57d5-ba89-bf44-8b0008b8b2f3_main_powerConsumptionReport_powerConsumption_deltaEnergy_meter',
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
})
# ---
# name: test_all_entities[da_ac_air_01011][sensor.air_filter_energy_difference-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'energy',
'friendly_name': 'Air filter Energy difference',
'state_class': <SensorStateClass.TOTAL: 'total'>,
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
}),
'context': <ANY>,
'entity_id': 'sensor.air_filter_energy_difference',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '0.004',
})
# ---
# name: test_all_entities[da_ac_air_01011][sensor.air_filter_energy_saved-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
}),
'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.air_filter_energy_saved',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'object_id_base': 'Energy saved',
'options': dict({
'sensor': dict({
'suggested_display_precision': 2,
}),
}),
'original_device_class': <SensorDeviceClass.ENERGY: 'energy'>,
'original_icon': None,
'original_name': 'Energy saved',
'platform': 'smartthings',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'energy_saved',
'unique_id': 'a5662f73-57d5-ba89-bf44-8b0008b8b2f3_main_powerConsumptionReport_powerConsumption_energySaved_meter',
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
})
# ---
# name: test_all_entities[da_ac_air_01011][sensor.air_filter_energy_saved-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'energy',
'friendly_name': 'Air filter Energy saved',
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
}),
'context': <ANY>,
'entity_id': 'sensor.air_filter_energy_saved',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '0.0',
})
# ---
# name: test_all_entities[da_ac_air_01011][sensor.air_filter_power-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'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.air_filter_power',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'object_id_base': 'Power',
'options': dict({
'sensor': dict({
'suggested_display_precision': 2,
}),
}),
'original_device_class': <SensorDeviceClass.POWER: 'power'>,
'original_icon': None,
'original_name': 'Power',
'platform': 'smartthings',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': None,
'unique_id': 'a5662f73-57d5-ba89-bf44-8b0008b8b2f3_main_powerConsumptionReport_powerConsumption_power_meter',
'unit_of_measurement': <UnitOfPower.WATT: 'W'>,
})
# ---
# name: test_all_entities[da_ac_air_01011][sensor.air_filter_power-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'power',
'friendly_name': 'Air filter Power',
'power_consumption_end': '2026-03-09T20:53:57Z',
'power_consumption_start': '2026-03-09T20:42:57Z',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': <UnitOfPower.WATT: 'W'>,
}),
'context': <ANY>,
'entity_id': 'sensor.air_filter_power',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '0',
})
# ---
# name: test_all_entities[da_ac_air_01011][sensor.air_filter_power_energy-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.TOTAL: 'total'>,
}),
'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.air_filter_power_energy',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'object_id_base': 'Power energy',
'options': dict({
'sensor': dict({
'suggested_display_precision': 2,
}),
}),
'original_device_class': <SensorDeviceClass.ENERGY: 'energy'>,
'original_icon': None,
'original_name': 'Power energy',
'platform': 'smartthings',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'power_energy',
'unique_id': 'a5662f73-57d5-ba89-bf44-8b0008b8b2f3_main_powerConsumptionReport_powerConsumption_powerEnergy_meter',
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
})
# ---
# name: test_all_entities[da_ac_air_01011][sensor.air_filter_power_energy-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'energy',
'friendly_name': 'Air filter Power energy',
'state_class': <SensorStateClass.TOTAL: 'total'>,
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
}),
'context': <ANY>,
'entity_id': 'sensor.air_filter_power_energy',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '0.0',
})
# ---
# name: test_all_entities[da_ac_airsensor_01001][sensor.eeomoniteo_peulreoseu_air_quality-entry]
EntityRegistryEntrySnapshot({
'aliases': set({

View File

@@ -97,55 +97,6 @@
'state': 'on',
})
# ---
# name: test_all_entities[da_ac_air_01011][switch.air_filter-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'switch',
'entity_category': None,
'entity_id': 'switch.air_filter',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'object_id_base': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': None,
'platform': 'smartthings',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': None,
'unique_id': 'a5662f73-57d5-ba89-bf44-8b0008b8b2f3_main_switch_switch_switch',
'unit_of_measurement': None,
})
# ---
# name: test_all_entities[da_ac_air_01011][switch.air_filter-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Air filter',
}),
'context': <ANY>,
'entity_id': 'switch.air_filter',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'on',
})
# ---
# name: test_all_entities[da_ac_cac_01001][switch.ar_varanda_sound_effect-entry]
EntityRegistryEntrySnapshot({
'aliases': set({

View File

@@ -692,6 +692,12 @@ async def test_platform_backwards_compatibility_for_new_style_configs(
""",
],
)
# Patch out binary sensor triggers, because loading sun triggers also loads
# binary sensor triggers and those are irrelevant for this test
@patch(
"homeassistant.components.binary_sensor.trigger.async_get_triggers",
new=AsyncMock(return_value={}),
)
async def test_async_get_all_descriptions(
hass: HomeAssistant,
hass_ws_client: WebSocketGenerator,