mirror of
https://github.com/home-assistant/core.git
synced 2026-01-21 06:57:01 +01:00
Compare commits
1 Commits
dev
...
script_rel
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7011280517 |
@@ -604,7 +604,7 @@ class AutomationEntity(BaseAutomationEntity, RestoreEntity):
|
||||
|
||||
if self._cond_func is not None:
|
||||
for conf in self._cond_func.config:
|
||||
referenced |= condition.async_extract_labels(conf)
|
||||
referenced |= condition.async_extract_targets(conf, ATTR_LABEL_ID)
|
||||
|
||||
for conf in self._trigger_config:
|
||||
referenced |= set(_get_targets_from_trigger_config(conf, ATTR_LABEL_ID))
|
||||
@@ -617,7 +617,7 @@ class AutomationEntity(BaseAutomationEntity, RestoreEntity):
|
||||
|
||||
if self._cond_func is not None:
|
||||
for conf in self._cond_func.config:
|
||||
referenced |= condition.async_extract_floors(conf)
|
||||
referenced |= condition.async_extract_targets(conf, ATTR_FLOOR_ID)
|
||||
|
||||
for conf in self._trigger_config:
|
||||
referenced |= set(_get_targets_from_trigger_config(conf, ATTR_FLOOR_ID))
|
||||
@@ -630,7 +630,7 @@ class AutomationEntity(BaseAutomationEntity, RestoreEntity):
|
||||
|
||||
if self._cond_func is not None:
|
||||
for conf in self._cond_func.config:
|
||||
referenced |= condition.async_extract_areas(conf)
|
||||
referenced |= condition.async_extract_targets(conf, ATTR_AREA_ID)
|
||||
|
||||
for conf in self._trigger_config:
|
||||
referenced |= set(_get_targets_from_trigger_config(conf, ATTR_AREA_ID))
|
||||
|
||||
@@ -18,6 +18,9 @@
|
||||
},
|
||||
"ozone": {
|
||||
"default": "mdi:molecule"
|
||||
},
|
||||
"sulphur_dioxide": {
|
||||
"default": "mdi:molecule"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,8 +173,8 @@ AIR_QUALITY_SENSOR_TYPES: tuple[AirQualitySensorEntityDescription, ...] = (
|
||||
),
|
||||
AirQualitySensorEntityDescription(
|
||||
key="so2",
|
||||
translation_key="sulphur_dioxide",
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
device_class=SensorDeviceClass.SULPHUR_DIOXIDE,
|
||||
native_unit_of_measurement_fn=lambda x: x.pollutants.so2.concentration.units,
|
||||
exists_fn=lambda x: "so2" in {p.code for p in x.pollutants},
|
||||
value_fn=lambda x: x.pollutants.so2.concentration.value,
|
||||
|
||||
@@ -217,6 +217,9 @@
|
||||
"ozone": {
|
||||
"name": "[%key:component::sensor::entity_component::ozone::name%]"
|
||||
},
|
||||
"sulphur_dioxide": {
|
||||
"name": "[%key:component::sensor::entity_component::sulphur_dioxide::name%]"
|
||||
},
|
||||
"uaqi": {
|
||||
"name": "Universal Air Quality Index"
|
||||
},
|
||||
|
||||
@@ -7,5 +7,5 @@
|
||||
"integration_type": "device",
|
||||
"iot_class": "local_polling",
|
||||
"loggers": ["kostal"],
|
||||
"requirements": ["pykoplenti==1.5.0"]
|
||||
"requirements": ["pykoplenti==1.3.0"]
|
||||
}
|
||||
|
||||
@@ -1,47 +1,24 @@
|
||||
"""Provides triggers for lights."""
|
||||
|
||||
from typing import Any
|
||||
|
||||
from homeassistant.const import STATE_OFF, STATE_ON
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.trigger import (
|
||||
EntityNumericalStateAttributeChangedTriggerBase,
|
||||
EntityNumericalStateAttributeCrossedThresholdTriggerBase,
|
||||
Trigger,
|
||||
make_entity_numerical_state_attribute_changed_trigger,
|
||||
make_entity_numerical_state_attribute_crossed_threshold_trigger,
|
||||
make_entity_target_state_trigger,
|
||||
)
|
||||
|
||||
from . import ATTR_BRIGHTNESS
|
||||
from .const import DOMAIN
|
||||
|
||||
|
||||
def _convert_uint8_to_percentage(value: Any) -> float:
|
||||
"""Convert a uint8 value (0-255) to a percentage (0-100)."""
|
||||
return (float(value) / 255.0) * 100.0
|
||||
|
||||
|
||||
class BrightnessChangedTrigger(EntityNumericalStateAttributeChangedTriggerBase):
|
||||
"""Trigger for brightness changed."""
|
||||
|
||||
_domain = DOMAIN
|
||||
_attribute = ATTR_BRIGHTNESS
|
||||
|
||||
_converter = staticmethod(_convert_uint8_to_percentage)
|
||||
|
||||
|
||||
class BrightnessCrossedThresholdTrigger(
|
||||
EntityNumericalStateAttributeCrossedThresholdTriggerBase
|
||||
):
|
||||
"""Trigger for brightness crossed threshold."""
|
||||
|
||||
_domain = DOMAIN
|
||||
_attribute = ATTR_BRIGHTNESS
|
||||
_converter = staticmethod(_convert_uint8_to_percentage)
|
||||
|
||||
|
||||
TRIGGERS: dict[str, type[Trigger]] = {
|
||||
"brightness_changed": BrightnessChangedTrigger,
|
||||
"brightness_crossed_threshold": BrightnessCrossedThresholdTrigger,
|
||||
"brightness_changed": make_entity_numerical_state_attribute_changed_trigger(
|
||||
DOMAIN, ATTR_BRIGHTNESS
|
||||
),
|
||||
"brightness_crossed_threshold": make_entity_numerical_state_attribute_crossed_threshold_trigger(
|
||||
DOMAIN, ATTR_BRIGHTNESS
|
||||
),
|
||||
"turned_off": make_entity_target_state_trigger(DOMAIN, STATE_OFF),
|
||||
"turned_on": make_entity_target_state_trigger(DOMAIN, STATE_ON),
|
||||
}
|
||||
|
||||
@@ -22,10 +22,7 @@
|
||||
number:
|
||||
selector:
|
||||
number:
|
||||
max: 100
|
||||
min: 0
|
||||
mode: box
|
||||
unit_of_measurement: "%"
|
||||
entity:
|
||||
selector:
|
||||
entity:
|
||||
|
||||
@@ -247,7 +247,7 @@ class NumberDeviceClass(StrEnum):
|
||||
NITROGEN_DIOXIDE = "nitrogen_dioxide"
|
||||
"""Amount of NO2.
|
||||
|
||||
Unit of measurement: `ppb` (parts per billion), `μg/m³`
|
||||
Unit of measurement: `μg/m³`
|
||||
"""
|
||||
|
||||
NITROGEN_MONOXIDE = "nitrogen_monoxide"
|
||||
@@ -517,10 +517,7 @@ DEVICE_CLASS_UNITS: dict[NumberDeviceClass, set[type[StrEnum] | str | None]] = {
|
||||
NumberDeviceClass.ILLUMINANCE: {LIGHT_LUX},
|
||||
NumberDeviceClass.IRRADIANCE: set(UnitOfIrradiance),
|
||||
NumberDeviceClass.MOISTURE: {PERCENTAGE},
|
||||
NumberDeviceClass.NITROGEN_DIOXIDE: {
|
||||
CONCENTRATION_PARTS_PER_BILLION,
|
||||
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||
},
|
||||
NumberDeviceClass.NITROGEN_DIOXIDE: {CONCENTRATION_MICROGRAMS_PER_CUBIC_METER},
|
||||
NumberDeviceClass.NITROGEN_MONOXIDE: {CONCENTRATION_MICROGRAMS_PER_CUBIC_METER},
|
||||
NumberDeviceClass.NITROUS_OXIDE: {CONCENTRATION_MICROGRAMS_PER_CUBIC_METER},
|
||||
NumberDeviceClass.OZONE: {CONCENTRATION_MICROGRAMS_PER_CUBIC_METER},
|
||||
|
||||
@@ -8,9 +8,6 @@
|
||||
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]",
|
||||
"unknown": "[%key:common::config_flow::error::unknown%]"
|
||||
},
|
||||
"initiate_flow": {
|
||||
"user": "[%key:common::config_flow::initiate_flow::account%]"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
|
||||
@@ -178,7 +178,6 @@ class OneDriveBackupAgent(BackupAgent):
|
||||
file,
|
||||
upload_chunk_size=upload_chunk_size,
|
||||
session=async_get_clientsession(self._hass),
|
||||
smart_chunk_size=True,
|
||||
)
|
||||
except HashMismatchError as err:
|
||||
raise BackupAgentError(
|
||||
|
||||
@@ -10,5 +10,5 @@
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["onedrive_personal_sdk"],
|
||||
"quality_scale": "platinum",
|
||||
"requirements": ["onedrive-personal-sdk==0.1.1"]
|
||||
"requirements": ["onedrive-personal-sdk==0.1.0"]
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
}
|
||||
],
|
||||
"documentation": "https://www.home-assistant.io/integrations/qnap_qsw",
|
||||
"integration_type": "device",
|
||||
"iot_class": "local_polling",
|
||||
"loggers": ["aioqsw"],
|
||||
"requirements": ["aioqsw==0.4.2"]
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
"codeowners": ["@rabbit-air"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/rabbitair",
|
||||
"integration_type": "device",
|
||||
"iot_class": "local_polling",
|
||||
"requirements": ["python-rabbitair==0.0.8"],
|
||||
"zeroconf": ["_rabbitair._udp.local."]
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
}
|
||||
],
|
||||
"documentation": "https://www.home-assistant.io/integrations/radiotherm",
|
||||
"integration_type": "device",
|
||||
"iot_class": "local_polling",
|
||||
"loggers": ["radiotherm"],
|
||||
"requirements": ["radiotherm==2.1.0"]
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
"config_flow": true,
|
||||
"dependencies": ["usb"],
|
||||
"documentation": "https://www.home-assistant.io/integrations/rainforest_raven",
|
||||
"integration_type": "hub",
|
||||
"iot_class": "local_polling",
|
||||
"requirements": ["aioraven==0.7.1"],
|
||||
"usb": [
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
"config_flow": true,
|
||||
"dependencies": ["bluetooth_adapters"],
|
||||
"documentation": "https://www.home-assistant.io/integrations/rapt_ble",
|
||||
"integration_type": "device",
|
||||
"iot_class": "local_push",
|
||||
"requirements": ["rapt-ble==0.1.2"]
|
||||
}
|
||||
|
||||
@@ -59,7 +59,6 @@ from homeassistant.util.unit_conversion import (
|
||||
InformationConverter,
|
||||
MassConverter,
|
||||
MassVolumeConcentrationConverter,
|
||||
NitrogenDioxideConcentrationConverter,
|
||||
PowerConverter,
|
||||
PressureConverter,
|
||||
ReactiveEnergyConverter,
|
||||
@@ -226,7 +225,6 @@ _PRIMARY_UNIT_CONVERTERS: list[type[BaseUnitConverter]] = [
|
||||
|
||||
_SECONDARY_UNIT_CONVERTERS: list[type[BaseUnitConverter]] = [
|
||||
CarbonMonoxideConcentrationConverter,
|
||||
NitrogenDioxideConcentrationConverter,
|
||||
TemperatureDeltaConverter,
|
||||
SulphurDioxideConcentrationConverter,
|
||||
]
|
||||
|
||||
@@ -33,7 +33,6 @@ from homeassistant.util.unit_conversion import (
|
||||
InformationConverter,
|
||||
MassConverter,
|
||||
MassVolumeConcentrationConverter,
|
||||
NitrogenDioxideConcentrationConverter,
|
||||
PowerConverter,
|
||||
PressureConverter,
|
||||
ReactiveEnergyConverter,
|
||||
@@ -91,9 +90,6 @@ UNIT_SCHEMA = vol.Schema(
|
||||
vol.Optional("energy_distance"): vol.In(EnergyDistanceConverter.VALID_UNITS),
|
||||
vol.Optional("information"): vol.In(InformationConverter.VALID_UNITS),
|
||||
vol.Optional("mass"): vol.In(MassConverter.VALID_UNITS),
|
||||
vol.Optional("nitrogen_dioxide"): vol.In(
|
||||
NitrogenDioxideConcentrationConverter.VALID_UNITS
|
||||
),
|
||||
vol.Optional("power"): vol.In(PowerConverter.VALID_UNITS),
|
||||
vol.Optional("pressure"): vol.In(PressureConverter.VALID_UNITS),
|
||||
vol.Optional("reactive_energy"): vol.In(ReactiveEnergyConverter.VALID_UNITS),
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
"codeowners": ["@ashionky"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/refoss",
|
||||
"integration_type": "hub",
|
||||
"iot_class": "local_polling",
|
||||
"requirements": ["refoss-ha==1.2.5"],
|
||||
"single_config_entry": true
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
}
|
||||
],
|
||||
"documentation": "https://www.home-assistant.io/integrations/rehlko",
|
||||
"integration_type": "hub",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["aiokem"],
|
||||
"quality_scale": "silver",
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
"codeowners": ["@jimmyd-be"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/renson",
|
||||
"integration_type": "device",
|
||||
"iot_class": "local_polling",
|
||||
"requirements": ["renson-endura-delta==1.7.2"]
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
"codeowners": ["@danielhiversen", "@elupus", "@RobBie1221"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/rfxtrx",
|
||||
"integration_type": "hub",
|
||||
"iot_class": "local_push",
|
||||
"loggers": ["RFXtrx"],
|
||||
"requirements": ["pyRFXtrx==0.31.1"]
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
"codeowners": ["@milanmeu", "@frenck", "@quebulm"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/rituals_perfume_genie",
|
||||
"integration_type": "hub",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["pyrituals"],
|
||||
"requirements": ["pyrituals==0.0.7"]
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
"codeowners": ["@xeniter"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/romy",
|
||||
"integration_type": "device",
|
||||
"iot_class": "local_polling",
|
||||
"requirements": ["romy==0.0.10"],
|
||||
"zeroconf": ["_aicu-http._tcp.local."]
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
}
|
||||
],
|
||||
"documentation": "https://www.home-assistant.io/integrations/roomba",
|
||||
"integration_type": "device",
|
||||
"iot_class": "local_push",
|
||||
"loggers": ["paho_mqtt", "roombapy"],
|
||||
"requirements": ["roombapy==1.9.0"],
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
"codeowners": ["@pavoni"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/roon",
|
||||
"integration_type": "hub",
|
||||
"iot_class": "local_push",
|
||||
"loggers": ["roonapi"],
|
||||
"requirements": ["roonapi==0.1.6"]
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
"codeowners": [],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/rova",
|
||||
"integration_type": "service",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["rova"],
|
||||
"requirements": ["rova==0.4.1"]
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
"codeowners": ["@noahhusby"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/russound_rio",
|
||||
"integration_type": "hub",
|
||||
"iot_class": "local_push",
|
||||
"loggers": ["aiorussound"],
|
||||
"quality_scale": "silver",
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
}
|
||||
],
|
||||
"documentation": "https://www.home-assistant.io/integrations/ruuvi_gateway",
|
||||
"integration_type": "device",
|
||||
"iot_class": "local_polling",
|
||||
"requirements": ["aioruuvigateway==0.1.0"]
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
"config_flow": true,
|
||||
"dependencies": ["bluetooth_adapters"],
|
||||
"documentation": "https://www.home-assistant.io/integrations/ruuvitag_ble",
|
||||
"integration_type": "device",
|
||||
"iot_class": "local_push",
|
||||
"requirements": ["ruuvitag-ble==0.4.0"]
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
"codeowners": ["@OnFreund", "@elad-bar", "@maorcc"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/rympro",
|
||||
"integration_type": "hub",
|
||||
"iot_class": "cloud_polling",
|
||||
"requirements": ["pyrympro==0.0.9"]
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
"codeowners": ["@shaiu", "@jpbede"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/sabnzbd",
|
||||
"integration_type": "service",
|
||||
"iot_class": "local_polling",
|
||||
"loggers": ["pysabnzbd"],
|
||||
"quality_scale": "bronze",
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
"codeowners": ["@dknowles2"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/schlage",
|
||||
"integration_type": "hub",
|
||||
"iot_class": "cloud_polling",
|
||||
"requirements": ["pyschlage==2025.9.0"]
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
}
|
||||
],
|
||||
"documentation": "https://www.home-assistant.io/integrations/sense",
|
||||
"integration_type": "hub",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["sense_energy"],
|
||||
"requirements": ["sense-energy==0.13.8"]
|
||||
|
||||
@@ -63,7 +63,6 @@ from homeassistant.util.unit_conversion import (
|
||||
InformationConverter,
|
||||
MassConverter,
|
||||
MassVolumeConcentrationConverter,
|
||||
NitrogenDioxideConcentrationConverter,
|
||||
PowerConverter,
|
||||
PressureConverter,
|
||||
ReactiveEnergyConverter,
|
||||
@@ -284,7 +283,7 @@ class SensorDeviceClass(StrEnum):
|
||||
NITROGEN_DIOXIDE = "nitrogen_dioxide"
|
||||
"""Amount of NO2.
|
||||
|
||||
Unit of measurement: `ppb` (parts per billion), `μg/m³`
|
||||
Unit of measurement: `μg/m³`
|
||||
"""
|
||||
|
||||
NITROGEN_MONOXIDE = "nitrogen_monoxide"
|
||||
@@ -564,7 +563,6 @@ UNIT_CONVERTERS: dict[SensorDeviceClass | str | None, type[BaseUnitConverter]] =
|
||||
SensorDeviceClass.ENERGY_DISTANCE: EnergyDistanceConverter,
|
||||
SensorDeviceClass.ENERGY_STORAGE: EnergyConverter,
|
||||
SensorDeviceClass.GAS: VolumeConverter,
|
||||
SensorDeviceClass.NITROGEN_DIOXIDE: NitrogenDioxideConcentrationConverter,
|
||||
SensorDeviceClass.POWER: PowerConverter,
|
||||
SensorDeviceClass.POWER_FACTOR: UnitlessRatioConverter,
|
||||
SensorDeviceClass.PRECIPITATION: DistanceConverter,
|
||||
@@ -633,10 +631,7 @@ DEVICE_CLASS_UNITS: dict[SensorDeviceClass, set[type[StrEnum] | str | None]] = {
|
||||
SensorDeviceClass.ILLUMINANCE: {LIGHT_LUX},
|
||||
SensorDeviceClass.IRRADIANCE: set(UnitOfIrradiance),
|
||||
SensorDeviceClass.MOISTURE: {PERCENTAGE},
|
||||
SensorDeviceClass.NITROGEN_DIOXIDE: {
|
||||
CONCENTRATION_PARTS_PER_BILLION,
|
||||
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||
},
|
||||
SensorDeviceClass.NITROGEN_DIOXIDE: {CONCENTRATION_MICROGRAMS_PER_CUBIC_METER},
|
||||
SensorDeviceClass.NITROGEN_MONOXIDE: {CONCENTRATION_MICROGRAMS_PER_CUBIC_METER},
|
||||
SensorDeviceClass.NITROUS_OXIDE: {CONCENTRATION_MICROGRAMS_PER_CUBIC_METER},
|
||||
SensorDeviceClass.OZONE: {CONCENTRATION_MICROGRAMS_PER_CUBIC_METER},
|
||||
|
||||
@@ -18,9 +18,6 @@
|
||||
"error": {
|
||||
"already_configured": "[%key:common::config_flow::abort::already_configured_account%]"
|
||||
},
|
||||
"initiate_flow": {
|
||||
"user": "[%key:common::config_flow::initiate_flow::account%]"
|
||||
},
|
||||
"step": {
|
||||
"pick_implementation": {
|
||||
"data": {
|
||||
|
||||
@@ -10,9 +10,6 @@
|
||||
"unknown": "[%key:common::config_flow::error::unknown%]",
|
||||
"wrong_account": "Wrong account: Please authenticate with {username}."
|
||||
},
|
||||
"initiate_flow": {
|
||||
"user": "[%key:common::config_flow::initiate_flow::account%]"
|
||||
},
|
||||
"step": {
|
||||
"reauth_confirm": {
|
||||
"description": "The Twitch integration needs to re-authenticate your account",
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
"iot_class": "local_push",
|
||||
"loggers": ["uiprotect", "unifi_discovery"],
|
||||
"quality_scale": "platinum",
|
||||
"requirements": ["uiprotect==10.0.0", "unifi-discovery==1.2.0"],
|
||||
"requirements": ["uiprotect==8.1.1", "unifi-discovery==1.2.0"],
|
||||
"ssdp": [
|
||||
{
|
||||
"manufacturer": "Ubiquiti Networks",
|
||||
|
||||
@@ -21,9 +21,6 @@
|
||||
"error": {
|
||||
"already_configured": "[%key:common::config_flow::abort::already_configured_account%]"
|
||||
},
|
||||
"initiate_flow": {
|
||||
"user": "[%key:common::config_flow::initiate_flow::account%]"
|
||||
},
|
||||
"step": {
|
||||
"oauth_discovery": {
|
||||
"description": "Home Assistant has found a Withings device on your network. Be aware that the setup of Withings is more complicated than many other integrations. Press **Submit** to continue setting up Withings."
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
"create_entry": {
|
||||
"default": "[%key:common::config_flow::create_entry::authenticated%]"
|
||||
},
|
||||
"initiate_flow": {
|
||||
"user": "[%key:common::config_flow::initiate_flow::account%]"
|
||||
},
|
||||
"step": {
|
||||
"oauth_discovery": {
|
||||
"description": "Home Assistant has found an Xbox device on your network. Press **Submit** to continue setting up the Xbox integration.",
|
||||
|
||||
@@ -17,9 +17,6 @@
|
||||
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
|
||||
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]"
|
||||
},
|
||||
"initiate_flow": {
|
||||
"user": "[%key:common::config_flow::initiate_flow::account%]"
|
||||
},
|
||||
"step": {
|
||||
"channels": {
|
||||
"data": { "channels": "YouTube channels" },
|
||||
|
||||
@@ -5375,7 +5375,7 @@
|
||||
"name": "QNAP"
|
||||
},
|
||||
"qnap_qsw": {
|
||||
"integration_type": "device",
|
||||
"integration_type": "hub",
|
||||
"config_flow": true,
|
||||
"iot_class": "local_polling",
|
||||
"name": "QNAP QSW"
|
||||
@@ -5413,7 +5413,7 @@
|
||||
},
|
||||
"rabbitair": {
|
||||
"name": "Rabbit Air",
|
||||
"integration_type": "device",
|
||||
"integration_type": "hub",
|
||||
"config_flow": true,
|
||||
"iot_class": "local_polling"
|
||||
},
|
||||
@@ -5438,7 +5438,7 @@
|
||||
},
|
||||
"radiotherm": {
|
||||
"name": "Radio Thermostat",
|
||||
"integration_type": "device",
|
||||
"integration_type": "hub",
|
||||
"config_flow": true,
|
||||
"iot_class": "local_polling"
|
||||
},
|
||||
@@ -5473,7 +5473,7 @@
|
||||
},
|
||||
"rapt_ble": {
|
||||
"name": "RAPT Bluetooth",
|
||||
"integration_type": "device",
|
||||
"integration_type": "hub",
|
||||
"config_flow": true,
|
||||
"iot_class": "local_push"
|
||||
},
|
||||
@@ -5571,7 +5571,7 @@
|
||||
},
|
||||
"renson": {
|
||||
"name": "Renson",
|
||||
"integration_type": "device",
|
||||
"integration_type": "hub",
|
||||
"config_flow": true,
|
||||
"iot_class": "local_polling"
|
||||
},
|
||||
@@ -5679,13 +5679,13 @@
|
||||
},
|
||||
"romy": {
|
||||
"name": "ROMY Vacuum Cleaner",
|
||||
"integration_type": "device",
|
||||
"integration_type": "hub",
|
||||
"config_flow": true,
|
||||
"iot_class": "local_polling"
|
||||
},
|
||||
"roomba": {
|
||||
"name": "iRobot Roomba and Braava",
|
||||
"integration_type": "device",
|
||||
"integration_type": "hub",
|
||||
"config_flow": true,
|
||||
"iot_class": "local_push"
|
||||
},
|
||||
@@ -5720,7 +5720,7 @@
|
||||
},
|
||||
"rova": {
|
||||
"name": "ROVA",
|
||||
"integration_type": "service",
|
||||
"integration_type": "hub",
|
||||
"config_flow": true,
|
||||
"iot_class": "cloud_polling"
|
||||
},
|
||||
@@ -5763,13 +5763,13 @@
|
||||
"name": "Ruuvi",
|
||||
"integrations": {
|
||||
"ruuvi_gateway": {
|
||||
"integration_type": "device",
|
||||
"integration_type": "hub",
|
||||
"config_flow": true,
|
||||
"iot_class": "local_polling",
|
||||
"name": "Ruuvi Gateway"
|
||||
},
|
||||
"ruuvitag_ble": {
|
||||
"integration_type": "device",
|
||||
"integration_type": "hub",
|
||||
"config_flow": true,
|
||||
"iot_class": "local_push",
|
||||
"name": "Ruuvi BLE"
|
||||
@@ -5784,7 +5784,7 @@
|
||||
},
|
||||
"sabnzbd": {
|
||||
"name": "SABnzbd",
|
||||
"integration_type": "service",
|
||||
"integration_type": "hub",
|
||||
"config_flow": true,
|
||||
"iot_class": "local_polling"
|
||||
},
|
||||
|
||||
@@ -29,10 +29,7 @@ from typing import (
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.const import (
|
||||
ATTR_AREA_ID,
|
||||
ATTR_DEVICE_CLASS,
|
||||
ATTR_FLOOR_ID,
|
||||
ATTR_LABEL_ID,
|
||||
CONF_ABOVE,
|
||||
CONF_AFTER,
|
||||
CONF_ATTRIBUTE,
|
||||
@@ -1387,27 +1384,9 @@ def async_extract_devices(config: ConfigType | Template) -> set[str]:
|
||||
|
||||
|
||||
@callback
|
||||
def async_extract_areas(config: ConfigType | Template) -> set[str]:
|
||||
"""Extract areas from a condition."""
|
||||
return _async_extract_targets(config, ATTR_AREA_ID)
|
||||
|
||||
|
||||
@callback
|
||||
def async_extract_floors(config: ConfigType | Template) -> set[str]:
|
||||
"""Extract floors from a condition."""
|
||||
return _async_extract_targets(config, ATTR_FLOOR_ID)
|
||||
|
||||
|
||||
@callback
|
||||
def async_extract_labels(config: ConfigType | Template) -> set[str]:
|
||||
"""Extract labels from a condition."""
|
||||
return _async_extract_targets(config, ATTR_LABEL_ID)
|
||||
|
||||
|
||||
@callback
|
||||
def _async_extract_targets(
|
||||
def async_extract_targets(
|
||||
config: ConfigType | Template,
|
||||
target_type: Literal["entity_id", "device_id", "area_id", "floor_id", "label_id"],
|
||||
target_type: Literal["area_id", "floor_id", "label_id"],
|
||||
) -> set[str]:
|
||||
"""Extract targets from a condition."""
|
||||
referenced: set[str] = set()
|
||||
|
||||
@@ -1601,8 +1601,13 @@ class Script:
|
||||
):
|
||||
_referenced_extract_ids(data, target, referenced)
|
||||
|
||||
elif action == cv.SCRIPT_ACTION_CHECK_CONDITION:
|
||||
referenced |= condition.async_extract_targets(step, target)
|
||||
|
||||
elif action == cv.SCRIPT_ACTION_CHOOSE:
|
||||
for choice in step[CONF_CHOOSE]:
|
||||
for cond in choice[CONF_CONDITIONS]:
|
||||
referenced |= condition.async_extract_targets(cond, target)
|
||||
Script._find_referenced_target(
|
||||
target, referenced, choice[CONF_SEQUENCE]
|
||||
)
|
||||
@@ -1612,6 +1617,8 @@ class Script:
|
||||
)
|
||||
|
||||
elif action == cv.SCRIPT_ACTION_IF:
|
||||
for cond in step[CONF_IF]:
|
||||
referenced |= condition.async_extract_targets(cond, target)
|
||||
Script._find_referenced_target(target, referenced, step[CONF_THEN])
|
||||
if CONF_ELSE in step:
|
||||
Script._find_referenced_target(target, referenced, step[CONF_ELSE])
|
||||
|
||||
@@ -594,8 +594,6 @@ class EntityNumericalStateAttributeChangedTriggerBase(EntityTriggerBase):
|
||||
_above: None | float | str
|
||||
_below: None | float | str
|
||||
|
||||
_converter: Callable[[Any], float] = float
|
||||
|
||||
def __init__(self, hass: HomeAssistant, config: TriggerConfig) -> None:
|
||||
"""Initialize the state trigger."""
|
||||
super().__init__(hass, config)
|
||||
@@ -618,7 +616,7 @@ class EntityNumericalStateAttributeChangedTriggerBase(EntityTriggerBase):
|
||||
return False
|
||||
|
||||
try:
|
||||
current_value = self._converter(_attribute_value)
|
||||
current_value = float(_attribute_value)
|
||||
except (TypeError, ValueError):
|
||||
# Attribute is not a valid number, don't trigger
|
||||
return False
|
||||
@@ -708,8 +706,6 @@ class EntityNumericalStateAttributeCrossedThresholdTriggerBase(EntityTriggerBase
|
||||
_upper_limit: float | str | None = None
|
||||
_threshold_type: ThresholdType
|
||||
|
||||
_converter: Callable[[Any], float] = float
|
||||
|
||||
def __init__(self, hass: HomeAssistant, config: TriggerConfig) -> None:
|
||||
"""Initialize the state trigger."""
|
||||
super().__init__(hass, config)
|
||||
@@ -745,7 +741,7 @@ class EntityNumericalStateAttributeCrossedThresholdTriggerBase(EntityTriggerBase
|
||||
return False
|
||||
|
||||
try:
|
||||
current_value = self._converter(_attribute_value)
|
||||
current_value = float(_attribute_value)
|
||||
except (TypeError, ValueError):
|
||||
# Attribute is not a valid number, don't trigger
|
||||
return False
|
||||
|
||||
@@ -103,7 +103,6 @@ _AMBIENT_IDEAL_GAS_MOLAR_VOLUME = ( # m3⋅mol⁻¹
|
||||
)
|
||||
# Molar masses in g⋅mol⁻¹
|
||||
_CARBON_MONOXIDE_MOLAR_MASS = 28.01
|
||||
_NITROGEN_DIOXIDE_MOLAR_MASS = 46.0055
|
||||
_SULPHUR_DIOXIDE_MOLAR_MASS = 64.066
|
||||
|
||||
|
||||
@@ -212,22 +211,6 @@ class CarbonMonoxideConcentrationConverter(BaseUnitConverter):
|
||||
}
|
||||
|
||||
|
||||
class NitrogenDioxideConcentrationConverter(BaseUnitConverter):
|
||||
"""Convert nitrogen dioxide ratio to mass per volume."""
|
||||
|
||||
UNIT_CLASS = "nitrogen_dioxide"
|
||||
_UNIT_CONVERSION: dict[str | None, float] = {
|
||||
CONCENTRATION_PARTS_PER_BILLION: 1e9,
|
||||
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER: (
|
||||
_NITROGEN_DIOXIDE_MOLAR_MASS / _AMBIENT_IDEAL_GAS_MOLAR_VOLUME * 1e6
|
||||
),
|
||||
}
|
||||
VALID_UNITS = {
|
||||
CONCENTRATION_PARTS_PER_BILLION,
|
||||
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||
}
|
||||
|
||||
|
||||
class SulphurDioxideConcentrationConverter(BaseUnitConverter):
|
||||
"""Convert sulphur dioxide ratio to mass per volume."""
|
||||
|
||||
|
||||
6
requirements_all.txt
generated
6
requirements_all.txt
generated
@@ -1646,7 +1646,7 @@ omnilogic==0.4.5
|
||||
ondilo==0.5.0
|
||||
|
||||
# homeassistant.components.onedrive
|
||||
onedrive-personal-sdk==0.1.1
|
||||
onedrive-personal-sdk==0.1.0
|
||||
|
||||
# homeassistant.components.onvif
|
||||
onvif-zeep-async==4.0.4
|
||||
@@ -2147,7 +2147,7 @@ pykmtronic==0.3.0
|
||||
pykodi==0.2.7
|
||||
|
||||
# homeassistant.components.kostal_plenticore
|
||||
pykoplenti==1.5.0
|
||||
pykoplenti==1.3.0
|
||||
|
||||
# homeassistant.components.kraken
|
||||
pykrakenapi==0.1.8
|
||||
@@ -3080,7 +3080,7 @@ typedmonarchmoney==0.4.4
|
||||
uasiren==0.0.1
|
||||
|
||||
# homeassistant.components.unifiprotect
|
||||
uiprotect==10.0.0
|
||||
uiprotect==8.1.1
|
||||
|
||||
# homeassistant.components.landisgyr_heat_meter
|
||||
ultraheat-api==0.5.7
|
||||
|
||||
6
requirements_test_all.txt
generated
6
requirements_test_all.txt
generated
@@ -1429,7 +1429,7 @@ omnilogic==0.4.5
|
||||
ondilo==0.5.0
|
||||
|
||||
# homeassistant.components.onedrive
|
||||
onedrive-personal-sdk==0.1.1
|
||||
onedrive-personal-sdk==0.1.0
|
||||
|
||||
# homeassistant.components.onvif
|
||||
onvif-zeep-async==4.0.4
|
||||
@@ -1821,7 +1821,7 @@ pykmtronic==0.3.0
|
||||
pykodi==0.2.7
|
||||
|
||||
# homeassistant.components.kostal_plenticore
|
||||
pykoplenti==1.5.0
|
||||
pykoplenti==1.3.0
|
||||
|
||||
# homeassistant.components.kraken
|
||||
pykrakenapi==0.1.8
|
||||
@@ -2577,7 +2577,7 @@ typedmonarchmoney==0.4.4
|
||||
uasiren==0.0.1
|
||||
|
||||
# homeassistant.components.unifiprotect
|
||||
uiprotect==10.0.0
|
||||
uiprotect==8.1.1
|
||||
|
||||
# homeassistant.components.landisgyr_heat_meter
|
||||
ultraheat-api==0.5.7
|
||||
|
||||
@@ -644,14 +644,14 @@
|
||||
'object_id_base': 'Sulphur dioxide',
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.SULPHUR_DIOXIDE: 'sulphur_dioxide'>,
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Sulphur dioxide',
|
||||
'platform': 'google_air_quality',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'translation_key': 'sulphur_dioxide',
|
||||
'unique_id': 'so2_10.1_20.1',
|
||||
'unit_of_measurement': 'ppb',
|
||||
})
|
||||
@@ -660,7 +660,6 @@
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'attribution': 'Data provided by Google Air Quality',
|
||||
'device_class': 'sulphur_dioxide',
|
||||
'friendly_name': 'Home Sulphur dioxide',
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
'unit_of_measurement': 'ppb',
|
||||
|
||||
@@ -5,25 +5,14 @@ from typing import Any
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.light import ATTR_BRIGHTNESS
|
||||
from homeassistant.const import (
|
||||
ATTR_LABEL_ID,
|
||||
CONF_ABOVE,
|
||||
CONF_BELOW,
|
||||
CONF_ENTITY_ID,
|
||||
STATE_OFF,
|
||||
STATE_ON,
|
||||
)
|
||||
from homeassistant.const import ATTR_LABEL_ID, CONF_ENTITY_ID, STATE_OFF, STATE_ON
|
||||
from homeassistant.core import HomeAssistant, ServiceCall
|
||||
from homeassistant.helpers.trigger import (
|
||||
CONF_LOWER_LIMIT,
|
||||
CONF_THRESHOLD_TYPE,
|
||||
CONF_UPPER_LIMIT,
|
||||
ThresholdType,
|
||||
)
|
||||
|
||||
from tests.components import (
|
||||
TriggerStateDescription,
|
||||
arm_trigger,
|
||||
parametrize_numerical_attribute_changed_trigger_states,
|
||||
parametrize_numerical_attribute_crossed_threshold_trigger_states,
|
||||
parametrize_target_entities,
|
||||
parametrize_trigger_states,
|
||||
set_or_remove_state,
|
||||
@@ -37,131 +26,6 @@ async def target_lights(hass: HomeAssistant) -> list[str]:
|
||||
return (await target_entities(hass, "light"))["included"]
|
||||
|
||||
|
||||
def parametrize_brightness_changed_trigger_states(
|
||||
trigger: str, state: str, attribute: str
|
||||
) -> list[tuple[str, dict[str, Any], list[TriggerStateDescription]]]:
|
||||
"""Parametrize states and expected service call counts for brightness changed triggers.
|
||||
|
||||
Note: The brightness in the trigger configuration is in percentage (0-100) scale,
|
||||
the underlying attribute in the state is in uint8 (0-255) scale.
|
||||
"""
|
||||
return [
|
||||
*parametrize_trigger_states(
|
||||
trigger=trigger,
|
||||
trigger_options={},
|
||||
target_states=[
|
||||
(state, {attribute: 0}),
|
||||
(state, {attribute: 128}),
|
||||
(state, {attribute: 255}),
|
||||
],
|
||||
other_states=[(state, {attribute: None})],
|
||||
retrigger_on_target_state=True,
|
||||
),
|
||||
*parametrize_trigger_states(
|
||||
trigger=trigger,
|
||||
trigger_options={CONF_ABOVE: 10},
|
||||
target_states=[
|
||||
(state, {attribute: 128}),
|
||||
(state, {attribute: 255}),
|
||||
],
|
||||
other_states=[
|
||||
(state, {attribute: None}),
|
||||
(state, {attribute: 0}),
|
||||
],
|
||||
retrigger_on_target_state=True,
|
||||
),
|
||||
*parametrize_trigger_states(
|
||||
trigger=trigger,
|
||||
trigger_options={CONF_BELOW: 90},
|
||||
target_states=[
|
||||
(state, {attribute: 0}),
|
||||
(state, {attribute: 128}),
|
||||
],
|
||||
other_states=[
|
||||
(state, {attribute: None}),
|
||||
(state, {attribute: 255}),
|
||||
],
|
||||
retrigger_on_target_state=True,
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
def parametrize_brightness_crossed_threshold_trigger_states(
|
||||
trigger: str, state: str, attribute: str
|
||||
) -> list[tuple[str, dict[str, Any], list[TriggerStateDescription]]]:
|
||||
"""Parametrize states and expected service call counts for brightness crossed threshold triggers.
|
||||
|
||||
Note: The brightness in the trigger configuration is in percentage (0-100) scale,
|
||||
the underlying attribute in the state is in uint8 (0-255) scale.
|
||||
"""
|
||||
return [
|
||||
*parametrize_trigger_states(
|
||||
trigger=trigger,
|
||||
trigger_options={
|
||||
CONF_THRESHOLD_TYPE: ThresholdType.BETWEEN,
|
||||
CONF_LOWER_LIMIT: 10,
|
||||
CONF_UPPER_LIMIT: 90,
|
||||
},
|
||||
target_states=[
|
||||
(state, {attribute: 128}),
|
||||
(state, {attribute: 153}),
|
||||
],
|
||||
other_states=[
|
||||
(state, {attribute: None}),
|
||||
(state, {attribute: 0}),
|
||||
(state, {attribute: 255}),
|
||||
],
|
||||
),
|
||||
*parametrize_trigger_states(
|
||||
trigger=trigger,
|
||||
trigger_options={
|
||||
CONF_THRESHOLD_TYPE: ThresholdType.OUTSIDE,
|
||||
CONF_LOWER_LIMIT: 10,
|
||||
CONF_UPPER_LIMIT: 90,
|
||||
},
|
||||
target_states=[
|
||||
(state, {attribute: 0}),
|
||||
(state, {attribute: 255}),
|
||||
],
|
||||
other_states=[
|
||||
(state, {attribute: None}),
|
||||
(state, {attribute: 128}),
|
||||
(state, {attribute: 153}),
|
||||
],
|
||||
),
|
||||
*parametrize_trigger_states(
|
||||
trigger=trigger,
|
||||
trigger_options={
|
||||
CONF_THRESHOLD_TYPE: ThresholdType.ABOVE,
|
||||
CONF_LOWER_LIMIT: 10,
|
||||
},
|
||||
target_states=[
|
||||
(state, {attribute: 128}),
|
||||
(state, {attribute: 255}),
|
||||
],
|
||||
other_states=[
|
||||
(state, {attribute: None}),
|
||||
(state, {attribute: 0}),
|
||||
],
|
||||
),
|
||||
*parametrize_trigger_states(
|
||||
trigger=trigger,
|
||||
trigger_options={
|
||||
CONF_THRESHOLD_TYPE: ThresholdType.BELOW,
|
||||
CONF_UPPER_LIMIT: 90,
|
||||
},
|
||||
target_states=[
|
||||
(state, {attribute: 0}),
|
||||
(state, {attribute: 128}),
|
||||
],
|
||||
other_states=[
|
||||
(state, {attribute: None}),
|
||||
(state, {attribute: 255}),
|
||||
],
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"trigger_key",
|
||||
[
|
||||
@@ -250,10 +114,10 @@ async def test_light_state_trigger_behavior_any(
|
||||
@pytest.mark.parametrize(
|
||||
("trigger", "trigger_options", "states"),
|
||||
[
|
||||
*parametrize_brightness_changed_trigger_states(
|
||||
*parametrize_numerical_attribute_changed_trigger_states(
|
||||
"light.brightness_changed", STATE_ON, ATTR_BRIGHTNESS
|
||||
),
|
||||
*parametrize_brightness_crossed_threshold_trigger_states(
|
||||
*parametrize_numerical_attribute_crossed_threshold_trigger_states(
|
||||
"light.brightness_crossed_threshold", STATE_ON, ATTR_BRIGHTNESS
|
||||
),
|
||||
],
|
||||
@@ -361,7 +225,7 @@ async def test_light_state_trigger_behavior_first(
|
||||
@pytest.mark.parametrize(
|
||||
("trigger", "trigger_options", "states"),
|
||||
[
|
||||
*parametrize_brightness_crossed_threshold_trigger_states(
|
||||
*parametrize_numerical_attribute_crossed_threshold_trigger_states(
|
||||
"light.brightness_crossed_threshold", STATE_ON, ATTR_BRIGHTNESS
|
||||
),
|
||||
],
|
||||
@@ -469,7 +333,7 @@ async def test_light_state_trigger_behavior_last(
|
||||
@pytest.mark.parametrize(
|
||||
("trigger", "trigger_options", "states"),
|
||||
[
|
||||
*parametrize_brightness_crossed_threshold_trigger_states(
|
||||
*parametrize_numerical_attribute_crossed_threshold_trigger_states(
|
||||
"light.brightness_crossed_threshold", STATE_ON, ATTR_BRIGHTNESS
|
||||
),
|
||||
],
|
||||
|
||||
@@ -3107,6 +3107,7 @@ def test_device_class_converters_are_complete() -> None:
|
||||
SensorDeviceClass.IRRADIANCE,
|
||||
SensorDeviceClass.MOISTURE,
|
||||
SensorDeviceClass.MONETARY,
|
||||
SensorDeviceClass.NITROGEN_DIOXIDE,
|
||||
SensorDeviceClass.NITROGEN_MONOXIDE,
|
||||
SensorDeviceClass.NITROUS_OXIDE,
|
||||
SensorDeviceClass.OZONE,
|
||||
|
||||
@@ -4209,6 +4209,16 @@ async def test_referenced_labels(hass: HomeAssistant) -> None:
|
||||
"data_template": {"label_id": "label_in_data_template"},
|
||||
},
|
||||
{"action": "test.script", "data": {"without": "label_id"}},
|
||||
{
|
||||
"condition": "light.is_on",
|
||||
"target": {"label_id": "label_condition_target"},
|
||||
},
|
||||
{
|
||||
"condition": "light.is_on",
|
||||
"target": {
|
||||
"label_id": ["label_condition_list_1", "label_condition_list_2"]
|
||||
},
|
||||
},
|
||||
{
|
||||
"choose": [
|
||||
{
|
||||
@@ -4221,7 +4231,10 @@ async def test_referenced_labels(hass: HomeAssistant) -> None:
|
||||
],
|
||||
},
|
||||
{
|
||||
"conditions": "{{ true == false }}",
|
||||
"conditions": {
|
||||
"condition": "light.is_on",
|
||||
"target": {"label_id": "label_choice_2_cond"},
|
||||
},
|
||||
"sequence": [
|
||||
{
|
||||
"action": "test.script",
|
||||
@@ -4240,7 +4253,10 @@ async def test_referenced_labels(hass: HomeAssistant) -> None:
|
||||
{"event": "test_event"},
|
||||
{"delay": "{{ delay_period }}"},
|
||||
{
|
||||
"if": [],
|
||||
"if": {
|
||||
"condition": "light.is_on",
|
||||
"target": {"label_id": "label_if_cond"},
|
||||
},
|
||||
"then": [
|
||||
{
|
||||
"action": "test.script",
|
||||
@@ -4277,17 +4293,22 @@ async def test_referenced_labels(hass: HomeAssistant) -> None:
|
||||
)
|
||||
assert script_obj.referenced_labels == {
|
||||
"label_choice_1_seq",
|
||||
"label_choice_2_cond",
|
||||
"label_choice_2_seq",
|
||||
"label_condition_list_1",
|
||||
"label_condition_list_2",
|
||||
"label_condition_target",
|
||||
"label_default_seq",
|
||||
"label_if_cond",
|
||||
"label_if_else",
|
||||
"label_if_then",
|
||||
"label_in_data_template",
|
||||
"label_in_target",
|
||||
"label_parallel",
|
||||
"label_sequence",
|
||||
"label_service_list_1",
|
||||
"label_service_list_2",
|
||||
"label_service_not_list",
|
||||
"label_if_then",
|
||||
"label_if_else",
|
||||
"label_parallel",
|
||||
"label_sequence",
|
||||
}
|
||||
# Test we cache results.
|
||||
assert script_obj.referenced_labels is script_obj.referenced_labels
|
||||
@@ -4320,6 +4341,16 @@ async def test_referenced_floors(hass: HomeAssistant) -> None:
|
||||
"data_template": {"floor_id": "floor_in_data_template"},
|
||||
},
|
||||
{"action": "test.script", "data": {"without": "floor_id"}},
|
||||
{
|
||||
"condition": "light.is_on",
|
||||
"target": {"floor_id": "floor_condition_target"},
|
||||
},
|
||||
{
|
||||
"condition": "light.is_on",
|
||||
"target": {
|
||||
"floor_id": ["floor_condition_list_1", "floor_condition_list_2"]
|
||||
},
|
||||
},
|
||||
{
|
||||
"choose": [
|
||||
{
|
||||
@@ -4332,7 +4363,10 @@ async def test_referenced_floors(hass: HomeAssistant) -> None:
|
||||
],
|
||||
},
|
||||
{
|
||||
"conditions": "{{ true == false }}",
|
||||
"conditions": {
|
||||
"condition": "light.is_on",
|
||||
"target": {"floor_id": "floor_choice_2_cond"},
|
||||
},
|
||||
"sequence": [
|
||||
{
|
||||
"action": "test.script",
|
||||
@@ -4351,7 +4385,10 @@ async def test_referenced_floors(hass: HomeAssistant) -> None:
|
||||
{"event": "test_event"},
|
||||
{"delay": "{{ delay_period }}"},
|
||||
{
|
||||
"if": [],
|
||||
"if": {
|
||||
"condition": "light.is_on",
|
||||
"target": {"floor_id": "floor_if_cond"},
|
||||
},
|
||||
"then": [
|
||||
{
|
||||
"action": "test.script",
|
||||
@@ -4388,16 +4425,21 @@ async def test_referenced_floors(hass: HomeAssistant) -> None:
|
||||
)
|
||||
assert script_obj.referenced_floors == {
|
||||
"floor_choice_1_seq",
|
||||
"floor_choice_2_cond",
|
||||
"floor_choice_2_seq",
|
||||
"floor_condition_list_1",
|
||||
"floor_condition_list_2",
|
||||
"floor_condition_target",
|
||||
"floor_default_seq",
|
||||
"floor_if_cond",
|
||||
"floor_if_else",
|
||||
"floor_if_then",
|
||||
"floor_in_data_template",
|
||||
"floor_in_target",
|
||||
"floor_service_list",
|
||||
"floor_service_not_list",
|
||||
"floor_if_then",
|
||||
"floor_if_else",
|
||||
"floor_parallel",
|
||||
"floor_sequence",
|
||||
"floor_service_list",
|
||||
"floor_service_not_list",
|
||||
}
|
||||
# Test we cache results.
|
||||
assert script_obj.referenced_floors is script_obj.referenced_floors
|
||||
@@ -4430,6 +4472,16 @@ async def test_referenced_areas(hass: HomeAssistant) -> None:
|
||||
"data_template": {"area_id": "area_in_data_template"},
|
||||
},
|
||||
{"action": "test.script", "data": {"without": "area_id"}},
|
||||
{
|
||||
"condition": "light.is_on",
|
||||
"target": {"area_id": "area_condition_target"},
|
||||
},
|
||||
{
|
||||
"condition": "light.is_on",
|
||||
"target": {
|
||||
"area_id": ["area_condition_list_1", "area_condition_list_2"]
|
||||
},
|
||||
},
|
||||
{
|
||||
"choose": [
|
||||
{
|
||||
@@ -4442,7 +4494,10 @@ async def test_referenced_areas(hass: HomeAssistant) -> None:
|
||||
],
|
||||
},
|
||||
{
|
||||
"conditions": "{{ true == false }}",
|
||||
"conditions": {
|
||||
"condition": "light.is_on",
|
||||
"target": {"area_id": "area_choice_2_cond"},
|
||||
},
|
||||
"sequence": [
|
||||
{
|
||||
"action": "test.script",
|
||||
@@ -4461,7 +4516,10 @@ async def test_referenced_areas(hass: HomeAssistant) -> None:
|
||||
{"event": "test_event"},
|
||||
{"delay": "{{ delay_period }}"},
|
||||
{
|
||||
"if": [],
|
||||
"if": {
|
||||
"condition": "light.is_on",
|
||||
"target": {"area_id": "area_if_cond"},
|
||||
},
|
||||
"then": [
|
||||
{
|
||||
"action": "test.script",
|
||||
@@ -4498,16 +4556,21 @@ async def test_referenced_areas(hass: HomeAssistant) -> None:
|
||||
)
|
||||
assert script_obj.referenced_areas == {
|
||||
"area_choice_1_seq",
|
||||
"area_choice_2_cond",
|
||||
"area_choice_2_seq",
|
||||
"area_condition_list_1",
|
||||
"area_condition_list_2",
|
||||
"area_condition_target",
|
||||
"area_default_seq",
|
||||
"area_if_cond",
|
||||
"area_if_else",
|
||||
"area_if_then",
|
||||
"area_in_data_template",
|
||||
"area_in_target",
|
||||
"area_service_list",
|
||||
"area_service_not_list",
|
||||
"area_if_then",
|
||||
"area_if_else",
|
||||
"area_parallel",
|
||||
"area_sequence",
|
||||
"area_service_list",
|
||||
"area_service_not_list",
|
||||
# 'area_service_template', # no area extraction from template
|
||||
}
|
||||
# Test we cache results.
|
||||
@@ -4608,6 +4671,19 @@ async def test_referenced_entities(hass: HomeAssistant) -> None:
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
"condition": "light.is_on",
|
||||
"target": {"entity_id": "light.condition_target"},
|
||||
},
|
||||
{
|
||||
"condition": "light.is_on",
|
||||
"target": {
|
||||
"entity_id": [
|
||||
"light.condition_list_1",
|
||||
"light.condition_list_2",
|
||||
]
|
||||
},
|
||||
},
|
||||
{
|
||||
"sequence": [
|
||||
{
|
||||
@@ -4626,6 +4702,9 @@ async def test_referenced_entities(hass: HomeAssistant) -> None:
|
||||
"light.choice_1_seq",
|
||||
"light.choice_2_cond",
|
||||
"light.choice_2_seq",
|
||||
"light.condition_list_1",
|
||||
"light.condition_list_2",
|
||||
"light.condition_target",
|
||||
"light.default_seq",
|
||||
"light.direct_entity_referenced",
|
||||
"light.entity_in_data_template",
|
||||
@@ -4656,6 +4735,19 @@ async def test_referenced_devices(hass: HomeAssistant) -> None:
|
||||
"device_id": "condition-dev-id",
|
||||
"domain": "switch",
|
||||
},
|
||||
{
|
||||
"condition": "light.is_on",
|
||||
"target": {"device_id": "condition-target-dev-id"},
|
||||
},
|
||||
{
|
||||
"condition": "light.is_on",
|
||||
"target": {
|
||||
"device_id": [
|
||||
"condition-target-list-1",
|
||||
"condition-target-list-2",
|
||||
]
|
||||
},
|
||||
},
|
||||
{
|
||||
"action": "test.script",
|
||||
"data": {"device_id": "data-string-id"},
|
||||
@@ -4753,6 +4845,9 @@ async def test_referenced_devices(hass: HomeAssistant) -> None:
|
||||
"choice-2-cond-dev-id",
|
||||
"choice-2-seq-device-target",
|
||||
"condition-dev-id",
|
||||
"condition-target-dev-id",
|
||||
"condition-target-list-1",
|
||||
"condition-target-list-2",
|
||||
"data-string-id",
|
||||
"data-template-string-id",
|
||||
"default-device-target",
|
||||
|
||||
@@ -56,7 +56,6 @@ from homeassistant.util.unit_conversion import (
|
||||
InformationConverter,
|
||||
MassConverter,
|
||||
MassVolumeConcentrationConverter,
|
||||
NitrogenDioxideConcentrationConverter,
|
||||
PowerConverter,
|
||||
PressureConverter,
|
||||
ReactiveEnergyConverter,
|
||||
@@ -104,7 +103,6 @@ _ALL_CONVERTERS: dict[type[BaseUnitConverter], list[str | None]] = {
|
||||
EnergyDistanceConverter,
|
||||
VolumeConverter,
|
||||
VolumeFlowRateConverter,
|
||||
NitrogenDioxideConcentrationConverter,
|
||||
SulphurDioxideConcentrationConverter,
|
||||
)
|
||||
}
|
||||
@@ -162,11 +160,6 @@ _GET_UNIT_RATIO: dict[type[BaseUnitConverter], tuple[str | None, str | None, flo
|
||||
CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER,
|
||||
1000,
|
||||
),
|
||||
NitrogenDioxideConcentrationConverter: (
|
||||
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||
CONCENTRATION_PARTS_PER_BILLION,
|
||||
1.912503,
|
||||
),
|
||||
PowerConverter: (UnitOfPower.WATT, UnitOfPower.KILO_WATT, 1000),
|
||||
PressureConverter: (UnitOfPressure.HPA, UnitOfPressure.INHG, 33.86389),
|
||||
ReactiveEnergyConverter: (
|
||||
@@ -386,20 +379,6 @@ _CONVERTED_VALUE: dict[
|
||||
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||
),
|
||||
],
|
||||
NitrogenDioxideConcentrationConverter: [
|
||||
(
|
||||
1,
|
||||
CONCENTRATION_PARTS_PER_BILLION,
|
||||
1.912503,
|
||||
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||
),
|
||||
(
|
||||
120,
|
||||
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||
62.744976,
|
||||
CONCENTRATION_PARTS_PER_BILLION,
|
||||
),
|
||||
],
|
||||
ConductivityConverter: [
|
||||
(
|
||||
5,
|
||||
|
||||
Reference in New Issue
Block a user