mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 16:57:53 +00:00
2025.3.1 (#140061)
This commit is contained in:
commit
4e89948b5c
@ -11,6 +11,7 @@ from typing import Any
|
||||
import evohomeasync as ec1
|
||||
import evohomeasync2 as ec2
|
||||
from evohomeasync2.const import (
|
||||
SZ_DHW,
|
||||
SZ_GATEWAY_ID,
|
||||
SZ_GATEWAY_INFO,
|
||||
SZ_GATEWAYS,
|
||||
@ -19,8 +20,9 @@ from evohomeasync2.const import (
|
||||
SZ_TEMPERATURE_CONTROL_SYSTEMS,
|
||||
SZ_TIME_ZONE,
|
||||
SZ_USE_DAYLIGHT_SAVE_SWITCHING,
|
||||
SZ_ZONES,
|
||||
)
|
||||
from evohomeasync2.schemas.typedefs import EvoLocStatusResponseT
|
||||
from evohomeasync2.schemas.typedefs import EvoLocStatusResponseT, EvoTcsConfigResponseT
|
||||
|
||||
from homeassistant.const import CONF_SCAN_INTERVAL
|
||||
from homeassistant.core import HomeAssistant
|
||||
@ -113,17 +115,19 @@ class EvoDataUpdateCoordinator(DataUpdateCoordinator):
|
||||
SZ_USE_DAYLIGHT_SAVE_SWITCHING
|
||||
],
|
||||
}
|
||||
tcs_info: EvoTcsConfigResponseT = self.tcs.config # type: ignore[assignment]
|
||||
tcs_info[SZ_ZONES] = [zone.config for zone in self.tcs.zones]
|
||||
if self.tcs.hotwater:
|
||||
tcs_info[SZ_DHW] = self.tcs.hotwater.config
|
||||
gwy_info = {
|
||||
SZ_GATEWAY_ID: self.loc.gateways[0].id,
|
||||
SZ_TEMPERATURE_CONTROL_SYSTEMS: [
|
||||
self.loc.gateways[0].systems[0].config
|
||||
],
|
||||
SZ_TEMPERATURE_CONTROL_SYSTEMS: [tcs_info],
|
||||
}
|
||||
config = {
|
||||
SZ_LOCATION_INFO: loc_info,
|
||||
SZ_GATEWAYS: [{SZ_GATEWAY_INFO: gwy_info}],
|
||||
}
|
||||
self.logger.debug("Config = %s", config)
|
||||
self.logger.debug("Config = %s", [config])
|
||||
|
||||
async def call_client_api(
|
||||
self,
|
||||
@ -203,10 +207,18 @@ class EvoDataUpdateCoordinator(DataUpdateCoordinator):
|
||||
|
||||
async def _update_v2_schedules(self) -> None:
|
||||
for zone in self.tcs.zones:
|
||||
await zone.get_schedule()
|
||||
try:
|
||||
await zone.get_schedule()
|
||||
except ec2.InvalidScheduleError as err:
|
||||
self.logger.warning(
|
||||
"Zone '%s' has an invalid/missing schedule: %r", zone.name, err
|
||||
)
|
||||
|
||||
if dhw := self.tcs.hotwater:
|
||||
await dhw.get_schedule()
|
||||
try:
|
||||
await dhw.get_schedule()
|
||||
except ec2.InvalidScheduleError as err:
|
||||
self.logger.warning("DHW has an invalid/missing schedule: %r", err)
|
||||
|
||||
async def _async_update_data(self) -> EvoLocStatusResponseT: # type: ignore[override]
|
||||
"""Fetch the latest state of an entire TCC Location.
|
||||
|
@ -6,6 +6,7 @@ import logging
|
||||
from typing import Any
|
||||
|
||||
import evohomeasync2 as evo
|
||||
from evohomeasync2.schemas.typedefs import DayOfWeekDhwT
|
||||
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
@ -102,7 +103,7 @@ class EvoChild(EvoEntity):
|
||||
|
||||
self._evo_tcs = evo_device.tcs
|
||||
|
||||
self._schedule: dict[str, Any] | None = None
|
||||
self._schedule: list[DayOfWeekDhwT] | None = None
|
||||
self._setpoints: dict[str, Any] = {}
|
||||
|
||||
@property
|
||||
@ -123,6 +124,9 @@ class EvoChild(EvoEntity):
|
||||
Only Zones & DHW controllers (but not the TCS) can have schedules.
|
||||
"""
|
||||
|
||||
if not self._schedule:
|
||||
return self._setpoints
|
||||
|
||||
this_sp_dtm, this_sp_val = self._evo_device.this_switchpoint
|
||||
next_sp_dtm, next_sp_val = self._evo_device.next_switchpoint
|
||||
|
||||
@ -152,10 +156,10 @@ class EvoChild(EvoEntity):
|
||||
self._evo_device,
|
||||
err,
|
||||
)
|
||||
self._schedule = {}
|
||||
self._schedule = []
|
||||
return
|
||||
else:
|
||||
self._schedule = schedule or {} # mypy hint
|
||||
self._schedule = schedule # type: ignore[assignment]
|
||||
|
||||
_LOGGER.debug("Schedule['%s'] = %s", self.name, schedule)
|
||||
|
||||
|
@ -20,5 +20,5 @@
|
||||
"documentation": "https://www.home-assistant.io/integrations/frontend",
|
||||
"integration_type": "system",
|
||||
"quality_scale": "internal",
|
||||
"requirements": ["home-assistant-frontend==20250305.0"]
|
||||
"requirements": ["home-assistant-frontend==20250306.0"]
|
||||
}
|
||||
|
@ -65,9 +65,9 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||
|
||||
prompt_parts = [call.data[CONF_PROMPT]]
|
||||
|
||||
config_entry: GoogleGenerativeAIConfigEntry = hass.config_entries.async_entries(
|
||||
DOMAIN
|
||||
)[0]
|
||||
config_entry: GoogleGenerativeAIConfigEntry = (
|
||||
hass.config_entries.async_loaded_entries(DOMAIN)[0]
|
||||
)
|
||||
|
||||
client = config_entry.runtime_data
|
||||
|
||||
|
@ -64,28 +64,18 @@ async def async_setup_entry(
|
||||
|
||||
|
||||
SUPPORTED_SCHEMA_KEYS = {
|
||||
"min_items",
|
||||
"example",
|
||||
"property_ordering",
|
||||
"pattern",
|
||||
"minimum",
|
||||
"default",
|
||||
"any_of",
|
||||
"max_length",
|
||||
"title",
|
||||
"min_properties",
|
||||
"min_length",
|
||||
"max_items",
|
||||
"maximum",
|
||||
"nullable",
|
||||
"max_properties",
|
||||
# Gemini API does not support all of the OpenAPI schema
|
||||
# SoT: https://ai.google.dev/api/caching#Schema
|
||||
"type",
|
||||
"description",
|
||||
"enum",
|
||||
"format",
|
||||
"items",
|
||||
"description",
|
||||
"nullable",
|
||||
"enum",
|
||||
"max_items",
|
||||
"min_items",
|
||||
"properties",
|
||||
"required",
|
||||
"items",
|
||||
}
|
||||
|
||||
|
||||
@ -109,9 +99,7 @@ def _format_schema(schema: dict[str, Any]) -> Schema:
|
||||
key = _camel_to_snake(key)
|
||||
if key not in SUPPORTED_SCHEMA_KEYS:
|
||||
continue
|
||||
if key == "any_of":
|
||||
val = [_format_schema(subschema) for subschema in val]
|
||||
elif key == "type":
|
||||
if key == "type":
|
||||
val = val.upper()
|
||||
elif key == "format":
|
||||
# Gemini API does not support all formats, see: https://ai.google.dev/api/caching#Schema
|
||||
|
@ -7,6 +7,6 @@
|
||||
"documentation": "https://www.home-assistant.io/integrations/home_connect",
|
||||
"iot_class": "cloud_push",
|
||||
"loggers": ["aiohomeconnect"],
|
||||
"requirements": ["aiohomeconnect==0.16.2"],
|
||||
"requirements": ["aiohomeconnect==0.16.3"],
|
||||
"single_config_entry": true
|
||||
}
|
||||
|
@ -386,6 +386,13 @@ class HomeConnectProgramSensor(HomeConnectSensor):
|
||||
|
||||
def update_native_value(self) -> None:
|
||||
"""Update the program sensor's status."""
|
||||
self.program_running = (
|
||||
status := self.appliance.status.get(StatusKey.BSH_COMMON_OPERATION_STATE)
|
||||
) is not None and status.value in [
|
||||
BSH_OPERATION_STATE_RUN,
|
||||
BSH_OPERATION_STATE_PAUSE,
|
||||
BSH_OPERATION_STATE_FINISHED,
|
||||
]
|
||||
event = self.appliance.events.get(cast(EventKey, self.bsh_key))
|
||||
if event:
|
||||
self._update_native_value(event.value)
|
||||
|
@ -3,6 +3,7 @@
|
||||
"step": {
|
||||
"init": {
|
||||
"title": "Pick Homematic IP access point",
|
||||
"description": "If you are about to register a **Homematic IP HCU1**, please press the button on top of the device before you continue.\n\nThe registration process must be completed within 5 minutes.",
|
||||
"data": {
|
||||
"hapid": "Access point ID (SGTIN)",
|
||||
"pin": "[%key:common::config_flow::data::pin%]",
|
||||
|
@ -11,6 +11,7 @@ import voluptuous as vol
|
||||
from homeassistant.components import sensor
|
||||
from homeassistant.components.sensor import (
|
||||
CONF_STATE_CLASS,
|
||||
DEVICE_CLASS_UNITS,
|
||||
DEVICE_CLASSES_SCHEMA,
|
||||
ENTITY_ID_FORMAT,
|
||||
STATE_CLASSES_SCHEMA,
|
||||
@ -107,6 +108,20 @@ def validate_sensor_state_and_device_class_config(config: ConfigType) -> ConfigT
|
||||
f"got `{CONF_DEVICE_CLASS}` '{device_class}'"
|
||||
)
|
||||
|
||||
if (device_class := config.get(CONF_DEVICE_CLASS)) is None or (
|
||||
unit_of_measurement := config.get(CONF_UNIT_OF_MEASUREMENT)
|
||||
) is None:
|
||||
return config
|
||||
|
||||
if (
|
||||
device_class in DEVICE_CLASS_UNITS
|
||||
and unit_of_measurement not in DEVICE_CLASS_UNITS[device_class]
|
||||
):
|
||||
raise vol.Invalid(
|
||||
f"The unit of measurement `{unit_of_measurement}` is not valid "
|
||||
f"together with device class `{device_class}`"
|
||||
)
|
||||
|
||||
return config
|
||||
|
||||
|
||||
|
@ -12,5 +12,5 @@
|
||||
"documentation": "https://www.home-assistant.io/integrations/nexia",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["nexia"],
|
||||
"requirements": ["nexia==2.2.1"]
|
||||
"requirements": ["nexia==2.2.2"]
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
import logging
|
||||
from typing import TYPE_CHECKING, cast
|
||||
@ -11,6 +12,7 @@ from pysmartthings import (
|
||||
Attribute,
|
||||
Capability,
|
||||
Device,
|
||||
DeviceEvent,
|
||||
Scene,
|
||||
SmartThings,
|
||||
SmartThingsAuthenticationFailedError,
|
||||
@ -28,7 +30,14 @@ from homeassistant.helpers.config_entry_oauth2_flow import (
|
||||
async_get_config_entry_implementation,
|
||||
)
|
||||
|
||||
from .const import CONF_INSTALLED_APP_ID, CONF_LOCATION_ID, DOMAIN, MAIN, OLD_DATA
|
||||
from .const import (
|
||||
CONF_INSTALLED_APP_ID,
|
||||
CONF_LOCATION_ID,
|
||||
DOMAIN,
|
||||
EVENT_BUTTON,
|
||||
MAIN,
|
||||
OLD_DATA,
|
||||
)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@ -114,6 +123,28 @@ async def async_setup_entry(hass: HomeAssistant, entry: SmartThingsConfigEntry)
|
||||
scenes=scenes,
|
||||
)
|
||||
|
||||
def handle_button_press(event: DeviceEvent) -> None:
|
||||
"""Handle a button press."""
|
||||
if (
|
||||
event.capability is Capability.BUTTON
|
||||
and event.attribute is Attribute.BUTTON
|
||||
):
|
||||
hass.bus.async_fire(
|
||||
EVENT_BUTTON,
|
||||
{
|
||||
"component_id": event.component_id,
|
||||
"device_id": event.device_id,
|
||||
"location_id": event.location_id,
|
||||
"value": event.value,
|
||||
"name": entry.runtime_data.devices[event.device_id].device.label,
|
||||
"data": event.data,
|
||||
},
|
||||
)
|
||||
|
||||
entry.async_on_unload(
|
||||
client.add_unspecified_device_event_listener(handle_button_press)
|
||||
)
|
||||
|
||||
entry.async_create_background_task(
|
||||
hass,
|
||||
client.subscribe(
|
||||
@ -160,26 +191,62 @@ async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
return True
|
||||
|
||||
|
||||
KEEP_CAPABILITY_QUIRK: dict[
|
||||
Capability | str, Callable[[dict[Attribute | str, Status]], bool]
|
||||
] = {
|
||||
Capability.WASHER_OPERATING_STATE: (
|
||||
lambda status: status[Attribute.SUPPORTED_MACHINE_STATES].value is not None
|
||||
),
|
||||
Capability.DEMAND_RESPONSE_LOAD_CONTROL: lambda _: True,
|
||||
}
|
||||
|
||||
POWER_CONSUMPTION_FIELDS = {
|
||||
"energy",
|
||||
"power",
|
||||
"deltaEnergy",
|
||||
"powerEnergy",
|
||||
"energySaved",
|
||||
}
|
||||
|
||||
CAPABILITY_VALIDATION: dict[
|
||||
Capability | str, Callable[[dict[Attribute | str, Status]], bool]
|
||||
] = {
|
||||
Capability.POWER_CONSUMPTION_REPORT: (
|
||||
lambda status: (
|
||||
(power_consumption := status[Attribute.POWER_CONSUMPTION].value) is not None
|
||||
and all(
|
||||
field in cast(dict, power_consumption)
|
||||
for field in POWER_CONSUMPTION_FIELDS
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
def process_status(
|
||||
status: dict[str, dict[Capability | str, dict[Attribute | str, Status]]],
|
||||
) -> dict[str, dict[Capability | str, dict[Attribute | str, Status]]]:
|
||||
"""Remove disabled capabilities from status."""
|
||||
if (main_component := status.get("main")) is None or (
|
||||
if (main_component := status.get(MAIN)) is None:
|
||||
return status
|
||||
if (
|
||||
disabled_capabilities_capability := main_component.get(
|
||||
Capability.CUSTOM_DISABLED_CAPABILITIES
|
||||
)
|
||||
) is None:
|
||||
return status
|
||||
disabled_capabilities = cast(
|
||||
list[Capability | str],
|
||||
disabled_capabilities_capability[Attribute.DISABLED_CAPABILITIES].value,
|
||||
)
|
||||
if disabled_capabilities is not None:
|
||||
for capability in disabled_capabilities:
|
||||
# We still need to make sure the climate entity can work without this capability
|
||||
if (
|
||||
capability in main_component
|
||||
and capability != Capability.DEMAND_RESPONSE_LOAD_CONTROL
|
||||
):
|
||||
) is not None:
|
||||
disabled_capabilities = cast(
|
||||
list[Capability | str],
|
||||
disabled_capabilities_capability[Attribute.DISABLED_CAPABILITIES].value,
|
||||
)
|
||||
if disabled_capabilities is not None:
|
||||
for capability in disabled_capabilities:
|
||||
if capability in main_component and (
|
||||
capability not in KEEP_CAPABILITY_QUIRK
|
||||
or not KEEP_CAPABILITY_QUIRK[capability](main_component[capability])
|
||||
):
|
||||
del main_component[capability]
|
||||
for capability in list(main_component):
|
||||
if capability in CAPABILITY_VALIDATION:
|
||||
if not CAPABILITY_VALIDATION[capability](main_component[capability]):
|
||||
del main_component[capability]
|
||||
return status
|
||||
|
@ -161,9 +161,7 @@ class SmartThingsThermostat(SmartThingsEntity, ClimateEntity):
|
||||
| ClimateEntityFeature.TURN_OFF
|
||||
| ClimateEntityFeature.TURN_ON
|
||||
)
|
||||
if self.get_attribute_value(
|
||||
Capability.THERMOSTAT_FAN_MODE, Attribute.THERMOSTAT_FAN_MODE
|
||||
):
|
||||
if self.supports_capability(Capability.THERMOSTAT_FAN_MODE):
|
||||
flags |= ClimateEntityFeature.FAN_MODE
|
||||
return flags
|
||||
|
||||
@ -445,12 +443,15 @@ class SmartThingsAirConditioner(SmartThingsEntity, ClimateEntity):
|
||||
)
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self) -> dict[str, Any]:
|
||||
def extra_state_attributes(self) -> dict[str, Any] | None:
|
||||
"""Return device specific state attributes.
|
||||
|
||||
Include attributes from the Demand Response Load Control (drlc)
|
||||
and Power Consumption capabilities.
|
||||
"""
|
||||
if not self.supports_capability(Capability.DEMAND_RESPONSE_LOAD_CONTROL):
|
||||
return None
|
||||
|
||||
drlc_status = self.get_attribute_value(
|
||||
Capability.DEMAND_RESPONSE_LOAD_CONTROL,
|
||||
Attribute.DEMAND_RESPONSE_LOAD_CONTROL_STATUS,
|
||||
@ -560,5 +561,6 @@ class SmartThingsAirConditioner(SmartThingsEntity, ClimateEntity):
|
||||
Capability.AIR_CONDITIONER_MODE, Attribute.SUPPORTED_AC_MODES
|
||||
)
|
||||
if (state := AC_MODE_TO_STATE.get(mode)) is not None
|
||||
if state not in modes
|
||||
)
|
||||
return modes
|
||||
|
@ -32,3 +32,5 @@ CONF_REFRESH_TOKEN = "refresh_token"
|
||||
|
||||
MAIN = "main"
|
||||
OLD_DATA = "old_data"
|
||||
|
||||
EVENT_BUTTON = "smartthings.button"
|
||||
|
@ -17,6 +17,15 @@ from .const import DOMAIN
|
||||
EVENT_WAIT_TIME = 5
|
||||
|
||||
|
||||
async def async_get_config_entry_diagnostics(
|
||||
hass: HomeAssistant,
|
||||
entry: SmartThingsConfigEntry,
|
||||
) -> dict[str, Any]:
|
||||
"""Return diagnostics for a config entry."""
|
||||
client = entry.runtime_data.client
|
||||
return await client.get_raw_devices()
|
||||
|
||||
|
||||
async def async_get_device_diagnostics(
|
||||
hass: HomeAssistant, entry: SmartThingsConfigEntry, device: DeviceEntry
|
||||
) -> dict[str, Any]:
|
||||
@ -26,7 +35,8 @@ async def async_get_device_diagnostics(
|
||||
identifier for identifier in device.identifiers if identifier[0] == DOMAIN
|
||||
)[1]
|
||||
|
||||
device_status = await client.get_device_status(device_id)
|
||||
device_status = await client.get_raw_device_status(device_id)
|
||||
device_info = await client.get_raw_device(device_id)
|
||||
|
||||
events: list[DeviceEvent] = []
|
||||
|
||||
@ -39,11 +49,8 @@ async def async_get_device_diagnostics(
|
||||
|
||||
listener()
|
||||
|
||||
status: dict[str, Any] = {}
|
||||
for component, capabilities in device_status.items():
|
||||
status[component] = {}
|
||||
for capability, attributes in capabilities.items():
|
||||
status[component][capability] = {}
|
||||
for attribute, value in attributes.items():
|
||||
status[component][capability][attribute] = asdict(value)
|
||||
return {"events": [asdict(event) for event in events], "status": status}
|
||||
return {
|
||||
"events": [asdict(event) for event in events],
|
||||
"status": device_status,
|
||||
"info": device_info,
|
||||
}
|
||||
|
@ -48,7 +48,9 @@ class SmartThingsEntity(Entity):
|
||||
self._attr_device_info.update(
|
||||
{
|
||||
"manufacturer": ocf.manufacturer_name,
|
||||
"model": ocf.model_number.split("|")[0],
|
||||
"model": (
|
||||
(ocf.model_number.split("|")[0]) if ocf.model_number else None
|
||||
),
|
||||
"hw_version": ocf.hardware_version,
|
||||
"sw_version": ocf.firmware_version,
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ class SmartThingsFan(SmartThingsEntity, FanEntity):
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""Return true if fan is on."""
|
||||
return self.get_attribute_value(Capability.SWITCH, Attribute.SWITCH)
|
||||
return self.get_attribute_value(Capability.SWITCH, Attribute.SWITCH) == "on"
|
||||
|
||||
@property
|
||||
def percentage(self) -> int | None:
|
||||
@ -132,6 +132,8 @@ class SmartThingsFan(SmartThingsEntity, FanEntity):
|
||||
|
||||
Requires FanEntityFeature.PRESET_MODE.
|
||||
"""
|
||||
if not self.supports_capability(Capability.AIR_CONDITIONER_FAN_MODE):
|
||||
return None
|
||||
return self.get_attribute_value(
|
||||
Capability.AIR_CONDITIONER_FAN_MODE, Attribute.FAN_MODE
|
||||
)
|
||||
@ -142,6 +144,8 @@ class SmartThingsFan(SmartThingsEntity, FanEntity):
|
||||
|
||||
Requires FanEntityFeature.PRESET_MODE.
|
||||
"""
|
||||
if not self.supports_capability(Capability.AIR_CONDITIONER_FAN_MODE):
|
||||
return None
|
||||
return self.get_attribute_value(
|
||||
Capability.AIR_CONDITIONER_FAN_MODE, Attribute.SUPPORTED_AC_FAN_MODES
|
||||
)
|
||||
|
@ -29,5 +29,5 @@
|
||||
"documentation": "https://www.home-assistant.io/integrations/smartthings",
|
||||
"iot_class": "cloud_push",
|
||||
"loggers": ["pysmartthings"],
|
||||
"requirements": ["pysmartthings==2.5.0"]
|
||||
"requirements": ["pysmartthings==2.7.0"]
|
||||
}
|
||||
|
@ -130,7 +130,6 @@ class SmartThingsSensorEntityDescription(SensorEntityDescription):
|
||||
unique_id_separator: str = "."
|
||||
capability_ignore_list: list[set[Capability]] | None = None
|
||||
options_attribute: Attribute | None = None
|
||||
except_if_state_none: bool = False
|
||||
|
||||
|
||||
CAPABILITY_TO_SENSORS: dict[
|
||||
@ -581,7 +580,6 @@ CAPABILITY_TO_SENSORS: dict[
|
||||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
value_fn=lambda value: value["energy"] / 1000,
|
||||
suggested_display_precision=2,
|
||||
except_if_state_none=True,
|
||||
),
|
||||
SmartThingsSensorEntityDescription(
|
||||
key="power_meter",
|
||||
@ -591,7 +589,6 @@ CAPABILITY_TO_SENSORS: dict[
|
||||
value_fn=lambda value: value["power"],
|
||||
extra_state_attributes_fn=power_attributes,
|
||||
suggested_display_precision=2,
|
||||
except_if_state_none=True,
|
||||
),
|
||||
SmartThingsSensorEntityDescription(
|
||||
key="deltaEnergy_meter",
|
||||
@ -601,7 +598,6 @@ CAPABILITY_TO_SENSORS: dict[
|
||||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
value_fn=lambda value: value["deltaEnergy"] / 1000,
|
||||
suggested_display_precision=2,
|
||||
except_if_state_none=True,
|
||||
),
|
||||
SmartThingsSensorEntityDescription(
|
||||
key="powerEnergy_meter",
|
||||
@ -611,7 +607,6 @@ CAPABILITY_TO_SENSORS: dict[
|
||||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
value_fn=lambda value: value["powerEnergy"] / 1000,
|
||||
suggested_display_precision=2,
|
||||
except_if_state_none=True,
|
||||
),
|
||||
SmartThingsSensorEntityDescription(
|
||||
key="energySaved_meter",
|
||||
@ -621,7 +616,6 @@ CAPABILITY_TO_SENSORS: dict[
|
||||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
value_fn=lambda value: value["energySaved"] / 1000,
|
||||
suggested_display_precision=2,
|
||||
except_if_state_none=True,
|
||||
),
|
||||
]
|
||||
},
|
||||
@ -951,6 +945,7 @@ UNITS = {
|
||||
"F": UnitOfTemperature.FAHRENHEIT,
|
||||
"lux": LIGHT_LUX,
|
||||
"mG": None,
|
||||
"μg/m^3": CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||
}
|
||||
|
||||
|
||||
@ -975,10 +970,6 @@ async def async_setup_entry(
|
||||
for capability_list in description.capability_ignore_list
|
||||
)
|
||||
)
|
||||
and (
|
||||
not description.except_if_state_none
|
||||
or device.status[MAIN][capability][attribute].value is not None
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
|
@ -7,5 +7,5 @@
|
||||
"iot_class": "cloud_push",
|
||||
"loggers": ["snoo"],
|
||||
"quality_scale": "bronze",
|
||||
"requirements": ["python-snoo==0.6.0"]
|
||||
"requirements": ["python-snoo==0.6.1"]
|
||||
}
|
||||
|
@ -43,6 +43,7 @@ SENSORS: tuple[SensorEntityDescription, ...] = (
|
||||
state_class=SensorStateClass.TOTAL,
|
||||
device_class=SensorDeviceClass.DURATION,
|
||||
native_unit_of_measurement=UnitOfTime.SECONDS,
|
||||
suggested_unit_of_measurement=UnitOfTime.HOURS,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key=STATUS_SENSOR_INFO_TOTAL_GENRES,
|
||||
|
@ -7,7 +7,7 @@
|
||||
"documentation": "https://www.home-assistant.io/integrations/synology_dsm",
|
||||
"iot_class": "local_polling",
|
||||
"loggers": ["synology_dsm"],
|
||||
"requirements": ["py-synologydsm-api==2.7.0"],
|
||||
"requirements": ["py-synologydsm-api==2.7.1"],
|
||||
"ssdp": [
|
||||
{
|
||||
"manufacturer": "Synology",
|
||||
|
@ -466,6 +466,7 @@ async def async_setup_entry(
|
||||
for energysite in entry.runtime_data.energysites
|
||||
for description in ENERGY_LIVE_DESCRIPTIONS
|
||||
if description.key in energysite.live_coordinator.data
|
||||
or description.key == "percentage_charged"
|
||||
),
|
||||
( # Add energy site history
|
||||
TeslaFleetEnergyHistorySensorEntity(energysite, description)
|
||||
|
@ -68,7 +68,7 @@ class TeslemetryVehicleSensorEntityDescription(SensorEntityDescription):
|
||||
|
||||
polling: bool = False
|
||||
polling_value_fn: Callable[[StateType], StateType] = lambda x: x
|
||||
polling_available_fn: Callable[[StateType], bool] = lambda x: x is not None
|
||||
nullable: bool = False
|
||||
streaming_key: Signal | None = None
|
||||
streaming_value_fn: Callable[[str | int | float], StateType] = lambda x: x
|
||||
streaming_firmware: str = "2024.26"
|
||||
@ -210,7 +210,7 @@ VEHICLE_DESCRIPTIONS: tuple[TeslemetryVehicleSensorEntityDescription, ...] = (
|
||||
TeslemetryVehicleSensorEntityDescription(
|
||||
key="drive_state_shift_state",
|
||||
polling=True,
|
||||
polling_available_fn=lambda x: True,
|
||||
nullable=True,
|
||||
polling_value_fn=lambda x: SHIFT_STATES.get(str(x), "p"),
|
||||
streaming_key=Signal.GEAR,
|
||||
streaming_value_fn=lambda x: str(ShiftState.get(x, "P")).lower(),
|
||||
@ -622,10 +622,10 @@ class TeslemetryStreamSensorEntity(TeslemetryVehicleStreamEntity, RestoreSensor)
|
||||
|
||||
def _async_value_from_stream(self, value) -> None:
|
||||
"""Update the value of the entity."""
|
||||
if value is None:
|
||||
self._attr_native_value = None
|
||||
else:
|
||||
if self.entity_description.nullable or value is not None:
|
||||
self._attr_native_value = self.entity_description.streaming_value_fn(value)
|
||||
else:
|
||||
self._attr_native_value = None
|
||||
|
||||
|
||||
class TeslemetryVehicleSensorEntity(TeslemetryVehicleEntity, SensorEntity):
|
||||
@ -644,7 +644,7 @@ class TeslemetryVehicleSensorEntity(TeslemetryVehicleEntity, SensorEntity):
|
||||
|
||||
def _async_update_attrs(self) -> None:
|
||||
"""Update the attributes of the sensor."""
|
||||
if self.entity_description.polling_available_fn(self._value):
|
||||
if self.entity_description.nullable or self._value is not None:
|
||||
self._attr_available = True
|
||||
self._attr_native_value = self.entity_description.polling_value_fn(
|
||||
self._value
|
||||
|
@ -148,7 +148,7 @@ DESCRIPTIONS: tuple[TessieSensorEntityDescription, ...] = (
|
||||
key="drive_state_shift_state",
|
||||
options=["p", "d", "r", "n"],
|
||||
device_class=SensorDeviceClass.ENUM,
|
||||
value_fn=lambda x: x.lower() if isinstance(x, str) else x,
|
||||
value_fn=lambda x: x.lower() if isinstance(x, str) else "p",
|
||||
),
|
||||
TessieSensorEntityDescription(
|
||||
key="vehicle_state_odometer",
|
||||
@ -397,6 +397,7 @@ async def async_setup_entry(
|
||||
for energysite in entry.runtime_data.energysites
|
||||
for description in ENERGY_LIVE_DESCRIPTIONS
|
||||
if description.key in energysite.live_coordinator.data
|
||||
or description.key == "percentage_charged"
|
||||
),
|
||||
( # Add wall connectors
|
||||
TessieWallConnectorSensorEntity(energysite, din, description)
|
||||
@ -449,7 +450,6 @@ class TessieEnergyLiveSensorEntity(TessieEnergyEntity, SensorEntity):
|
||||
|
||||
def _async_update_attrs(self) -> None:
|
||||
"""Update the attributes of the sensor."""
|
||||
self._attr_available = self._value is not None
|
||||
self._attr_native_value = self.entity_description.value_fn(self._value)
|
||||
|
||||
|
||||
|
@ -54,5 +54,5 @@
|
||||
"dependencies": ["bluetooth_adapters"],
|
||||
"documentation": "https://www.home-assistant.io/integrations/thermobeacon",
|
||||
"iot_class": "local_push",
|
||||
"requirements": ["thermobeacon-ble==0.8.0"]
|
||||
"requirements": ["thermobeacon-ble==0.8.1"]
|
||||
}
|
||||
|
@ -171,6 +171,7 @@ class WebDavBackupAgent(BackupAgent):
|
||||
await open_stream(),
|
||||
f"{self._backup_path}/{filename_tar}",
|
||||
timeout=BACKUP_TIMEOUT,
|
||||
content_length=backup.size,
|
||||
)
|
||||
|
||||
_LOGGER.debug(
|
||||
|
@ -8,5 +8,5 @@
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["aiowebdav2"],
|
||||
"quality_scale": "bronze",
|
||||
"requirements": ["aiowebdav2==0.3.1"]
|
||||
"requirements": ["aiowebdav2==0.4.1"]
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ if TYPE_CHECKING:
|
||||
APPLICATION_NAME: Final = "HomeAssistant"
|
||||
MAJOR_VERSION: Final = 2025
|
||||
MINOR_VERSION: Final = 3
|
||||
PATCH_VERSION: Final = "0"
|
||||
PATCH_VERSION: Final = "1"
|
||||
__short_version__: Final = f"{MAJOR_VERSION}.{MINOR_VERSION}"
|
||||
__version__: Final = f"{__short_version__}.{PATCH_VERSION}"
|
||||
REQUIRED_PYTHON_VER: Final[tuple[int, int, int]] = (3, 13, 0)
|
||||
|
@ -37,7 +37,7 @@ habluetooth==3.24.1
|
||||
hass-nabucasa==0.92.0
|
||||
hassil==2.2.3
|
||||
home-assistant-bluetooth==1.13.1
|
||||
home-assistant-frontend==20250305.0
|
||||
home-assistant-frontend==20250306.0
|
||||
home-assistant-intents==2025.3.5
|
||||
httpx==0.28.1
|
||||
ifaddr==0.2.0
|
||||
|
@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "homeassistant"
|
||||
version = "2025.3.0"
|
||||
version = "2025.3.1"
|
||||
license = {text = "Apache-2.0"}
|
||||
description = "Open-source home automation platform running on Python 3."
|
||||
readme = "README.rst"
|
||||
|
16
requirements_all.txt
generated
16
requirements_all.txt
generated
@ -264,7 +264,7 @@ aioharmony==0.4.1
|
||||
aiohasupervisor==0.3.0
|
||||
|
||||
# homeassistant.components.home_connect
|
||||
aiohomeconnect==0.16.2
|
||||
aiohomeconnect==0.16.3
|
||||
|
||||
# homeassistant.components.homekit_controller
|
||||
aiohomekit==3.2.8
|
||||
@ -422,7 +422,7 @@ aiowaqi==3.1.0
|
||||
aiowatttime==0.1.1
|
||||
|
||||
# homeassistant.components.webdav
|
||||
aiowebdav2==0.3.1
|
||||
aiowebdav2==0.4.1
|
||||
|
||||
# homeassistant.components.webostv
|
||||
aiowebostv==0.7.3
|
||||
@ -1152,7 +1152,7 @@ hole==0.8.0
|
||||
holidays==0.68
|
||||
|
||||
# homeassistant.components.frontend
|
||||
home-assistant-frontend==20250305.0
|
||||
home-assistant-frontend==20250306.0
|
||||
|
||||
# homeassistant.components.conversation
|
||||
home-assistant-intents==2025.3.5
|
||||
@ -1483,7 +1483,7 @@ nettigo-air-monitor==4.0.0
|
||||
neurio==0.3.1
|
||||
|
||||
# homeassistant.components.nexia
|
||||
nexia==2.2.1
|
||||
nexia==2.2.2
|
||||
|
||||
# homeassistant.components.nextcloud
|
||||
nextcloudmonitor==1.5.1
|
||||
@ -1755,7 +1755,7 @@ py-schluter==0.1.7
|
||||
py-sucks==0.9.10
|
||||
|
||||
# homeassistant.components.synology_dsm
|
||||
py-synologydsm-api==2.7.0
|
||||
py-synologydsm-api==2.7.1
|
||||
|
||||
# homeassistant.components.atome
|
||||
pyAtome==0.1.1
|
||||
@ -2310,7 +2310,7 @@ pysma==0.7.5
|
||||
pysmappee==0.2.29
|
||||
|
||||
# homeassistant.components.smartthings
|
||||
pysmartthings==2.5.0
|
||||
pysmartthings==2.7.0
|
||||
|
||||
# homeassistant.components.smarty
|
||||
pysmarty2==0.10.2
|
||||
@ -2467,7 +2467,7 @@ python-roborock==2.11.1
|
||||
python-smarttub==0.0.39
|
||||
|
||||
# homeassistant.components.snoo
|
||||
python-snoo==0.6.0
|
||||
python-snoo==0.6.1
|
||||
|
||||
# homeassistant.components.songpal
|
||||
python-songpal==0.16.2
|
||||
@ -2890,7 +2890,7 @@ tessie-api==0.1.1
|
||||
# tf-models-official==2.5.0
|
||||
|
||||
# homeassistant.components.thermobeacon
|
||||
thermobeacon-ble==0.8.0
|
||||
thermobeacon-ble==0.8.1
|
||||
|
||||
# homeassistant.components.thermopro
|
||||
thermopro-ble==0.11.0
|
||||
|
16
requirements_test_all.txt
generated
16
requirements_test_all.txt
generated
@ -249,7 +249,7 @@ aioharmony==0.4.1
|
||||
aiohasupervisor==0.3.0
|
||||
|
||||
# homeassistant.components.home_connect
|
||||
aiohomeconnect==0.16.2
|
||||
aiohomeconnect==0.16.3
|
||||
|
||||
# homeassistant.components.homekit_controller
|
||||
aiohomekit==3.2.8
|
||||
@ -404,7 +404,7 @@ aiowaqi==3.1.0
|
||||
aiowatttime==0.1.1
|
||||
|
||||
# homeassistant.components.webdav
|
||||
aiowebdav2==0.3.1
|
||||
aiowebdav2==0.4.1
|
||||
|
||||
# homeassistant.components.webostv
|
||||
aiowebostv==0.7.3
|
||||
@ -981,7 +981,7 @@ hole==0.8.0
|
||||
holidays==0.68
|
||||
|
||||
# homeassistant.components.frontend
|
||||
home-assistant-frontend==20250305.0
|
||||
home-assistant-frontend==20250306.0
|
||||
|
||||
# homeassistant.components.conversation
|
||||
home-assistant-intents==2025.3.5
|
||||
@ -1246,7 +1246,7 @@ netmap==0.7.0.2
|
||||
nettigo-air-monitor==4.0.0
|
||||
|
||||
# homeassistant.components.nexia
|
||||
nexia==2.2.1
|
||||
nexia==2.2.2
|
||||
|
||||
# homeassistant.components.nextcloud
|
||||
nextcloudmonitor==1.5.1
|
||||
@ -1453,7 +1453,7 @@ py-nightscout==1.2.2
|
||||
py-sucks==0.9.10
|
||||
|
||||
# homeassistant.components.synology_dsm
|
||||
py-synologydsm-api==2.7.0
|
||||
py-synologydsm-api==2.7.1
|
||||
|
||||
# homeassistant.components.hdmi_cec
|
||||
pyCEC==0.5.2
|
||||
@ -1882,7 +1882,7 @@ pysma==0.7.5
|
||||
pysmappee==0.2.29
|
||||
|
||||
# homeassistant.components.smartthings
|
||||
pysmartthings==2.5.0
|
||||
pysmartthings==2.7.0
|
||||
|
||||
# homeassistant.components.smarty
|
||||
pysmarty2==0.10.2
|
||||
@ -2000,7 +2000,7 @@ python-roborock==2.11.1
|
||||
python-smarttub==0.0.39
|
||||
|
||||
# homeassistant.components.snoo
|
||||
python-snoo==0.6.0
|
||||
python-snoo==0.6.1
|
||||
|
||||
# homeassistant.components.songpal
|
||||
python-songpal==0.16.2
|
||||
@ -2327,7 +2327,7 @@ teslemetry-stream==0.6.10
|
||||
tessie-api==0.1.1
|
||||
|
||||
# homeassistant.components.thermobeacon
|
||||
thermobeacon-ble==0.8.0
|
||||
thermobeacon-ble==0.8.1
|
||||
|
||||
# homeassistant.components.thermopro
|
||||
thermopro-ble==0.11.0
|
||||
|
@ -48,18 +48,18 @@ def location_status_fixture(install: str, loc_id: str | None = None) -> JsonObje
|
||||
return load_json_object_fixture(f"{install}/status_{loc_id}.json", DOMAIN)
|
||||
|
||||
|
||||
def dhw_schedule_fixture(install: str) -> JsonObjectType:
|
||||
def dhw_schedule_fixture(install: str, dhw_id: str | None = None) -> JsonObjectType:
|
||||
"""Load JSON for the schedule of a domesticHotWater zone."""
|
||||
try:
|
||||
return load_json_object_fixture(f"{install}/schedule_dhw.json", DOMAIN)
|
||||
return load_json_object_fixture(f"{install}/schedule_{dhw_id}.json", DOMAIN)
|
||||
except FileNotFoundError:
|
||||
return load_json_object_fixture("default/schedule_dhw.json", DOMAIN)
|
||||
|
||||
|
||||
def zone_schedule_fixture(install: str) -> JsonObjectType:
|
||||
def zone_schedule_fixture(install: str, zon_id: str | None = None) -> JsonObjectType:
|
||||
"""Load JSON for the schedule of a temperatureZone zone."""
|
||||
try:
|
||||
return load_json_object_fixture(f"{install}/schedule_zone.json", DOMAIN)
|
||||
return load_json_object_fixture(f"{install}/schedule_{zon_id}.json", DOMAIN)
|
||||
except FileNotFoundError:
|
||||
return load_json_object_fixture("default/schedule_zone.json", DOMAIN)
|
||||
|
||||
@ -120,9 +120,9 @@ def mock_make_request(install: str) -> Callable:
|
||||
|
||||
elif "schedule" in url:
|
||||
if url.startswith("domesticHotWater"): # /v2/domesticHotWater/{id}/schedule
|
||||
return dhw_schedule_fixture(install)
|
||||
return dhw_schedule_fixture(install, url[16:23])
|
||||
if url.startswith("temperatureZone"): # /v2/temperatureZone/{id}/schedule
|
||||
return zone_schedule_fixture(install)
|
||||
return zone_schedule_fixture(install, url[16:23])
|
||||
|
||||
pytest.fail(f"Unexpected request: {HTTPMethod.GET} {url}")
|
||||
|
||||
|
@ -15,8 +15,9 @@ TEST_INSTALLS: Final = (
|
||||
"default", # evohome: multi-zone, with DHW
|
||||
"h032585", # VisionProWifi: no preset modes for TCS, zoneId=systemId
|
||||
"h099625", # RoundThermostat
|
||||
"h139906", # zone with null schedule
|
||||
"sys_004", # RoundModulation
|
||||
)
|
||||
# "botched", # as default: but with activeFaults, ghost zones & unknown types
|
||||
|
||||
TEST_INSTALLS_WITH_DHW: Final = ("default",)
|
||||
TEST_INSTALLS_WITH_DHW: Final = ("default", "botched")
|
||||
|
@ -0,0 +1,3 @@
|
||||
{
|
||||
"dailySchedules": []
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
{
|
||||
"dailySchedules": []
|
||||
}
|
143
tests/components/evohome/fixtures/h139906/schedule_3454855.json
Normal file
143
tests/components/evohome/fixtures/h139906/schedule_3454855.json
Normal file
@ -0,0 +1,143 @@
|
||||
{
|
||||
"dailySchedules": [
|
||||
{
|
||||
"dayOfWeek": "Monday",
|
||||
"switchpoints": [
|
||||
{
|
||||
"heatSetpoint": 22.0,
|
||||
"timeOfDay": "05:30:00"
|
||||
},
|
||||
{
|
||||
"heatSetpoint": 20.0,
|
||||
"timeOfDay": "08:00:00"
|
||||
},
|
||||
{
|
||||
"heatSetpoint": 22.5,
|
||||
"timeOfDay": "16:00:00"
|
||||
},
|
||||
{
|
||||
"heatSetpoint": 15.0,
|
||||
"timeOfDay": "23:00:00"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"dayOfWeek": "Tuesday",
|
||||
"switchpoints": [
|
||||
{
|
||||
"heatSetpoint": 22.0,
|
||||
"timeOfDay": "05:30:00"
|
||||
},
|
||||
{
|
||||
"heatSetpoint": 20.0,
|
||||
"timeOfDay": "08:00:00"
|
||||
},
|
||||
{
|
||||
"heatSetpoint": 22.5,
|
||||
"timeOfDay": "16:00:00"
|
||||
},
|
||||
{
|
||||
"heatSetpoint": 15.0,
|
||||
"timeOfDay": "23:00:00"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"dayOfWeek": "Wednesday",
|
||||
"switchpoints": [
|
||||
{
|
||||
"heatSetpoint": 22.0,
|
||||
"timeOfDay": "05:30:00"
|
||||
},
|
||||
{
|
||||
"heatSetpoint": 20.0,
|
||||
"timeOfDay": "08:00:00"
|
||||
},
|
||||
{
|
||||
"heatSetpoint": 22.5,
|
||||
"timeOfDay": "12:00:00"
|
||||
},
|
||||
{
|
||||
"heatSetpoint": 15.0,
|
||||
"timeOfDay": "23:00:00"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"dayOfWeek": "Thursday",
|
||||
"switchpoints": [
|
||||
{
|
||||
"heatSetpoint": 22.0,
|
||||
"timeOfDay": "05:30:00"
|
||||
},
|
||||
{
|
||||
"heatSetpoint": 20.0,
|
||||
"timeOfDay": "08:00:00"
|
||||
},
|
||||
{
|
||||
"heatSetpoint": 22.5,
|
||||
"timeOfDay": "16:00:00"
|
||||
},
|
||||
{
|
||||
"heatSetpoint": 15.0,
|
||||
"timeOfDay": "23:00:00"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"dayOfWeek": "Friday",
|
||||
"switchpoints": [
|
||||
{
|
||||
"heatSetpoint": 22.0,
|
||||
"timeOfDay": "05:30:00"
|
||||
},
|
||||
{
|
||||
"heatSetpoint": 20.0,
|
||||
"timeOfDay": "08:00:00"
|
||||
},
|
||||
{
|
||||
"heatSetpoint": 22.5,
|
||||
"timeOfDay": "16:00:00"
|
||||
},
|
||||
{
|
||||
"heatSetpoint": 15.0,
|
||||
"timeOfDay": "23:00:00"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"dayOfWeek": "Saturday",
|
||||
"switchpoints": [
|
||||
{
|
||||
"heatSetpoint": 22.0,
|
||||
"timeOfDay": "07:00:00"
|
||||
},
|
||||
{
|
||||
"heatSetpoint": 22.5,
|
||||
"timeOfDay": "16:00:00"
|
||||
},
|
||||
{
|
||||
"heatSetpoint": 15.0,
|
||||
"timeOfDay": "23:00:00"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"dayOfWeek": "Sunday",
|
||||
"switchpoints": [
|
||||
{
|
||||
"heatSetpoint": 22.0,
|
||||
"timeOfDay": "07:30:00"
|
||||
},
|
||||
{
|
||||
"heatSetpoint": 22.5,
|
||||
"timeOfDay": "16:00:00"
|
||||
},
|
||||
{
|
||||
"heatSetpoint": 15.0,
|
||||
"timeOfDay": "23:00:00"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
{
|
||||
"locationId": "2727366",
|
||||
"gateways": [
|
||||
{
|
||||
"gatewayId": "2513794",
|
||||
"temperatureControlSystems": [
|
||||
{
|
||||
"systemId": "3454856",
|
||||
"zones": [
|
||||
{
|
||||
"zoneId": "3454854",
|
||||
"temperatureStatus": {
|
||||
"temperature": 22.0,
|
||||
"isAvailable": true
|
||||
},
|
||||
"activeFaults": [
|
||||
{
|
||||
"faultType": "TempZoneSensorCommunicationLost",
|
||||
"since": "2025-02-06T11:20:29"
|
||||
}
|
||||
],
|
||||
"setpointStatus": {
|
||||
"targetHeatTemperature": 5.0,
|
||||
"setpointMode": "FollowSchedule"
|
||||
},
|
||||
"name": "Thermostat"
|
||||
},
|
||||
{
|
||||
"zoneId": "3454855",
|
||||
"temperatureStatus": {
|
||||
"temperature": 22.0,
|
||||
"isAvailable": true
|
||||
},
|
||||
"activeFaults": [],
|
||||
"setpointStatus": {
|
||||
"targetHeatTemperature": 20.0,
|
||||
"setpointMode": "FollowSchedule"
|
||||
},
|
||||
"name": "Thermostat 2"
|
||||
}
|
||||
],
|
||||
"activeFaults": [],
|
||||
"systemModeStatus": {
|
||||
"mode": "Auto",
|
||||
"isPermanent": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"activeFaults": []
|
||||
}
|
||||
]
|
||||
}
|
125
tests/components/evohome/fixtures/h139906/user_locations.json
Normal file
125
tests/components/evohome/fixtures/h139906/user_locations.json
Normal file
@ -0,0 +1,125 @@
|
||||
[
|
||||
{
|
||||
"locationInfo": {
|
||||
"locationId": "2727366",
|
||||
"name": "Vr**********",
|
||||
"streetAddress": "********** *",
|
||||
"city": "*********",
|
||||
"country": "Netherlands",
|
||||
"postcode": "******",
|
||||
"locationType": "Residential",
|
||||
"useDaylightSaveSwitching": true,
|
||||
"timeZone": {
|
||||
"timeZoneId": "WEuropeStandardTime",
|
||||
"displayName": "(UTC+01:00) Amsterdam, Berlijn, Bern, Rome, Stockholm, Wenen",
|
||||
"offsetMinutes": 60,
|
||||
"currentOffsetMinutes": 60,
|
||||
"supportsDaylightSaving": true
|
||||
},
|
||||
"locationOwner": {
|
||||
"userId": "2276512",
|
||||
"username": "nobody@nowhere.com",
|
||||
"firstname": "Gl***",
|
||||
"lastname": "de*****"
|
||||
}
|
||||
},
|
||||
"gateways": [
|
||||
{
|
||||
"gatewayInfo": {
|
||||
"gatewayId": "2513794",
|
||||
"mac": "************",
|
||||
"crc": "****",
|
||||
"isWiFi": false
|
||||
},
|
||||
"temperatureControlSystems": [
|
||||
{
|
||||
"systemId": "3454856",
|
||||
"modelType": "EvoTouch",
|
||||
"zones": [
|
||||
{
|
||||
"zoneId": "3454854",
|
||||
"modelType": "HeatingZone",
|
||||
"setpointCapabilities": {
|
||||
"maxHeatSetpoint": 35.0,
|
||||
"minHeatSetpoint": 5.0,
|
||||
"valueResolution": 0.5,
|
||||
"canControlHeat": true,
|
||||
"canControlCool": false,
|
||||
"allowedSetpointModes": [
|
||||
"PermanentOverride",
|
||||
"FollowSchedule",
|
||||
"TemporaryOverride"
|
||||
],
|
||||
"maxDuration": "1.00:00:00",
|
||||
"timingResolution": "00:10:00"
|
||||
},
|
||||
"scheduleCapabilities": {
|
||||
"maxSwitchpointsPerDay": 6,
|
||||
"minSwitchpointsPerDay": 1,
|
||||
"timingResolution": "00:10:00",
|
||||
"setpointValueResolution": 0.5
|
||||
},
|
||||
"name": "Thermostat",
|
||||
"zoneType": "ZoneTemperatureControl"
|
||||
},
|
||||
{
|
||||
"zoneId": "3454855",
|
||||
"modelType": "RoundWireless",
|
||||
"setpointCapabilities": {
|
||||
"maxHeatSetpoint": 35.0,
|
||||
"minHeatSetpoint": 5.0,
|
||||
"valueResolution": 0.5,
|
||||
"canControlHeat": true,
|
||||
"canControlCool": false,
|
||||
"allowedSetpointModes": [
|
||||
"PermanentOverride",
|
||||
"FollowSchedule",
|
||||
"TemporaryOverride"
|
||||
],
|
||||
"maxDuration": "1.00:00:00",
|
||||
"timingResolution": "00:10:00"
|
||||
},
|
||||
"scheduleCapabilities": {
|
||||
"maxSwitchpointsPerDay": 6,
|
||||
"minSwitchpointsPerDay": 0,
|
||||
"timingResolution": "00:10:00",
|
||||
"setpointValueResolution": 0.5
|
||||
},
|
||||
"name": "Thermostat 2",
|
||||
"zoneType": "Thermostat"
|
||||
}
|
||||
],
|
||||
"allowedSystemModes": [
|
||||
{
|
||||
"systemMode": "Auto",
|
||||
"canBePermanent": true,
|
||||
"canBeTemporary": false
|
||||
},
|
||||
{
|
||||
"systemMode": "AutoWithEco",
|
||||
"canBePermanent": true,
|
||||
"canBeTemporary": true,
|
||||
"maxDuration": "1.00:00:00",
|
||||
"timingResolution": "01:00:00",
|
||||
"timingMode": "Duration"
|
||||
},
|
||||
{
|
||||
"systemMode": "Away",
|
||||
"canBePermanent": true,
|
||||
"canBeTemporary": true,
|
||||
"maxDuration": "99.00:00:00",
|
||||
"timingResolution": "1.00:00:00",
|
||||
"timingMode": "Period"
|
||||
},
|
||||
{
|
||||
"systemMode": "HeatingOff",
|
||||
"canBePermanent": true,
|
||||
"canBeTemporary": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
@ -29,6 +29,16 @@
|
||||
),
|
||||
])
|
||||
# ---
|
||||
# name: test_ctl_set_hvac_mode[h139906]
|
||||
list([
|
||||
tuple(
|
||||
<SystemMode.HEATING_OFF: 'HeatingOff'>,
|
||||
),
|
||||
tuple(
|
||||
<SystemMode.AUTO: 'Auto'>,
|
||||
),
|
||||
])
|
||||
# ---
|
||||
# name: test_ctl_set_hvac_mode[minimal]
|
||||
list([
|
||||
tuple(
|
||||
@ -70,6 +80,13 @@
|
||||
),
|
||||
])
|
||||
# ---
|
||||
# name: test_ctl_turn_off[h139906]
|
||||
list([
|
||||
tuple(
|
||||
<SystemMode.HEATING_OFF: 'HeatingOff'>,
|
||||
),
|
||||
])
|
||||
# ---
|
||||
# name: test_ctl_turn_off[minimal]
|
||||
list([
|
||||
tuple(
|
||||
@ -105,6 +122,13 @@
|
||||
),
|
||||
])
|
||||
# ---
|
||||
# name: test_ctl_turn_on[h139906]
|
||||
list([
|
||||
tuple(
|
||||
<SystemMode.AUTO: 'Auto'>,
|
||||
),
|
||||
])
|
||||
# ---
|
||||
# name: test_ctl_turn_on[minimal]
|
||||
list([
|
||||
tuple(
|
||||
@ -1118,6 +1142,136 @@
|
||||
'state': 'heat',
|
||||
})
|
||||
# ---
|
||||
# name: test_setup_platform[h139906][climate.thermostat-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'current_temperature': 22.0,
|
||||
'friendly_name': 'Thermostat',
|
||||
'hvac_modes': list([
|
||||
<HVACMode.OFF: 'off'>,
|
||||
<HVACMode.HEAT: 'heat'>,
|
||||
]),
|
||||
'max_temp': 35.0,
|
||||
'min_temp': 5.0,
|
||||
'preset_mode': 'none',
|
||||
'preset_modes': list([
|
||||
'none',
|
||||
'temporary',
|
||||
'permanent',
|
||||
]),
|
||||
'status': dict({
|
||||
'activeFaults': tuple(
|
||||
dict({
|
||||
'fault_type': 'TempZoneSensorCommunicationLost',
|
||||
'since': '2025-02-06T11:20:29+01:00',
|
||||
}),
|
||||
),
|
||||
'setpoint_status': dict({
|
||||
'setpoint_mode': 'FollowSchedule',
|
||||
'target_heat_temperature': 5.0,
|
||||
}),
|
||||
'setpoints': dict({
|
||||
}),
|
||||
'temperature_status': dict({
|
||||
'is_available': True,
|
||||
'temperature': 22.0,
|
||||
}),
|
||||
'zone_id': '3454854',
|
||||
}),
|
||||
'supported_features': <ClimateEntityFeature: 401>,
|
||||
'temperature': 5.0,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'climate.thermostat',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_setup_platform[h139906][climate.thermostat_2-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'current_temperature': 22.0,
|
||||
'friendly_name': 'Thermostat 2',
|
||||
'hvac_modes': list([
|
||||
<HVACMode.OFF: 'off'>,
|
||||
<HVACMode.HEAT: 'heat'>,
|
||||
]),
|
||||
'max_temp': 35.0,
|
||||
'min_temp': 5.0,
|
||||
'preset_mode': 'none',
|
||||
'preset_modes': list([
|
||||
'none',
|
||||
'temporary',
|
||||
'permanent',
|
||||
]),
|
||||
'status': dict({
|
||||
'activeFaults': tuple(
|
||||
),
|
||||
'setpoint_status': dict({
|
||||
'setpoint_mode': 'FollowSchedule',
|
||||
'target_heat_temperature': 20.0,
|
||||
}),
|
||||
'setpoints': dict({
|
||||
'next_sp_from': HAFakeDatetime(2024, 7, 10, 23, 0, tzinfo=zoneinfo.ZoneInfo(key='Europe/Berlin')),
|
||||
'next_sp_temp': 15.0,
|
||||
'this_sp_from': HAFakeDatetime(2024, 7, 10, 12, 0, tzinfo=zoneinfo.ZoneInfo(key='Europe/Berlin')),
|
||||
'this_sp_temp': 22.5,
|
||||
}),
|
||||
'temperature_status': dict({
|
||||
'is_available': True,
|
||||
'temperature': 22.0,
|
||||
}),
|
||||
'zone_id': '3454855',
|
||||
}),
|
||||
'supported_features': <ClimateEntityFeature: 401>,
|
||||
'temperature': 20.0,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'climate.thermostat_2',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'heat',
|
||||
})
|
||||
# ---
|
||||
# name: test_setup_platform[h139906][climate.vr-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'current_temperature': 22.0,
|
||||
'friendly_name': 'Vr**********',
|
||||
'hvac_modes': list([
|
||||
<HVACMode.OFF: 'off'>,
|
||||
<HVACMode.HEAT: 'heat'>,
|
||||
]),
|
||||
'icon': 'mdi:thermostat',
|
||||
'max_temp': 35,
|
||||
'min_temp': 7,
|
||||
'preset_mode': None,
|
||||
'preset_modes': list([
|
||||
'eco',
|
||||
'away',
|
||||
]),
|
||||
'status': dict({
|
||||
'activeSystemFaults': tuple(
|
||||
),
|
||||
'system_id': '3454856',
|
||||
'system_mode_status': dict({
|
||||
'is_permanent': True,
|
||||
'mode': 'Auto',
|
||||
}),
|
||||
}),
|
||||
'supported_features': <ClimateEntityFeature: 400>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'climate.vr',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'heat',
|
||||
})
|
||||
# ---
|
||||
# name: test_setup_platform[minimal][climate.main_room-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
@ -1312,6 +1466,13 @@
|
||||
),
|
||||
])
|
||||
# ---
|
||||
# name: test_zone_set_hvac_mode[h139906]
|
||||
list([
|
||||
tuple(
|
||||
5.0,
|
||||
),
|
||||
])
|
||||
# ---
|
||||
# name: test_zone_set_hvac_mode[minimal]
|
||||
list([
|
||||
tuple(
|
||||
@ -1365,6 +1526,19 @@
|
||||
}),
|
||||
])
|
||||
# ---
|
||||
# name: test_zone_set_preset_mode[h139906]
|
||||
list([
|
||||
tuple(
|
||||
5.0,
|
||||
),
|
||||
tuple(
|
||||
5.0,
|
||||
),
|
||||
dict({
|
||||
'until': None,
|
||||
}),
|
||||
])
|
||||
# ---
|
||||
# name: test_zone_set_preset_mode[minimal]
|
||||
list([
|
||||
tuple(
|
||||
@ -1412,6 +1586,13 @@
|
||||
}),
|
||||
])
|
||||
# ---
|
||||
# name: test_zone_set_temperature[h139906]
|
||||
list([
|
||||
dict({
|
||||
'until': None,
|
||||
}),
|
||||
])
|
||||
# ---
|
||||
# name: test_zone_set_temperature[minimal]
|
||||
list([
|
||||
dict({
|
||||
@ -1447,6 +1628,13 @@
|
||||
),
|
||||
])
|
||||
# ---
|
||||
# name: test_zone_turn_off[h139906]
|
||||
list([
|
||||
tuple(
|
||||
5.0,
|
||||
),
|
||||
])
|
||||
# ---
|
||||
# name: test_zone_turn_off[minimal]
|
||||
list([
|
||||
tuple(
|
||||
|
@ -11,6 +11,9 @@
|
||||
# name: test_setup[h099625]
|
||||
dict_keys(['refresh_system', 'set_system_mode', 'clear_zone_override', 'set_zone_override'])
|
||||
# ---
|
||||
# name: test_setup[h139906]
|
||||
dict_keys(['refresh_system', 'set_system_mode', 'clear_zone_override', 'set_zone_override'])
|
||||
# ---
|
||||
# name: test_setup[minimal]
|
||||
dict_keys(['refresh_system', 'reset_system', 'set_system_mode', 'clear_zone_override', 'set_zone_override'])
|
||||
# ---
|
||||
|
@ -1,4 +1,14 @@
|
||||
# serializer version: 1
|
||||
# name: test_set_operation_mode[botched]
|
||||
list([
|
||||
dict({
|
||||
'until': HAFakeDatetime(2024, 7, 10, 12, 0, tzinfo=datetime.timezone.utc),
|
||||
}),
|
||||
dict({
|
||||
'until': HAFakeDatetime(2024, 7, 10, 12, 0, tzinfo=datetime.timezone.utc),
|
||||
}),
|
||||
])
|
||||
# ---
|
||||
# name: test_set_operation_mode[default]
|
||||
list([
|
||||
dict({
|
||||
|
@ -33,7 +33,7 @@ from .const import TEST_INSTALLS_WITH_DHW
|
||||
DHW_ENTITY_ID = "water_heater.domestic_hot_water"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("install", [*TEST_INSTALLS_WITH_DHW, "botched"])
|
||||
@pytest.mark.parametrize("install", TEST_INSTALLS_WITH_DHW)
|
||||
async def test_setup_platform(
|
||||
hass: HomeAssistant,
|
||||
config: dict[str, str],
|
||||
|
@ -6,7 +6,7 @@
|
||||
tuple(
|
||||
),
|
||||
dict({
|
||||
'config': GenerateContentConfig(http_options=None, system_instruction="Current time is 05:00:00. Today's date is 2024-05-24.\nYou are a voice assistant for Home Assistant.\nAnswer questions about the world truthfully.\nAnswer in plain text. Keep it simple and to the point.\nOnly if the user wants to control a device, tell them to expose entities to their voice assistant in Home Assistant.", temperature=1.0, top_p=0.95, top_k=64.0, candidate_count=None, max_output_tokens=150, stop_sequences=None, response_logprobs=None, logprobs=None, presence_penalty=None, frequency_penalty=None, seed=None, response_mime_type=None, response_schema=None, routing_config=None, safety_settings=[SafetySetting(method=None, category=<HarmCategory.HARM_CATEGORY_HATE_SPEECH: 'HARM_CATEGORY_HATE_SPEECH'>, threshold=<HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE: 'BLOCK_MEDIUM_AND_ABOVE'>), SafetySetting(method=None, category=<HarmCategory.HARM_CATEGORY_HARASSMENT: 'HARM_CATEGORY_HARASSMENT'>, threshold=<HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE: 'BLOCK_MEDIUM_AND_ABOVE'>), SafetySetting(method=None, category=<HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT: 'HARM_CATEGORY_DANGEROUS_CONTENT'>, threshold=<HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE: 'BLOCK_MEDIUM_AND_ABOVE'>), SafetySetting(method=None, category=<HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT: 'HARM_CATEGORY_SEXUALLY_EXPLICIT'>, threshold=<HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE: 'BLOCK_MEDIUM_AND_ABOVE'>)], tools=[Tool(function_declarations=[FunctionDeclaration(response=None, description='Test function', name='test_tool', parameters=Schema(min_items=None, example=None, property_ordering=None, pattern=None, minimum=None, default=None, any_of=None, max_length=None, title=None, min_length=None, min_properties=None, max_items=None, maximum=None, nullable=None, max_properties=None, type=<Type.OBJECT: 'OBJECT'>, description=None, enum=None, format=None, items=None, properties={'param1': Schema(min_items=None, example=None, property_ordering=None, pattern=None, minimum=None, default=None, any_of=None, max_length=None, title=None, min_length=None, min_properties=None, max_items=None, maximum=None, nullable=None, max_properties=None, type=<Type.ARRAY: 'ARRAY'>, description='Test parameters', enum=None, format=None, items=Schema(min_items=None, example=None, property_ordering=None, pattern=None, minimum=None, default=None, any_of=None, max_length=None, title=None, min_length=None, min_properties=None, max_items=None, maximum=None, nullable=None, max_properties=None, type=<Type.STRING: 'STRING'>, description=None, enum=None, format=None, items=None, properties=None, required=None), properties=None, required=None), 'param2': Schema(min_items=None, example=None, property_ordering=None, pattern=None, minimum=None, default=None, any_of=[Schema(min_items=None, example=None, property_ordering=None, pattern=None, minimum=None, default=None, any_of=None, max_length=None, title=None, min_length=None, min_properties=None, max_items=None, maximum=None, nullable=None, max_properties=None, type=<Type.NUMBER: 'NUMBER'>, description=None, enum=None, format=None, items=None, properties=None, required=None), Schema(min_items=None, example=None, property_ordering=None, pattern=None, minimum=None, default=None, any_of=None, max_length=None, title=None, min_length=None, min_properties=None, max_items=None, maximum=None, nullable=None, max_properties=None, type=<Type.INTEGER: 'INTEGER'>, description=None, enum=None, format=None, items=None, properties=None, required=None)], max_length=None, title=None, min_length=None, min_properties=None, max_items=None, maximum=None, nullable=None, max_properties=None, type=None, description=None, enum=None, format=None, items=None, properties=None, required=None), 'param3': Schema(min_items=None, example=None, property_ordering=None, pattern=None, minimum=None, default=None, any_of=None, max_length=None, title=None, min_length=None, min_properties=None, max_items=None, maximum=None, nullable=None, max_properties=None, type=<Type.OBJECT: 'OBJECT'>, description=None, enum=None, format=None, items=None, properties={'json': Schema(min_items=None, example=None, property_ordering=None, pattern=None, minimum=None, default=None, any_of=None, max_length=None, title=None, min_length=None, min_properties=None, max_items=None, maximum=None, nullable=None, max_properties=None, type=<Type.STRING: 'STRING'>, description=None, enum=None, format=None, items=None, properties=None, required=None)}, required=[])}, required=[]))], retrieval=None, google_search=None, google_search_retrieval=None, code_execution=None)], tool_config=None, labels=None, cached_content=None, response_modalities=None, media_resolution=None, speech_config=None, audio_timestamp=None, automatic_function_calling=AutomaticFunctionCallingConfig(disable=True, maximum_remote_calls=None, ignore_call_history=None), thinking_config=None),
|
||||
'config': GenerateContentConfig(http_options=None, system_instruction="Current time is 05:00:00. Today's date is 2024-05-24.\nYou are a voice assistant for Home Assistant.\nAnswer questions about the world truthfully.\nAnswer in plain text. Keep it simple and to the point.\nOnly if the user wants to control a device, tell them to expose entities to their voice assistant in Home Assistant.", temperature=1.0, top_p=0.95, top_k=64.0, candidate_count=None, max_output_tokens=150, stop_sequences=None, response_logprobs=None, logprobs=None, presence_penalty=None, frequency_penalty=None, seed=None, response_mime_type=None, response_schema=None, routing_config=None, safety_settings=[SafetySetting(method=None, category=<HarmCategory.HARM_CATEGORY_HATE_SPEECH: 'HARM_CATEGORY_HATE_SPEECH'>, threshold=<HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE: 'BLOCK_MEDIUM_AND_ABOVE'>), SafetySetting(method=None, category=<HarmCategory.HARM_CATEGORY_HARASSMENT: 'HARM_CATEGORY_HARASSMENT'>, threshold=<HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE: 'BLOCK_MEDIUM_AND_ABOVE'>), SafetySetting(method=None, category=<HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT: 'HARM_CATEGORY_DANGEROUS_CONTENT'>, threshold=<HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE: 'BLOCK_MEDIUM_AND_ABOVE'>), SafetySetting(method=None, category=<HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT: 'HARM_CATEGORY_SEXUALLY_EXPLICIT'>, threshold=<HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE: 'BLOCK_MEDIUM_AND_ABOVE'>)], tools=[Tool(function_declarations=[FunctionDeclaration(response=None, description='Test function', name='test_tool', parameters=Schema(min_items=None, example=None, property_ordering=None, pattern=None, minimum=None, default=None, any_of=None, max_length=None, title=None, min_length=None, min_properties=None, max_items=None, maximum=None, nullable=None, max_properties=None, type=<Type.OBJECT: 'OBJECT'>, description=None, enum=None, format=None, items=None, properties={'param1': Schema(min_items=None, example=None, property_ordering=None, pattern=None, minimum=None, default=None, any_of=None, max_length=None, title=None, min_length=None, min_properties=None, max_items=None, maximum=None, nullable=None, max_properties=None, type=<Type.ARRAY: 'ARRAY'>, description='Test parameters', enum=None, format=None, items=Schema(min_items=None, example=None, property_ordering=None, pattern=None, minimum=None, default=None, any_of=None, max_length=None, title=None, min_length=None, min_properties=None, max_items=None, maximum=None, nullable=None, max_properties=None, type=<Type.STRING: 'STRING'>, description=None, enum=None, format=None, items=None, properties=None, required=None), properties=None, required=None), 'param2': Schema(min_items=None, example=None, property_ordering=None, pattern=None, minimum=None, default=None, any_of=None, max_length=None, title=None, min_length=None, min_properties=None, max_items=None, maximum=None, nullable=None, max_properties=None, type=None, description=None, enum=None, format=None, items=None, properties=None, required=None), 'param3': Schema(min_items=None, example=None, property_ordering=None, pattern=None, minimum=None, default=None, any_of=None, max_length=None, title=None, min_length=None, min_properties=None, max_items=None, maximum=None, nullable=None, max_properties=None, type=<Type.OBJECT: 'OBJECT'>, description=None, enum=None, format=None, items=None, properties={'json': Schema(min_items=None, example=None, property_ordering=None, pattern=None, minimum=None, default=None, any_of=None, max_length=None, title=None, min_length=None, min_properties=None, max_items=None, maximum=None, nullable=None, max_properties=None, type=<Type.STRING: 'STRING'>, description=None, enum=None, format=None, items=None, properties=None, required=None)}, required=[])}, required=[]))], retrieval=None, google_search=None, google_search_retrieval=None, code_execution=None)], tool_config=None, labels=None, cached_content=None, response_modalities=None, media_resolution=None, speech_config=None, audio_timestamp=None, automatic_function_calling=AutomaticFunctionCallingConfig(disable=True, maximum_remote_calls=None, ignore_call_history=None), thinking_config=None),
|
||||
'history': list([
|
||||
]),
|
||||
'model': 'models/gemini-2.0-flash',
|
||||
|
@ -31,3 +31,18 @@
|
||||
),
|
||||
])
|
||||
# ---
|
||||
# name: test_load_entry_with_unloaded_entries
|
||||
list([
|
||||
tuple(
|
||||
'',
|
||||
tuple(
|
||||
),
|
||||
dict({
|
||||
'contents': list([
|
||||
'Write an opening speech for a Home Assistant release party',
|
||||
]),
|
||||
'model': 'models/gemini-2.0-flash',
|
||||
}),
|
||||
),
|
||||
])
|
||||
# ---
|
||||
|
@ -493,6 +493,26 @@ async def test_escape_decode() -> None:
|
||||
{"type": "string", "enum": ["a", "b", "c"]},
|
||||
{"type": "STRING", "enum": ["a", "b", "c"]},
|
||||
),
|
||||
(
|
||||
{"type": "string", "default": "default"},
|
||||
{"type": "STRING"},
|
||||
),
|
||||
(
|
||||
{"type": "string", "pattern": "default"},
|
||||
{"type": "STRING"},
|
||||
),
|
||||
(
|
||||
{"type": "string", "maxLength": 10},
|
||||
{"type": "STRING"},
|
||||
),
|
||||
(
|
||||
{"type": "string", "minLength": 10},
|
||||
{"type": "STRING"},
|
||||
),
|
||||
(
|
||||
{"type": "string", "title": "title"},
|
||||
{"type": "STRING"},
|
||||
),
|
||||
(
|
||||
{"type": "string", "format": "enum", "enum": ["a", "b", "c"]},
|
||||
{"type": "STRING", "format": "enum", "enum": ["a", "b", "c"]},
|
||||
@ -517,6 +537,10 @@ async def test_escape_decode() -> None:
|
||||
{"type": "number", "format": "hex"},
|
||||
{"type": "NUMBER"},
|
||||
),
|
||||
(
|
||||
{"type": "number", "minimum": 1},
|
||||
{"type": "NUMBER"},
|
||||
),
|
||||
(
|
||||
{"type": "integer", "format": "int32"},
|
||||
{"type": "INTEGER", "format": "int32"},
|
||||
@ -535,21 +559,7 @@ async def test_escape_decode() -> None:
|
||||
),
|
||||
(
|
||||
{"anyOf": [{"type": "integer"}, {"type": "number"}]},
|
||||
{"any_of": [{"type": "INTEGER"}, {"type": "NUMBER"}]},
|
||||
),
|
||||
(
|
||||
{
|
||||
"any_of": [
|
||||
{"any_of": [{"type": "integer"}, {"type": "number"}]},
|
||||
{"any_of": [{"type": "integer"}, {"type": "number"}]},
|
||||
]
|
||||
},
|
||||
{
|
||||
"any_of": [
|
||||
{"any_of": [{"type": "INTEGER"}, {"type": "NUMBER"}]},
|
||||
{"any_of": [{"type": "INTEGER"}, {"type": "NUMBER"}]},
|
||||
]
|
||||
},
|
||||
{},
|
||||
),
|
||||
({"type": "string", "format": "lower"}, {"type": "STRING"}),
|
||||
({"type": "boolean", "format": "bool"}, {"type": "BOOLEAN"}),
|
||||
@ -570,7 +580,15 @@ async def test_escape_decode() -> None:
|
||||
},
|
||||
),
|
||||
(
|
||||
{"type": "object", "additionalProperties": True},
|
||||
{"type": "object", "additionalProperties": True, "minProperties": 1},
|
||||
{
|
||||
"type": "OBJECT",
|
||||
"properties": {"json": {"type": "STRING"}},
|
||||
"required": [],
|
||||
},
|
||||
),
|
||||
(
|
||||
{"type": "object", "additionalProperties": True, "maxProperties": 1},
|
||||
{
|
||||
"type": "OBJECT",
|
||||
"properties": {"json": {"type": "STRING"}},
|
||||
@ -581,6 +599,20 @@ async def test_escape_decode() -> None:
|
||||
{"type": "array", "items": {"type": "string"}},
|
||||
{"type": "ARRAY", "items": {"type": "STRING"}},
|
||||
),
|
||||
(
|
||||
{
|
||||
"type": "array",
|
||||
"items": {"type": "string"},
|
||||
"minItems": 1,
|
||||
"maxItems": 2,
|
||||
},
|
||||
{
|
||||
"type": "ARRAY",
|
||||
"items": {"type": "STRING"},
|
||||
"min_items": 1,
|
||||
"max_items": 2,
|
||||
},
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_format_schema(openapi, genai_schema) -> None:
|
||||
|
@ -224,3 +224,52 @@ async def test_config_entry_error(
|
||||
await hass.async_block_till_done()
|
||||
assert mock_config_entry.state == state
|
||||
assert any(mock_config_entry.async_get_active_flows(hass, {"reauth"})) == reauth
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("mock_init_component")
|
||||
async def test_load_entry_with_unloaded_entries(
|
||||
hass: HomeAssistant, snapshot: SnapshotAssertion
|
||||
) -> None:
|
||||
"""Test loading an entry with unloaded entries."""
|
||||
config_entries = hass.config_entries.async_entries(
|
||||
"google_generative_ai_conversation"
|
||||
)
|
||||
runtime_data = config_entries[0].runtime_data
|
||||
await hass.config_entries.async_unload(config_entries[0].entry_id)
|
||||
|
||||
entry = MockConfigEntry(
|
||||
domain="google_generative_ai_conversation",
|
||||
title="Google Generative AI Conversation",
|
||||
data={
|
||||
"api_key": "bla",
|
||||
},
|
||||
state=ConfigEntryState.LOADED,
|
||||
)
|
||||
entry.runtime_data = runtime_data
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
stubbed_generated_content = (
|
||||
"I'm thrilled to welcome you all to the release "
|
||||
"party for the latest version of Home Assistant!"
|
||||
)
|
||||
|
||||
with patch(
|
||||
"google.genai.models.AsyncModels.generate_content",
|
||||
return_value=Mock(
|
||||
text=stubbed_generated_content,
|
||||
prompt_feedback=None,
|
||||
candidates=[Mock()],
|
||||
),
|
||||
) as mock_generate:
|
||||
response = await hass.services.async_call(
|
||||
"google_generative_ai_conversation",
|
||||
"generate_content",
|
||||
{"prompt": "Write an opening speech for a Home Assistant release party"},
|
||||
blocking=True,
|
||||
return_response=True,
|
||||
)
|
||||
|
||||
assert response == {
|
||||
"text": stubbed_generated_content,
|
||||
}
|
||||
assert [tuple(mock_call) for mock_call in mock_generate.mock_calls] == snapshot
|
||||
|
@ -27,7 +27,7 @@ from homeassistant.components.home_connect.const import (
|
||||
DOMAIN,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntryState
|
||||
from homeassistant.const import STATE_UNAVAILABLE, Platform
|
||||
from homeassistant.const import STATE_UNAVAILABLE, STATE_UNKNOWN, Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||
|
||||
@ -302,7 +302,7 @@ ENTITY_ID_STATES = {
|
||||
)
|
||||
),
|
||||
)
|
||||
async def test_event_sensors(
|
||||
async def test_program_sensors(
|
||||
client: MagicMock,
|
||||
appliance_ha_id: str,
|
||||
states: tuple,
|
||||
@ -313,7 +313,7 @@ async def test_event_sensors(
|
||||
integration_setup: Callable[[MagicMock], Awaitable[bool]],
|
||||
setup_credentials: None,
|
||||
) -> None:
|
||||
"""Test sequence for sensors that are only available after an event happens."""
|
||||
"""Test sequence for sensors that expose information about a program."""
|
||||
entity_ids = ENTITY_ID_STATES.keys()
|
||||
|
||||
time_to_freeze = "2021-01-09 12:00:00+00:00"
|
||||
@ -358,6 +358,82 @@ async def test_event_sensors(
|
||||
assert hass.states.is_state(entity_id, state)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("appliance_ha_id", [TEST_HC_APP], indirect=True)
|
||||
@pytest.mark.parametrize(
|
||||
("initial_operation_state", "initial_state", "event_order", "entity_states"),
|
||||
[
|
||||
(
|
||||
"BSH.Common.EnumType.OperationState.Ready",
|
||||
STATE_UNAVAILABLE,
|
||||
(EventType.STATUS, EventType.EVENT),
|
||||
(STATE_UNKNOWN, "60"),
|
||||
),
|
||||
(
|
||||
"BSH.Common.EnumType.OperationState.Run",
|
||||
STATE_UNKNOWN,
|
||||
(EventType.EVENT, EventType.STATUS),
|
||||
("60", "60"),
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_program_sensor_edge_case(
|
||||
initial_operation_state: str,
|
||||
initial_state: str,
|
||||
event_order: tuple[EventType, EventType],
|
||||
entity_states: tuple[str, str],
|
||||
appliance_ha_id: str,
|
||||
hass: HomeAssistant,
|
||||
config_entry: MockConfigEntry,
|
||||
integration_setup: Callable[[MagicMock], Awaitable[bool]],
|
||||
setup_credentials: None,
|
||||
client: MagicMock,
|
||||
) -> None:
|
||||
"""Test edge case for the program related entities."""
|
||||
entity_id = "sensor.dishwasher_program_progress"
|
||||
client.get_status = AsyncMock(
|
||||
return_value=ArrayOfStatus(
|
||||
[
|
||||
Status(
|
||||
StatusKey.BSH_COMMON_OPERATION_STATE,
|
||||
StatusKey.BSH_COMMON_OPERATION_STATE.value,
|
||||
initial_operation_state,
|
||||
)
|
||||
]
|
||||
)
|
||||
)
|
||||
|
||||
assert config_entry.state == ConfigEntryState.NOT_LOADED
|
||||
assert await integration_setup(client)
|
||||
assert config_entry.state == ConfigEntryState.LOADED
|
||||
|
||||
assert hass.states.is_state(entity_id, initial_state)
|
||||
|
||||
for event_type, state in zip(event_order, entity_states, strict=True):
|
||||
await client.add_events(
|
||||
[
|
||||
EventMessage(
|
||||
appliance_ha_id,
|
||||
event_type,
|
||||
ArrayOfEvents(
|
||||
[
|
||||
Event(
|
||||
key=event_key,
|
||||
raw_key=event_key.value,
|
||||
timestamp=0,
|
||||
level="",
|
||||
handling="",
|
||||
value=value,
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
for event_key, value in EVENT_PROG_RUN[event_type].items()
|
||||
]
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert hass.states.is_state(entity_id, state)
|
||||
|
||||
|
||||
# Program sequence for SensorDeviceClass.TIMESTAMP edge cases.
|
||||
PROGRAM_SEQUENCE_EDGE_CASE = [
|
||||
EVENT_PROG_DELAYED_START,
|
||||
|
@ -870,6 +870,32 @@ async def test_invalid_device_class(
|
||||
assert "expected SensorDeviceClass or one of" in caplog.text
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"hass_config",
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "test-topic",
|
||||
"device_class": "energy",
|
||||
"unit_of_measurement": "ppm",
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
)
|
||||
async def test_invalid_unit_of_measurement(
|
||||
mqtt_mock_entry: MqttMockHAClientGenerator, caplog: pytest.LogCaptureFixture
|
||||
) -> None:
|
||||
"""Test device_class with invalid unit of measurement."""
|
||||
assert await mqtt_mock_entry()
|
||||
assert (
|
||||
"The unit of measurement `ppm` is not valid together with device class `energy`"
|
||||
in caplog.text
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"hass_config",
|
||||
[
|
||||
|
@ -68,6 +68,8 @@ async def trigger_update(
|
||||
value,
|
||||
data,
|
||||
)
|
||||
for call in mock.add_unspecified_device_event_listener.call_args_list:
|
||||
call[0][0](event)
|
||||
for call in mock.add_device_event_listener.call_args_list:
|
||||
if call[0][0] == device_id:
|
||||
call[0][3](event)
|
||||
|
@ -84,6 +84,7 @@ def mock_smartthings() -> Generator[AsyncMock]:
|
||||
@pytest.fixture(
|
||||
params=[
|
||||
"da_ac_rac_000001",
|
||||
"da_ac_rac_100001",
|
||||
"da_ac_rac_01001",
|
||||
"multipurpose_sensor",
|
||||
"contact_sensor",
|
||||
@ -100,6 +101,7 @@ def mock_smartthings() -> Generator[AsyncMock]:
|
||||
"da_wm_dw_000001",
|
||||
"da_wm_wd_000001",
|
||||
"da_wm_wm_000001",
|
||||
"da_wm_wm_000001_1",
|
||||
"da_rvc_normal_000001",
|
||||
"da_ks_microwave_0101x",
|
||||
"hue_color_temperature_bulb",
|
||||
@ -114,6 +116,8 @@ def mock_smartthings() -> Generator[AsyncMock]:
|
||||
"ecobee_sensor",
|
||||
"ecobee_thermostat",
|
||||
"fake_fan",
|
||||
"generic_fan_3_speed",
|
||||
"heatit_ztrm3_thermostat",
|
||||
]
|
||||
)
|
||||
def device_fixture(
|
||||
|
@ -0,0 +1,21 @@
|
||||
{
|
||||
"components": {
|
||||
"main": {
|
||||
"button": {
|
||||
"button": {
|
||||
"value": "pushed",
|
||||
"timestamp": "2025-03-07T12:20:43.363Z"
|
||||
},
|
||||
"numberOfButtons": {
|
||||
"value": 1,
|
||||
"timestamp": "2025-03-07T12:20:43.363Z"
|
||||
},
|
||||
"supportedButtonValues": {
|
||||
"value": ["pushed", "held", "pushed_2x"],
|
||||
"timestamp": "2025-03-07T12:20:43.363Z"
|
||||
}
|
||||
},
|
||||
"refresh": {}
|
||||
}
|
||||
}
|
||||
}
|
@ -58,6 +58,15 @@
|
||||
"timestamp": "2025-02-08T21:56:09.761Z"
|
||||
}
|
||||
},
|
||||
"powerConsumptionReport": {
|
||||
"powerConsumption": {
|
||||
"value": {
|
||||
"start": "2025-02-09T15:45:29Z",
|
||||
"end": "2025-02-09T16:15:33Z"
|
||||
},
|
||||
"timestamp": "2025-02-09T16:15:33.639Z"
|
||||
}
|
||||
},
|
||||
"battery": {
|
||||
"quantity": {
|
||||
"value": null
|
||||
|
@ -32,7 +32,7 @@
|
||||
"timestamp": "2025-02-09T14:35:56.800Z"
|
||||
},
|
||||
"supportedAcModes": {
|
||||
"value": ["auto", "cool", "dry", "wind", "heat"],
|
||||
"value": ["auto", "cool", "dry", "wind", "heat", "dryClean"],
|
||||
"timestamp": "2025-02-09T15:42:13.444Z"
|
||||
},
|
||||
"airConditionerMode": {
|
||||
|
@ -0,0 +1,171 @@
|
||||
{
|
||||
"components": {
|
||||
"main": {
|
||||
"refresh": {},
|
||||
"custom.thermostatSetpointControl": {
|
||||
"minimumSetpoint": {
|
||||
"value": 16,
|
||||
"timestamp": "2024-11-25T22:17:38.251Z"
|
||||
},
|
||||
"maximumSetpoint": {
|
||||
"value": 30,
|
||||
"timestamp": "2024-11-25T22:17:38.251Z"
|
||||
}
|
||||
},
|
||||
"airConditionerMode": {
|
||||
"availableAcModes": {
|
||||
"value": null
|
||||
},
|
||||
"supportedAcModes": {
|
||||
"value": ["cool", "dry", "wind", "auto"],
|
||||
"timestamp": "2025-03-02T10:16:19.519Z"
|
||||
},
|
||||
"airConditionerMode": {
|
||||
"value": "cool",
|
||||
"timestamp": "2025-03-02T10:16:19.519Z"
|
||||
}
|
||||
},
|
||||
"execute": {
|
||||
"data": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"airQualitySensor": {
|
||||
"airQuality": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"switch": {
|
||||
"switch": {
|
||||
"value": "off",
|
||||
"timestamp": "2025-03-02T06:54:52.852Z"
|
||||
}
|
||||
},
|
||||
"ocf": {
|
||||
"st": {
|
||||
"value": null
|
||||
},
|
||||
"mndt": {
|
||||
"value": null
|
||||
},
|
||||
"mnfv": {
|
||||
"value": null
|
||||
},
|
||||
"mnhw": {
|
||||
"value": null
|
||||
},
|
||||
"di": {
|
||||
"value": "F8042E25-0E53-0000-0000-000000000000",
|
||||
"timestamp": "2025-02-28T21:15:28.920Z"
|
||||
},
|
||||
"mnsl": {
|
||||
"value": null
|
||||
},
|
||||
"dmv": {
|
||||
"value": "res.1.1.0,sh.1.1.0",
|
||||
"timestamp": "2025-02-28T21:15:28.920Z"
|
||||
},
|
||||
"n": {
|
||||
"value": "Room A/C",
|
||||
"timestamp": "2025-02-28T21:15:28.920Z"
|
||||
},
|
||||
"mnmo": {
|
||||
"value": "TP6X_RAC_15K",
|
||||
"timestamp": "2025-02-28T21:15:28.920Z"
|
||||
},
|
||||
"vid": {
|
||||
"value": "DA-AC-RAC-100001",
|
||||
"timestamp": "2025-02-28T21:15:28.920Z"
|
||||
},
|
||||
"mnmn": {
|
||||
"value": "Samsung Electronics",
|
||||
"timestamp": "2025-02-28T21:15:28.920Z"
|
||||
},
|
||||
"mnml": {
|
||||
"value": null
|
||||
},
|
||||
"mnpv": {
|
||||
"value": null
|
||||
},
|
||||
"mnos": {
|
||||
"value": null
|
||||
},
|
||||
"pi": {
|
||||
"value": "shp",
|
||||
"timestamp": "2025-02-28T21:15:28.920Z"
|
||||
},
|
||||
"icv": {
|
||||
"value": "core.1.1.0",
|
||||
"timestamp": "2025-02-28T21:15:28.920Z"
|
||||
}
|
||||
},
|
||||
"odorSensor": {
|
||||
"odorLevel": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"airConditionerFanMode": {
|
||||
"fanMode": {
|
||||
"value": "auto",
|
||||
"timestamp": "2025-02-28T21:15:28.941Z"
|
||||
},
|
||||
"supportedAcFanModes": {
|
||||
"value": ["auto", "low", "medium", "high", "turbo"],
|
||||
"timestamp": "2025-02-28T21:15:28.941Z"
|
||||
},
|
||||
"availableAcFanModes": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"samsungce.driverState": {
|
||||
"driverState": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"custom.disabledCapabilities": {
|
||||
"disabledCapabilities": {
|
||||
"value": ["odorSensor"],
|
||||
"timestamp": "2024-11-25T22:17:38.251Z"
|
||||
}
|
||||
},
|
||||
"samsungce.driverVersion": {
|
||||
"versionNumber": {
|
||||
"value": 22090101,
|
||||
"timestamp": "2024-11-25T22:17:38.251Z"
|
||||
}
|
||||
},
|
||||
"temperatureMeasurement": {
|
||||
"temperatureRange": {
|
||||
"value": null
|
||||
},
|
||||
"temperature": {
|
||||
"value": 27,
|
||||
"unit": "C",
|
||||
"timestamp": "2025-03-02T08:28:39.409Z"
|
||||
}
|
||||
},
|
||||
"dustSensor": {
|
||||
"dustLevel": {
|
||||
"value": 46,
|
||||
"unit": "\u03bcg/m^3",
|
||||
"timestamp": "2025-03-06T16:01:49.656000+00:00"
|
||||
},
|
||||
"fineDustLevel": {
|
||||
"value": 10,
|
||||
"unit": "\u03bcg/m^3",
|
||||
"timestamp": "2025-03-06T16:01:49.656000+00:00"
|
||||
}
|
||||
},
|
||||
"thermostatCoolingSetpoint": {
|
||||
"coolingSetpointRange": {
|
||||
"value": null
|
||||
},
|
||||
"coolingSetpoint": {
|
||||
"value": 18,
|
||||
"unit": "C",
|
||||
"timestamp": "2025-03-02T06:54:23.887Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,19 @@
|
||||
{
|
||||
"components": {
|
||||
"main": {
|
||||
"refresh": {},
|
||||
"fanSpeed": {
|
||||
"fanSpeed": {
|
||||
"value": 0,
|
||||
"timestamp": "2025-03-06T11:47:32.683Z"
|
||||
}
|
||||
},
|
||||
"switch": {
|
||||
"switch": {
|
||||
"value": "off",
|
||||
"timestamp": "2025-03-06T11:47:32.697Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
{
|
||||
"components": {
|
||||
"main": {
|
||||
"powerMeter": {
|
||||
"power": {
|
||||
"value": 368.17,
|
||||
"unit": "W",
|
||||
"timestamp": "2025-03-07T12:52:08.997Z"
|
||||
}
|
||||
},
|
||||
"thermostatOperatingState": {
|
||||
"thermostatOperatingState": {
|
||||
"value": "heating",
|
||||
"timestamp": "2025-03-07T12:49:53.638Z"
|
||||
}
|
||||
},
|
||||
"energyMeter": {
|
||||
"energy": {
|
||||
"value": 2339.5,
|
||||
"unit": "kWh",
|
||||
"timestamp": "2025-03-07T12:26:37.133Z"
|
||||
}
|
||||
},
|
||||
"temperatureMeasurement": {
|
||||
"temperatureRange": {
|
||||
"value": null
|
||||
},
|
||||
"temperature": {
|
||||
"value": 19.0,
|
||||
"unit": "C",
|
||||
"timestamp": "2025-03-07T12:52:39.210Z"
|
||||
}
|
||||
},
|
||||
"thermostatHeatingSetpoint": {
|
||||
"heatingSetpoint": {
|
||||
"value": 19.0,
|
||||
"unit": "C",
|
||||
"timestamp": "2025-03-06T21:38:22.856Z"
|
||||
},
|
||||
"heatingSetpointRange": {
|
||||
"value": null
|
||||
}
|
||||
},
|
||||
"refresh": {},
|
||||
"thermostatMode": {
|
||||
"thermostatMode": {
|
||||
"value": "heat",
|
||||
"data": {
|
||||
"supportedThermostatModes": ["off", "heat"]
|
||||
},
|
||||
"timestamp": "2025-03-06T21:38:23.046Z"
|
||||
},
|
||||
"supportedThermostatModes": {
|
||||
"value": ["off", "heat"],
|
||||
"timestamp": "2023-09-22T15:41:01.268Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
49
tests/components/smartthings/fixtures/devices/button.json
Normal file
49
tests/components/smartthings/fixtures/devices/button.json
Normal file
@ -0,0 +1,49 @@
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"deviceId": "c4bdd19f-85d1-4d58-8f9c-e75ac3cf113b",
|
||||
"name": "button",
|
||||
"label": "button",
|
||||
"manufacturerName": "SmartThingsCommunity",
|
||||
"presentationId": "238c483a-10e8-359b-b032-1be2b2fcdee7",
|
||||
"locationId": "88a3a314-f0c8-40b4-bb44-44ba06c9c42f",
|
||||
"ownerId": "12d4af93-cb68-b108-87f5-625437d7371f",
|
||||
"components": [
|
||||
{
|
||||
"id": "main",
|
||||
"label": "main",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "button",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "refresh",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "Other",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"createTime": "2025-03-07T12:20:43.273Z",
|
||||
"profile": {
|
||||
"id": "b045d731-4d01-35bc-8018-b3da711d8904"
|
||||
},
|
||||
"virtual": {
|
||||
"name": "button",
|
||||
"executingLocally": false
|
||||
},
|
||||
"type": "VIRTUAL",
|
||||
"restrictionTier": 0,
|
||||
"allowed": null,
|
||||
"executionContext": "CLOUD",
|
||||
"relationships": []
|
||||
}
|
||||
],
|
||||
"_links": {}
|
||||
}
|
@ -286,18 +286,10 @@
|
||||
"id": "60fbc713-8da5-315d-b31a-6d6dcde4be7b"
|
||||
},
|
||||
"ocf": {
|
||||
"ocfDeviceType": "oic.d.airconditioner",
|
||||
"name": "[room a/c] Samsung",
|
||||
"specVersion": "core.1.1.0",
|
||||
"verticalDomainSpecVersion": "res.1.1.0,sh.1.1.0",
|
||||
"ocfDeviceType": "x.com.st.d.sensor.light",
|
||||
"manufacturerName": "Samsung Electronics",
|
||||
"modelNumber": "ARTIK051_KRAC_18K|10193441|60010132001111110200000000000000",
|
||||
"platformVersion": "0G3MPDCKA00010E",
|
||||
"platformOS": "TizenRT2.0",
|
||||
"hwVersion": "1.0",
|
||||
"firmwareVersion": "0.1.0",
|
||||
"vendorId": "DA-AC-RAC-000001",
|
||||
"lastSignupTime": "2021-04-06T16:43:27.889445Z",
|
||||
"vendorId": "VD-Sensor.Light-2023",
|
||||
"lastSignupTime": "2025-01-08T02:32:04.631093137Z",
|
||||
"transferCandidate": false,
|
||||
"additionalAuthCodeRequired": false
|
||||
},
|
||||
|
@ -0,0 +1,112 @@
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"deviceId": "F8042E25-0E53-0000-0000-000000000000",
|
||||
"name": "Room A/C",
|
||||
"label": "Corridor A/C",
|
||||
"manufacturerName": "Samsung Electronics",
|
||||
"presentationId": "DA-AC-RAC-100001",
|
||||
"deviceManufacturerCode": "Samsung Electronics",
|
||||
"locationId": "5df0730b-38ed-43e4-b291-ec14feb3224c",
|
||||
"ownerId": "63b9c79b-90fe-5262-9a6a-5e24db90915e",
|
||||
"roomId": "7715151d-0314-457a-a82c-5ce48900e065",
|
||||
"deviceTypeName": "Samsung OCF Air Conditioner",
|
||||
"components": [
|
||||
{
|
||||
"id": "main",
|
||||
"label": "main",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "ocf",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "switch",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "airConditionerMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "airConditionerFanMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "temperatureMeasurement",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "thermostatCoolingSetpoint",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "airQualitySensor",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "dustSensor",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "odorSensor",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "refresh",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "execute",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.driverVersion",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.driverState",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.thermostatSetpointControl",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.disabledCapabilities",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "AirConditioner",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"createTime": "2024-11-25T22:17:38.129Z",
|
||||
"profile": {
|
||||
"id": "9e3e03b1-7f8c-3ea2-8568-6902b79b99dd"
|
||||
},
|
||||
"ocf": {
|
||||
"ocfDeviceType": "oic.d.airconditioner",
|
||||
"name": "Room A/C",
|
||||
"specVersion": "core.1.1.0",
|
||||
"verticalDomainSpecVersion": "res.1.1.0,sh.1.1.0",
|
||||
"manufacturerName": "Samsung Electronics",
|
||||
"modelNumber": "TP6X_RAC_15K",
|
||||
"vendorId": "DA-AC-RAC-100001",
|
||||
"lastSignupTime": "2024-11-25T22:17:37.928118320Z",
|
||||
"transferCandidate": false,
|
||||
"additionalAuthCodeRequired": false
|
||||
},
|
||||
"type": "OCF",
|
||||
"restrictionTier": 0,
|
||||
"allowed": [],
|
||||
"executionContext": "CLOUD",
|
||||
"relationships": []
|
||||
}
|
||||
],
|
||||
"_links": {}
|
||||
}
|
@ -0,0 +1,261 @@
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"deviceId": "63803fae-cbed-f356-a063-2cf148ae3ca7",
|
||||
"name": "[washer] Samsung",
|
||||
"label": "Washing Machine",
|
||||
"manufacturerName": "Samsung Electronics",
|
||||
"presentationId": "DA-WM-WM-000001",
|
||||
"deviceManufacturerCode": "Samsung Electronics",
|
||||
"locationId": "ca23214d-d9ae-41e5-9d26-f1a604c864d8",
|
||||
"ownerId": "9b53a4ba-4422-b04d-f436-33c0490e7c37",
|
||||
"roomId": "e226f1ae-1112-4794-bd3a-0beddf811645",
|
||||
"deviceTypeName": "Samsung OCF Washer",
|
||||
"components": [
|
||||
{
|
||||
"id": "main",
|
||||
"label": "Washing Machine",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "execute",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "ocf",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "powerConsumptionReport",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "refresh",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "remoteControlStatus",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "demandResponseLoadControl",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "switch",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "washerOperatingState",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.disabledCapabilities",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.dryerDryLevel",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.energyType",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.jobBeginningStatus",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.supportedOptions",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.washerAutoDetergent",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.washerAutoSoftener",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.washerRinseCycles",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.washerSoilLevel",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.washerSpinLevel",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "custom.washerWaterTemperature",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.autoDispenseDetergent",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.autoDispenseSoftener",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.detergentOrder",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.detergentState",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.deviceIdentification",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.dongleSoftwareInstallation",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.detergentAutoReplenishment",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.softenerAutoReplenishment",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.driverVersion",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.softwareUpdate",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.kidsLock",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.softenerOrder",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.softenerState",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.washerBubbleSoak",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.washerCycle",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.washerCyclePreset",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.washerDelayEnd",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.washerFreezePrevent",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.washerOperatingState",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.washerWashingTime",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.washerWaterLevel",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.washerWaterValve",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.welcomeMessage",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.waterConsumptionReport",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.quickControl",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "samsungce.energyPlanner",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "sec.diagnosticsInformation",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "sec.wifiConfiguration",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "Washer",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "hca.main",
|
||||
"label": "hca.main",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "hca.washerMode",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "Other",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"createTime": "2020-03-04T03:03:19Z",
|
||||
"profile": {
|
||||
"id": "3f221c79-d81c-315f-8e8b-b5742802a1e3"
|
||||
},
|
||||
"ocf": {
|
||||
"ocfDeviceType": "oic.d.washer",
|
||||
"name": "[washer] Samsung",
|
||||
"specVersion": "core.1.1.0",
|
||||
"verticalDomainSpecVersion": "1.2.1",
|
||||
"manufacturerName": "Samsung Electronics",
|
||||
"modelNumber": "DA_WM_A51_20_COMMON|20224941|20010102011211030203000000000000",
|
||||
"platformVersion": "DAWIT 2.0",
|
||||
"platformOS": "TizenRT 1.0 + IPv6",
|
||||
"hwVersion": "ARTIK051",
|
||||
"firmwareVersion": "DA_WM_A51_20_COMMON_30230708",
|
||||
"vendorId": "DA-WM-WM-000001",
|
||||
"vendorResourceClientServerVersion": "ARTIK051 Release 2.210224.1",
|
||||
"lastSignupTime": "2024-12-27T04:47:59.763899737Z",
|
||||
"transferCandidate": false,
|
||||
"additionalAuthCodeRequired": false
|
||||
},
|
||||
"type": "OCF",
|
||||
"restrictionTier": 0,
|
||||
"allowed": null,
|
||||
"executionContext": "CLOUD",
|
||||
"relationships": []
|
||||
}
|
||||
],
|
||||
"_links": {}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"deviceId": "6d95a8b7-4ee3-429a-a13a-00ec9354170c",
|
||||
"name": "GE In-Wall Smart Dimmer",
|
||||
"label": "Bedroom Fan",
|
||||
"manufacturerName": "SmartThingsEdge",
|
||||
"presentationId": "generic-fan-3-speed",
|
||||
"deviceManufacturerCode": "0063-4944-3131",
|
||||
"locationId": "f1313f27-6732-481d-a2a9-c7bbf900f867",
|
||||
"ownerId": "e5216062-ac82-79b8-20db-ea65fa3d3fdd",
|
||||
"roomId": "5f77f7cf-ece8-485e-a409-98f7b128a41a",
|
||||
"components": [
|
||||
{
|
||||
"id": "main",
|
||||
"label": "Bedroom Fan",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "fanSpeed",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "switch",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "refresh",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "Fan",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"createTime": "2018-01-12T22:12:15Z",
|
||||
"parentDeviceId": "4ceb9b86-2f0d-4e98-ba4e-3fbe705f7805",
|
||||
"profile": {
|
||||
"id": "9bd81754-fc81-3ed1-86c2-d1094d6cbf6d"
|
||||
},
|
||||
"zwave": {
|
||||
"networkId": "02",
|
||||
"driverId": "e7947a05-947d-4bb5-92c4-2aafaff6d69c",
|
||||
"executingLocally": true,
|
||||
"hubId": "4ceb9b86-2f0d-4e98-ba4e-3fbe705f7805",
|
||||
"networkSecurityLevel": "ZWAVE_LEGACY_NON_SECURE",
|
||||
"provisioningState": "PROVISIONED",
|
||||
"manufacturerId": 99,
|
||||
"productType": 18756,
|
||||
"productId": 12593
|
||||
},
|
||||
"type": "ZWAVE",
|
||||
"restrictionTier": 0,
|
||||
"allowed": null,
|
||||
"executionContext": "LOCAL",
|
||||
"relationships": []
|
||||
}
|
||||
],
|
||||
"_links": {}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"deviceId": "69a271f6-6537-4982-8cd9-979866872692",
|
||||
"name": "heatit-ztrm3-thermostat",
|
||||
"label": "Hall thermostat",
|
||||
"manufacturerName": "SmartThingsCommunity",
|
||||
"presentationId": "8c5c0adc-73d6-33db-a1bd-67d746ab0e00",
|
||||
"deviceManufacturerCode": "019B-0003-0203",
|
||||
"locationId": "6cf6637b-9bc5-4e52-bc99-7497e322fb0d",
|
||||
"ownerId": "7b68139b-d068-45d8-bf27-961320350024",
|
||||
"roomId": "746b4d54-8026-44f1-b50f-8833dafdeea3",
|
||||
"components": [
|
||||
{
|
||||
"id": "main",
|
||||
"label": "main",
|
||||
"capabilities": [
|
||||
{
|
||||
"id": "temperatureMeasurement",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "thermostatHeatingSetpoint",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "thermostatOperatingState",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "thermostatMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "powerMeter",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "energyMeter",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"id": "refresh",
|
||||
"version": 1
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"name": "Thermostat",
|
||||
"categoryType": "manufacturer"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"createTime": "2023-09-22T15:40:58.942Z",
|
||||
"parentDeviceId": "d04f5ba0-1430-4826-9aa4-fba4efb57c24",
|
||||
"profile": {
|
||||
"id": "2677e0e8-9241-3163-815e-6b1d6743f280"
|
||||
},
|
||||
"zwave": {
|
||||
"networkId": "28",
|
||||
"driverId": "28198799-de20-4cfd-a9f3-67860a0877d5",
|
||||
"executingLocally": true,
|
||||
"hubId": "d04f5ba0-1430-4826-9aa4-fba4efb57c24",
|
||||
"networkSecurityLevel": "ZWAVE_S2_AUTHENTICATED",
|
||||
"provisioningState": "PROVISIONED",
|
||||
"manufacturerId": 411,
|
||||
"productType": 3,
|
||||
"productId": 515
|
||||
},
|
||||
"type": "ZWAVE",
|
||||
"restrictionTier": 0,
|
||||
"allowed": null,
|
||||
"executionContext": "LOCAL",
|
||||
"relationships": []
|
||||
}
|
||||
],
|
||||
"_links": {}
|
||||
}
|
@ -209,6 +209,90 @@
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_ac_rac_100001][climate.corridor_a_c-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'fan_modes': list([
|
||||
'auto',
|
||||
'low',
|
||||
'medium',
|
||||
'high',
|
||||
'turbo',
|
||||
]),
|
||||
'hvac_modes': list([
|
||||
<HVACMode.OFF: 'off'>,
|
||||
<HVACMode.COOL: 'cool'>,
|
||||
<HVACMode.DRY: 'dry'>,
|
||||
<HVACMode.FAN_ONLY: 'fan_only'>,
|
||||
<HVACMode.HEAT_COOL: 'heat_cool'>,
|
||||
]),
|
||||
'max_temp': 35,
|
||||
'min_temp': 7,
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'climate',
|
||||
'entity_category': None,
|
||||
'entity_id': 'climate.corridor_a_c',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': None,
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': <ClimateEntityFeature: 393>,
|
||||
'translation_key': None,
|
||||
'unique_id': 'F8042E25-0E53-0000-0000-000000000000',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_ac_rac_100001][climate.corridor_a_c-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'current_temperature': 27,
|
||||
'fan_mode': 'auto',
|
||||
'fan_modes': list([
|
||||
'auto',
|
||||
'low',
|
||||
'medium',
|
||||
'high',
|
||||
'turbo',
|
||||
]),
|
||||
'friendly_name': 'Corridor A/C',
|
||||
'hvac_modes': list([
|
||||
<HVACMode.OFF: 'off'>,
|
||||
<HVACMode.COOL: 'cool'>,
|
||||
<HVACMode.DRY: 'dry'>,
|
||||
<HVACMode.FAN_ONLY: 'fan_only'>,
|
||||
<HVACMode.HEAT_COOL: 'heat_cool'>,
|
||||
]),
|
||||
'max_temp': 35,
|
||||
'min_temp': 7,
|
||||
'supported_features': <ClimateEntityFeature: 393>,
|
||||
'temperature': 18,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'climate.corridor_a_c',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[ecobee_thermostat][climate.main_floor-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
@ -285,6 +369,70 @@
|
||||
'state': 'heat',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[heatit_ztrm3_thermostat][climate.hall_thermostat-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'hvac_modes': list([
|
||||
<HVACMode.HEAT: 'heat'>,
|
||||
]),
|
||||
'max_temp': 35,
|
||||
'min_temp': 7,
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'climate',
|
||||
'entity_category': None,
|
||||
'entity_id': 'climate.hall_thermostat',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': None,
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': <ClimateEntityFeature: 387>,
|
||||
'translation_key': None,
|
||||
'unique_id': '69a271f6-6537-4982-8cd9-979866872692',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[heatit_ztrm3_thermostat][climate.hall_thermostat-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'current_temperature': 19.0,
|
||||
'friendly_name': 'Hall thermostat',
|
||||
'hvac_action': <HVACAction.HEATING: 'heating'>,
|
||||
'hvac_modes': list([
|
||||
<HVACMode.HEAT: 'heat'>,
|
||||
]),
|
||||
'max_temp': 35,
|
||||
'min_temp': 7,
|
||||
'supported_features': <ClimateEntityFeature: 387>,
|
||||
'target_temp_high': None,
|
||||
'target_temp_low': None,
|
||||
'temperature': 19.0,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'climate.hall_thermostat',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'heat',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[virtual_thermostat][climate.asd-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -62,6 +62,60 @@
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'on',
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[generic_fan_3_speed][fan.bedroom_fan-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'preset_modes': None,
|
||||
}),
|
||||
'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.bedroom_fan',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': None,
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': <FanEntityFeature: 49>,
|
||||
'translation_key': None,
|
||||
'unique_id': '6d95a8b7-4ee3-429a-a13a-00ec9354170c',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[generic_fan_3_speed][fan.bedroom_fan-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Bedroom Fan',
|
||||
'percentage': 0,
|
||||
'percentage_step': 33.333333333333336,
|
||||
'preset_mode': None,
|
||||
'preset_modes': None,
|
||||
'supported_features': <FanEntityFeature: 49>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'fan.bedroom_fan',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
|
@ -1,4 +1,7 @@
|
||||
# serializer version: 1
|
||||
# name: test_button_event[button]
|
||||
<Event smartthings.button[L]: component_id=main, device_id=c4bdd19f-85d1-4d58-8f9c-e75ac3cf113b, location_id=abc, value=pushed, name=button, data=None>
|
||||
# ---
|
||||
# name: test_devices[aeotec_home_energy_meter_gen5]
|
||||
DeviceRegistryEntrySnapshot({
|
||||
'area_id': None,
|
||||
@ -207,7 +210,7 @@
|
||||
}),
|
||||
'disabled_by': None,
|
||||
'entry_type': None,
|
||||
'hw_version': '1.0',
|
||||
'hw_version': None,
|
||||
'id': <ANY>,
|
||||
'identifiers': set({
|
||||
tuple(
|
||||
@ -219,14 +222,14 @@
|
||||
'labels': set({
|
||||
}),
|
||||
'manufacturer': 'Samsung Electronics',
|
||||
'model': 'ARTIK051_KRAC_18K',
|
||||
'model': None,
|
||||
'model_id': None,
|
||||
'name': 'AC Office Granit',
|
||||
'name_by_user': None,
|
||||
'primary_config_entry': <ANY>,
|
||||
'serial_number': None,
|
||||
'suggested_area': None,
|
||||
'sw_version': '0.1.0',
|
||||
'sw_version': None,
|
||||
'via_device_id': None,
|
||||
})
|
||||
# ---
|
||||
@ -263,6 +266,39 @@
|
||||
'via_device_id': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_devices[da_ac_rac_100001]
|
||||
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': None,
|
||||
'id': <ANY>,
|
||||
'identifiers': set({
|
||||
tuple(
|
||||
'smartthings',
|
||||
'F8042E25-0E53-0000-0000-000000000000',
|
||||
),
|
||||
}),
|
||||
'is_new': False,
|
||||
'labels': set({
|
||||
}),
|
||||
'manufacturer': 'Samsung Electronics',
|
||||
'model': 'TP6X_RAC_15K',
|
||||
'model_id': None,
|
||||
'name': 'Corridor A/C',
|
||||
'name_by_user': None,
|
||||
'primary_config_entry': <ANY>,
|
||||
'serial_number': None,
|
||||
'suggested_area': None,
|
||||
'sw_version': None,
|
||||
'via_device_id': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_devices[da_ks_microwave_0101x]
|
||||
DeviceRegistryEntrySnapshot({
|
||||
'area_id': None,
|
||||
@ -461,6 +497,39 @@
|
||||
'via_device_id': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_devices[da_wm_wm_000001_1]
|
||||
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': 'ARTIK051',
|
||||
'id': <ANY>,
|
||||
'identifiers': set({
|
||||
tuple(
|
||||
'smartthings',
|
||||
'63803fae-cbed-f356-a063-2cf148ae3ca7',
|
||||
),
|
||||
}),
|
||||
'is_new': False,
|
||||
'labels': set({
|
||||
}),
|
||||
'manufacturer': 'Samsung Electronics',
|
||||
'model': 'DA_WM_A51_20_COMMON',
|
||||
'model_id': None,
|
||||
'name': 'Washing Machine',
|
||||
'name_by_user': None,
|
||||
'primary_config_entry': <ANY>,
|
||||
'serial_number': None,
|
||||
'suggested_area': None,
|
||||
'sw_version': 'DA_WM_A51_20_COMMON_30230708',
|
||||
'via_device_id': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_devices[ecobee_sensor]
|
||||
DeviceRegistryEntrySnapshot({
|
||||
'area_id': None,
|
||||
@ -593,6 +662,72 @@
|
||||
'via_device_id': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_devices[generic_fan_3_speed]
|
||||
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': None,
|
||||
'id': <ANY>,
|
||||
'identifiers': set({
|
||||
tuple(
|
||||
'smartthings',
|
||||
'6d95a8b7-4ee3-429a-a13a-00ec9354170c',
|
||||
),
|
||||
}),
|
||||
'is_new': False,
|
||||
'labels': set({
|
||||
}),
|
||||
'manufacturer': None,
|
||||
'model': None,
|
||||
'model_id': None,
|
||||
'name': 'Bedroom Fan',
|
||||
'name_by_user': None,
|
||||
'primary_config_entry': <ANY>,
|
||||
'serial_number': None,
|
||||
'suggested_area': None,
|
||||
'sw_version': None,
|
||||
'via_device_id': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_devices[heatit_ztrm3_thermostat]
|
||||
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': None,
|
||||
'id': <ANY>,
|
||||
'identifiers': set({
|
||||
tuple(
|
||||
'smartthings',
|
||||
'69a271f6-6537-4982-8cd9-979866872692',
|
||||
),
|
||||
}),
|
||||
'is_new': False,
|
||||
'labels': set({
|
||||
}),
|
||||
'manufacturer': None,
|
||||
'model': None,
|
||||
'model_id': None,
|
||||
'name': 'Hall thermostat',
|
||||
'name_by_user': None,
|
||||
'primary_config_entry': <ANY>,
|
||||
'serial_number': None,
|
||||
'suggested_area': None,
|
||||
'sw_version': None,
|
||||
'via_device_id': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_devices[hue_color_temperature_bulb]
|
||||
DeviceRegistryEntrySnapshot({
|
||||
'area_id': None,
|
||||
|
@ -1379,6 +1379,213 @@
|
||||
'state': '0',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_ac_rac_100001][sensor.corridor_a_c_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.corridor_a_c_air_quality',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Air quality',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'air_quality',
|
||||
'unique_id': 'F8042E25-0E53-0000-0000-000000000000.airQuality',
|
||||
'unit_of_measurement': 'CAQI',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_ac_rac_100001][sensor.corridor_a_c_air_quality-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Corridor A/C Air quality',
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
'unit_of_measurement': 'CAQI',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.corridor_a_c_air_quality',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_ac_rac_100001][sensor.corridor_a_c_pm10-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.corridor_a_c_pm10',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.PM10: 'pm10'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'PM10',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'F8042E25-0E53-0000-0000-000000000000.dustLevel',
|
||||
'unit_of_measurement': 'µg/m³',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_ac_rac_100001][sensor.corridor_a_c_pm10-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'pm10',
|
||||
'friendly_name': 'Corridor A/C PM10',
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
'unit_of_measurement': 'µg/m³',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.corridor_a_c_pm10',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '46',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_ac_rac_100001][sensor.corridor_a_c_pm2_5-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.corridor_a_c_pm2_5',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.PM25: 'pm25'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'PM2.5',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'F8042E25-0E53-0000-0000-000000000000.fineDustLevel',
|
||||
'unit_of_measurement': 'µg/m³',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_ac_rac_100001][sensor.corridor_a_c_pm2_5-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'pm25',
|
||||
'friendly_name': 'Corridor A/C PM2.5',
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
'unit_of_measurement': 'µg/m³',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.corridor_a_c_pm2_5',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '10',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_ac_rac_100001][sensor.corridor_a_c_temperature-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.corridor_a_c_temperature',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.TEMPERATURE: 'temperature'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Temperature',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': 'F8042E25-0E53-0000-0000-000000000000.temperature',
|
||||
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_ac_rac_100001][sensor.corridor_a_c_temperature-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'temperature',
|
||||
'friendly_name': 'Corridor A/C Temperature',
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.corridor_a_c_temperature',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '27',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_ks_microwave_0101x][sensor.microwave_completion_time-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
@ -3692,6 +3899,475 @@
|
||||
'state': '0.0',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_wm_wm_000001_1][sensor.washing_machine_completion_time-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': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.washing_machine_completion_time',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Completion time',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'completion_time',
|
||||
'unique_id': '63803fae-cbed-f356-a063-2cf148ae3ca7.completionTime',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_wm_wm_000001_1][sensor.washing_machine_completion_time-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'timestamp',
|
||||
'friendly_name': 'Washing Machine Completion time',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.washing_machine_completion_time',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '2025-03-07T07:01:12+00:00',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_wm_wm_000001_1][sensor.washing_machine_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.washing_machine_energy',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'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,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '63803fae-cbed-f356-a063-2cf148ae3ca7.energy_meter',
|
||||
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_wm_wm_000001_1][sensor.washing_machine_energy-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'energy',
|
||||
'friendly_name': 'Washing Machine Energy',
|
||||
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
|
||||
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.washing_machine_energy',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '1323.6',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_wm_wm_000001_1][sensor.washing_machine_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.washing_machine_energy_difference',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'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,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'energy_difference',
|
||||
'unique_id': '63803fae-cbed-f356-a063-2cf148ae3ca7.deltaEnergy_meter',
|
||||
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_wm_wm_000001_1][sensor.washing_machine_energy_difference-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'energy',
|
||||
'friendly_name': 'Washing Machine Energy difference',
|
||||
'state_class': <SensorStateClass.TOTAL: 'total'>,
|
||||
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.washing_machine_energy_difference',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '0.1',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_wm_wm_000001_1][sensor.washing_machine_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.washing_machine_energy_saved',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'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,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'energy_saved',
|
||||
'unique_id': '63803fae-cbed-f356-a063-2cf148ae3ca7.energySaved_meter',
|
||||
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_wm_wm_000001_1][sensor.washing_machine_energy_saved-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'energy',
|
||||
'friendly_name': 'Washing Machine Energy saved',
|
||||
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
|
||||
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.washing_machine_energy_saved',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '0.0',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_wm_wm_000001_1][sensor.washing_machine_job_state-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'options': list([
|
||||
'air_wash',
|
||||
'ai_rinse',
|
||||
'ai_spin',
|
||||
'ai_wash',
|
||||
'cooling',
|
||||
'delay_wash',
|
||||
'drying',
|
||||
'finish',
|
||||
'none',
|
||||
'pre_wash',
|
||||
'rinse',
|
||||
'spin',
|
||||
'wash',
|
||||
'weight_sensing',
|
||||
'wrinkle_prevent',
|
||||
'freeze_protection',
|
||||
]),
|
||||
}),
|
||||
'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.washing_machine_job_state',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.ENUM: 'enum'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Job state',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'washer_job_state',
|
||||
'unique_id': '63803fae-cbed-f356-a063-2cf148ae3ca7.washerJobState',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_wm_wm_000001_1][sensor.washing_machine_job_state-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'enum',
|
||||
'friendly_name': 'Washing Machine Job state',
|
||||
'options': list([
|
||||
'air_wash',
|
||||
'ai_rinse',
|
||||
'ai_spin',
|
||||
'ai_wash',
|
||||
'cooling',
|
||||
'delay_wash',
|
||||
'drying',
|
||||
'finish',
|
||||
'none',
|
||||
'pre_wash',
|
||||
'rinse',
|
||||
'spin',
|
||||
'wash',
|
||||
'weight_sensing',
|
||||
'wrinkle_prevent',
|
||||
'freeze_protection',
|
||||
]),
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.washing_machine_job_state',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'wash',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_wm_wm_000001_1][sensor.washing_machine_machine_state-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'options': list([
|
||||
'pause',
|
||||
'run',
|
||||
'stop',
|
||||
]),
|
||||
}),
|
||||
'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.washing_machine_machine_state',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.ENUM: 'enum'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Machine state',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'washer_machine_state',
|
||||
'unique_id': '63803fae-cbed-f356-a063-2cf148ae3ca7.machineState',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_wm_wm_000001_1][sensor.washing_machine_machine_state-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'enum',
|
||||
'friendly_name': 'Washing Machine Machine state',
|
||||
'options': list([
|
||||
'pause',
|
||||
'run',
|
||||
'stop',
|
||||
]),
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.washing_machine_machine_state',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'run',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_wm_wm_000001_1][sensor.washing_machine_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.washing_machine_power',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'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,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '63803fae-cbed-f356-a063-2cf148ae3ca7.power_meter',
|
||||
'unit_of_measurement': <UnitOfPower.WATT: 'W'>,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_wm_wm_000001_1][sensor.washing_machine_power-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'power',
|
||||
'friendly_name': 'Washing Machine Power',
|
||||
'power_consumption_end': '2025-03-07T06:23:21Z',
|
||||
'power_consumption_start': '2025-03-07T06:21:09Z',
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
'unit_of_measurement': <UnitOfPower.WATT: 'W'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.washing_machine_power',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '0',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_wm_wm_000001_1][sensor.washing_machine_power_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.washing_machine_power_energy',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'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,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'power_energy',
|
||||
'unique_id': '63803fae-cbed-f356-a063-2cf148ae3ca7.powerEnergy_meter',
|
||||
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_wm_wm_000001_1][sensor.washing_machine_power_energy-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'energy',
|
||||
'friendly_name': 'Washing Machine Power energy',
|
||||
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
|
||||
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.washing_machine_power_energy',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '0.0',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[ecobee_sensor][sensor.child_bedroom_temperature-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
@ -3848,6 +4524,162 @@
|
||||
'state': '22',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[heatit_ztrm3_thermostat][sensor.hall_thermostat_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.hall_thermostat_energy',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.ENERGY: 'energy'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Energy',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '69a271f6-6537-4982-8cd9-979866872692.energy',
|
||||
'unit_of_measurement': 'kWh',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[heatit_ztrm3_thermostat][sensor.hall_thermostat_energy-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'energy',
|
||||
'friendly_name': 'Hall thermostat Energy',
|
||||
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
|
||||
'unit_of_measurement': 'kWh',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.hall_thermostat_energy',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '2339.5',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[heatit_ztrm3_thermostat][sensor.hall_thermostat_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.hall_thermostat_power',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.POWER: 'power'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Power',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '69a271f6-6537-4982-8cd9-979866872692.power',
|
||||
'unit_of_measurement': 'W',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[heatit_ztrm3_thermostat][sensor.hall_thermostat_power-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'power',
|
||||
'friendly_name': 'Hall thermostat Power',
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
'unit_of_measurement': 'W',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.hall_thermostat_power',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '368.17',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[heatit_ztrm3_thermostat][sensor.hall_thermostat_temperature-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.hall_thermostat_temperature',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.TEMPERATURE: 'temperature'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Temperature',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '69a271f6-6537-4982-8cd9-979866872692.temperature',
|
||||
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[heatit_ztrm3_thermostat][sensor.hall_thermostat_temperature-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'temperature',
|
||||
'friendly_name': 'Hall thermostat Temperature',
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.hall_thermostat_temperature',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '19.0',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[multipurpose_sensor][sensor.deck_door_battery-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
|
@ -281,6 +281,53 @@
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_wm_wm_000001_1][switch.washing_machine-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.washing_machine',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': None,
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '63803fae-cbed-f356-a063-2cf148ae3ca7',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_wm_wm_000001_1][switch.washing_machine-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Washing Machine',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'switch.washing_machine',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensibo_airconditioner_1][switch.office-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
|
@ -12,13 +12,36 @@ from homeassistant.helpers import device_registry as dr
|
||||
|
||||
from . import setup_integration
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
from tests.components.diagnostics import get_diagnostics_for_device
|
||||
from tests.common import MockConfigEntry, load_json_object_fixture
|
||||
from tests.components.diagnostics import (
|
||||
get_diagnostics_for_config_entry,
|
||||
get_diagnostics_for_device,
|
||||
)
|
||||
from tests.typing import ClientSessionGenerator
|
||||
|
||||
|
||||
@pytest.mark.parametrize("device_fixture", ["da_ac_rac_000001"])
|
||||
async def test_device(
|
||||
async def test_config_entry_diagnostics(
|
||||
hass: HomeAssistant,
|
||||
hass_client: ClientSessionGenerator,
|
||||
devices: AsyncMock,
|
||||
mock_smartthings: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test generating diagnostics for a device entry."""
|
||||
mock_smartthings.get_raw_devices.return_value = load_json_object_fixture(
|
||||
"devices/da_ac_rac_000001.json", DOMAIN
|
||||
)
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
assert (
|
||||
await get_diagnostics_for_config_entry(hass, hass_client, mock_config_entry)
|
||||
== snapshot
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("device_fixture", ["da_ac_rac_000001"])
|
||||
async def test_device_diagnostics(
|
||||
hass: HomeAssistant,
|
||||
hass_client: ClientSessionGenerator,
|
||||
device_registry: dr.DeviceRegistry,
|
||||
@ -28,13 +51,19 @@ async def test_device(
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test generating diagnostics for a device entry."""
|
||||
mock_smartthings.get_raw_device_status.return_value = load_json_object_fixture(
|
||||
"device_status/da_ac_rac_000001.json", DOMAIN
|
||||
)
|
||||
mock_smartthings.get_raw_device.return_value = load_json_object_fixture(
|
||||
"devices/da_ac_rac_000001.json", DOMAIN
|
||||
)["items"][0]
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
device = device_registry.async_get_device(
|
||||
identifiers={(DOMAIN, "96a5ef74-5832-a84b-f1f7-ca799957065d")}
|
||||
)
|
||||
|
||||
mock_smartthings.get_device_status.reset_mock()
|
||||
mock_smartthings.get_raw_device_status.reset_mock()
|
||||
|
||||
with patch("homeassistant.components.smartthings.diagnostics.EVENT_WAIT_TIME", 0.1):
|
||||
diag = await get_diagnostics_for_device(
|
||||
@ -44,6 +73,6 @@ async def test_device(
|
||||
assert diag == snapshot(
|
||||
exclude=props("last_changed", "last_reported", "last_updated")
|
||||
)
|
||||
mock_smartthings.get_device_status.assert_called_once_with(
|
||||
mock_smartthings.get_raw_device_status.assert_called_once_with(
|
||||
"96a5ef74-5832-a84b-f1f7-ca799957065d"
|
||||
)
|
||||
|
@ -2,14 +2,16 @@
|
||||
|
||||
from unittest.mock import AsyncMock
|
||||
|
||||
from pysmartthings import Attribute, Capability
|
||||
import pytest
|
||||
from syrupy import SnapshotAssertion
|
||||
|
||||
from homeassistant.components.smartthings import EVENT_BUTTON
|
||||
from homeassistant.components.smartthings.const import DOMAIN
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.core import Event, HomeAssistant
|
||||
from homeassistant.helpers import device_registry as dr
|
||||
|
||||
from . import setup_integration
|
||||
from . import setup_integration, trigger_update
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
@ -32,6 +34,35 @@ async def test_devices(
|
||||
assert device == snapshot
|
||||
|
||||
|
||||
@pytest.mark.parametrize("device_fixture", ["button"])
|
||||
async def test_button_event(
|
||||
hass: HomeAssistant,
|
||||
devices: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test button event."""
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
events = []
|
||||
|
||||
def capture_event(event: Event) -> None:
|
||||
events.append(event)
|
||||
|
||||
hass.bus.async_listen_once(EVENT_BUTTON, capture_event)
|
||||
|
||||
await trigger_update(
|
||||
hass,
|
||||
devices,
|
||||
"c4bdd19f-85d1-4d58-8f9c-e75ac3cf113b",
|
||||
Capability.BUTTON,
|
||||
Attribute.BUTTON,
|
||||
"pushed",
|
||||
)
|
||||
|
||||
assert len(events) == 1
|
||||
assert events[0] == snapshot
|
||||
|
||||
|
||||
@pytest.mark.parametrize("device_fixture", ["da_ac_rac_000001"])
|
||||
async def test_removing_stale_devices(
|
||||
hass: HomeAssistant,
|
||||
|
@ -1614,7 +1614,7 @@
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
'state': 'p',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.test_speed-entry]
|
||||
|
Loading…
x
Reference in New Issue
Block a user