Compare commits

..

1 Commits

Author SHA1 Message Date
renovate[bot] cdb2440dd3 Update cryptography to 49.0.0 2026-06-25 07:43:31 +00:00
37 changed files with 467 additions and 880 deletions
@@ -28,7 +28,7 @@ async def async_update_unique_id(
for serial_num in coordinator.data:
unique_id = f"{serial_num}-{old_key}"
if entity_id := entity_registry.async_get_entity_id(
platform, DOMAIN, unique_id
DOMAIN, platform, unique_id
):
_LOGGER.debug("Updating unique_id for %s", entity_id)
new_unique_id = unique_id.replace(old_key, new_key)
@@ -48,7 +48,7 @@ async def async_remove_entity_from_virtual_group(
for serial_num in coordinator.data:
unique_id = f"{serial_num}-{key}"
entity_id = entity_registry.async_get_entity_id(platform, DOMAIN, unique_id)
entity_id = entity_registry.async_get_entity_id(DOMAIN, platform, unique_id)
is_group = coordinator.data[serial_num].device_family == SPEAKER_GROUP_FAMILY
if entity_id and is_group:
entity_registry.async_remove(entity_id)
@@ -70,7 +70,7 @@ async def async_remove_unsupported_notification_sensors(
):
unique_id = f"{serial_num}-{notification_key}"
entity_id = entity_registry.async_get_entity_id(
SENSOR_DOMAIN, DOMAIN, unique_id=unique_id
DOMAIN, SENSOR_DOMAIN, unique_id=unique_id
)
is_unsupported = not coordinator.data[serial_num].notifications_supported
+12 -29
View File
@@ -731,32 +731,17 @@ class AutomationEntity(BaseAutomationEntity, RestoreEntity):
trace_element = TraceElement(variables, trigger_path)
trace_append_element(trace_element)
if not skip_condition and self._condition is not None:
try:
conditions_pass = self._condition.async_check(variables=variables)
except (vol.Invalid, HomeAssistantError) as err:
self._logger.error(
"Error while checking conditions of automation %s: %s",
self.entity_id,
err,
)
automation_trace.set_error(err)
return None
except Exception as err:
self._logger.exception(
"Unexpected error while checking conditions of automation %s",
self.entity_id,
)
automation_trace.set_error(err)
return None
if not conditions_pass:
self._logger.debug(
"Conditions not met, aborting automation. Condition summary: %s",
trace_get(clear=False),
)
script_execution_set("failed_conditions")
return None
if (
not skip_condition
and self._condition is not None
and not self._condition.async_check(variables=variables)
):
self._logger.debug(
"Conditions not met, aborting automation. Condition summary: %s",
trace_get(clear=False),
)
script_execution_set("failed_conditions")
return None
self.async_set_context(trigger_context)
event_data = {
@@ -809,9 +794,7 @@ class AutomationEntity(BaseAutomationEntity, RestoreEntity):
)
automation_trace.set_error(err)
except Exception as err:
self._logger.exception(
"Unexpected error while executing automation %s", self.entity_id
)
self._logger.exception("While executing automation %s", self.entity_id)
automation_trace.set_error(err)
return None
+8 -7
View File
@@ -15,15 +15,16 @@ from homeassistant.components.sensor import (
SensorStateClass,
)
from homeassistant.const import (
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
CONCENTRATION_PARTS_PER_MILLION,
LIGHT_LUX,
PERCENTAGE,
UnitOfApparentPower,
UnitOfDensity,
UnitOfElectricCurrent,
UnitOfElectricPotential,
UnitOfEnergy,
UnitOfFrequency,
UnitOfPower,
UnitOfRatio,
UnitOfReactiveEnergy,
UnitOfReactivePower,
UnitOfSpeed,
@@ -52,19 +53,19 @@ SENSOR_TYPES: tuple[BleBoxSensorEntityDescription, ...] = (
BleBoxSensorEntityDescription(
key="pm1",
device_class=SensorDeviceClass.PM1,
native_unit_of_measurement=UnitOfDensity.MICROGRAMS_PER_CUBIC_METER,
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
state_class=SensorStateClass.MEASUREMENT,
),
BleBoxSensorEntityDescription(
key="pm2_5",
device_class=SensorDeviceClass.PM25,
native_unit_of_measurement=UnitOfDensity.MICROGRAMS_PER_CUBIC_METER,
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
state_class=SensorStateClass.MEASUREMENT,
),
BleBoxSensorEntityDescription(
key="pm10",
device_class=SensorDeviceClass.PM10,
native_unit_of_measurement=UnitOfDensity.MICROGRAMS_PER_CUBIC_METER,
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
state_class=SensorStateClass.MEASUREMENT,
),
BleBoxSensorEntityDescription(
@@ -83,7 +84,7 @@ SENSOR_TYPES: tuple[BleBoxSensorEntityDescription, ...] = (
BleBoxSensorEntityDescription(
key="humidity",
device_class=SensorDeviceClass.HUMIDITY,
native_unit_of_measurement=UnitOfRatio.PERCENTAGE,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
),
BleBoxSensorEntityDescription(
@@ -178,7 +179,7 @@ SENSOR_TYPES: tuple[BleBoxSensorEntityDescription, ...] = (
BleBoxSensorEntityDescription(
key="co2",
device_class=SensorDeviceClass.CO2,
native_unit_of_measurement=UnitOfRatio.PARTS_PER_MILLION,
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
state_class=SensorStateClass.MEASUREMENT,
),
BleBoxSensorEntityDescription(
@@ -805,10 +805,6 @@ class DefaultAgent(ConversationEntity):
else:
num_unmatched_entities += 1
# Literal text matched is the dominant signal
same_text_matched = (maybe_result is not None) and (
result.text_chunks_matched == maybe_result.text_chunks_matched
)
if (
(maybe_result is None) # first result
or (
@@ -817,25 +813,22 @@ class DefaultAgent(ConversationEntity):
)
or (
# More entities matched
same_text_matched
and (num_matched_entities > best_num_matched_entities)
num_matched_entities > best_num_matched_entities
)
or (
# Fewer unmatched entities
same_text_matched
and (num_matched_entities == best_num_matched_entities)
(num_matched_entities == best_num_matched_entities)
and (num_unmatched_entities < best_num_unmatched_entities)
)
or (
# Prefer unmatched ranges
same_text_matched
and (num_matched_entities == best_num_matched_entities)
(num_matched_entities == best_num_matched_entities)
and (num_unmatched_entities == best_num_unmatched_entities)
and (num_unmatched_ranges > best_num_unmatched_ranges)
)
or (
# Prefer match failures with entities
same_text_matched
(result.text_chunks_matched == maybe_result.text_chunks_matched)
and (num_unmatched_entities == best_num_unmatched_entities)
and (num_unmatched_ranges == best_num_unmatched_ranges)
and (
@@ -6,5 +6,5 @@
"documentation": "https://www.home-assistant.io/integrations/conversation",
"integration_type": "entity",
"quality_scale": "internal",
"requirements": ["hassil==3.8.0", "home-assistant-intents==2026.6.24"]
"requirements": ["hassil==3.8.0", "home-assistant-intents==2026.6.1"]
}
+7 -6
View File
@@ -15,9 +15,10 @@ from homeassistant.components.sensor import (
SensorStateClass,
)
from homeassistant.const import (
CONCENTRATION_PARTS_PER_MILLION,
PERCENTAGE,
SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
EntityCategory,
UnitOfRatio,
UnitOfTime,
)
from homeassistant.core import HomeAssistant, callback
@@ -71,7 +72,7 @@ SENSOR_DESCRIPTIONS: tuple[DucoSensorEntityDescription, ...] = (
key="target_flow_level",
translation_key="target_flow_level",
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfRatio.PERCENTAGE,
native_unit_of_measurement=PERCENTAGE,
suggested_display_precision=0,
value_fn=lambda node: (
node.ventilation.flow_lvl_tgt if node.ventilation else None
@@ -95,7 +96,7 @@ SENSOR_DESCRIPTIONS: tuple[DucoSensorEntityDescription, ...] = (
key="co2",
device_class=SensorDeviceClass.CO2,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfRatio.PARTS_PER_MILLION,
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
value_fn=lambda node: node.sensor.co2 if node.sensor else None,
node_types=(
NodeType.BSCO2,
@@ -107,7 +108,7 @@ SENSOR_DESCRIPTIONS: tuple[DucoSensorEntityDescription, ...] = (
DucoSensorEntityDescription(
key="iaq_co2",
translation_key="iaq_co2",
native_unit_of_measurement=UnitOfRatio.PERCENTAGE,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
entity_registry_enabled_default=False,
value_fn=lambda node: node.sensor.iaq_co2 if node.sensor else None,
@@ -122,14 +123,14 @@ SENSOR_DESCRIPTIONS: tuple[DucoSensorEntityDescription, ...] = (
key="humidity",
device_class=SensorDeviceClass.HUMIDITY,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfRatio.PERCENTAGE,
native_unit_of_measurement=PERCENTAGE,
value_fn=lambda node: node.sensor.rh if node.sensor else None,
node_types=(NodeType.BSRH, NodeType.UCRH, NodeType.VLVRH, NodeType.VLVCO2RH),
),
DucoSensorEntityDescription(
key="iaq_rh",
translation_key="iaq_rh",
native_unit_of_measurement=UnitOfRatio.PERCENTAGE,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
entity_registry_enabled_default=False,
value_fn=lambda node: node.sensor.iaq_rh if node.sensor else None,
@@ -13,7 +13,7 @@ from homeassistant.components.sensor import (
SensorEntityDescription,
SensorStateClass,
)
from homeassistant.const import EntityCategory, UnitOfRatio, UnitOfVolume
from homeassistant.const import PERCENTAGE, EntityCategory, UnitOfVolume
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from homeassistant.util import dt as dt_util, slugify
@@ -67,7 +67,7 @@ BSH_PROGRAM_SENSORS = (
),
HomeConnectSensorEntityDescription(
key=EventKey.BSH_COMMON_OPTION_PROGRAM_PROGRESS,
native_unit_of_measurement=UnitOfRatio.PERCENTAGE,
native_unit_of_measurement=PERCENTAGE,
translation_key="program_progress",
appliance_types=APPLIANCES_WITH_PROGRAMS,
),
@@ -158,7 +158,6 @@ SENSORS = (
HomeConnectSensorEntityDescription(
key=StatusKey.BSH_COMMON_BATTERY_LEVEL,
device_class=SensorDeviceClass.BATTERY,
native_unit_of_measurement=UnitOfRatio.PERCENTAGE,
),
HomeConnectSensorEntityDescription(
key=StatusKey.BSH_COMMON_VIDEO_CAMERA_STATE,
@@ -26,17 +26,18 @@ from homeassistant.components.sensor import (
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
CONCENTRATION_PARTS_PER_MILLION,
LIGHT_LUX,
PERCENTAGE,
SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
EntityCategory,
Platform,
UnitOfDensity,
UnitOfElectricCurrent,
UnitOfElectricPotential,
UnitOfEnergy,
UnitOfPower,
UnitOfPressure,
UnitOfRatio,
UnitOfSoundPressure,
UnitOfTemperature,
)
@@ -253,7 +254,7 @@ SIMPLE_SENSOR: dict[str, HomeKitSensorEntityDescription] = {
name="Current Humidity",
device_class=SensorDeviceClass.HUMIDITY,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfRatio.PERCENTAGE,
native_unit_of_measurement=PERCENTAGE,
# This sensor is only for humidity characteristics that are not part
# of a humidity sensor service.
probe=(lambda char: char.service.type != ServicesTypes.HUMIDITY_SENSOR),
@@ -269,42 +270,42 @@ SIMPLE_SENSOR: dict[str, HomeKitSensorEntityDescription] = {
name="PM2.5 Density",
device_class=SensorDeviceClass.PM25,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfDensity.MICROGRAMS_PER_CUBIC_METER,
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
),
CharacteristicsTypes.DENSITY_PM10: HomeKitSensorEntityDescription(
key=CharacteristicsTypes.DENSITY_PM10,
name="PM10 Density",
device_class=SensorDeviceClass.PM10,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfDensity.MICROGRAMS_PER_CUBIC_METER,
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
),
CharacteristicsTypes.DENSITY_OZONE: HomeKitSensorEntityDescription(
key=CharacteristicsTypes.DENSITY_OZONE,
name="Ozone Density",
device_class=SensorDeviceClass.OZONE,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfDensity.MICROGRAMS_PER_CUBIC_METER,
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
),
CharacteristicsTypes.DENSITY_NO2: HomeKitSensorEntityDescription(
key=CharacteristicsTypes.DENSITY_NO2,
name="Nitrogen Dioxide Density",
device_class=SensorDeviceClass.NITROGEN_DIOXIDE,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfDensity.MICROGRAMS_PER_CUBIC_METER,
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
),
CharacteristicsTypes.DENSITY_SO2: HomeKitSensorEntityDescription(
key=CharacteristicsTypes.DENSITY_SO2,
name="Sulphur Dioxide Density",
device_class=SensorDeviceClass.SULPHUR_DIOXIDE,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfDensity.MICROGRAMS_PER_CUBIC_METER,
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
),
CharacteristicsTypes.DENSITY_VOC: HomeKitSensorEntityDescription(
key=CharacteristicsTypes.DENSITY_VOC,
name="Volatile Organic Compound Density",
device_class=SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfDensity.MICROGRAMS_PER_CUBIC_METER,
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
),
CharacteristicsTypes.THREAD_NODE_CAPABILITIES: HomeKitSensorEntityDescription(
key=CharacteristicsTypes.THREAD_NODE_CAPABILITIES,
@@ -362,13 +363,13 @@ SIMPLE_SENSOR: dict[str, HomeKitSensorEntityDescription] = {
key=CharacteristicsTypes.FILTER_LIFE_LEVEL,
name="Filter lifetime",
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfRatio.PERCENTAGE,
native_unit_of_measurement=PERCENTAGE,
),
CharacteristicsTypes.WATER_LEVEL: HomeKitSensorEntityDescription(
key=CharacteristicsTypes.WATER_LEVEL,
name="Water level",
translation_key="water_level",
native_unit_of_measurement=UnitOfRatio.PERCENTAGE,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
),
CharacteristicsTypes.VENDOR_EVE_THERMO_VALVE_POSITION: (
@@ -378,7 +379,7 @@ SIMPLE_SENSOR: dict[str, HomeKitSensorEntityDescription] = {
translation_key="valve_position",
entity_category=EntityCategory.DIAGNOSTIC,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfRatio.PERCENTAGE,
native_unit_of_measurement=PERCENTAGE,
)
),
}
@@ -408,7 +409,7 @@ class HomeKitHumiditySensor(HomeKitSensor):
"""Representation of a Homekit humidity sensor."""
_attr_device_class = SensorDeviceClass.HUMIDITY
_attr_native_unit_of_measurement = UnitOfRatio.PERCENTAGE
_attr_native_unit_of_measurement = PERCENTAGE
@override
def get_characteristic_types(self) -> list[str]:
@@ -480,7 +481,7 @@ class HomeKitCarbonDioxideSensor(HomeKitSensor):
"""Representation of a Homekit Carbon Dioxide sensor."""
_attr_device_class = SensorDeviceClass.CO2
_attr_native_unit_of_measurement = UnitOfRatio.PARTS_PER_MILLION
_attr_native_unit_of_measurement = CONCENTRATION_PARTS_PER_MILLION
@override
def get_characteristic_types(self) -> list[str]:
@@ -504,7 +505,7 @@ class HomeKitBatterySensor(HomeKitSensor):
"""Representation of a Homekit battery sensor."""
_attr_device_class = SensorDeviceClass.BATTERY
_attr_native_unit_of_measurement = UnitOfRatio.PERCENTAGE
_attr_native_unit_of_measurement = PERCENTAGE
_attr_entity_category = EntityCategory.DIAGNOSTIC
@override
@@ -50,13 +50,14 @@ from homeassistant.components.sensor import (
SensorStateClass,
)
from homeassistant.const import (
CONCENTRATION_GRAMS_PER_CUBIC_METER,
CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER,
DEGREE,
LIGHT_LUX,
UnitOfDensity,
PERCENTAGE,
UnitOfEnergy,
UnitOfPower,
UnitOfPrecipitationDepth,
UnitOfRatio,
UnitOfSpeed,
UnitOfTemperature,
UnitOfVolume,
@@ -83,7 +84,7 @@ SMOKE_DETECTOR_SENSORS: tuple[HmipSmokeDetectorSensorDescription, ...] = (
HmipSmokeDetectorSensorDescription(
key="dirt_level",
translation_key="smoke_detector_dirt_level",
native_unit_of_measurement=UnitOfRatio.PERCENTAGE,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
entity_registry_enabled_default=False,
channel_field="dirtLevel",
@@ -531,7 +532,7 @@ class HomematicipFloorTerminalBlockMechanicChannelValve(
):
"""Representation of the HomematicIP floor terminal block."""
_attr_native_unit_of_measurement = UnitOfRatio.PERCENTAGE
_attr_native_unit_of_measurement = PERCENTAGE
_attr_state_class = SensorStateClass.MEASUREMENT
def __init__(
@@ -580,7 +581,7 @@ class HomematicipAccesspointDutyCycle(HomematicipGenericEntity, SensorEntity):
"""Representation of then HomeMaticIP access point."""
_attr_icon = "mdi:access-point-network"
_attr_native_unit_of_measurement = UnitOfRatio.PERCENTAGE
_attr_native_unit_of_measurement = PERCENTAGE
_attr_state_class = SensorStateClass.MEASUREMENT
def __init__(self, hap: HomematicipHAP, device) -> None:
@@ -599,7 +600,7 @@ class HomematicipAccesspointDutyCycle(HomematicipGenericEntity, SensorEntity):
class HomematicipHeatingThermostat(HomematicipGenericEntity, SensorEntity):
"""Representation of the HomematicIP heating thermostat."""
_attr_native_unit_of_measurement = UnitOfRatio.PERCENTAGE
_attr_native_unit_of_measurement = PERCENTAGE
def __init__(self, hap: HomematicipHAP, device) -> None:
"""Initialize heating thermostat device."""
@@ -628,7 +629,7 @@ class HomematicipHumiditySensor(HomematicipGenericEntity, SensorEntity):
"""Representation of the HomematicIP humidity sensor."""
_attr_device_class = SensorDeviceClass.HUMIDITY
_attr_native_unit_of_measurement = UnitOfRatio.PERCENTAGE
_attr_native_unit_of_measurement = PERCENTAGE
_attr_state_class = SensorStateClass.MEASUREMENT
def __init__(self, hap: HomematicipHAP, device) -> None:
@@ -679,9 +680,9 @@ class HomematicipAbsoluteHumiditySensor(HomematicipGenericEntity, SensorEntity):
"""Representation of the HomematicIP absolute humidity sensor."""
_attr_device_class = SensorDeviceClass.ABSOLUTE_HUMIDITY
_attr_native_unit_of_measurement = UnitOfDensity.GRAMS_PER_CUBIC_METER
_attr_native_unit_of_measurement = CONCENTRATION_GRAMS_PER_CUBIC_METER
_attr_suggested_display_precision = 1
_attr_suggested_unit_of_measurement = UnitOfDensity.MILLIGRAMS_PER_CUBIC_METER
_attr_suggested_unit_of_measurement = CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER
_attr_state_class = SensorStateClass.MEASUREMENT
def __init__(self, hap: HomematicipHAP, device) -> None:
@@ -1142,7 +1143,7 @@ class HomematicipSoilMoistureSensor(HomematicipGenericEntity, SensorEntity):
"""Representation of the HomematicIP soil moisture sensor."""
_attr_device_class = SensorDeviceClass.MOISTURE
_attr_native_unit_of_measurement = UnitOfRatio.PERCENTAGE
_attr_native_unit_of_measurement = PERCENTAGE
_attr_state_class = SensorStateClass.MEASUREMENT
def __init__(self, hap: HomematicipHAP, device) -> None:
+6 -4
View File
@@ -12,9 +12,11 @@ from homeassistant.components.sensor import (
SensorStateClass,
)
from homeassistant.const import (
CONCENTRATION_PARTS_PER_BILLION,
CONCENTRATION_PARTS_PER_MILLION,
LIGHT_LUX,
PERCENTAGE,
UnitOfPressure,
UnitOfRatio,
UnitOfTemperature,
)
from homeassistant.core import HomeAssistant
@@ -30,7 +32,7 @@ SENSOR_TYPES: Final[dict[str, SensorEntityDescription]] = {
SensorType.AIR_HUMIDITY: SensorEntityDescription(
key="air_humidity",
device_class=SensorDeviceClass.HUMIDITY,
native_unit_of_measurement=UnitOfRatio.PERCENTAGE,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
),
SensorType.AIR_PRESSURE: SensorEntityDescription(
@@ -47,7 +49,7 @@ SENSOR_TYPES: Final[dict[str, SensorEntityDescription]] = {
SensorType.ECO2: SensorEntityDescription(
key="eco2",
device_class=SensorDeviceClass.CO2,
native_unit_of_measurement=UnitOfRatio.PARTS_PER_MILLION,
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
state_class=SensorStateClass.MEASUREMENT,
),
SensorType.LIGHT: SensorEntityDescription(
@@ -65,7 +67,7 @@ SENSOR_TYPES: Final[dict[str, SensorEntityDescription]] = {
SensorType.VOC: SensorEntityDescription(
key="voc",
device_class=SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS_PARTS,
native_unit_of_measurement=UnitOfRatio.PARTS_PER_BILLION,
native_unit_of_measurement=CONCENTRATION_PARTS_PER_BILLION,
state_class=SensorStateClass.MEASUREMENT,
),
}
@@ -11,7 +11,6 @@ from homeassistant.components.sensor import (
SensorEntityDescription,
SensorStateClass,
)
from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from homeassistant.helpers.typing import StateType
@@ -74,7 +73,6 @@ async def async_setup_entry(
class MealieStatisticSensors(MealieEntity, SensorEntity):
"""Defines a Mealie sensor."""
_attr_entity_category = EntityCategory.DIAGNOSTIC
entity_description: MealieStatisticsSensorEntityDescription
coordinator: MealieStatisticsCoordinator
+3 -3
View File
@@ -16,7 +16,7 @@ from homeassistant.components.sensor import (
SensorStateClass,
StateType,
)
from homeassistant.const import UnitOfInformation, UnitOfRatio
from homeassistant.const import PERCENTAGE, UnitOfInformation
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
@@ -122,7 +122,7 @@ CONTAINER_SENSORS: tuple[PortainerContainerSensorEntityDescription, ...] = (
and data.stats.memory_stats.usage > 0
else 0.0
),
native_unit_of_measurement=UnitOfRatio.PERCENTAGE,
native_unit_of_measurement=PERCENTAGE,
entity_category=EntityCategory.DIAGNOSTIC,
suggested_display_precision=2,
state_class=SensorStateClass.MEASUREMENT,
@@ -151,7 +151,7 @@ CONTAINER_SENSORS: tuple[PortainerContainerSensorEntityDescription, ...] = (
and data.stats.cpu_stats.online_cpus > 0
else 0.0
),
native_unit_of_measurement=UnitOfRatio.PERCENTAGE,
native_unit_of_measurement=PERCENTAGE,
entity_category=EntityCategory.DIAGNOSTIC,
suggested_display_precision=2,
state_class=SensorStateClass.MEASUREMENT,
+6 -5
View File
@@ -22,14 +22,15 @@ from homeassistant.components.sensor import (
SensorStateClass,
)
from homeassistant.const import (
CONCENTRATION_PARTS_PER_MILLION,
LIGHT_LUX,
PERCENTAGE,
UnitOfElectricCurrent,
UnitOfElectricPotential,
UnitOfEnergy,
UnitOfLength,
UnitOfPower,
UnitOfPressure,
UnitOfRatio,
UnitOfSoundPressure,
UnitOfSpeed,
UnitOfTemperature,
@@ -125,7 +126,7 @@ _GAUGE_VARIANT_DESCRIPTIONS = {
"AIRQUALITY": SensorEntityDescription(
key="airquality",
device_class=SensorDeviceClass.CO2,
native_unit_of_measurement=UnitOfRatio.PARTS_PER_MILLION,
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
state_class=SensorStateClass.MEASUREMENT,
),
"CURRENT": SensorEntityDescription(
@@ -155,7 +156,7 @@ _GAUGE_VARIANT_DESCRIPTIONS = {
"HUMIDITY": SensorEntityDescription(
key="humidity",
device_class=SensorDeviceClass.HUMIDITY,
native_unit_of_measurement=UnitOfRatio.PERCENTAGE,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
),
"LIGHT": SensorEntityDescription(
@@ -352,7 +353,7 @@ class QbusHumiditySensor(QbusEntity, SensorEntity):
_attr_device_class = SensorDeviceClass.HUMIDITY
_attr_name = None
_attr_native_unit_of_measurement = UnitOfRatio.PERCENTAGE
_attr_native_unit_of_measurement = PERCENTAGE
_attr_state_class = SensorStateClass.MEASUREMENT
@override
@@ -381,7 +382,7 @@ class QbusVentilationSensor(QbusEntity, SensorEntity):
_attr_device_class = SensorDeviceClass.CO2
_attr_name = None
_attr_native_unit_of_measurement = UnitOfRatio.PARTS_PER_MILLION
_attr_native_unit_of_measurement = CONCENTRATION_PARTS_PER_MILLION
_attr_state_class = SensorStateClass.MEASUREMENT
_attr_suggested_display_precision = 0
@@ -30,7 +30,6 @@ from homeassistant.util.event_type import EventType
# startup
from . import (
backup, # noqa: F401
entity_options,
entity_registry,
websocket_api,
)
@@ -43,7 +42,6 @@ from .const import ( # noqa: F401
SupportedDialect,
)
from .core import Recorder
from .entity_options import is_entity_recorded # noqa: F401
from .services import async_setup_services
from .tasks import AddRecorderPlatformTask
from .util import get_instance
@@ -127,6 +125,15 @@ CONFIG_SCHEMA = vol.Schema(
)
def is_entity_recorded(hass: HomeAssistant, entity_id: str) -> bool:
"""Check if an entity is being recorded.
Async friendly.
"""
instance = get_instance(hass)
return instance.entity_filter is None or instance.entity_filter(entity_id)
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up the recorder."""
conf = config[DOMAIN]
@@ -160,7 +167,6 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
)
get_instance.cache_clear()
entity_registry.async_setup(hass)
entity_options.async_setup(hass)
instance.async_initialize()
instance.async_register()
instance.start()
@@ -1,68 +0,0 @@
"""Control recorder entity options."""
import dataclasses
from enum import StrEnum
from typing import Any
import voluptuous as vol
from homeassistant.components import websocket_api
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import config_validation as cv
from .util import get_instance
def is_entity_recorded(hass: HomeAssistant, entity_id: str) -> bool:
"""Check if an entity is being recorded.
Async friendly.
"""
instance = get_instance(hass)
return instance.entity_filter is None or instance.entity_filter(entity_id)
@callback
def async_setup(hass: HomeAssistant) -> None:
"""Set up the recorder entity options."""
websocket_api.async_register_command(hass, ws_get_entity_options)
class EntityRecordingDisabler(StrEnum):
"""What disabled recording of an entity."""
USER = "user"
@dataclasses.dataclass(frozen=True)
class RecorderEntityOptions:
"""Recorder options for an entity."""
recording_disabled_by: EntityRecordingDisabler | None = None
def to_json(self) -> dict[str, Any]:
"""Return a JSON serializable representation for storage."""
return {
"recording_disabled_by": self.recording_disabled_by,
}
@websocket_api.require_admin
@websocket_api.websocket_command(
{
vol.Required("type"): "recorder/entity_options/get",
vol.Required("entity_id"): cv.strict_entity_id,
}
)
@callback
def ws_get_entity_options(
hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict[str, Any]
) -> None:
"""Get recorder settings for a single entity."""
entity_id: str = msg["entity_id"]
recording_disabled = (
None if is_entity_recorded(hass, entity_id) else EntityRecordingDisabler.USER
)
options = RecorderEntityOptions(recording_disabled_by=recording_disabled)
connection.send_result(msg["id"], options.to_json())
+17 -17
View File
@@ -20,16 +20,16 @@ from homeassistant.components.sensor import (
SensorStateClass,
)
from homeassistant.const import (
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
PERCENTAGE,
REVOLUTIONS_PER_MINUTE,
SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
EntityCategory,
UnitOfDensity,
UnitOfElectricCurrent,
UnitOfEnergy,
UnitOfMass,
UnitOfPower,
UnitOfPressure,
UnitOfRatio,
UnitOfTemperature,
UnitOfTime,
UnitOfVolume,
@@ -80,7 +80,7 @@ VICARE_UNIT_TO_HA_UNIT = {
VICARE_CUBIC_METER: UnitOfVolume.CUBIC_METERS,
VICARE_KW: UnitOfPower.KILO_WATT,
VICARE_KWH: UnitOfEnergy.KILO_WATT_HOUR,
VICARE_PERCENT: UnitOfRatio.PERCENTAGE,
VICARE_PERCENT: PERCENTAGE,
VICARE_W: UnitOfPower.WATT,
VICARE_WH: UnitOfEnergy.WATT_HOUR,
}
@@ -117,7 +117,7 @@ GLOBAL_SENSORS: tuple[ViCareSensorEntityDescription, ...] = (
ViCareSensorEntityDescription(
key="outside_humidity",
translation_key="outside_humidity",
native_unit_of_measurement=UnitOfRatio.PERCENTAGE,
native_unit_of_measurement=PERCENTAGE,
value_getter=lambda api: api.getOutsideHumidity(),
device_class=SensorDeviceClass.HUMIDITY,
state_class=SensorStateClass.MEASUREMENT,
@@ -165,7 +165,7 @@ GLOBAL_SENSORS: tuple[ViCareSensorEntityDescription, ...] = (
ViCareSensorEntityDescription(
key="primary_circuit_pump_rotation",
translation_key="primary_circuit_pump_rotation",
native_unit_of_measurement=UnitOfRatio.PERCENTAGE,
native_unit_of_measurement=PERCENTAGE,
value_getter=lambda api: api.getPrimaryCircuitPumpRotation(),
unit_getter=lambda api: api.getPrimaryCircuitPumpRotationUnit(),
state_class=SensorStateClass.MEASUREMENT,
@@ -799,7 +799,7 @@ GLOBAL_SENSORS: tuple[ViCareSensorEntityDescription, ...] = (
ViCareSensorEntityDescription(
key="ess_state_of_charge",
translation_key="ess_state_of_charge",
native_unit_of_measurement=UnitOfRatio.PERCENTAGE,
native_unit_of_measurement=PERCENTAGE,
device_class=SensorDeviceClass.BATTERY,
state_class=SensorStateClass.MEASUREMENT,
value_getter=lambda api: api.getElectricalEnergySystemSOC(),
@@ -996,7 +996,7 @@ GLOBAL_SENSORS: tuple[ViCareSensorEntityDescription, ...] = (
ViCareSensorEntityDescription(
key="room_humidity",
device_class=SensorDeviceClass.HUMIDITY,
native_unit_of_measurement=UnitOfRatio.PERCENTAGE,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
value_getter=lambda api: api.getHumidity(),
),
@@ -1122,7 +1122,7 @@ GLOBAL_SENSORS: tuple[ViCareSensorEntityDescription, ...] = (
),
ViCareSensorEntityDescription(
key="battery_level",
native_unit_of_measurement=UnitOfRatio.PERCENTAGE,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.BATTERY,
entity_category=EntityCategory.DIAGNOSTIC,
@@ -1142,7 +1142,7 @@ GLOBAL_SENSORS: tuple[ViCareSensorEntityDescription, ...] = (
translation_key="zigbee_signal_strength",
state_class=SensorStateClass.MEASUREMENT,
entity_category=EntityCategory.DIAGNOSTIC,
native_unit_of_measurement=UnitOfRatio.PERCENTAGE,
native_unit_of_measurement=PERCENTAGE,
value_getter=lambda api: api.getZigbeeSignalStrength(),
entity_registry_enabled_default=False,
),
@@ -1150,7 +1150,7 @@ GLOBAL_SENSORS: tuple[ViCareSensorEntityDescription, ...] = (
key="valve_position",
translation_key="valve_position",
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfRatio.PERCENTAGE,
native_unit_of_measurement=PERCENTAGE,
value_getter=lambda api: api.getValvePosition(),
entity_registry_enabled_default=False,
),
@@ -1177,7 +1177,7 @@ GLOBAL_SENSORS: tuple[ViCareSensorEntityDescription, ...] = (
key="supply_humidity",
translation_key="supply_humidity",
device_class=SensorDeviceClass.HUMIDITY,
native_unit_of_measurement=UnitOfRatio.PERCENTAGE,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
value_getter=lambda api: api.getSupplyHumidity(),
),
@@ -1229,28 +1229,28 @@ GLOBAL_SENSORS: tuple[ViCareSensorEntityDescription, ...] = (
ViCareSensorEntityDescription(
key="pm01",
device_class=SensorDeviceClass.PM1,
native_unit_of_measurement=UnitOfDensity.MICROGRAMS_PER_CUBIC_METER,
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
state_class=SensorStateClass.MEASUREMENT,
value_getter=lambda api: api.getAirborneDustPM1(),
),
ViCareSensorEntityDescription(
key="pm02",
device_class=SensorDeviceClass.PM25,
native_unit_of_measurement=UnitOfDensity.MICROGRAMS_PER_CUBIC_METER,
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
state_class=SensorStateClass.MEASUREMENT,
value_getter=lambda api: api.getAirborneDustPM2d5(),
),
ViCareSensorEntityDescription(
key="pm04",
device_class=SensorDeviceClass.PM4,
native_unit_of_measurement=UnitOfDensity.MICROGRAMS_PER_CUBIC_METER,
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
state_class=SensorStateClass.MEASUREMENT,
value_getter=lambda api: api.getAirborneDustPM4(),
),
ViCareSensorEntityDescription(
key="pm10",
device_class=SensorDeviceClass.PM10,
native_unit_of_measurement=UnitOfDensity.MICROGRAMS_PER_CUBIC_METER,
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
state_class=SensorStateClass.MEASUREMENT,
value_getter=lambda api: api.getAirborneDustPM10(),
),
@@ -1293,7 +1293,7 @@ BURNER_SENSORS: tuple[ViCareSensorEntityDescription, ...] = (
ViCareSensorEntityDescription(
key="burner_modulation",
translation_key="burner_modulation",
native_unit_of_measurement=UnitOfRatio.PERCENTAGE,
native_unit_of_measurement=PERCENTAGE,
value_getter=lambda api: api.getModulation(),
state_class=SensorStateClass.MEASUREMENT,
),
@@ -1312,7 +1312,7 @@ COMPRESSOR_SENSORS: tuple[ViCareSensorEntityDescription, ...] = (
ViCareSensorEntityDescription(
key="compressor_modulation",
translation_key="compressor_modulation",
native_unit_of_measurement=UnitOfRatio.PERCENTAGE,
native_unit_of_measurement=PERCENTAGE,
value_getter=lambda api: api.getModulation(),
unit_getter=lambda api: api.getModulationUnit(),
state_class=SensorStateClass.MEASUREMENT,
+2 -2
View File
@@ -29,7 +29,7 @@ cached-ipaddress==1.1.2
certifi>=2021.5.30
ciso8601==2.3.3
cronsim==2.7
cryptography==48.0.1
cryptography==49.0.0
dbus-fast==5.0.22
file-read-backwards==2.0.0
fnv-hash-fast==2.0.3
@@ -40,7 +40,7 @@ hass-nabucasa==2.2.0
hassil==3.8.0
home-assistant-bluetooth==2.0.0
home-assistant-frontend==20260624.0
home-assistant-intents==2026.6.24
home-assistant-intents==2026.6.1
httpx==0.28.1
ifaddr==0.2.0
Jinja2==3.1.6
+1 -1
View File
@@ -57,7 +57,7 @@ dependencies = [
"lru-dict==1.4.1",
"PyJWT==2.12.1",
# PyJWT has loose dependency. We want the latest one.
"cryptography==48.0.1",
"cryptography==49.0.0",
"Pillow==12.2.0",
"propcache==0.5.2",
"pyOpenSSL==26.2.0",
+2 -2
View File
@@ -21,13 +21,13 @@ bcrypt==5.0.0
certifi>=2021.5.30
ciso8601==2.3.3
cronsim==2.7
cryptography==48.0.1
cryptography==49.0.0
fnv-hash-fast==2.0.3
ha-ffmpeg==3.2.2
hass-nabucasa==2.2.0
hassil==3.8.0
home-assistant-bluetooth==2.0.0
home-assistant-intents==2026.6.24
home-assistant-intents==2026.6.1
httpx==0.28.1
ifaddr==0.2.0
infrared-protocols==6.3.0
+1 -1
View File
@@ -1275,7 +1275,7 @@ holidays==0.99
home-assistant-frontend==20260624.0
# homeassistant.components.conversation
home-assistant-intents==2026.6.24
home-assistant-intents==2026.6.1
# homeassistant.components.homekit
homekit-audio-proxy==1.2.1
+3 -3
View File
@@ -107,8 +107,8 @@ async def test_alexa_unique_id_migration(
)
entity = entity_registry.async_get_or_create(
SWITCH_DOMAIN,
DOMAIN,
SWITCH_DOMAIN,
unique_id=f"{TEST_DEVICE_1_SN}-do_not_disturb",
device_id=device.id,
config_entry=mock_config_entry,
@@ -145,8 +145,8 @@ async def test_alexa_dnd_group_removal(
)
entity = entity_registry.async_get_or_create(
SWITCH_DOMAIN,
DOMAIN,
SWITCH_DOMAIN,
unique_id=f"{TEST_DEVICE_1_SN}-do_not_disturb",
device_id=device.id,
config_entry=mock_config_entry,
@@ -184,8 +184,8 @@ async def test_alexa_unsupported_notification_sensor_removal(
)
entity = entity_registry.async_get_or_create(
SENSOR_DOMAIN,
DOMAIN,
SENSOR_DOMAIN,
unique_id=f"{TEST_DEVICE_1_SN}-Timer",
device_id=device.id,
config_entry=mock_config_entry,
@@ -853,7 +853,7 @@
'speech': dict({
'plain': dict({
'extra_data': None,
'speech': 'Sorry, I am not aware of any device called Are the',
'speech': 'Sorry, I am not aware of any area called Are the',
}),
}),
}),
@@ -902,7 +902,7 @@
'speech': dict({
'plain': dict({
'extra_data': None,
'speech': 'Sorry, I am not aware of any device called Are the',
'speech': 'Sorry, I am not aware of any area called Are the',
}),
}),
}),
-182
View File
@@ -7,7 +7,6 @@ from typing import Any
from unittest.mock import ANY, Mock, patch
import pytest
import voluptuous as vol
from homeassistant.components import automation, input_boolean, script
from homeassistant.components.automation import (
@@ -1931,187 +1930,6 @@ async def test_automation_with_error_in_script_2(
assert "string value is None" in caplog.text
@pytest.mark.parametrize(
("side_effect", "expected_error", "expect_traceback"),
[
(
HomeAssistantError("boom"),
"Error while executing automation automation.hello: boom",
False,
),
(
vol.Invalid("not valid"),
"Error while executing automation automation.hello: not valid",
False,
),
(
ValueError("unexpected"),
"Unexpected error while executing automation automation.hello",
True,
),
],
ids=["home_assistant_error", "voluptuous_invalid", "unexpected_exception"],
)
async def test_automation_with_error_in_action_script(
hass: HomeAssistant,
calls: list[ServiceCall],
caplog: pytest.LogCaptureFixture,
hass_ws_client: WebSocketGenerator,
side_effect: Exception,
expected_error: str,
expect_traceback: bool,
) -> None:
"""Test errors raised while running the action script are handled and traced."""
assert await async_setup_component(
hass,
automation.DOMAIN,
{
automation.DOMAIN: {
"id": "hello",
"alias": "hello",
"trigger": {"platform": "event", "event_type": "test_event"},
"action": {"action": "test.automation"},
}
},
)
with patch(
"homeassistant.helpers.script.Script.async_run",
side_effect=side_effect,
):
hass.bus.async_fire("test_event")
await hass.async_block_till_done()
assert len(calls) == 0
assert expected_error in caplog.text
# A HomeAssistantError/voluptuous error is logged without a traceback, an
# unexpected error is logged with a traceback.
assert ("Traceback" in caplog.text) is expect_traceback
# The error is recorded on the automation trace.
client = await hass_ws_client()
await client.send_json_auto_id(
{"type": "trace/list", "domain": "automation", "item_id": "hello"}
)
response = await client.receive_json()
assert response["success"]
traces = response["result"]
assert len(traces) == 1
assert traces[0]["error"] == str(side_effect)
@pytest.mark.parametrize(
("side_effect", "expected_error", "expect_traceback"),
[
(
HomeAssistantError("boom"),
"Error while checking conditions of automation automation.hello: boom",
False,
),
(
vol.Invalid("not valid"),
"Error while checking conditions of automation automation.hello: not valid",
False,
),
(
ValueError("unexpected"),
"Unexpected error while checking conditions of automation automation.hello",
True,
),
],
ids=["home_assistant_error", "voluptuous_invalid", "unexpected_exception"],
)
async def test_automation_with_error_in_condition(
hass: HomeAssistant,
calls: list[ServiceCall],
caplog: pytest.LogCaptureFixture,
hass_ws_client: WebSocketGenerator,
side_effect: Exception,
expected_error: str,
expect_traceback: bool,
) -> None:
"""Test errors raised while checking conditions are handled and traced."""
assert await async_setup_component(
hass,
automation.DOMAIN,
{
automation.DOMAIN: {
"id": "hello",
"alias": "hello",
"trigger": {"platform": "event", "event_type": "test_event"},
"condition": {
"condition": "state",
"entity_id": "test.entity",
"state": "on",
},
"action": {"action": "test.automation"},
}
},
)
with patch(
"homeassistant.helpers.condition.ConditionsChecker.async_check",
side_effect=side_effect,
):
hass.bus.async_fire("test_event")
await hass.async_block_till_done()
# The action must not run when the condition check raises.
assert len(calls) == 0
assert expected_error in caplog.text
# A HomeAssistantError/voluptuous error is logged without a traceback, an
# unexpected error is logged with a traceback.
assert ("Traceback" in caplog.text) is expect_traceback
# The error is recorded on the automation trace.
client = await hass_ws_client()
await client.send_json_auto_id(
{"type": "trace/list", "domain": "automation", "item_id": "hello"}
)
response = await client.receive_json()
assert response["success"]
traces = response["result"]
assert len(traces) == 1
assert traces[0]["error"] == str(side_effect)
async def test_automation_with_error_in_condition_continues_after_recovery(
hass: HomeAssistant,
calls: list[ServiceCall],
) -> None:
"""Test the automation still runs once the condition stops raising."""
assert await async_setup_component(
hass,
automation.DOMAIN,
{
automation.DOMAIN: {
"alias": "hello",
"trigger": {"platform": "event", "event_type": "test_event"},
"condition": {
"condition": "state",
"entity_id": "test.entity",
"state": "on",
},
"action": {"action": "test.automation"},
}
},
)
hass.states.async_set("test.entity", "on")
with patch(
"homeassistant.helpers.condition.ConditionsChecker.async_check",
side_effect=HomeAssistantError("boom"),
):
hass.bus.async_fire("test_event")
await hass.async_block_till_done()
assert len(calls) == 0
# Without the error, the condition passes and the action runs.
hass.bus.async_fire("test_event")
await hass.async_block_till_done()
assert len(calls) == 1
async def test_automation_restore_last_triggered_with_initial_state(
hass: HomeAssistant,
) -> None:
@@ -302,7 +302,7 @@
'speech': dict({
'plain': dict({
'extra_data': None,
'speech': 'Sorry, I am not aware of any device called late added',
'speech': 'Sorry, I am not aware of any area called late added',
}),
}),
}),
@@ -373,7 +373,7 @@
'speech': dict({
'plain': dict({
'extra_data': None,
'speech': 'Sorry, I am not aware of any device called kitchen',
'speech': 'Sorry, I am not aware of any area called kitchen',
}),
}),
}),
@@ -423,7 +423,7 @@
'speech': dict({
'plain': dict({
'extra_data': None,
'speech': 'Sorry, I am not aware of any device called renamed',
'speech': 'Sorry, I am not aware of any area called renamed',
}),
}),
}),
@@ -467,11 +467,10 @@
'name': 'HassTurnOn',
}),
'match': True,
'sentence_template': '<turn> on [<the>] {name}',
'sentence_template': '<turn> on (<area> <name>|<name> [in <area>])',
'slots': dict({
'name': 'my cool light',
}),
'source': 'builtin',
'targets': dict({
'light.kitchen': dict({
'matched': True,
@@ -492,11 +491,10 @@
'name': 'HassTurnOff',
}),
'match': True,
'sentence_template': '[<turn>] [<the>] {name} [to] off',
'sentence_template': '[<turn>] (<area> <name>|<name> [in <area>]) [to] off',
'slots': dict({
'name': 'my cool light',
}),
'source': 'builtin',
'targets': dict({
'light.kitchen': dict({
'matched': True,
@@ -522,12 +520,11 @@
'name': 'HassTurnOn',
}),
'match': True,
'sentence_template': '<turn> on [(<all>|<the>)] <light> <in> [<the>] {area}',
'sentence_template': '<turn> on [(<all>|<the>)] <light> <in> <area>',
'slots': dict({
'area': 'kitchen',
'domain': 'light',
}),
'source': 'builtin',
'targets': dict({
'light.kitchen': dict({
'matched': True,
@@ -545,7 +542,7 @@
}),
'domain': dict({
'name': 'domain',
'text': '',
'text': 'lights',
'value': 'light',
}),
'state': dict({
@@ -558,13 +555,12 @@
'name': 'HassGetState',
}),
'match': True,
'sentence_template': '<how_many> <light> <is> {on_off_states:state} [<in>] [<the>] {area}',
'sentence_template': '[tell me] how many {on_off_domains:domain} (is|are) {on_off_states:state} [<in_area_floor>]',
'slots': dict({
'area': 'kitchen',
'domain': 'light',
'domain': 'lights',
'state': 'on',
}),
'source': 'builtin',
'targets': dict({
'light.kitchen': dict({
'matched': False,
@@ -633,12 +629,11 @@
'name': 'HassLightSet',
}),
'match': True,
'sentence_template': '[<numeric_value_set>] [<the>] {name} brightness [to] {brightness}[([ ]%)| percent]',
'sentence_template': '[<numeric_value_set>] <name> brightness [to] <brightness>',
'slots': dict({
'brightness': '100',
'name': 'test light',
}),
'source': 'builtin',
'targets': dict({
'light.demo_1234': dict({
'matched': True,
@@ -665,11 +660,10 @@
'name': 'HassLightSet',
}),
'match': False,
'sentence_template': '[<numeric_value_set>] [<the>] {name} brightness [to] {brightness}[([ ]%)| percent]',
'sentence_template': '[<numeric_value_set>] <name> brightness [to] <brightness>',
'slots': dict({
'name': 'test light',
}),
'source': 'builtin',
'targets': dict({
}),
'unmatched_slots': dict({
@@ -729,6 +729,19 @@ async def test_satellite_area_context(
}
turn_off_calls.clear()
# Turn on/off all lights also works
for command in ("on", "off"):
result = await conversation.async_converse(
hass, f"turn {command} all lights", None, Context(), None
)
await hass.async_block_till_done()
assert result.response.response_type is intent.IntentResponseType.ACTION_DONE
# All lights should have been targeted
assert {s.entity_id for s in result.response.matched_states} == {
e.entity_id for e in all_lights
}
@pytest.mark.usefixtures("init_components")
async def test_error_no_device(hass: HomeAssistant) -> None:
@@ -828,7 +841,7 @@ async def test_error_no_device_on_floor(
assert result.response.error_code == intent.IntentResponseErrorCode.NO_VALID_TARGETS
assert (
result.response.speech["plain"]["speech"]
== "Sorry, I am not aware of any device called missing entity in the ground floor"
== "Sorry, I am not aware of any device called missing entity on ground floor"
)
@@ -1115,7 +1128,7 @@ async def test_error_no_domain_on_floor_exposed(
await hass.async_block_till_done()
result = await conversation.async_converse(
hass, "turn on all lights in the ground floor", None, Context(), None
hass, "turn on all lights on the ground floor", None, Context(), None
)
assert result.response.response_type is intent.IntentResponseType.ERROR
@@ -1480,6 +1493,21 @@ async def test_error_duplicate_names_same_area(
f" {name} in the {area_kitchen.name} area"
)
# question
result = await conversation.async_converse(
hass, f"is {name} on in the {area_kitchen.name}?", None, Context(), None
)
assert result.response.response_type is intent.IntentResponseType.ERROR
assert (
result.response.error_code
== intent.IntentResponseErrorCode.NO_VALID_TARGETS
)
assert (
result.response.speech["plain"]["speech"]
== f"Sorry, there are multiple devices called"
f" {name} in the {area_kitchen.name} area"
)
@pytest.mark.usefixtures("init_components")
async def test_duplicate_names_same_area_but_one_is_exposed(
@@ -2827,9 +2855,9 @@ async def test_config_sentences_priority(
{
"conversation": {
"intents": {
"CustomIntent": ["turn on [the] {name}"],
"CustomIntent": ["turn on <name>"],
"WorseCustomIntent": ["turn on the lamp"],
"FakeCustomIntent": ["turn on [the] {name}"],
"FakeCustomIntent": ["turn on <name>"],
}
}
},
@@ -127,39 +127,29 @@ async def test_cover_set_position(
async def test_cover_device_class(
hass: HomeAssistant,
init_components,
area_registry: ar.AreaRegistry,
entity_registry: er.EntityRegistry,
) -> None:
"""Test the open position for covers by device class."""
await cover_intent.async_setup_intents(hass)
area_kitchen = area_registry.async_get_or_create("kitchen_id")
area_kitchen = area_registry.async_update(area_kitchen.id, name="kitchen")
kitchen_window = entity_registry.async_get_or_create(
"cover", "demo", "kitchen_window"
)
kitchen_window = entity_registry.async_update_entity(
kitchen_window.entity_id, area_id=area_kitchen.id
)
entity_id = f"{cover.DOMAIN}.front"
hass.states.async_set(
kitchen_window.entity_id, STATE_CLOSED, attributes={"device_class": "window"}
entity_id, STATE_CLOSED, attributes={"device_class": "garage"}
)
async_expose_entity(hass, conversation.DOMAIN, kitchen_window.entity_id, True)
async_expose_entity(hass, conversation.DOMAIN, entity_id, True)
# Open service
calls = async_mock_service(hass, cover.DOMAIN, cover.SERVICE_OPEN_COVER)
result = await conversation.async_converse(
hass, "open the window in the kitchen", None, Context(), None, device_id=None
hass, "open the garage door", None, Context(), None
)
await hass.async_block_till_done()
response = result.response
assert response.response_type is intent.IntentResponseType.ACTION_DONE
assert response.speech["plain"]["speech"] == "Opening the window"
assert response.speech["plain"]["speech"] == "Opening the garage"
assert len(calls) == 1
call = calls[0]
assert call.data == {"entity_id": kitchen_window.entity_id}
assert call.data == {"entity_id": entity_id}
async def test_valve_intents(
@@ -35,7 +35,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': 'aa:bb:cc:dd:ee:ff_113_humidity',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
})
# ---
# name: test_sensor_entities_state[sensor.bathroom_rh_humidity-state]
@@ -44,7 +44,7 @@
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'humidity',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Bathroom RH Humidity',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'context': <ANY>,
'entity_id': 'sensor.bathroom_rh_humidity',
@@ -90,7 +90,7 @@
'supported_features': 0,
'translation_key': 'iaq_rh',
'unique_id': 'aa:bb:cc:dd:ee:ff_113_iaq_rh',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
})
# ---
# name: test_sensor_entities_state[sensor.bathroom_rh_humidity_air_quality_index-state]
@@ -98,7 +98,7 @@
'attributes': ReadOnlyDict({
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Bathroom RH Humidity air quality index',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'context': <ANY>,
'entity_id': 'sensor.bathroom_rh_humidity_air_quality_index',
@@ -144,7 +144,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': 'aa:bb:cc:dd:ee:ff_60_humidity',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
})
# ---
# name: test_sensor_entities_state[sensor.bedroom_valve_humidity-state]
@@ -153,7 +153,7 @@
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'humidity',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Bedroom valve Humidity',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'context': <ANY>,
'entity_id': 'sensor.bedroom_valve_humidity',
@@ -199,7 +199,7 @@
'supported_features': 0,
'translation_key': 'iaq_rh',
'unique_id': 'aa:bb:cc:dd:ee:ff_60_iaq_rh',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
})
# ---
# name: test_sensor_entities_state[sensor.bedroom_valve_humidity_air_quality_index-state]
@@ -207,7 +207,7 @@
'attributes': ReadOnlyDict({
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Bedroom valve Humidity air quality index',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'context': <ANY>,
'entity_id': 'sensor.bedroom_valve_humidity_air_quality_index',
@@ -253,7 +253,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': 'aa:bb:cc:dd:ee:ff_61_co2',
'unit_of_measurement': <UnitOfRatio.PARTS_PER_MILLION: 'ppm'>,
'unit_of_measurement': 'ppm',
})
# ---
# name: test_sensor_entities_state[sensor.hall_valve_carbon_dioxide-state]
@@ -262,7 +262,7 @@
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'carbon_dioxide',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Hall valve Carbon dioxide',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PARTS_PER_MILLION: 'ppm'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: 'ppm',
}),
'context': <ANY>,
'entity_id': 'sensor.hall_valve_carbon_dioxide',
@@ -308,7 +308,7 @@
'supported_features': 0,
'translation_key': 'iaq_co2',
'unique_id': 'aa:bb:cc:dd:ee:ff_61_iaq_co2',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
})
# ---
# name: test_sensor_entities_state[sensor.hall_valve_co2_air_quality_index-state]
@@ -316,7 +316,7 @@
'attributes': ReadOnlyDict({
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Hall valve CO2 air quality index',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'context': <ANY>,
'entity_id': 'sensor.hall_valve_co2_air_quality_index',
@@ -362,7 +362,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': 'aa:bb:cc:dd:ee:ff_50_humidity',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
})
# ---
# name: test_sensor_entities_state[sensor.kitchen_rh_humidity-state]
@@ -371,7 +371,7 @@
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'humidity',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Kitchen RH Humidity',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'context': <ANY>,
'entity_id': 'sensor.kitchen_rh_humidity',
@@ -417,7 +417,7 @@
'supported_features': 0,
'translation_key': 'iaq_rh',
'unique_id': 'aa:bb:cc:dd:ee:ff_50_iaq_rh',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
})
# ---
# name: test_sensor_entities_state[sensor.kitchen_rh_humidity_air_quality_index-state]
@@ -425,7 +425,7 @@
'attributes': ReadOnlyDict({
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Kitchen RH Humidity air quality index',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'context': <ANY>,
'entity_id': 'sensor.kitchen_rh_humidity_air_quality_index',
@@ -635,7 +635,7 @@
'supported_features': 0,
'translation_key': 'target_flow_level',
'unique_id': 'aa:bb:cc:dd:ee:ff_1_target_flow_level',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
})
# ---
# name: test_sensor_entities_state[sensor.living_target_flow_level-state]
@@ -643,7 +643,7 @@
'attributes': ReadOnlyDict({
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Living Target flow level',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'context': <ANY>,
'entity_id': 'sensor.living_target_flow_level',
@@ -781,7 +781,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': 'aa:bb:cc:dd:ee:ff_2_co2',
'unit_of_measurement': <UnitOfRatio.PARTS_PER_MILLION: 'ppm'>,
'unit_of_measurement': 'ppm',
})
# ---
# name: test_sensor_entities_state[sensor.office_co2_carbon_dioxide-state]
@@ -790,7 +790,7 @@
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'carbon_dioxide',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Office CO2 Carbon dioxide',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PARTS_PER_MILLION: 'ppm'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: 'ppm',
}),
'context': <ANY>,
'entity_id': 'sensor.office_co2_carbon_dioxide',
@@ -836,7 +836,7 @@
'supported_features': 0,
'translation_key': 'iaq_co2',
'unique_id': 'aa:bb:cc:dd:ee:ff_2_iaq_co2',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
})
# ---
# name: test_sensor_entities_state[sensor.office_co2_co2_air_quality_index-state]
@@ -844,7 +844,7 @@
'attributes': ReadOnlyDict({
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Office CO2 CO2 air quality index',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'context': <ANY>,
'entity_id': 'sensor.office_co2_co2_air_quality_index',
@@ -890,7 +890,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': 'aa:bb:cc:dd:ee:ff_62_co2',
'unit_of_measurement': <UnitOfRatio.PARTS_PER_MILLION: 'ppm'>,
'unit_of_measurement': 'ppm',
})
# ---
# name: test_sensor_entities_state[sensor.study_valve_carbon_dioxide-state]
@@ -899,7 +899,7 @@
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'carbon_dioxide',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Study valve Carbon dioxide',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PARTS_PER_MILLION: 'ppm'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: 'ppm',
}),
'context': <ANY>,
'entity_id': 'sensor.study_valve_carbon_dioxide',
@@ -945,7 +945,7 @@
'supported_features': 0,
'translation_key': 'iaq_co2',
'unique_id': 'aa:bb:cc:dd:ee:ff_62_iaq_co2',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
})
# ---
# name: test_sensor_entities_state[sensor.study_valve_co2_air_quality_index-state]
@@ -953,7 +953,7 @@
'attributes': ReadOnlyDict({
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Study valve CO2 air quality index',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'context': <ANY>,
'entity_id': 'sensor.study_valve_co2_air_quality_index',
@@ -999,7 +999,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': 'aa:bb:cc:dd:ee:ff_62_humidity',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
})
# ---
# name: test_sensor_entities_state[sensor.study_valve_humidity-state]
@@ -1008,7 +1008,7 @@
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'humidity',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Study valve Humidity',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'context': <ANY>,
'entity_id': 'sensor.study_valve_humidity',
@@ -1054,7 +1054,7 @@
'supported_features': 0,
'translation_key': 'iaq_rh',
'unique_id': 'aa:bb:cc:dd:ee:ff_62_iaq_rh',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
})
# ---
# name: test_sensor_entities_state[sensor.study_valve_humidity_air_quality_index-state]
@@ -1062,7 +1062,7 @@
'attributes': ReadOnlyDict({
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Study valve Humidity air quality index',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'context': <ANY>,
'entity_id': 'sensor.study_valve_humidity_air_quality_index',
@@ -325,13 +325,13 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_1_32896_32900',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Airversa AP2 1808 Filter lifetime',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.airversa_ap2_1808_filter_lifetime',
'state': '100.0',
@@ -373,14 +373,14 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_1_2576_2580',
'unit_of_measurement': <UnitOfDensity.MICROGRAMS_PER_CUBIC_METER: 'μg/m³'>,
'unit_of_measurement': 'μg/m³',
}),
'state': dict({
'attributes': dict({
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'pm25',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Airversa AP2 1808 PM2.5 Density',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfDensity.MICROGRAMS_PER_CUBIC_METER: 'μg/m³'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: 'μg/m³',
}),
'entity_id': 'sensor.airversa_ap2_1808_pm2_5_density',
'state': '3.0',
@@ -930,7 +930,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_4_101',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
@@ -938,7 +938,7 @@
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'eufyCam2-0000 Battery',
<EntityStateAttribute.ICON: 'icon'>: 'mdi:battery-20',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.eufycam2_0000_battery',
'state': '17',
@@ -1192,7 +1192,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_2_101',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
@@ -1200,7 +1200,7 @@
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'eufyCam2-000A Battery',
<EntityStateAttribute.ICON: 'icon'>: 'mdi:battery-40',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.eufycam2_000a_battery',
'state': '38',
@@ -1454,7 +1454,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_3_101',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
@@ -1462,7 +1462,7 @@
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'eufyCam2-000A Battery',
<EntityStateAttribute.ICON: 'icon'>: 'mdi:battery-alert',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.eufycam2_000a_battery_2',
'state': '100',
@@ -1898,7 +1898,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_33_5',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
@@ -1906,7 +1906,7 @@
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Contact Sensor Battery Sensor',
<EntityStateAttribute.ICON: 'icon'>: 'mdi:battery',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.contact_sensor_battery_sensor',
'state': '100',
@@ -2321,7 +2321,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_1_5',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
@@ -2329,7 +2329,7 @@
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Programmable Switch Battery Sensor',
<EntityStateAttribute.ICON: 'icon'>: 'mdi:battery',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.programmable_switch_battery_sensor',
'state': '100',
@@ -2655,7 +2655,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_1_700',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
@@ -2663,7 +2663,7 @@
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'ArloBabyA0 Battery',
<EntityStateAttribute.ICON: 'icon'>: 'mdi:battery-80',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.arlobabya0_battery',
'state': '82',
@@ -2705,14 +2705,14 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_1_900',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'humidity',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'ArloBabyA0 Humidity',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.arlobabya0_humidity',
'state': '60.099998',
@@ -3950,14 +3950,14 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_1_16_24',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'humidity',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'HomeW Current Humidity',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.homew_current_humidity',
'state': '34',
@@ -4573,7 +4573,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_4295608960_192',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
@@ -4581,7 +4581,7 @@
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Basement Battery',
<EntityStateAttribute.ICON: 'icon'>: 'mdi:battery',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.basement_battery',
'state': '100',
@@ -4888,7 +4888,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_4298360914_192',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
@@ -4896,7 +4896,7 @@
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Basement Window 1 Battery',
<EntityStateAttribute.ICON: 'icon'>: 'mdi:battery',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.basement_window_1_battery',
'state': '100',
@@ -5151,7 +5151,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_4298360921_192',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
@@ -5159,7 +5159,7 @@
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Deck Door Battery',
<EntityStateAttribute.ICON: 'icon'>: 'mdi:battery',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.deck_door_battery',
'state': '100',
@@ -5414,7 +5414,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_4298527970_192',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
@@ -5422,7 +5422,7 @@
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Front Door Battery',
<EntityStateAttribute.ICON: 'icon'>: 'mdi:battery',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.front_door_battery',
'state': '100',
@@ -5677,7 +5677,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_4298527962_192',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
@@ -5685,7 +5685,7 @@
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Garage Door Battery',
<EntityStateAttribute.ICON: 'icon'>: 'mdi:battery',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.garage_door_battery',
'state': '100',
@@ -5895,7 +5895,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_4295016858_192',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
@@ -5903,7 +5903,7 @@
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Living Room Battery',
<EntityStateAttribute.ICON: 'icon'>: 'mdi:battery',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.living_room_battery',
'state': '100',
@@ -6210,7 +6210,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_4298360712_192',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
@@ -6218,7 +6218,7 @@
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Living Room Window 1 Battery',
<EntityStateAttribute.ICON: 'icon'>: 'mdi:battery',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.living_room_window_1_battery',
'state': '100',
@@ -6473,7 +6473,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_4298649931_192',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
@@ -6481,7 +6481,7 @@
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Loft window Battery',
<EntityStateAttribute.ICON: 'icon'>: 'mdi:battery',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.loft_window_battery',
'state': '100',
@@ -6691,7 +6691,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_4295608971_192',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
@@ -6699,7 +6699,7 @@
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Master BR Battery',
<EntityStateAttribute.ICON: 'icon'>: 'mdi:battery',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.master_br_battery',
'state': '100',
@@ -7006,7 +7006,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_4298584118_192',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
@@ -7014,7 +7014,7 @@
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Master BR Window Battery',
<EntityStateAttribute.ICON: 'icon'>: 'mdi:battery',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.master_br_window_battery',
'state': '100',
@@ -7363,14 +7363,14 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_1_16_24',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'humidity',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Thermostat Current Humidity',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.thermostat_current_humidity',
'state': '45.0',
@@ -7632,7 +7632,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_4295016969_192',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
@@ -7640,7 +7640,7 @@
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Upstairs BR Battery',
<EntityStateAttribute.ICON: 'icon'>: 'mdi:battery',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.upstairs_br_battery',
'state': '100',
@@ -7947,7 +7947,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_4298568508_192',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
@@ -7955,7 +7955,7 @@
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Upstairs BR Window Battery',
<EntityStateAttribute.ICON: 'icon'>: 'mdi:battery',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.upstairs_br_window_battery',
'state': '100',
@@ -8394,14 +8394,14 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_1_16_24',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'humidity',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'HomeW Current Humidity',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.homew_current_humidity',
'state': '34',
@@ -8826,14 +8826,14 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_1_16_24',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'humidity',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'HomeW Current Humidity',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.homew_current_humidity',
'state': '34',
@@ -9683,14 +9683,14 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_1_16_24',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'humidity',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'My ecobee Current Humidity',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.my_ecobee_current_humidity',
'state': '55.0',
@@ -10341,7 +10341,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_1_17',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
@@ -10349,7 +10349,7 @@
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Eve Degree AA11 Battery',
<EntityStateAttribute.ICON: 'icon'>: 'mdi:battery-60',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.eve_degree_aa11_battery',
'state': '65',
@@ -10391,14 +10391,14 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_1_27',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'humidity',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Eve Degree AA11 Humidity',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.eve_degree_aa11_humidity',
'state': '59.4818115234375',
@@ -11350,7 +11350,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_123016423_162',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
@@ -11358,7 +11358,7 @@
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Family Room North Battery',
<EntityStateAttribute.ICON: 'icon'>: 'mdi:battery',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.family_room_north_battery',
'state': '100',
@@ -11603,7 +11603,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_878448248_9',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
@@ -11611,7 +11611,7 @@
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Kitchen Window Battery',
<EntityStateAttribute.ICON: 'icon'>: 'mdi:battery',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.kitchen_window_battery',
'state': '100',
@@ -12255,14 +12255,14 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_1233851541_169_180',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'humidity',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: '89 Living Room Current Humidity',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.89_living_room_current_humidity',
'state': '60',
@@ -12648,7 +12648,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_3982136094_604',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
@@ -12656,7 +12656,7 @@
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Laundry Smoke ED78 Battery',
<EntityStateAttribute.ICON: 'icon'>: 'mdi:battery',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.laundry_smoke_ed78_battery',
'state': '100',
@@ -12827,7 +12827,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_123016423_162',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
@@ -12835,7 +12835,7 @@
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Family Room North Battery',
<EntityStateAttribute.ICON: 'icon'>: 'mdi:battery',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.family_room_north_battery',
'state': '100',
@@ -13080,7 +13080,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_878448248_9',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
@@ -13088,7 +13088,7 @@
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Kitchen Window Battery',
<EntityStateAttribute.ICON: 'icon'>: 'mdi:battery',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.kitchen_window_battery',
'state': '100',
@@ -13957,14 +13957,14 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_1233851541_169_180',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'humidity',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: '89 Living Room Current Humidity',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.89_living_room_current_humidity',
'state': '60',
@@ -14358,14 +14358,14 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_293334836_8_9',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'humidity',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Humidifier 182A Current Humidity',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.humidifier_182a_current_humidity',
'state': '0',
@@ -14629,14 +14629,14 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_293334836_8_9',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'humidity',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Humidifier 182A Current Humidity',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.humidifier_182a_current_humidity',
'state': '0',
@@ -14902,7 +14902,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_3982136094_604',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
@@ -14910,7 +14910,7 @@
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Laundry Smoke ED78 Battery',
<EntityStateAttribute.ICON: 'icon'>: 'mdi:battery',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.laundry_smoke_ed78_battery',
'state': '100',
@@ -16320,7 +16320,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_6623462389072572_644245094400',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
@@ -16328,7 +16328,7 @@
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Hue dimmer switch Battery',
<EntityStateAttribute.ICON: 'icon'>: 'mdi:battery',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.hue_dimmer_switch_battery',
'state': '100',
@@ -18122,14 +18122,14 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_1_100_107',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'humidity',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Lennox Current Humidity',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.lennox_current_humidity',
'state': '34',
@@ -19321,14 +19321,14 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_1_20_27',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'humidity',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Mysa-85dda9 Current Humidity',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.mysa_85dda9_current_humidity',
'state': '40',
@@ -20323,14 +20323,14 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_1_10',
'unit_of_measurement': <UnitOfRatio.PARTS_PER_MILLION: 'ppm'>,
'unit_of_measurement': 'ppm',
}),
'state': dict({
'attributes': dict({
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'carbon_dioxide',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Healthy Home Coach Carbon Dioxide sensor',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PARTS_PER_MILLION: 'ppm'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: 'ppm',
}),
'entity_id': 'sensor.healthy_home_coach_carbon_dioxide_sensor',
'state': '804',
@@ -20372,14 +20372,14 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_1_14',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'humidity',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Healthy Home Coach Humidity sensor',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.healthy_home_coach_humidity_sensor',
'state': '59',
@@ -21112,7 +21112,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_2_64',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
@@ -21120,7 +21120,7 @@
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Master Bath South RYSE Shade Battery',
<EntityStateAttribute.ICON: 'icon'>: 'mdi:battery',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.master_bath_south_ryse_shade_battery',
'state': '100',
@@ -21365,7 +21365,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_3_64',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
@@ -21373,7 +21373,7 @@
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'RYSE SmartShade RYSE Shade Battery',
<EntityStateAttribute.ICON: 'icon'>: 'mdi:battery',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.ryse_smartshade_ryse_shade_battery',
'state': '100',
@@ -21544,7 +21544,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_4_64',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
@@ -21552,7 +21552,7 @@
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'BR Left RYSE Shade Battery',
<EntityStateAttribute.ICON: 'icon'>: 'mdi:battery',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.br_left_ryse_shade_battery',
'state': '100',
@@ -21719,7 +21719,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_2_64',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
@@ -21727,7 +21727,7 @@
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'LR Left RYSE Shade Battery',
<EntityStateAttribute.ICON: 'icon'>: 'mdi:battery-90',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.lr_left_ryse_shade_battery',
'state': '89',
@@ -21894,7 +21894,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_3_64',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
@@ -21902,7 +21902,7 @@
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'LR Right RYSE Shade Battery',
<EntityStateAttribute.ICON: 'icon'>: 'mdi:battery',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.lr_right_ryse_shade_battery',
'state': '100',
@@ -22147,7 +22147,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_5_64',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
@@ -22155,7 +22155,7 @@
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'RZSS RYSE Shade Battery',
<EntityStateAttribute.ICON: 'icon'>: 'mdi:battery-alert',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.rzss_ryse_shade_battery',
'state': '0',
@@ -23151,14 +23151,14 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_1_14',
'unit_of_measurement': <UnitOfRatio.PARTS_PER_MILLION: 'ppm'>,
'unit_of_measurement': 'ppm',
}),
'state': dict({
'attributes': dict({
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'carbon_dioxide',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'VELUX Sensor Carbon Dioxide sensor',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PARTS_PER_MILLION: 'ppm'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: 'ppm',
}),
'entity_id': 'sensor.velux_sensor_carbon_dioxide_sensor',
'state': '1124.0',
@@ -23200,14 +23200,14 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_1_11',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'humidity',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'VELUX Sensor Humidity sensor',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.velux_sensor_humidity_sensor',
'state': '69.0',
@@ -23461,14 +23461,14 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_2_14',
'unit_of_measurement': <UnitOfRatio.PARTS_PER_MILLION: 'ppm'>,
'unit_of_measurement': 'ppm',
}),
'state': dict({
'attributes': dict({
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'carbon_dioxide',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'VELUX Sensor Carbon Dioxide sensor',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PARTS_PER_MILLION: 'ppm'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: 'ppm',
}),
'entity_id': 'sensor.velux_sensor_carbon_dioxide_sensor',
'state': '400',
@@ -23510,14 +23510,14 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_2_11',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'humidity',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'VELUX Sensor Humidity sensor',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.velux_sensor_humidity_sensor',
'state': '58',
@@ -24267,14 +24267,14 @@
'supported_features': 0,
'translation_key': None,
'unique_id': '00:00:00:00:00:00_1_30_33',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
}),
'state': dict({
'attributes': dict({
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'humidity',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'VOCOlinc-Flowerbud-0d324b Current Humidity',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'entity_id': 'sensor.vocolinc_flowerbud_0d324b_current_humidity',
'state': '45.0',
@@ -151,7 +151,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': 'be37ca9c47c24498a38bc62c7c711840-sensor2-air_humidity',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
})
# ---
# name: test_setup[sensor.test_sensor_2-state]
@@ -160,7 +160,7 @@
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'humidity',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Test Sensor 2',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'context': <ANY>,
'entity_id': 'sensor.test_sensor_2',
@@ -14,7 +14,7 @@
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
'entity_category': None,
'entity_id': 'sensor.mealie_categories',
'has_entity_name': True,
'hidden_by': None,
@@ -68,7 +68,7 @@
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
'entity_category': None,
'entity_id': 'sensor.mealie_recipes',
'has_entity_name': True,
'hidden_by': None,
@@ -122,7 +122,7 @@
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
'entity_category': None,
'entity_id': 'sensor.mealie_tags',
'has_entity_name': True,
'hidden_by': None,
@@ -176,7 +176,7 @@
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
'entity_category': None,
'entity_id': 'sensor.mealie_tools',
'has_entity_name': True,
'hidden_by': None,
@@ -230,7 +230,7 @@
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
'entity_category': None,
'entity_id': 'sensor.mealie_users',
'has_entity_name': True,
'hidden_by': None,
@@ -203,7 +203,7 @@
'supported_features': 0,
'translation_key': 'cpu_usage_total',
'unique_id': 'portainer_test_entry_123_dashy_dashy.1.qgza68hnz4n1qvyz3iohynx05_cpu_usage_total',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
})
# ---
# name: test_all_entities[sensor.dashy_dashy_1_qgza68hnz4n1qvyz3iohynx05_cpu_usage_total-state]
@@ -211,7 +211,7 @@
'attributes': ReadOnlyDict({
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'dashy_dashy.1.qgza68hnz4n1qvyz3iohynx05 CPU usage total',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'context': <ANY>,
'entity_id': 'sensor.dashy_dashy_1_qgza68hnz4n1qvyz3iohynx05_cpu_usage_total',
@@ -432,7 +432,7 @@
'supported_features': 0,
'translation_key': 'memory_usage_percentage',
'unique_id': 'portainer_test_entry_123_dashy_dashy.1.qgza68hnz4n1qvyz3iohynx05_memory_usage_percentage',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
})
# ---
# name: test_all_entities[sensor.dashy_dashy_1_qgza68hnz4n1qvyz3iohynx05_memory_usage_percentage-state]
@@ -440,7 +440,7 @@
'attributes': ReadOnlyDict({
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'dashy_dashy.1.qgza68hnz4n1qvyz3iohynx05 Memory usage percentage',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'context': <ANY>,
'entity_id': 'sensor.dashy_dashy_1_qgza68hnz4n1qvyz3iohynx05_memory_usage_percentage',
@@ -730,7 +730,7 @@
'supported_features': 0,
'translation_key': 'cpu_usage_total',
'unique_id': 'portainer_test_entry_123_focused_einstein_cpu_usage_total',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
})
# ---
# name: test_all_entities[sensor.focused_einstein_cpu_usage_total-state]
@@ -738,7 +738,7 @@
'attributes': ReadOnlyDict({
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'focused_einstein CPU usage total',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'context': <ANY>,
'entity_id': 'sensor.focused_einstein_cpu_usage_total',
@@ -959,7 +959,7 @@
'supported_features': 0,
'translation_key': 'memory_usage_percentage',
'unique_id': 'portainer_test_entry_123_focused_einstein_memory_usage_percentage',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
})
# ---
# name: test_all_entities[sensor.focused_einstein_memory_usage_percentage-state]
@@ -967,7 +967,7 @@
'attributes': ReadOnlyDict({
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'focused_einstein Memory usage percentage',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'context': <ANY>,
'entity_id': 'sensor.focused_einstein_memory_usage_percentage',
@@ -1084,7 +1084,7 @@
'supported_features': 0,
'translation_key': 'cpu_usage_total',
'unique_id': 'portainer_test_entry_123_funny_chatelet_cpu_usage_total',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
})
# ---
# name: test_all_entities[sensor.funny_chatelet_cpu_usage_total-state]
@@ -1092,7 +1092,7 @@
'attributes': ReadOnlyDict({
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'funny_chatelet CPU usage total',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'context': <ANY>,
'entity_id': 'sensor.funny_chatelet_cpu_usage_total',
@@ -1313,7 +1313,7 @@
'supported_features': 0,
'translation_key': 'memory_usage_percentage',
'unique_id': 'portainer_test_entry_123_funny_chatelet_memory_usage_percentage',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
})
# ---
# name: test_all_entities[sensor.funny_chatelet_memory_usage_percentage-state]
@@ -1321,7 +1321,7 @@
'attributes': ReadOnlyDict({
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'funny_chatelet Memory usage percentage',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'context': <ANY>,
'entity_id': 'sensor.funny_chatelet_memory_usage_percentage',
@@ -2533,7 +2533,7 @@
'supported_features': 0,
'translation_key': 'cpu_usage_total',
'unique_id': 'portainer_test_entry_123_practical_morse_cpu_usage_total',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
})
# ---
# name: test_all_entities[sensor.practical_morse_cpu_usage_total-state]
@@ -2541,7 +2541,7 @@
'attributes': ReadOnlyDict({
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'practical_morse CPU usage total',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'context': <ANY>,
'entity_id': 'sensor.practical_morse_cpu_usage_total',
@@ -2762,7 +2762,7 @@
'supported_features': 0,
'translation_key': 'memory_usage_percentage',
'unique_id': 'portainer_test_entry_123_practical_morse_memory_usage_percentage',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
})
# ---
# name: test_all_entities[sensor.practical_morse_memory_usage_percentage-state]
@@ -2770,7 +2770,7 @@
'attributes': ReadOnlyDict({
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'practical_morse Memory usage percentage',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'context': <ANY>,
'entity_id': 'sensor.practical_morse_memory_usage_percentage',
@@ -2887,7 +2887,7 @@
'supported_features': 0,
'translation_key': 'cpu_usage_total',
'unique_id': 'portainer_test_entry_123_serene_banach_cpu_usage_total',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
})
# ---
# name: test_all_entities[sensor.serene_banach_cpu_usage_total-state]
@@ -2895,7 +2895,7 @@
'attributes': ReadOnlyDict({
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'serene_banach CPU usage total',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'context': <ANY>,
'entity_id': 'sensor.serene_banach_cpu_usage_total',
@@ -3116,7 +3116,7 @@
'supported_features': 0,
'translation_key': 'memory_usage_percentage',
'unique_id': 'portainer_test_entry_123_serene_banach_memory_usage_percentage',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
})
# ---
# name: test_all_entities[sensor.serene_banach_memory_usage_percentage-state]
@@ -3124,7 +3124,7 @@
'attributes': ReadOnlyDict({
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'serene_banach Memory usage percentage',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'context': <ANY>,
'entity_id': 'sensor.serene_banach_memory_usage_percentage',
@@ -3241,7 +3241,7 @@
'supported_features': 0,
'translation_key': 'cpu_usage_total',
'unique_id': 'portainer_test_entry_123_stoic_turing_cpu_usage_total',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
})
# ---
# name: test_all_entities[sensor.stoic_turing_cpu_usage_total-state]
@@ -3249,7 +3249,7 @@
'attributes': ReadOnlyDict({
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'stoic_turing CPU usage total',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'context': <ANY>,
'entity_id': 'sensor.stoic_turing_cpu_usage_total',
@@ -3470,7 +3470,7 @@
'supported_features': 0,
'translation_key': 'memory_usage_percentage',
'unique_id': 'portainer_test_entry_123_stoic_turing_memory_usage_percentage',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
})
# ---
# name: test_all_entities[sensor.stoic_turing_memory_usage_percentage-state]
@@ -3478,7 +3478,7 @@
'attributes': ReadOnlyDict({
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'stoic_turing Memory usage percentage',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'context': <ANY>,
'entity_id': 'sensor.stoic_turing_memory_usage_percentage',
@@ -267,7 +267,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': 'ctd_000001_94-1',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
})
# ---
# name: test_sensor[sensor.kitchen_vochtigheid_keuken-state]
@@ -276,7 +276,7 @@
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'humidity',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Vochtigheid Keuken',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'context': <ANY>,
'entity_id': 'sensor.kitchen_vochtigheid_keuken',
@@ -441,7 +441,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': 'ctd_000001_224',
'unit_of_measurement': <UnitOfRatio.PARTS_PER_MILLION: 'ppm'>,
'unit_of_measurement': 'ppm',
})
# ---
# name: test_sensor[sensor.luchtsensor-state]
@@ -450,7 +450,7 @@
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'carbon_dioxide',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Luchtsensor',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PARTS_PER_MILLION: 'ppm'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: 'ppm',
}),
'context': <ANY>,
'entity_id': 'sensor.luchtsensor',
@@ -615,7 +615,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': 'ctd_000001_82',
'unit_of_measurement': <UnitOfRatio.PARTS_PER_MILLION: 'ppm'>,
'unit_of_measurement': 'ppm',
})
# ---
# name: test_sensor[sensor.tuin_luchtkwaliteit-state]
@@ -624,7 +624,7 @@
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'carbon_dioxide',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Luchtkwaliteit',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PARTS_PER_MILLION: 'ppm'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: 'ppm',
}),
'context': <ANY>,
'entity_id': 'sensor.tuin_luchtkwaliteit',
@@ -4765,46 +4765,3 @@ async def test_import_statistics_with_last_reset(
},
]
}
async def test_entity_options_ws(
hass: HomeAssistant,
async_setup_recorder_instance: RecorderInstanceGenerator,
hass_ws_client: WebSocketGenerator,
) -> None:
"""Test recorder entity options WS commands."""
client = await hass_ws_client()
await async_setup_recorder_instance(hass, {"exclude": {"domains": "test2"}})
# Test getting a single entity's settings
await client.send_json_auto_id(
{
"type": "recorder/entity_options/get",
"entity_id": "test.recorder",
}
)
response = await client.receive_json()
assert response["success"]
assert response["result"] == {"recording_disabled_by": None}
await client.send_json_auto_id(
{
"type": "recorder/entity_options/get",
"entity_id": "test2.recorder",
}
)
response = await client.receive_json()
assert response["success"]
assert response["result"] == {"recording_disabled_by": "user"}
# Test getting settings for an unknown entity
await client.send_json_auto_id(
{
"type": "recorder/entity_options/get",
"entity_id": "unknown.entity",
}
)
response = await client.receive_json()
assert response["success"]
assert response["result"] == {"recording_disabled_by": None}
+97 -174
View File
@@ -16,11 +16,8 @@ from homeassistant.util import dt as dt_util
from tests.typing import WebSocketGenerator
# San Diego (default test location), Kotzebue, Alaska (just inside the Arctic
# Circle - brief midnight sun in June) and Longyearbyen, Svalbard (deep polar -
# long polar night in December).
# San Diego (default test location) and Longyearbyen, Svalbard (deep polar).
_SAN_DIEGO = (32.87336, -117.22743, "US/Pacific")
_KOTZEBUE = (66.8983, -162.5966, "America/Anchorage")
_SVALBARD = (78.22, 15.65, "Europe/Oslo")
_TWILIGHT_TYPES = ("any", "civil", "nautical", "astronomical")
@@ -41,8 +38,8 @@ def _find_run_id(traces, trace_type, item_id):
return None
async def _get_automation_condition_trace(hass_ws_client, automation_id):
"""Return the condition trace for a given automation."""
async def assert_automation_condition_trace(hass_ws_client, automation_id, expected):
"""Test the result of automation condition."""
msg_id = 1
def next_id():
@@ -74,25 +71,8 @@ async def _get_automation_condition_trace(hass_ws_client, automation_id):
assert response["success"]
trace = response["result"]
assert len(trace["trace"]["condition/0"]) == 1
return trace["trace"]["condition/0"][0]
async def assert_automation_condition_trace(hass_ws_client, automation_id, expected):
"""Test the result of automation condition."""
condition_trace = await _get_automation_condition_trace(
hass_ws_client, automation_id
)
assert condition_trace["result"] == expected
async def assert_automation_condition_trace_error(
hass_ws_client, automation_id, expected
):
"""Test the error of automation condition."""
condition_trace = await _get_automation_condition_trace(
hass_ws_client, automation_id
)
assert condition_trace["error"] == expected
condition_trace = trace["trace"]["condition/0"][0]["result"]
assert condition_trace == expected
async def test_if_action_before_sunrise_no_offset(
@@ -957,14 +937,14 @@ async def test_if_action_before_sunrise_no_offset_kotzebue(
) -> None:
"""Test if action was before sunrise.
Local timezone: Alaska time (America/Anchorage)
Location: Kotzebue, Alaska, whose far-west longitude skews local time by
~3 hours, so in late July sunrise is ~04:48 local. Before sunrise is true
from local midnight until sunrise.
Local timezone: Alaska time
Location: Kotzebue, which has a very skewed local timezone with sunrise
at 7 AM and sunset at 3AM during summer
After sunrise is true from sunrise until midnight, local time.
"""
await hass.config.async_set_time_zone("America/Anchorage")
hass.config.latitude = 66.8983
hass.config.longitude = -162.5966
hass.config.latitude = 66.5
hass.config.longitude = 162.4
await async_setup_component(
hass,
automation.DOMAIN,
@@ -981,9 +961,10 @@ async def test_if_action_before_sunrise_no_offset_kotzebue(
},
)
# sunrise: 2015-07-24 04:48:24 local = 2015-07-24 12:48:24 UTC
# sunrise: 2015-07-24 07:21:12 local, sunset: 2015-07-25 03:13:33 local
# sunrise: 2015-07-24 15:21:12 UTC, sunset: 2015-07-25 11:13:33 UTC
# now = sunrise + 1s -> 'before sunrise' not true
now = datetime(2015, 7, 24, 12, 48, 25, tzinfo=dt_util.UTC)
now = datetime(2015, 7, 24, 15, 21, 13, tzinfo=dt_util.UTC)
with freeze_time(now):
hass.bus.async_fire("test_event")
await hass.async_block_till_done()
@@ -991,11 +972,11 @@ async def test_if_action_before_sunrise_no_offset_kotzebue(
await assert_automation_condition_trace(
hass_ws_client,
"sun",
{"result": False, "wanted_time_before": "2015-07-24T12:48:24.249497+00:00"},
{"result": False, "wanted_time_before": "2015-07-24T15:16:46.975735+00:00"},
)
# now = sunrise - 1h -> 'before sunrise' true
now = datetime(2015, 7, 24, 11, 48, 24, tzinfo=dt_util.UTC)
now = datetime(2015, 7, 24, 14, 21, 12, tzinfo=dt_util.UTC)
with freeze_time(now):
hass.bus.async_fire("test_event")
await hass.async_block_till_done()
@@ -1003,7 +984,7 @@ async def test_if_action_before_sunrise_no_offset_kotzebue(
await assert_automation_condition_trace(
hass_ws_client,
"sun",
{"result": True, "wanted_time_before": "2015-07-24T12:48:24.249497+00:00"},
{"result": True, "wanted_time_before": "2015-07-24T15:16:46.975735+00:00"},
)
# now = local midnight -> 'before sunrise' true
@@ -1015,7 +996,7 @@ async def test_if_action_before_sunrise_no_offset_kotzebue(
await assert_automation_condition_trace(
hass_ws_client,
"sun",
{"result": True, "wanted_time_before": "2015-07-24T12:48:24.249497+00:00"},
{"result": True, "wanted_time_before": "2015-07-24T15:16:46.975735+00:00"},
)
# now = local midnight - 1s -> 'before sunrise' not true
@@ -1027,7 +1008,7 @@ async def test_if_action_before_sunrise_no_offset_kotzebue(
await assert_automation_condition_trace(
hass_ws_client,
"sun",
{"result": False, "wanted_time_before": "2015-07-23T12:43:32.413351+00:00"},
{"result": False, "wanted_time_before": "2015-07-23T15:12:19.155123+00:00"},
)
@@ -1038,14 +1019,14 @@ async def test_if_action_after_sunrise_no_offset_kotzebue(
) -> None:
"""Test if action was after sunrise.
Local timezone: Alaska time (America/Anchorage)
Location: Kotzebue, Alaska, whose far-west longitude skews local time by
~3 hours, so in late July sunrise is ~04:48 local. After sunrise is true
from sunrise until local midnight.
Local timezone: Alaska time
Location: Kotzebue, which has a very skewed local timezone with sunrise
at 7 AM and sunset at 3AM during summer
Before sunrise is true from midnight until sunrise, local time.
"""
await hass.config.async_set_time_zone("America/Anchorage")
hass.config.latitude = 66.8983
hass.config.longitude = -162.5966
hass.config.latitude = 66.5
hass.config.longitude = 162.4
await async_setup_component(
hass,
automation.DOMAIN,
@@ -1062,9 +1043,10 @@ async def test_if_action_after_sunrise_no_offset_kotzebue(
},
)
# sunrise: 2015-07-24 04:48:24 local = 2015-07-24 12:48:24 UTC
# now = sunrise + 1s -> 'after sunrise' true
now = datetime(2015, 7, 24, 12, 48, 25, tzinfo=dt_util.UTC)
# sunrise: 2015-07-24 07:21:12 local, sunset: 2015-07-25 03:13:33 local
# sunrise: 2015-07-24 15:21:12 UTC, sunset: 2015-07-25 11:13:33 UTC
# now = sunrise -> 'after sunrise' true
now = datetime(2015, 7, 24, 15, 21, 12, tzinfo=dt_util.UTC)
with freeze_time(now):
hass.bus.async_fire("test_event")
await hass.async_block_till_done()
@@ -1072,11 +1054,11 @@ async def test_if_action_after_sunrise_no_offset_kotzebue(
await assert_automation_condition_trace(
hass_ws_client,
"sun",
{"result": True, "wanted_time_after": "2015-07-24T12:48:24.249497+00:00"},
{"result": True, "wanted_time_after": "2015-07-24T15:16:46.975735+00:00"},
)
# now = sunrise - 1h -> 'after sunrise' not true
now = datetime(2015, 7, 24, 11, 48, 24, tzinfo=dt_util.UTC)
now = datetime(2015, 7, 24, 14, 21, 12, tzinfo=dt_util.UTC)
with freeze_time(now):
hass.bus.async_fire("test_event")
await hass.async_block_till_done()
@@ -1084,7 +1066,7 @@ async def test_if_action_after_sunrise_no_offset_kotzebue(
await assert_automation_condition_trace(
hass_ws_client,
"sun",
{"result": False, "wanted_time_after": "2015-07-24T12:48:24.249497+00:00"},
{"result": False, "wanted_time_after": "2015-07-24T15:16:46.975735+00:00"},
)
# now = local midnight -> 'after sunrise' not true
@@ -1096,7 +1078,7 @@ async def test_if_action_after_sunrise_no_offset_kotzebue(
await assert_automation_condition_trace(
hass_ws_client,
"sun",
{"result": False, "wanted_time_after": "2015-07-24T12:48:24.249497+00:00"},
{"result": False, "wanted_time_after": "2015-07-24T15:16:46.975735+00:00"},
)
# now = local midnight - 1s -> 'after sunrise' true
@@ -1108,7 +1090,7 @@ async def test_if_action_after_sunrise_no_offset_kotzebue(
await assert_automation_condition_trace(
hass_ws_client,
"sun",
{"result": True, "wanted_time_after": "2015-07-23T12:43:32.413351+00:00"},
{"result": True, "wanted_time_after": "2015-07-23T15:12:19.155123+00:00"},
)
@@ -1117,17 +1099,16 @@ async def test_if_action_before_sunset_no_offset_kotzebue(
hass_ws_client: WebSocketGenerator,
service_calls: list[ServiceCall],
) -> None:
"""Test if action was before sunset on a day with two sunsets.
"""Test if action was before sunrise.
Local timezone: Alaska time (America/Anchorage)
Location: Kotzebue, Alaska. On 2015-08-07 (local) the sun sets twice - at
00:03 and again at 23:59 - because solar midnight falls near local midnight.
The condition tracks the day's (late) sunset, so 'before sunset' stays true
across the early sunset and only turns false after the late one.
Local timezone: Alaska time
Location: Kotzebue, which has a very skewed local timezone with sunrise
at 7 AM and sunset at 3AM during summer
Before sunset is true from midnight until sunset, local time.
"""
await hass.config.async_set_time_zone("America/Anchorage")
hass.config.latitude = 66.8983
hass.config.longitude = -162.5966
hass.config.latitude = 66.5
hass.config.longitude = 162.4
await async_setup_component(
hass,
automation.DOMAIN,
@@ -1144,9 +1125,22 @@ async def test_if_action_before_sunset_no_offset_kotzebue(
},
)
# 2015-08-07 local has two sunsets: 00:03 (08:03 UTC) and 23:59 (08-08 07:59 UTC)
# now = local midnight -> 'before sunset' true
now = datetime(2015, 8, 7, 8, 0, 0, tzinfo=dt_util.UTC)
# sunrise: 2015-07-24 07:21:12 local, sunset: 2015-07-25 03:13:33 local
# sunrise: 2015-07-24 15:21:12 UTC, sunset: 2015-07-25 11:13:33 UTC
# now = sunset + 1s -> 'before sunset' not true
now = datetime(2015, 7, 25, 11, 13, 34, tzinfo=dt_util.UTC)
with freeze_time(now):
hass.bus.async_fire("test_event")
await hass.async_block_till_done()
assert len(service_calls) == 0
await assert_automation_condition_trace(
hass_ws_client,
"sun",
{"result": False, "wanted_time_before": "2015-07-25T11:13:32.501837+00:00"},
)
# now = sunset - 1h-> 'before sunset' true
now = datetime(2015, 7, 25, 10, 13, 33, tzinfo=dt_util.UTC)
with freeze_time(now):
hass.bus.async_fire("test_event")
await hass.async_block_till_done()
@@ -1154,11 +1148,11 @@ async def test_if_action_before_sunset_no_offset_kotzebue(
await assert_automation_condition_trace(
hass_ws_client,
"sun",
{"result": True, "wanted_time_before": "2015-08-08T07:59:25.982224+00:00"},
{"result": True, "wanted_time_before": "2015-07-25T11:13:32.501837+00:00"},
)
# now = first (early) sunset + 1s -> still 'before sunset' (tracks the late one)
now = datetime(2015, 8, 7, 8, 3, 43, tzinfo=dt_util.UTC)
# now = local midnight -> 'before sunrise' true
now = datetime(2015, 7, 24, 8, 0, 0, tzinfo=dt_util.UTC)
with freeze_time(now):
hass.bus.async_fire("test_event")
await hass.async_block_till_done()
@@ -1166,31 +1160,19 @@ async def test_if_action_before_sunset_no_offset_kotzebue(
await assert_automation_condition_trace(
hass_ws_client,
"sun",
{"result": True, "wanted_time_before": "2015-08-08T07:59:25.982224+00:00"},
{"result": True, "wanted_time_before": "2015-07-24T11:17:54.446913+00:00"},
)
# now = late sunset - 1h -> 'before sunset' true
now = datetime(2015, 8, 8, 6, 59, 25, tzinfo=dt_util.UTC)
# now = local midnight - 1s -> 'before sunrise' not true
now = datetime(2015, 7, 24, 7, 59, 59, tzinfo=dt_util.UTC)
with freeze_time(now):
hass.bus.async_fire("test_event")
await hass.async_block_till_done()
assert len(service_calls) == 3
assert len(service_calls) == 2
await assert_automation_condition_trace(
hass_ws_client,
"sun",
{"result": True, "wanted_time_before": "2015-08-08T07:59:25.982224+00:00"},
)
# now = late sunset + 1s -> 'before sunset' not true
now = datetime(2015, 8, 8, 7, 59, 26, tzinfo=dt_util.UTC)
with freeze_time(now):
hass.bus.async_fire("test_event")
await hass.async_block_till_done()
assert len(service_calls) == 3
await assert_automation_condition_trace(
hass_ws_client,
"sun",
{"result": False, "wanted_time_before": "2015-08-08T07:59:25.982224+00:00"},
{"result": False, "wanted_time_before": "2015-07-23T11:22:18.467277+00:00"},
)
@@ -1199,17 +1181,16 @@ async def test_if_action_after_sunset_no_offset_kotzebue(
hass_ws_client: WebSocketGenerator,
service_calls: list[ServiceCall],
) -> None:
"""Test if action was after sunset on a day with two sunsets.
"""Test if action was after sunrise.
Local timezone: Alaska time (America/Anchorage)
Location: Kotzebue, Alaska. On 2015-08-07 (local) the sun sets twice - at
00:03 and again at 23:59. The condition tracks the day's (late) sunset, so
'after sunset' is false right after the early sunset and only true in the
short window after the late sunset before local midnight.
Local timezone: Alaska time
Location: Kotzebue, which has a very skewed local timezone with sunrise
at 7 AM and sunset at 3AM during summer
After sunset is true from sunset until midnight, local time.
"""
await hass.config.async_set_time_zone("America/Anchorage")
hass.config.latitude = 66.8983
hass.config.longitude = -162.5966
hass.config.latitude = 66.5
hass.config.longitude = 162.4
await async_setup_component(
hass,
automation.DOMAIN,
@@ -1226,33 +1207,10 @@ async def test_if_action_after_sunset_no_offset_kotzebue(
},
)
# 2015-08-07 local has two sunsets: 00:03 (08:03 UTC) and 23:59 (08-08 07:59 UTC)
# now = first (early) sunset + 1s -> 'after sunset' not true (tracks the late one)
now = datetime(2015, 8, 7, 8, 4, 0, tzinfo=dt_util.UTC)
with freeze_time(now):
hass.bus.async_fire("test_event")
await hass.async_block_till_done()
assert len(service_calls) == 0
await assert_automation_condition_trace(
hass_ws_client,
"sun",
{"result": False, "wanted_time_after": "2015-08-08T07:59:25.982224+00:00"},
)
# now = late sunset - 1s -> 'after sunset' not true
now = datetime(2015, 8, 8, 7, 59, 25, tzinfo=dt_util.UTC)
with freeze_time(now):
hass.bus.async_fire("test_event")
await hass.async_block_till_done()
assert len(service_calls) == 0
await assert_automation_condition_trace(
hass_ws_client,
"sun",
{"result": False, "wanted_time_after": "2015-08-08T07:59:25.982224+00:00"},
)
# now = late sunset + 1s -> 'after sunset' true
now = datetime(2015, 8, 8, 7, 59, 27, tzinfo=dt_util.UTC)
# sunrise: 2015-07-24 07:21:12 local, sunset: 2015-07-25 03:13:33 local
# sunrise: 2015-07-24 15:21:12 UTC, sunset: 2015-07-25 11:13:33 UTC
# now = sunset -> 'after sunset' true
now = datetime(2015, 7, 25, 11, 13, 33, tzinfo=dt_util.UTC)
with freeze_time(now):
hass.bus.async_fire("test_event")
await hass.async_block_till_done()
@@ -1260,11 +1218,11 @@ async def test_if_action_after_sunset_no_offset_kotzebue(
await assert_automation_condition_trace(
hass_ws_client,
"sun",
{"result": True, "wanted_time_after": "2015-08-08T07:59:25.982224+00:00"},
{"result": True, "wanted_time_after": "2015-07-25T11:13:32.501837+00:00"},
)
# now = local midnight (next day) -> 'after sunset' not true
now = datetime(2015, 8, 8, 8, 0, 1, tzinfo=dt_util.UTC)
# now = sunset - 1s -> 'after sunset' not true
now = datetime(2015, 7, 25, 11, 13, 32, tzinfo=dt_util.UTC)
with freeze_time(now):
hass.bus.async_fire("test_event")
await hass.async_block_till_done()
@@ -1272,66 +1230,31 @@ async def test_if_action_after_sunset_no_offset_kotzebue(
await assert_automation_condition_trace(
hass_ws_client,
"sun",
{"result": False, "wanted_time_after": "2015-08-09T07:55:10.646523+00:00"},
)
@pytest.mark.parametrize(
("location", "now", "event"),
[
# Midnight sun at Kotzebue (early June to early July): the sun neither
# rises nor sets, so neither a sunrise nor a sunset condition can be met.
(_KOTZEBUE, datetime(2015, 6, 15, 12, tzinfo=dt_util.UTC), SUN_EVENT_SUNSET),
(_KOTZEBUE, datetime(2015, 6, 15, 12, tzinfo=dt_util.UTC), SUN_EVENT_SUNRISE),
# Polar night at Svalbard: the sun neither rises nor sets here either.
(_SVALBARD, datetime(2015, 12, 15, 12, tzinfo=dt_util.UTC), SUN_EVENT_SUNSET),
(_SVALBARD, datetime(2015, 12, 15, 12, tzinfo=dt_util.UTC), SUN_EVENT_SUNRISE),
],
)
async def test_if_action_no_sun_event_in_polar_regions(
hass: HomeAssistant,
hass_ws_client: WebSocketGenerator,
service_calls: list[ServiceCall],
location: tuple[float, float, str],
now: datetime,
event: str,
) -> None:
"""Test a sun condition where the requested event never occurs.
During midnight sun and polar night the sun neither rises nor sets, so
``get_astral_event_date`` returns None for both events. This documents the
legacy condition crashing on the missing event (it passes None to
``dt_util.as_local``); the crash fix and the matching "no sunrise/sunset
today" results are a follow-up.
"""
latitude, longitude, time_zone = location
await hass.config.async_set_time_zone(time_zone)
hass.config.latitude = latitude
hass.config.longitude = longitude
await async_setup_component(
hass,
automation.DOMAIN,
{
automation.DOMAIN: {
"id": "sun",
"trigger": {"platform": "event", "event_type": "test_event"},
"condition": {
"condition": "sun",
"options": {"after": event},
},
"action": {"service": "test.automation"},
}
},
{"result": False, "wanted_time_after": "2015-07-25T11:13:32.501837+00:00"},
)
# now = local midnight -> 'after sunset' not true
now = datetime(2015, 7, 24, 8, 0, 1, tzinfo=dt_util.UTC)
with freeze_time(now):
hass.bus.async_fire("test_event")
await hass.async_block_till_done()
assert len(service_calls) == 0
await assert_automation_condition_trace_error(
assert len(service_calls) == 1
await assert_automation_condition_trace(
hass_ws_client,
"sun",
"'NoneType' object has no attribute 'tzinfo'",
{"result": False, "wanted_time_after": "2015-07-24T11:17:54.446913+00:00"},
)
# now = local midnight - 1s -> 'after sunset' true
now = datetime(2015, 7, 24, 7, 59, 59, tzinfo=dt_util.UTC)
with freeze_time(now):
hass.bus.async_fire("test_event")
await hass.async_block_till_done()
assert len(service_calls) == 2
await assert_automation_condition_trace(
hass_ws_client,
"sun",
{"result": True, "wanted_time_after": "2015-07-23T11:22:18.467277+00:00"},
)
-41
View File
@@ -346,12 +346,6 @@ async def test_dawn_defaults_to_civil(
_SVALBARD = (78.22, 15.65, "Europe/Oslo")
_KOTZEBUE = (66.8983, -162.5966, "America/Anchorage")
# A two-sunrise day is the mirror of Kotzebue's two-sunset day: it needs solar
# noon (not midnight) near local midnight, which no real location has because
# time zones keep solar noon near local noon. This synthetic location forces it
# with a polar latitude on a deliberately ~12 h-offset time zone.
_TWO_SUNRISE_LOCATION = (66.5, -32.5, "America/Anchorage")
@pytest.mark.parametrize(
("location", "now", "trigger_key", "astral_event", "options", "depression"),
@@ -458,41 +452,6 @@ async def test_two_sunsets_on_one_day_at_kotzebue(
assert len(service_calls) == 2
async def test_two_sunrises_on_one_day(
hass: HomeAssistant, service_calls: list[ServiceCall]
) -> None:
"""Test both sunrises fire on a calendar day that has two.
The mirror of the two-sunset case: a synthetic polar location on a
deliberately offset time zone puts solar noon near local midnight, so
2015-03-07 (local) has two sunrises ~24 h apart - one just after midnight
and one just before - and the scheduler must fire for both.
"""
latitude, longitude, time_zone = _TWO_SUNRISE_LOCATION
await hass.config.async_set_time_zone(time_zone)
await hass.config.async_update(latitude=latitude, longitude=longitude, elevation=0)
# 2015-03-07 09:02:36 UTC (00:02 local) and 2015-03-08 08:58:43 UTC (23:58 local)
now = datetime(2015, 3, 7, 9, tzinfo=dt_util.UTC)
with freeze_time(now) as freezer:
await _arm_automation(hass, {"platform": "sun.sunrise"}, {})
first = get_astral_event_next(hass, "sunrise", now)
second = get_astral_event_next(hass, "sunrise", first)
# Two sunrises ~24 h apart that share one local calendar day.
assert dt_util.as_local(first).date() == dt_util.as_local(second).date()
assert timedelta(hours=23) < second - first < timedelta(hours=25)
freezer.move_to(first + timedelta(seconds=1))
async_fire_time_changed(hass, first + timedelta(seconds=1))
await hass.async_block_till_done()
assert len(service_calls) == 1
freezer.move_to(second + timedelta(seconds=1))
async_fire_time_changed(hass, second + timedelta(seconds=1))
await hass.async_block_till_done()
assert len(service_calls) == 2
@pytest.mark.parametrize(
("trigger_key", "astral_event", "now", "above_horizon"),
[
@@ -147,7 +147,7 @@
'supported_features': 0,
'translation_key': 'burner_modulation',
'unique_id': 'gateway0_deviceSerialVitodens300W-burner_modulation-0',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
})
# ---
# name: test_all_entities[sensor.model0_burner_modulation-state]
@@ -155,7 +155,7 @@
'attributes': ReadOnlyDict({
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'model0 Burner modulation',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'context': <ANY>,
'entity_id': 'sensor.model0_burner_modulation',
@@ -1200,7 +1200,7 @@
'supported_features': 0,
'translation_key': 'zigbee_signal_strength',
'unique_id': 'gateway10_zigbee_################-zigbee_signal_strength',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
})
# ---
# name: test_all_entities[sensor.model10_signal_strength-state]
@@ -1208,7 +1208,7 @@
'attributes': ReadOnlyDict({
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'model10 Signal strength',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'context': <ANY>,
'entity_id': 'sensor.model10_signal_strength',
@@ -1254,7 +1254,7 @@
'supported_features': 0,
'translation_key': 'zigbee_signal_strength',
'unique_id': 'gateway11_zigbee_################-zigbee_signal_strength',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
})
# ---
# name: test_all_entities[sensor.model11_signal_strength-state]
@@ -1262,7 +1262,7 @@
'attributes': ReadOnlyDict({
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'model11 Signal strength',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'context': <ANY>,
'entity_id': 'sensor.model11_signal_strength',
@@ -5389,7 +5389,7 @@
'supported_features': 0,
'translation_key': 'primary_circuit_pump_rotation',
'unique_id': 'gateway2_################-primary_circuit_pump_rotation',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
})
# ---
# name: test_all_entities[sensor.model2_primary_circuit_pump_rotation-state]
@@ -5397,7 +5397,7 @@
'attributes': ReadOnlyDict({
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'model2 Primary circuit pump rotation',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'context': <ANY>,
'entity_id': 'sensor.model2_primary_circuit_pump_rotation',
@@ -6387,7 +6387,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': 'gateway4_deviceId4-pm01',
'unit_of_measurement': <UnitOfDensity.MICROGRAMS_PER_CUBIC_METER: 'μg/m³'>,
'unit_of_measurement': 'μg/m³',
})
# ---
# name: test_all_entities[sensor.model4_pm1-state]
@@ -6396,7 +6396,7 @@
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'pm1',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'model4 PM1',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfDensity.MICROGRAMS_PER_CUBIC_METER: 'μg/m³'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: 'μg/m³',
}),
'context': <ANY>,
'entity_id': 'sensor.model4_pm1',
@@ -6442,7 +6442,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': 'gateway4_deviceId4-pm10',
'unit_of_measurement': <UnitOfDensity.MICROGRAMS_PER_CUBIC_METER: 'μg/m³'>,
'unit_of_measurement': 'μg/m³',
})
# ---
# name: test_all_entities[sensor.model4_pm10-state]
@@ -6451,7 +6451,7 @@
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'pm10',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'model4 PM10',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfDensity.MICROGRAMS_PER_CUBIC_METER: 'μg/m³'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: 'μg/m³',
}),
'context': <ANY>,
'entity_id': 'sensor.model4_pm10',
@@ -6497,7 +6497,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': 'gateway4_deviceId4-pm02',
'unit_of_measurement': <UnitOfDensity.MICROGRAMS_PER_CUBIC_METER: 'μg/m³'>,
'unit_of_measurement': 'μg/m³',
})
# ---
# name: test_all_entities[sensor.model4_pm2_5-state]
@@ -6506,7 +6506,7 @@
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'pm25',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'model4 PM2.5',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfDensity.MICROGRAMS_PER_CUBIC_METER: 'μg/m³'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: 'μg/m³',
}),
'context': <ANY>,
'entity_id': 'sensor.model4_pm2_5',
@@ -6552,7 +6552,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': 'gateway4_deviceId4-pm04',
'unit_of_measurement': <UnitOfDensity.MICROGRAMS_PER_CUBIC_METER: 'μg/m³'>,
'unit_of_measurement': 'μg/m³',
})
# ---
# name: test_all_entities[sensor.model4_pm4-state]
@@ -6561,7 +6561,7 @@
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'pm4',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'model4 PM4',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfDensity.MICROGRAMS_PER_CUBIC_METER: 'μg/m³'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: 'μg/m³',
}),
'context': <ANY>,
'entity_id': 'sensor.model4_pm4',
@@ -6770,7 +6770,7 @@
'supported_features': 0,
'translation_key': 'supply_humidity',
'unique_id': 'gateway4_deviceId4-supply_humidity',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
})
# ---
# name: test_all_entities[sensor.model4_supply_humidity-state]
@@ -6779,7 +6779,7 @@
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'humidity',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'model4 Supply humidity',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'context': <ANY>,
'entity_id': 'sensor.model4_supply_humidity',
@@ -7075,7 +7075,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': 'gateway7_zigbee_d87a3bfffe5d844a-battery_level',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
})
# ---
# name: test_all_entities[sensor.model7_battery-state]
@@ -7084,7 +7084,7 @@
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'battery',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'model7 Battery',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'context': <ANY>,
'entity_id': 'sensor.model7_battery',
@@ -7130,7 +7130,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': 'gateway7_zigbee_d87a3bfffe5d844a-room_humidity',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
})
# ---
# name: test_all_entities[sensor.model7_humidity-state]
@@ -7139,7 +7139,7 @@
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'humidity',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'model7 Humidity',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'context': <ANY>,
'entity_id': 'sensor.model7_humidity',
@@ -7243,7 +7243,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': 'gateway8_zigbee_5cc7c1fffea33a3b-room_humidity',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
})
# ---
# name: test_all_entities[sensor.model8_humidity-state]
@@ -7252,7 +7252,7 @@
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'humidity',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'model8 Humidity',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'context': <ANY>,
'entity_id': 'sensor.model8_humidity',
@@ -7356,7 +7356,7 @@
'supported_features': 0,
'translation_key': None,
'unique_id': 'gateway9_zigbee_################-battery_level',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
})
# ---
# name: test_all_entities[sensor.model9_battery-state]
@@ -7365,7 +7365,7 @@
<EntityStateAttribute.DEVICE_CLASS: 'device_class'>: 'battery',
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'model9 Battery',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'context': <ANY>,
'entity_id': 'sensor.model9_battery',
@@ -7411,7 +7411,7 @@
'supported_features': 0,
'translation_key': 'zigbee_signal_strength',
'unique_id': 'gateway9_zigbee_################-zigbee_signal_strength',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
})
# ---
# name: test_all_entities[sensor.model9_signal_strength-state]
@@ -7419,7 +7419,7 @@
'attributes': ReadOnlyDict({
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'model9 Signal strength',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'context': <ANY>,
'entity_id': 'sensor.model9_signal_strength',
@@ -7581,7 +7581,7 @@
'supported_features': 0,
'translation_key': 'valve_position',
'unique_id': 'gateway9_zigbee_################-valve_position',
'unit_of_measurement': <UnitOfRatio.PERCENTAGE: '%'>,
'unit_of_measurement': '%',
})
# ---
# name: test_all_entities[sensor.model9_valve_position-state]
@@ -7589,7 +7589,7 @@
'attributes': ReadOnlyDict({
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'model9 Valve position',
<SensorEntityCapabilityAttribute.STATE_CLASS: 'state_class'>: <SensorStateClass.MEASUREMENT: 'measurement'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: <UnitOfRatio.PERCENTAGE: '%'>,
<EntityStateAttribute.UNIT_OF_MEASUREMENT: 'unit_of_measurement'>: '%',
}),
'context': <ANY>,
'entity_id': 'sensor.model9_valve_position',