mirror of
https://github.com/home-assistant/core.git
synced 2026-03-11 06:29:17 +00:00
Compare commits
1 Commits
revert_bin
...
windows-98
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
df06a5878c |
@@ -137,6 +137,7 @@ _EXPERIMENTAL_CONDITION_PLATFORMS = {
|
||||
_EXPERIMENTAL_TRIGGER_PLATFORMS = {
|
||||
"alarm_control_panel",
|
||||
"assist_satellite",
|
||||
"binary_sensor",
|
||||
"button",
|
||||
"climate",
|
||||
"cover",
|
||||
|
||||
@@ -174,5 +174,13 @@
|
||||
"on": "mdi:window-open"
|
||||
}
|
||||
}
|
||||
},
|
||||
"triggers": {
|
||||
"occupancy_cleared": {
|
||||
"trigger": "mdi:home-outline"
|
||||
},
|
||||
"occupancy_detected": {
|
||||
"trigger": "mdi:home"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
67
homeassistant/components/binary_sensor/trigger.py
Normal file
67
homeassistant/components/binary_sensor/trigger.py
Normal 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
|
||||
25
homeassistant/components/binary_sensor/triggers.yaml
Normal file
25
homeassistant/components/binary_sensor/triggers.yaml
Normal 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
|
||||
@@ -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"]
|
||||
}
|
||||
|
||||
@@ -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.",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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"]
|
||||
}
|
||||
|
||||
@@ -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"]
|
||||
}
|
||||
|
||||
5
homeassistant/generated/labs.py
generated
5
homeassistant/generated/labs.py
generated
@@ -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
2
requirements_all.txt
generated
@@ -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
|
||||
|
||||
2
requirements_test_all.txt
generated
2
requirements_test_all.txt
generated
@@ -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
|
||||
|
||||
258
tests/components/binary_sensor/test_trigger.py
Normal file
258
tests/components/binary_sensor/test_trigger.py
Normal 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
|
||||
@@ -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(
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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": {}
|
||||
}
|
||||
@@ -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({
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user