mirror of
https://github.com/home-assistant/core.git
synced 2025-04-24 01:08:12 +00:00
Move temperature conversions to sensor base class (1/8) (#48261)
* Move temperature conversions to entity base class (1/8) * Update integrations a-c * Leave old temperature conversion until all integrations are migrated * tweak * Use contextlib.suppress * Remove the MeasurableUnitEntity mixin * Address comments, add tests * Fix f-string * Drop deprecation warning from base entity class * Update with _attr-shorthand * Fix rebase mistakes * Fix additional rebase mistakes * Only report temperature conversion once * Fix additional rebase mistakes * Format homeassistant/components/bbox/sensor.py * Fix check for overidden _attr_state * Remove test workarounds from implementation * Remove useless None-check * Tweaks * Migrate new sensors a-c * Update climacell * Push deprecation of temperature conversion forward * Override __repr__ in SensorEntity * Include native_value in SensorEntity attributes * Pylint * Black * Black * Fix rebase mistakes * black * Fix rebase mistakes * Revert changes in august/sensor.py * Revert handling of unit converted restored state * Apply code review suggestion * Fix arlo test
This commit is contained in:
parent
930c1dbe9b
commit
4e07ab1b32
@ -61,14 +61,14 @@ class AbodeSensor(AbodeDevice, SensorEntity):
|
||||
self._attr_name = f"{device.name} {description.name}"
|
||||
self._attr_unique_id = f"{device.device_uuid}-{description.key}"
|
||||
if description.key == CONST.TEMP_STATUS_KEY:
|
||||
self._attr_unit_of_measurement = device.temp_unit
|
||||
self._attr_native_unit_of_measurement = device.temp_unit
|
||||
elif description.key == CONST.HUMI_STATUS_KEY:
|
||||
self._attr_unit_of_measurement = device.humidity_unit
|
||||
self._attr_native_unit_of_measurement = device.humidity_unit
|
||||
elif description.key == CONST.LUX_STATUS_KEY:
|
||||
self._attr_unit_of_measurement = device.lux_unit
|
||||
self._attr_native_unit_of_measurement = device.lux_unit
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def native_value(self):
|
||||
"""Return the state of the sensor."""
|
||||
if self.entity_description.key == CONST.TEMP_STATUS_KEY:
|
||||
return self._device.temp
|
||||
|
@ -88,10 +88,10 @@ class AccuWeatherSensor(CoordinatorEntity, SensorEntity):
|
||||
)
|
||||
if coordinator.is_metric:
|
||||
self._unit_system = API_METRIC
|
||||
self._attr_unit_of_measurement = description.unit_metric
|
||||
self._attr_native_unit_of_measurement = description.unit_metric
|
||||
else:
|
||||
self._unit_system = API_IMPERIAL
|
||||
self._attr_unit_of_measurement = description.unit_imperial
|
||||
self._attr_native_unit_of_measurement = description.unit_imperial
|
||||
self._attr_device_info = {
|
||||
"identifiers": {(DOMAIN, coordinator.location_key)},
|
||||
"name": NAME,
|
||||
@ -101,7 +101,7 @@ class AccuWeatherSensor(CoordinatorEntity, SensorEntity):
|
||||
self.forecast_day = forecast_day
|
||||
|
||||
@property
|
||||
def state(self) -> StateType:
|
||||
def native_value(self) -> StateType:
|
||||
"""Return the state."""
|
||||
if self.forecast_day is not None:
|
||||
if self.entity_description.device_class == DEVICE_CLASS_TEMPERATURE:
|
||||
|
@ -42,6 +42,6 @@ class AcmedaBattery(AcmedaBase, SensorEntity):
|
||||
return f"{super().name} Battery"
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def native_value(self):
|
||||
"""Return the state of the device."""
|
||||
return self.roller.battery
|
||||
|
@ -82,12 +82,12 @@ class AdGuardHomeSensor(AdGuardHomeDeviceEntity, SensorEntity):
|
||||
)
|
||||
|
||||
@property
|
||||
def state(self) -> str | None:
|
||||
def native_value(self) -> str | None:
|
||||
"""Return the state of the sensor."""
|
||||
return self._state
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self) -> str | None:
|
||||
def native_unit_of_measurement(self) -> str | None:
|
||||
"""Return the unit this state is expressed in."""
|
||||
return self._unit_of_measurement
|
||||
|
||||
|
@ -50,7 +50,7 @@ class AdsSensor(AdsEntity, SensorEntity):
|
||||
def __init__(self, ads_hub, ads_var, ads_type, name, unit_of_measurement, factor):
|
||||
"""Initialize AdsSensor entity."""
|
||||
super().__init__(ads_hub, name, ads_var)
|
||||
self._attr_unit_of_measurement = unit_of_measurement
|
||||
self._attr_native_unit_of_measurement = unit_of_measurement
|
||||
self._ads_type = ads_type
|
||||
self._factor = factor
|
||||
|
||||
@ -64,6 +64,6 @@ class AdsSensor(AdsEntity, SensorEntity):
|
||||
)
|
||||
|
||||
@property
|
||||
def state(self) -> StateType:
|
||||
def native_value(self) -> StateType:
|
||||
"""Return the state of the device."""
|
||||
return self._state_dict[STATE_KEY_STATE]
|
||||
|
@ -45,7 +45,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
class AdvantageAirTimeTo(AdvantageAirEntity, SensorEntity):
|
||||
"""Representation of Advantage Air timer control."""
|
||||
|
||||
_attr_unit_of_measurement = ADVANTAGE_AIR_SET_COUNTDOWN_UNIT
|
||||
_attr_native_unit_of_measurement = ADVANTAGE_AIR_SET_COUNTDOWN_UNIT
|
||||
|
||||
def __init__(self, instance, ac_key, action):
|
||||
"""Initialize the Advantage Air timer control."""
|
||||
@ -58,7 +58,7 @@ class AdvantageAirTimeTo(AdvantageAirEntity, SensorEntity):
|
||||
)
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def native_value(self):
|
||||
"""Return the current value."""
|
||||
return self._ac[self._time_key]
|
||||
|
||||
@ -78,7 +78,7 @@ class AdvantageAirTimeTo(AdvantageAirEntity, SensorEntity):
|
||||
class AdvantageAirZoneVent(AdvantageAirEntity, SensorEntity):
|
||||
"""Representation of Advantage Air Zone Vent Sensor."""
|
||||
|
||||
_attr_unit_of_measurement = PERCENTAGE
|
||||
_attr_native_unit_of_measurement = PERCENTAGE
|
||||
_attr_state_class = STATE_CLASS_MEASUREMENT
|
||||
|
||||
def __init__(self, instance, ac_key, zone_key):
|
||||
@ -90,7 +90,7 @@ class AdvantageAirZoneVent(AdvantageAirEntity, SensorEntity):
|
||||
)
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def native_value(self):
|
||||
"""Return the current value of the air vent."""
|
||||
if self._zone["state"] == ADVANTAGE_AIR_STATE_OPEN:
|
||||
return self._zone["value"]
|
||||
@ -107,7 +107,7 @@ class AdvantageAirZoneVent(AdvantageAirEntity, SensorEntity):
|
||||
class AdvantageAirZoneSignal(AdvantageAirEntity, SensorEntity):
|
||||
"""Representation of Advantage Air Zone wireless signal sensor."""
|
||||
|
||||
_attr_unit_of_measurement = PERCENTAGE
|
||||
_attr_native_unit_of_measurement = PERCENTAGE
|
||||
_attr_state_class = STATE_CLASS_MEASUREMENT
|
||||
|
||||
def __init__(self, instance, ac_key, zone_key):
|
||||
@ -119,7 +119,7 @@ class AdvantageAirZoneSignal(AdvantageAirEntity, SensorEntity):
|
||||
)
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def native_value(self):
|
||||
"""Return the current value of the wireless signal."""
|
||||
return self._zone["rssi"]
|
||||
|
||||
@ -140,7 +140,7 @@ class AdvantageAirZoneSignal(AdvantageAirEntity, SensorEntity):
|
||||
class AdvantageAirZoneTemp(AdvantageAirEntity, SensorEntity):
|
||||
"""Representation of Advantage Air Zone wireless signal sensor."""
|
||||
|
||||
_attr_unit_of_measurement = TEMP_CELSIUS
|
||||
_attr_native_unit_of_measurement = TEMP_CELSIUS
|
||||
_attr_state_class = STATE_CLASS_MEASUREMENT
|
||||
_attr_icon = "mdi:thermometer"
|
||||
_attr_entity_registry_enabled_default = False
|
||||
|
@ -85,7 +85,7 @@ class AbstractAemetSensor(CoordinatorEntity, SensorEntity):
|
||||
self._attr_name = f"{self._name} {self._sensor_name}"
|
||||
self._attr_unique_id = self._unique_id
|
||||
self._attr_device_class = sensor_configuration.get(SENSOR_DEVICE_CLASS)
|
||||
self._attr_unit_of_measurement = sensor_configuration.get(SENSOR_UNIT)
|
||||
self._attr_native_unit_of_measurement = sensor_configuration.get(SENSOR_UNIT)
|
||||
|
||||
|
||||
class AemetSensor(AbstractAemetSensor):
|
||||
@ -106,7 +106,7 @@ class AemetSensor(AbstractAemetSensor):
|
||||
self._weather_coordinator = weather_coordinator
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def native_value(self):
|
||||
"""Return the state of the device."""
|
||||
return self._weather_coordinator.data.get(self._sensor_type)
|
||||
|
||||
@ -134,7 +134,7 @@ class AemetForecastSensor(AbstractAemetSensor):
|
||||
)
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def native_value(self):
|
||||
"""Return the state of the device."""
|
||||
forecast = None
|
||||
forecasts = self._weather_coordinator.data.get(
|
||||
|
@ -109,7 +109,7 @@ async def async_setup_platform(
|
||||
class AfterShipSensor(SensorEntity):
|
||||
"""Representation of a AfterShip sensor."""
|
||||
|
||||
_attr_unit_of_measurement: str = "packages"
|
||||
_attr_native_unit_of_measurement: str = "packages"
|
||||
_attr_icon: str = ICON
|
||||
|
||||
def __init__(self, aftership: Tracking, name: str) -> None:
|
||||
@ -120,7 +120,7 @@ class AfterShipSensor(SensorEntity):
|
||||
self._attr_name = name
|
||||
|
||||
@property
|
||||
def state(self) -> int | None:
|
||||
def native_value(self) -> int | None:
|
||||
"""Return the state of the sensor."""
|
||||
return self._state
|
||||
|
||||
|
@ -50,34 +50,34 @@ SENSOR_TYPES: tuple[AirlySensorEntityDescription, ...] = (
|
||||
AirlySensorEntityDescription(
|
||||
key=ATTR_API_CAQI,
|
||||
name=ATTR_API_CAQI,
|
||||
unit_of_measurement="CAQI",
|
||||
native_unit_of_measurement="CAQI",
|
||||
),
|
||||
AirlySensorEntityDescription(
|
||||
key=ATTR_API_PM1,
|
||||
icon="mdi:blur",
|
||||
name=ATTR_API_PM1,
|
||||
unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
AirlySensorEntityDescription(
|
||||
key=ATTR_API_PM25,
|
||||
icon="mdi:blur",
|
||||
name="PM2.5",
|
||||
unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
AirlySensorEntityDescription(
|
||||
key=ATTR_API_PM10,
|
||||
icon="mdi:blur",
|
||||
name=ATTR_API_PM10,
|
||||
unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
AirlySensorEntityDescription(
|
||||
key=ATTR_API_HUMIDITY,
|
||||
device_class=DEVICE_CLASS_HUMIDITY,
|
||||
name=ATTR_API_HUMIDITY.capitalize(),
|
||||
unit_of_measurement=PERCENTAGE,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
value=lambda value: round(value, 1),
|
||||
),
|
||||
@ -85,14 +85,14 @@ SENSOR_TYPES: tuple[AirlySensorEntityDescription, ...] = (
|
||||
key=ATTR_API_PRESSURE,
|
||||
device_class=DEVICE_CLASS_PRESSURE,
|
||||
name=ATTR_API_PRESSURE.capitalize(),
|
||||
unit_of_measurement=PRESSURE_HPA,
|
||||
native_unit_of_measurement=PRESSURE_HPA,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
AirlySensorEntityDescription(
|
||||
key=ATTR_API_TEMPERATURE,
|
||||
device_class=DEVICE_CLASS_TEMPERATURE,
|
||||
name=ATTR_API_TEMPERATURE.capitalize(),
|
||||
unit_of_measurement=TEMP_CELSIUS,
|
||||
native_unit_of_measurement=TEMP_CELSIUS,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
value=lambda value: round(value, 1),
|
||||
),
|
||||
|
@ -84,7 +84,7 @@ class AirlySensor(CoordinatorEntity, SensorEntity):
|
||||
self.entity_description = description
|
||||
|
||||
@property
|
||||
def state(self) -> StateType:
|
||||
def native_value(self) -> StateType:
|
||||
"""Return the state."""
|
||||
state = self.coordinator.data[self.entity_description.key]
|
||||
return cast(StateType, self.entity_description.value(state))
|
||||
|
@ -72,11 +72,11 @@ class AirNowSensor(CoordinatorEntity, SensorEntity):
|
||||
self._attr_name = f"AirNow {SENSOR_TYPES[self.kind][ATTR_LABEL]}"
|
||||
self._attr_icon = SENSOR_TYPES[self.kind][ATTR_ICON]
|
||||
self._attr_device_class = SENSOR_TYPES[self.kind][ATTR_DEVICE_CLASS]
|
||||
self._attr_unit_of_measurement = SENSOR_TYPES[self.kind][ATTR_UNIT]
|
||||
self._attr_native_unit_of_measurement = SENSOR_TYPES[self.kind][ATTR_UNIT]
|
||||
self._attr_unique_id = f"{self.coordinator.latitude}-{self.coordinator.longitude}-{self.kind.lower()}"
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def native_value(self):
|
||||
"""Return the state."""
|
||||
self._state = self.coordinator.data[self.kind]
|
||||
return self._state
|
||||
|
@ -212,7 +212,7 @@ class AirVisualGeographySensor(AirVisualEntity, SensorEntity):
|
||||
self._attr_icon = icon
|
||||
self._attr_name = f"{GEOGRAPHY_SENSOR_LOCALES[locale]} {name}"
|
||||
self._attr_unique_id = f"{config_entry.unique_id}_{locale}_{kind}"
|
||||
self._attr_unit_of_measurement = unit
|
||||
self._attr_native_unit_of_measurement = unit
|
||||
self._config_entry = config_entry
|
||||
self._kind = kind
|
||||
self._locale = locale
|
||||
@ -232,16 +232,16 @@ class AirVisualGeographySensor(AirVisualEntity, SensorEntity):
|
||||
|
||||
if self._kind == SENSOR_KIND_LEVEL:
|
||||
aqi = data[f"aqi{self._locale}"]
|
||||
[(self._attr_state, self._attr_icon)] = [
|
||||
[(self._attr_native_value, self._attr_icon)] = [
|
||||
(name, icon)
|
||||
for (floor, ceiling), (name, icon) in POLLUTANT_LEVELS.items()
|
||||
if floor <= aqi <= ceiling
|
||||
]
|
||||
elif self._kind == SENSOR_KIND_AQI:
|
||||
self._attr_state = data[f"aqi{self._locale}"]
|
||||
self._attr_native_value = data[f"aqi{self._locale}"]
|
||||
elif self._kind == SENSOR_KIND_POLLUTANT:
|
||||
symbol = data[f"main{self._locale}"]
|
||||
self._attr_state = symbol
|
||||
self._attr_native_value = symbol
|
||||
self._attr_extra_state_attributes.update(
|
||||
{
|
||||
ATTR_POLLUTANT_SYMBOL: symbol,
|
||||
@ -298,7 +298,7 @@ class AirVisualNodeProSensor(AirVisualEntity, SensorEntity):
|
||||
f"{coordinator.data['settings']['node_name']} Node/Pro: {name}"
|
||||
)
|
||||
self._attr_unique_id = f"{coordinator.data['serial_number']}_{kind}"
|
||||
self._attr_unit_of_measurement = unit
|
||||
self._attr_native_unit_of_measurement = unit
|
||||
self._kind = kind
|
||||
|
||||
@property
|
||||
@ -320,24 +320,30 @@ class AirVisualNodeProSensor(AirVisualEntity, SensorEntity):
|
||||
"""Update the entity from the latest data."""
|
||||
if self._kind == SENSOR_KIND_AQI:
|
||||
if self.coordinator.data["settings"]["is_aqi_usa"]:
|
||||
self._attr_state = self.coordinator.data["measurements"]["aqi_us"]
|
||||
self._attr_native_value = self.coordinator.data["measurements"][
|
||||
"aqi_us"
|
||||
]
|
||||
else:
|
||||
self._attr_state = self.coordinator.data["measurements"]["aqi_cn"]
|
||||
self._attr_native_value = self.coordinator.data["measurements"][
|
||||
"aqi_cn"
|
||||
]
|
||||
elif self._kind == SENSOR_KIND_BATTERY_LEVEL:
|
||||
self._attr_state = self.coordinator.data["status"]["battery"]
|
||||
self._attr_native_value = self.coordinator.data["status"]["battery"]
|
||||
elif self._kind == SENSOR_KIND_CO2:
|
||||
self._attr_state = self.coordinator.data["measurements"].get("co2")
|
||||
self._attr_native_value = self.coordinator.data["measurements"].get("co2")
|
||||
elif self._kind == SENSOR_KIND_HUMIDITY:
|
||||
self._attr_state = self.coordinator.data["measurements"].get("humidity")
|
||||
self._attr_native_value = self.coordinator.data["measurements"].get(
|
||||
"humidity"
|
||||
)
|
||||
elif self._kind == SENSOR_KIND_PM_0_1:
|
||||
self._attr_state = self.coordinator.data["measurements"].get("pm0_1")
|
||||
self._attr_native_value = self.coordinator.data["measurements"].get("pm0_1")
|
||||
elif self._kind == SENSOR_KIND_PM_1_0:
|
||||
self._attr_state = self.coordinator.data["measurements"].get("pm1_0")
|
||||
self._attr_native_value = self.coordinator.data["measurements"].get("pm1_0")
|
||||
elif self._kind == SENSOR_KIND_PM_2_5:
|
||||
self._attr_state = self.coordinator.data["measurements"].get("pm2_5")
|
||||
self._attr_native_value = self.coordinator.data["measurements"].get("pm2_5")
|
||||
elif self._kind == SENSOR_KIND_TEMPERATURE:
|
||||
self._attr_state = self.coordinator.data["measurements"].get(
|
||||
self._attr_native_value = self.coordinator.data["measurements"].get(
|
||||
"temperature_C"
|
||||
)
|
||||
elif self._kind == SENSOR_KIND_VOC:
|
||||
self._attr_state = self.coordinator.data["measurements"].get("voc")
|
||||
self._attr_native_value = self.coordinator.data["measurements"].get("voc")
|
||||
|
@ -32,6 +32,6 @@ class AlarmDecoderSensor(SensorEntity):
|
||||
)
|
||||
|
||||
def _message_callback(self, message):
|
||||
if self._attr_state != message.text:
|
||||
self._attr_state = message.text
|
||||
if self._attr_native_value != message.text:
|
||||
self._attr_native_value = message.text
|
||||
self.schedule_update_ha_state()
|
||||
|
@ -112,7 +112,7 @@ class AlphaVantageSensor(SensorEntity):
|
||||
self._symbol = symbol[CONF_SYMBOL]
|
||||
self._attr_name = symbol.get(CONF_NAME, self._symbol)
|
||||
self._timeseries = timeseries
|
||||
self._attr_unit_of_measurement = symbol.get(CONF_CURRENCY, self._symbol)
|
||||
self._attr_native_unit_of_measurement = symbol.get(CONF_CURRENCY, self._symbol)
|
||||
self._attr_icon = ICONS.get(symbol.get(CONF_CURRENCY, "USD"))
|
||||
|
||||
def update(self):
|
||||
@ -120,7 +120,7 @@ class AlphaVantageSensor(SensorEntity):
|
||||
_LOGGER.debug("Requesting new data for symbol %s", self._symbol)
|
||||
all_values, _ = self._timeseries.get_intraday(self._symbol)
|
||||
values = next(iter(all_values.values()))
|
||||
self._attr_state = values["1. open"]
|
||||
self._attr_native_value = values["1. open"]
|
||||
self._attr_extra_state_attributes = (
|
||||
{
|
||||
ATTR_ATTRIBUTION: ATTRIBUTION,
|
||||
@ -148,7 +148,7 @@ class AlphaVantageForeignExchange(SensorEntity):
|
||||
else f"{self._to_currency}/{self._from_currency}"
|
||||
)
|
||||
self._attr_icon = ICONS.get(self._from_currency, "USD")
|
||||
self._attr_unit_of_measurement = self._to_currency
|
||||
self._attr_native_unit_of_measurement = self._to_currency
|
||||
|
||||
def update(self):
|
||||
"""Get the latest data and updates the states."""
|
||||
@ -160,7 +160,7 @@ class AlphaVantageForeignExchange(SensorEntity):
|
||||
values, _ = self._foreign_exchange.get_currency_exchange_rate(
|
||||
from_currency=self._from_currency, to_currency=self._to_currency
|
||||
)
|
||||
self._attr_state = round(float(values["5. Exchange Rate"]), 4)
|
||||
self._attr_native_value = round(float(values["5. Exchange Rate"]), 4)
|
||||
self._attr_extra_state_attributes = (
|
||||
{
|
||||
ATTR_ATTRIBUTION: ATTRIBUTION,
|
||||
|
@ -39,38 +39,38 @@ SENSORS: dict[str, list[SensorEntityDescription]] = {
|
||||
SensorEntityDescription(
|
||||
key="particulate_matter_2_5",
|
||||
name="Particulate Matter < 2.5 μm",
|
||||
unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="particulate_matter_10",
|
||||
name="Particulate Matter < 10 μm",
|
||||
unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="sulphur_dioxide",
|
||||
name="Sulphur Dioxide (SO2)",
|
||||
unit_of_measurement=CONCENTRATION_PARTS_PER_BILLION,
|
||||
native_unit_of_measurement=CONCENTRATION_PARTS_PER_BILLION,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="nitrogen_dioxide",
|
||||
name="Nitrogen Dioxide (NO2)",
|
||||
unit_of_measurement=CONCENTRATION_PARTS_PER_BILLION,
|
||||
native_unit_of_measurement=CONCENTRATION_PARTS_PER_BILLION,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="ozone",
|
||||
name="Ozone",
|
||||
unit_of_measurement=CONCENTRATION_PARTS_PER_BILLION,
|
||||
native_unit_of_measurement=CONCENTRATION_PARTS_PER_BILLION,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="carbon_monoxide",
|
||||
name="Carbon Monoxide (CO)",
|
||||
device_class=DEVICE_CLASS_CO,
|
||||
unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
|
||||
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
@ -85,21 +85,21 @@ SENSORS: dict[str, list[SensorEntityDescription]] = {
|
||||
name="Grass Pollen",
|
||||
icon="mdi:grass",
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
unit_of_measurement=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
native_unit_of_measurement=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="tree",
|
||||
name="Tree Pollen",
|
||||
icon="mdi:tree",
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
unit_of_measurement=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
native_unit_of_measurement=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="weed",
|
||||
name="Weed Pollen",
|
||||
icon="mdi:sprout",
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
unit_of_measurement=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
native_unit_of_measurement=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="grass_risk",
|
||||
@ -124,7 +124,7 @@ SENSORS: dict[str, list[SensorEntityDescription]] = {
|
||||
name="Poaceae Grass Pollen",
|
||||
icon="mdi:grass",
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
unit_of_measurement=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
native_unit_of_measurement=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
entity_registry_enabled_default=False,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
@ -132,7 +132,7 @@ SENSORS: dict[str, list[SensorEntityDescription]] = {
|
||||
name="Alder Tree Pollen",
|
||||
icon="mdi:tree",
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
unit_of_measurement=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
native_unit_of_measurement=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
entity_registry_enabled_default=False,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
@ -140,7 +140,7 @@ SENSORS: dict[str, list[SensorEntityDescription]] = {
|
||||
name="Birch Tree Pollen",
|
||||
icon="mdi:tree",
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
unit_of_measurement=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
native_unit_of_measurement=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
entity_registry_enabled_default=False,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
@ -148,7 +148,7 @@ SENSORS: dict[str, list[SensorEntityDescription]] = {
|
||||
name="Cypress Tree Pollen",
|
||||
icon="mdi:tree",
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
unit_of_measurement=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
native_unit_of_measurement=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
entity_registry_enabled_default=False,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
@ -156,7 +156,7 @@ SENSORS: dict[str, list[SensorEntityDescription]] = {
|
||||
name="Elm Tree Pollen",
|
||||
icon="mdi:tree",
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
unit_of_measurement=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
native_unit_of_measurement=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
entity_registry_enabled_default=False,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
@ -164,7 +164,7 @@ SENSORS: dict[str, list[SensorEntityDescription]] = {
|
||||
name="Hazel Tree Pollen",
|
||||
icon="mdi:tree",
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
unit_of_measurement=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
native_unit_of_measurement=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
entity_registry_enabled_default=False,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
@ -172,7 +172,7 @@ SENSORS: dict[str, list[SensorEntityDescription]] = {
|
||||
name="Oak Tree Pollen",
|
||||
icon="mdi:tree",
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
unit_of_measurement=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
native_unit_of_measurement=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
entity_registry_enabled_default=False,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
@ -180,7 +180,7 @@ SENSORS: dict[str, list[SensorEntityDescription]] = {
|
||||
name="Pine Tree Pollen",
|
||||
icon="mdi:tree",
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
unit_of_measurement=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
native_unit_of_measurement=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
entity_registry_enabled_default=False,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
@ -188,7 +188,7 @@ SENSORS: dict[str, list[SensorEntityDescription]] = {
|
||||
name="Plane Tree Pollen",
|
||||
icon="mdi:tree",
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
unit_of_measurement=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
native_unit_of_measurement=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
entity_registry_enabled_default=False,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
@ -196,7 +196,7 @@ SENSORS: dict[str, list[SensorEntityDescription]] = {
|
||||
name="Poplar Tree Pollen",
|
||||
icon="mdi:tree",
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
unit_of_measurement=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
native_unit_of_measurement=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
entity_registry_enabled_default=False,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
@ -204,7 +204,7 @@ SENSORS: dict[str, list[SensorEntityDescription]] = {
|
||||
name="Chenopod Weed Pollen",
|
||||
icon="mdi:sprout",
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
unit_of_measurement=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
native_unit_of_measurement=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
entity_registry_enabled_default=False,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
@ -212,7 +212,7 @@ SENSORS: dict[str, list[SensorEntityDescription]] = {
|
||||
name="Mugwort Weed Pollen",
|
||||
icon="mdi:sprout",
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
unit_of_measurement=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
native_unit_of_measurement=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
entity_registry_enabled_default=False,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
@ -220,7 +220,7 @@ SENSORS: dict[str, list[SensorEntityDescription]] = {
|
||||
name="Nettle Weed Pollen",
|
||||
icon="mdi:sprout",
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
unit_of_measurement=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
native_unit_of_measurement=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
entity_registry_enabled_default=False,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
@ -228,7 +228,7 @@ SENSORS: dict[str, list[SensorEntityDescription]] = {
|
||||
name="Ragweed Weed Pollen",
|
||||
icon="mdi:sprout",
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
unit_of_measurement=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
native_unit_of_measurement=CONCENTRATION_PARTS_PER_CUBIC_METER,
|
||||
entity_registry_enabled_default=False,
|
||||
),
|
||||
],
|
||||
|
@ -66,7 +66,7 @@ class AmbeeSensorEntity(CoordinatorEntity, SensorEntity):
|
||||
}
|
||||
|
||||
@property
|
||||
def state(self) -> StateType:
|
||||
def native_value(self) -> StateType:
|
||||
"""Return the state of the sensor."""
|
||||
value = getattr(self.coordinator.data, self.entity_description.key)
|
||||
if isinstance(value, str):
|
||||
|
@ -61,7 +61,7 @@ class AmbientWeatherSensor(AmbientWeatherEntity, SensorEntity):
|
||||
ambient, mac_address, station_name, sensor_type, sensor_name, device_class
|
||||
)
|
||||
|
||||
self._attr_unit_of_measurement = unit
|
||||
self._attr_native_unit_of_measurement = unit
|
||||
|
||||
@callback
|
||||
def update_from_latest_data(self) -> None:
|
||||
@ -75,10 +75,10 @@ class AmbientWeatherSensor(AmbientWeatherEntity, SensorEntity):
|
||||
].get(TYPE_SOLARRADIATION)
|
||||
|
||||
if w_m2_brightness_val is None:
|
||||
self._attr_state = None
|
||||
self._attr_native_value = None
|
||||
else:
|
||||
self._attr_state = round(float(w_m2_brightness_val) / 0.0079)
|
||||
self._attr_native_value = round(float(w_m2_brightness_val) / 0.0079)
|
||||
else:
|
||||
self._attr_state = self._ambient.stations[self._mac_address][
|
||||
self._attr_native_value = self._ambient.stations[self._mac_address][
|
||||
ATTR_LAST_DATA
|
||||
].get(self._sensor_type)
|
||||
|
@ -61,7 +61,7 @@ class AmcrestSensor(SensorEntity):
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def native_value(self):
|
||||
"""Return the state of the sensor."""
|
||||
return self._state
|
||||
|
||||
@ -76,7 +76,7 @@ class AmcrestSensor(SensorEntity):
|
||||
return self._icon
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self):
|
||||
def native_unit_of_measurement(self):
|
||||
"""Return the units of measurement."""
|
||||
return self._unit_of_measurement
|
||||
|
||||
|
@ -50,12 +50,12 @@ class IPWebcamSensor(AndroidIPCamEntity, SensorEntity):
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self):
|
||||
def native_unit_of_measurement(self):
|
||||
"""Return the unit the value is expressed in."""
|
||||
return self._unit
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def native_value(self):
|
||||
"""Return the state of the sensor."""
|
||||
return self._state
|
||||
|
||||
|
@ -165,16 +165,16 @@ class APCUPSdSensor(SensorEntity):
|
||||
self.type = sensor_type
|
||||
self._attr_name = SENSOR_PREFIX + SENSOR_TYPES[sensor_type][0]
|
||||
self._attr_icon = SENSOR_TYPES[self.type][2]
|
||||
self._attr_unit_of_measurement = SENSOR_TYPES[sensor_type][1]
|
||||
self._attr_native_unit_of_measurement = SENSOR_TYPES[sensor_type][1]
|
||||
self._attr_device_class = SENSOR_TYPES[sensor_type][3]
|
||||
|
||||
def update(self):
|
||||
"""Get the latest status and use it to update our sensor state."""
|
||||
if self.type.upper() not in self._data.status:
|
||||
self._attr_state = None
|
||||
self._attr_native_value = None
|
||||
else:
|
||||
self._attr_state, inferred_unit = infer_unit(
|
||||
self._attr_native_value, inferred_unit = infer_unit(
|
||||
self._data.status[self.type.upper()]
|
||||
)
|
||||
if not self._attr_unit_of_measurement:
|
||||
self._attr_unit_of_measurement = inferred_unit
|
||||
if not self._attr_native_unit_of_measurement:
|
||||
self._attr_native_unit_of_measurement = inferred_unit
|
||||
|
@ -92,11 +92,11 @@ class AquaLogicSensor(SensorEntity):
|
||||
panel = self._processor.panel
|
||||
if panel is not None:
|
||||
if panel.is_metric:
|
||||
self._attr_unit_of_measurement = SENSOR_TYPES[self._type][1][0]
|
||||
self._attr_native_unit_of_measurement = SENSOR_TYPES[self._type][1][0]
|
||||
else:
|
||||
self._attr_unit_of_measurement = SENSOR_TYPES[self._type][1][1]
|
||||
self._attr_native_unit_of_measurement = SENSOR_TYPES[self._type][1][1]
|
||||
|
||||
self._attr_state = getattr(panel, self._type)
|
||||
self._attr_native_value = getattr(panel, self._type)
|
||||
self.async_write_ha_state()
|
||||
else:
|
||||
self._attr_unit_of_measurement = None
|
||||
self._attr_native_unit_of_measurement = None
|
||||
|
@ -42,4 +42,4 @@ class ArduinoSensor(SensorEntity):
|
||||
|
||||
def update(self):
|
||||
"""Get the latest value from the pin."""
|
||||
self._attr_state = self._board.get_analog_inputs()[self._pin][1]
|
||||
self._attr_native_value = self._board.get_analog_inputs()[self._pin][1]
|
||||
|
@ -141,7 +141,7 @@ class ArestSensor(SensorEntity):
|
||||
self.arest = arest
|
||||
self._attr_name = f"{location.title()} {name.title()}"
|
||||
self._variable = variable
|
||||
self._attr_unit_of_measurement = unit_of_measurement
|
||||
self._attr_native_unit_of_measurement = unit_of_measurement
|
||||
self._renderer = renderer
|
||||
|
||||
if pin is not None:
|
||||
@ -155,9 +155,9 @@ class ArestSensor(SensorEntity):
|
||||
self._attr_available = self.arest.available
|
||||
values = self.arest.data
|
||||
if "error" in values:
|
||||
self._attr_state = values["error"]
|
||||
self._attr_native_value = values["error"]
|
||||
else:
|
||||
self._attr_state = self._renderer(
|
||||
self._attr_native_value = self._renderer(
|
||||
values.get("value", values.get(self._variable, None))
|
||||
)
|
||||
|
||||
|
@ -127,7 +127,7 @@ class ArloSensor(SensorEntity):
|
||||
self.async_schedule_update_ha_state(True)
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def native_value(self):
|
||||
"""Return the state of the sensor."""
|
||||
return self._state
|
||||
|
||||
|
@ -138,7 +138,7 @@ class ArwnSensor(SensorEntity):
|
||||
# This mqtt topic for the sensor which is its uid
|
||||
self._attr_unique_id = topic
|
||||
self._state_key = state_key
|
||||
self._attr_unit_of_measurement = units
|
||||
self._attr_native_unit_of_measurement = units
|
||||
self._attr_icon = icon
|
||||
self._attr_device_class = device_class
|
||||
|
||||
@ -147,5 +147,5 @@ class ArwnSensor(SensorEntity):
|
||||
ev = {}
|
||||
ev.update(event)
|
||||
self._attr_extra_state_attributes = ev
|
||||
self._attr_state = ev.get(self._state_key, None)
|
||||
self._attr_native_value = ev.get(self._state_key, None)
|
||||
self.async_write_ha_state()
|
||||
|
@ -48,13 +48,13 @@ CONNECTION_SENSORS: tuple[AsusWrtSensorEntityDescription, ...] = (
|
||||
key=SENSORS_CONNECTED_DEVICE[0],
|
||||
name="Devices Connected",
|
||||
icon="mdi:router-network",
|
||||
unit_of_measurement=UNIT_DEVICES,
|
||||
native_unit_of_measurement=UNIT_DEVICES,
|
||||
),
|
||||
AsusWrtSensorEntityDescription(
|
||||
key=SENSORS_RATES[0],
|
||||
name="Download Speed",
|
||||
icon="mdi:download-network",
|
||||
unit_of_measurement=DATA_RATE_MEGABITS_PER_SECOND,
|
||||
native_unit_of_measurement=DATA_RATE_MEGABITS_PER_SECOND,
|
||||
entity_registry_enabled_default=False,
|
||||
factor=125000,
|
||||
),
|
||||
@ -62,7 +62,7 @@ CONNECTION_SENSORS: tuple[AsusWrtSensorEntityDescription, ...] = (
|
||||
key=SENSORS_RATES[1],
|
||||
name="Upload Speed",
|
||||
icon="mdi:upload-network",
|
||||
unit_of_measurement=DATA_RATE_MEGABITS_PER_SECOND,
|
||||
native_unit_of_measurement=DATA_RATE_MEGABITS_PER_SECOND,
|
||||
entity_registry_enabled_default=False,
|
||||
factor=125000,
|
||||
),
|
||||
@ -70,7 +70,7 @@ CONNECTION_SENSORS: tuple[AsusWrtSensorEntityDescription, ...] = (
|
||||
key=SENSORS_BYTES[0],
|
||||
name="Download",
|
||||
icon="mdi:download",
|
||||
unit_of_measurement=DATA_GIGABYTES,
|
||||
native_unit_of_measurement=DATA_GIGABYTES,
|
||||
entity_registry_enabled_default=False,
|
||||
factor=1000000000,
|
||||
),
|
||||
@ -78,7 +78,7 @@ CONNECTION_SENSORS: tuple[AsusWrtSensorEntityDescription, ...] = (
|
||||
key=SENSORS_BYTES[1],
|
||||
name="Upload",
|
||||
icon="mdi:upload",
|
||||
unit_of_measurement=DATA_GIGABYTES,
|
||||
native_unit_of_measurement=DATA_GIGABYTES,
|
||||
entity_registry_enabled_default=False,
|
||||
factor=1000000000,
|
||||
),
|
||||
@ -150,11 +150,11 @@ class AsusWrtSensor(CoordinatorEntity, SensorEntity):
|
||||
self._attr_unique_id = f"{DOMAIN} {self.name}"
|
||||
self._attr_state_class = STATE_CLASS_MEASUREMENT
|
||||
|
||||
if description.unit_of_measurement == DATA_GIGABYTES:
|
||||
if description.native_unit_of_measurement == DATA_GIGABYTES:
|
||||
self._attr_last_reset = dt_util.utc_from_timestamp(0)
|
||||
|
||||
@property
|
||||
def state(self) -> str:
|
||||
def native_value(self) -> str:
|
||||
"""Return current state."""
|
||||
descr = self.entity_description
|
||||
state = self.coordinator.data.get(descr.key)
|
||||
|
@ -49,10 +49,12 @@ class AtagSensor(AtagEntity, SensorEntity):
|
||||
PERCENTAGE,
|
||||
TIME_HOURS,
|
||||
):
|
||||
self._attr_unit_of_measurement = coordinator.data.report[self._id].measure
|
||||
self._attr_native_unit_of_measurement = coordinator.data.report[
|
||||
self._id
|
||||
].measure
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def native_value(self):
|
||||
"""Return the state of the sensor."""
|
||||
return self.coordinator.data.report[self._id].state
|
||||
|
||||
|
@ -258,10 +258,10 @@ class AtomeSensor(SensorEntity):
|
||||
|
||||
if sensor_type == LIVE_TYPE:
|
||||
self._attr_device_class = DEVICE_CLASS_POWER
|
||||
self._attr_unit_of_measurement = POWER_WATT
|
||||
self._attr_native_unit_of_measurement = POWER_WATT
|
||||
else:
|
||||
self._attr_device_class = DEVICE_CLASS_ENERGY
|
||||
self._attr_unit_of_measurement = ENERGY_KILO_WATT_HOUR
|
||||
self._attr_native_unit_of_measurement = ENERGY_KILO_WATT_HOUR
|
||||
|
||||
def update(self):
|
||||
"""Update device state."""
|
||||
@ -269,13 +269,13 @@ class AtomeSensor(SensorEntity):
|
||||
update_function()
|
||||
|
||||
if self._sensor_type == LIVE_TYPE:
|
||||
self._attr_state = self._data.live_power
|
||||
self._attr_native_value = self._data.live_power
|
||||
self._attr_extra_state_attributes = {
|
||||
"subscribed_power": self._data.subscribed_power,
|
||||
"is_connected": self._data.is_connected,
|
||||
}
|
||||
else:
|
||||
self._attr_state = getattr(self._data, f"{self._sensor_type}_usage")
|
||||
self._attr_native_value = getattr(self._data, f"{self._sensor_type}_usage")
|
||||
self._attr_last_reset = dt_util.as_utc(
|
||||
getattr(self._data, f"{self._sensor_type}_last_reset")
|
||||
)
|
||||
|
@ -146,7 +146,7 @@ class AugustOperatorSensor(AugustEntityMixin, RestoreEntity, SensorEntity):
|
||||
|
||||
self._attr_available = True
|
||||
if lock_activity is not None:
|
||||
self._attr_state = lock_activity.operated_by
|
||||
self._attr_native_value = lock_activity.operated_by
|
||||
self._operated_remote = lock_activity.operated_remote
|
||||
self._operated_keypad = lock_activity.operated_keypad
|
||||
self._operated_autorelock = lock_activity.operated_autorelock
|
||||
@ -208,7 +208,7 @@ class AugustBatterySensor(AugustEntityMixin, SensorEntity):
|
||||
"""Representation of an August sensor."""
|
||||
|
||||
_attr_device_class = DEVICE_CLASS_BATTERY
|
||||
_attr_unit_of_measurement = PERCENTAGE
|
||||
_attr_native_unit_of_measurement = PERCENTAGE
|
||||
|
||||
def __init__(self, data, sensor_type, device, old_device):
|
||||
"""Initialize the sensor."""
|
||||
@ -223,8 +223,8 @@ class AugustBatterySensor(AugustEntityMixin, SensorEntity):
|
||||
def _update_from_data(self):
|
||||
"""Get the latest state of the sensor."""
|
||||
state_provider = SENSOR_TYPES_BATTERY[self._sensor_type]["state_provider"]
|
||||
self._attr_state = state_provider(self._detail)
|
||||
self._attr_available = self._attr_state is not None
|
||||
self._attr_native_value = state_provider(self._detail)
|
||||
self._attr_available = self._attr_native_value is not None
|
||||
|
||||
@property
|
||||
def old_unique_id(self) -> str:
|
||||
|
@ -22,9 +22,9 @@ async def async_setup_entry(hass, entry, async_add_entries):
|
||||
class AuroraSensor(AuroraEntity, SensorEntity):
|
||||
"""Implementation of an aurora sensor."""
|
||||
|
||||
_attr_unit_of_measurement = PERCENTAGE
|
||||
_attr_native_unit_of_measurement = PERCENTAGE
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def native_value(self):
|
||||
"""Return % chance the aurora is visible."""
|
||||
return self.coordinator.data
|
||||
|
@ -51,7 +51,7 @@ class AuroraABBSolarPVMonitorSensor(SensorEntity):
|
||||
"""Representation of a Sensor."""
|
||||
|
||||
_attr_state_class = STATE_CLASS_MEASUREMENT
|
||||
_attr_unit_of_measurement = POWER_WATT
|
||||
_attr_native_unit_of_measurement = POWER_WATT
|
||||
_attr_device_class = DEVICE_CLASS_POWER
|
||||
|
||||
def __init__(self, client, name, typename):
|
||||
@ -68,7 +68,7 @@ class AuroraABBSolarPVMonitorSensor(SensorEntity):
|
||||
self.client.connect()
|
||||
# read ADC channel 3 (grid power output)
|
||||
power_watts = self.client.measure(3, True)
|
||||
self._attr_state = round(power_watts, 1)
|
||||
self._attr_native_value = round(power_watts, 1)
|
||||
except AuroraError as error:
|
||||
# aurorapy does not have different exceptions (yet) for dealing
|
||||
# with timeout vs other comms errors.
|
||||
@ -82,7 +82,7 @@ class AuroraABBSolarPVMonitorSensor(SensorEntity):
|
||||
_LOGGER.debug("No response from inverter (could be dark)")
|
||||
else:
|
||||
raise error
|
||||
self._attr_state = None
|
||||
self._attr_native_value = None
|
||||
finally:
|
||||
if self.client.serline.isOpen():
|
||||
self.client.close()
|
||||
|
@ -144,7 +144,7 @@ class AwairSensor(CoordinatorEntity, SensorEntity):
|
||||
return False
|
||||
|
||||
@property
|
||||
def state(self) -> float:
|
||||
def native_value(self) -> float:
|
||||
"""Return the state, rounding off to reasonable values."""
|
||||
state: float
|
||||
|
||||
@ -175,7 +175,7 @@ class AwairSensor(CoordinatorEntity, SensorEntity):
|
||||
return SENSOR_TYPES[self._kind][ATTR_DEVICE_CLASS]
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self) -> str:
|
||||
def native_unit_of_measurement(self) -> str:
|
||||
"""Return the unit the value is expressed in."""
|
||||
return SENSOR_TYPES[self._kind][ATTR_UNIT]
|
||||
|
||||
|
@ -71,7 +71,7 @@ class AzureDevOpsSensor(AzureDevOpsDeviceEntity, SensorEntity):
|
||||
unit_of_measurement: str = "",
|
||||
) -> None:
|
||||
"""Initialize Azure DevOps sensor."""
|
||||
self._attr_unit_of_measurement = unit_of_measurement
|
||||
self._attr_native_unit_of_measurement = unit_of_measurement
|
||||
self.client = client
|
||||
self.organization = organization
|
||||
self.project = project
|
||||
@ -107,7 +107,7 @@ class AzureDevOpsLatestBuildSensor(AzureDevOpsSensor):
|
||||
_LOGGER.warning(exception)
|
||||
self._attr_available = False
|
||||
return False
|
||||
self._attr_state = build.build_number
|
||||
self._attr_native_value = build.build_number
|
||||
self._attr_extra_state_attributes = {
|
||||
"definition_id": build.definition.id,
|
||||
"definition_name": build.definition.name,
|
||||
|
@ -94,7 +94,7 @@ class BboxUptimeSensor(SensorEntity):
|
||||
def __init__(self, bbox_data, sensor_type, name):
|
||||
"""Initialize the sensor."""
|
||||
self._attr_name = f"{name} {SENSOR_TYPES[sensor_type][0]}"
|
||||
self._unit_of_measurement = SENSOR_TYPES[sensor_type][1]
|
||||
self._attr_native_unit_of_measurement = SENSOR_TYPES[sensor_type][1]
|
||||
self._attr_icon = SENSOR_TYPES[sensor_type][2]
|
||||
self.bbox_data = bbox_data
|
||||
|
||||
@ -104,7 +104,7 @@ class BboxUptimeSensor(SensorEntity):
|
||||
uptime = utcnow() - timedelta(
|
||||
seconds=self.bbox_data.router_infos["device"]["uptime"]
|
||||
)
|
||||
self._attr_state = uptime.replace(microsecond=0).isoformat()
|
||||
self._attr_native_value = uptime.replace(microsecond=0).isoformat()
|
||||
|
||||
|
||||
class BboxSensor(SensorEntity):
|
||||
@ -116,7 +116,7 @@ class BboxSensor(SensorEntity):
|
||||
"""Initialize the sensor."""
|
||||
self.type = sensor_type
|
||||
self._attr_name = f"{name} {SENSOR_TYPES[sensor_type][0]}"
|
||||
self._attr_unit_of_measurement = SENSOR_TYPES[sensor_type][1]
|
||||
self._attr_native_unit_of_measurement = SENSOR_TYPES[sensor_type][1]
|
||||
self._attr_icon = SENSOR_TYPES[sensor_type][2]
|
||||
self.bbox_data = bbox_data
|
||||
|
||||
@ -124,19 +124,25 @@ class BboxSensor(SensorEntity):
|
||||
"""Get the latest data from Bbox and update the state."""
|
||||
self.bbox_data.update()
|
||||
if self.type == "down_max_bandwidth":
|
||||
self._attr_state = round(
|
||||
self._attr_native_value = round(
|
||||
self.bbox_data.data["rx"]["maxBandwidth"] / 1000, 2
|
||||
)
|
||||
elif self.type == "up_max_bandwidth":
|
||||
self._attr_state = round(
|
||||
self._attr_native_value = round(
|
||||
self.bbox_data.data["tx"]["maxBandwidth"] / 1000, 2
|
||||
)
|
||||
elif self.type == "current_down_bandwidth":
|
||||
self._attr_state = round(self.bbox_data.data["rx"]["bandwidth"] / 1000, 2)
|
||||
self._attr_native_value = round(
|
||||
self.bbox_data.data["rx"]["bandwidth"] / 1000, 2
|
||||
)
|
||||
elif self.type == "current_up_bandwidth":
|
||||
self._attr_state = round(self.bbox_data.data["tx"]["bandwidth"] / 1000, 2)
|
||||
self._attr_native_value = round(
|
||||
self.bbox_data.data["tx"]["bandwidth"] / 1000, 2
|
||||
)
|
||||
elif self.type == "number_of_reboots":
|
||||
self._attr_state = self.bbox_data.router_infos["device"]["numberofboots"]
|
||||
self._attr_native_value = self.bbox_data.router_infos["device"][
|
||||
"numberofboots"
|
||||
]
|
||||
|
||||
|
||||
class BboxData:
|
||||
|
@ -63,17 +63,17 @@ class BeewiSmartclimSensor(SensorEntity):
|
||||
self._poller = poller
|
||||
self._attr_name = name
|
||||
self._device = device
|
||||
self._attr_unit_of_measurement = unit
|
||||
self._attr_native_unit_of_measurement = unit
|
||||
self._attr_device_class = self._device
|
||||
self._attr_unique_id = f"{mac}_{device}"
|
||||
|
||||
def update(self):
|
||||
"""Fetch new state data from the poller."""
|
||||
self._poller.update_sensor()
|
||||
self._attr_state = None
|
||||
self._attr_native_value = None
|
||||
if self._device == DEVICE_CLASS_TEMPERATURE:
|
||||
self._attr_state = self._poller.get_temperature()
|
||||
self._attr_native_value = self._poller.get_temperature()
|
||||
if self._device == DEVICE_CLASS_HUMIDITY:
|
||||
self._attr_state = self._poller.get_humidity()
|
||||
self._attr_native_value = self._poller.get_humidity()
|
||||
if self._device == DEVICE_CLASS_BATTERY:
|
||||
self._attr_state = self._poller.get_battery()
|
||||
self._attr_native_value = self._poller.get_battery()
|
||||
|
@ -101,7 +101,7 @@ class BH1750Sensor(SensorEntity):
|
||||
def __init__(self, bh1750_sensor, name, unit, multiplier=1.0):
|
||||
"""Initialize the sensor."""
|
||||
self._attr_name = name
|
||||
self._attr_unit_of_measurement = unit
|
||||
self._attr_native_unit_of_measurement = unit
|
||||
self._multiplier = multiplier
|
||||
self.bh1750_sensor = bh1750_sensor
|
||||
|
||||
@ -109,7 +109,7 @@ class BH1750Sensor(SensorEntity):
|
||||
"""Get the latest data from the BH1750 and update the states."""
|
||||
await self.hass.async_add_executor_job(self.bh1750_sensor.update)
|
||||
if self.bh1750_sensor.sample_ok and self.bh1750_sensor.light_level >= 0:
|
||||
self._attr_state = int(
|
||||
self._attr_native_value = int(
|
||||
round(self.bh1750_sensor.light_level * self._multiplier)
|
||||
)
|
||||
else:
|
||||
|
@ -39,22 +39,22 @@ SENSOR_TYPES: tuple[SensorEntityDescription, ...] = (
|
||||
SensorEntityDescription(
|
||||
key="trade_volume_btc",
|
||||
name="Trade volume",
|
||||
unit_of_measurement="BTC",
|
||||
native_unit_of_measurement="BTC",
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="miners_revenue_usd",
|
||||
name="Miners revenue",
|
||||
unit_of_measurement="USD",
|
||||
native_unit_of_measurement="USD",
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="btc_mined",
|
||||
name="Mined",
|
||||
unit_of_measurement="BTC",
|
||||
native_unit_of_measurement="BTC",
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="trade_volume_usd",
|
||||
name="Trade volume",
|
||||
unit_of_measurement="USD",
|
||||
native_unit_of_measurement="USD",
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="difficulty",
|
||||
@ -63,7 +63,7 @@ SENSOR_TYPES: tuple[SensorEntityDescription, ...] = (
|
||||
SensorEntityDescription(
|
||||
key="minutes_between_blocks",
|
||||
name="Time between Blocks",
|
||||
unit_of_measurement=TIME_MINUTES,
|
||||
native_unit_of_measurement=TIME_MINUTES,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="number_of_transactions",
|
||||
@ -72,7 +72,7 @@ SENSOR_TYPES: tuple[SensorEntityDescription, ...] = (
|
||||
SensorEntityDescription(
|
||||
key="hash_rate",
|
||||
name="Hash rate",
|
||||
unit_of_measurement=f"PH/{TIME_SECONDS}",
|
||||
native_unit_of_measurement=f"PH/{TIME_SECONDS}",
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="timestamp",
|
||||
@ -89,22 +89,22 @@ SENSOR_TYPES: tuple[SensorEntityDescription, ...] = (
|
||||
SensorEntityDescription(
|
||||
key="total_fees_btc",
|
||||
name="Total fees",
|
||||
unit_of_measurement="BTC",
|
||||
native_unit_of_measurement="BTC",
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="total_btc_sent",
|
||||
name="Total sent",
|
||||
unit_of_measurement="BTC",
|
||||
native_unit_of_measurement="BTC",
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="estimated_btc_sent",
|
||||
name="Estimated sent",
|
||||
unit_of_measurement="BTC",
|
||||
native_unit_of_measurement="BTC",
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="total_btc",
|
||||
name="Total",
|
||||
unit_of_measurement="BTC",
|
||||
native_unit_of_measurement="BTC",
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="total_blocks",
|
||||
@ -117,17 +117,17 @@ SENSOR_TYPES: tuple[SensorEntityDescription, ...] = (
|
||||
SensorEntityDescription(
|
||||
key="estimated_transaction_volume_usd",
|
||||
name="Est. Transaction volume",
|
||||
unit_of_measurement="USD",
|
||||
native_unit_of_measurement="USD",
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="miners_revenue_btc",
|
||||
name="Miners revenue",
|
||||
unit_of_measurement="BTC",
|
||||
native_unit_of_measurement="BTC",
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="market_price_usd",
|
||||
name="Market price",
|
||||
unit_of_measurement="USD",
|
||||
native_unit_of_measurement="USD",
|
||||
),
|
||||
)
|
||||
|
||||
@ -182,48 +182,48 @@ class BitcoinSensor(SensorEntity):
|
||||
|
||||
sensor_type = self.entity_description.key
|
||||
if sensor_type == "exchangerate":
|
||||
self._attr_state = ticker[self._currency].p15min
|
||||
self._attr_unit_of_measurement = self._currency
|
||||
self._attr_native_value = ticker[self._currency].p15min
|
||||
self._attr_native_unit_of_measurement = self._currency
|
||||
elif sensor_type == "trade_volume_btc":
|
||||
self._attr_state = f"{stats.trade_volume_btc:.1f}"
|
||||
self._attr_native_value = f"{stats.trade_volume_btc:.1f}"
|
||||
elif sensor_type == "miners_revenue_usd":
|
||||
self._attr_state = f"{stats.miners_revenue_usd:.0f}"
|
||||
self._attr_native_value = f"{stats.miners_revenue_usd:.0f}"
|
||||
elif sensor_type == "btc_mined":
|
||||
self._attr_state = str(stats.btc_mined * 0.00000001)
|
||||
self._attr_native_value = str(stats.btc_mined * 0.00000001)
|
||||
elif sensor_type == "trade_volume_usd":
|
||||
self._attr_state = f"{stats.trade_volume_usd:.1f}"
|
||||
self._attr_native_value = f"{stats.trade_volume_usd:.1f}"
|
||||
elif sensor_type == "difficulty":
|
||||
self._attr_state = f"{stats.difficulty:.0f}"
|
||||
self._attr_native_value = f"{stats.difficulty:.0f}"
|
||||
elif sensor_type == "minutes_between_blocks":
|
||||
self._attr_state = f"{stats.minutes_between_blocks:.2f}"
|
||||
self._attr_native_value = f"{stats.minutes_between_blocks:.2f}"
|
||||
elif sensor_type == "number_of_transactions":
|
||||
self._attr_state = str(stats.number_of_transactions)
|
||||
self._attr_native_value = str(stats.number_of_transactions)
|
||||
elif sensor_type == "hash_rate":
|
||||
self._attr_state = f"{stats.hash_rate * 0.000001:.1f}"
|
||||
self._attr_native_value = f"{stats.hash_rate * 0.000001:.1f}"
|
||||
elif sensor_type == "timestamp":
|
||||
self._attr_state = stats.timestamp
|
||||
self._attr_native_value = stats.timestamp
|
||||
elif sensor_type == "mined_blocks":
|
||||
self._attr_state = str(stats.mined_blocks)
|
||||
self._attr_native_value = str(stats.mined_blocks)
|
||||
elif sensor_type == "blocks_size":
|
||||
self._attr_state = f"{stats.blocks_size:.1f}"
|
||||
self._attr_native_value = f"{stats.blocks_size:.1f}"
|
||||
elif sensor_type == "total_fees_btc":
|
||||
self._attr_state = f"{stats.total_fees_btc * 0.00000001:.2f}"
|
||||
self._attr_native_value = f"{stats.total_fees_btc * 0.00000001:.2f}"
|
||||
elif sensor_type == "total_btc_sent":
|
||||
self._attr_state = f"{stats.total_btc_sent * 0.00000001:.2f}"
|
||||
self._attr_native_value = f"{stats.total_btc_sent * 0.00000001:.2f}"
|
||||
elif sensor_type == "estimated_btc_sent":
|
||||
self._attr_state = f"{stats.estimated_btc_sent * 0.00000001:.2f}"
|
||||
self._attr_native_value = f"{stats.estimated_btc_sent * 0.00000001:.2f}"
|
||||
elif sensor_type == "total_btc":
|
||||
self._attr_state = f"{stats.total_btc * 0.00000001:.2f}"
|
||||
self._attr_native_value = f"{stats.total_btc * 0.00000001:.2f}"
|
||||
elif sensor_type == "total_blocks":
|
||||
self._attr_state = f"{stats.total_blocks:.0f}"
|
||||
self._attr_native_value = f"{stats.total_blocks:.0f}"
|
||||
elif sensor_type == "next_retarget":
|
||||
self._attr_state = f"{stats.next_retarget:.2f}"
|
||||
self._attr_native_value = f"{stats.next_retarget:.2f}"
|
||||
elif sensor_type == "estimated_transaction_volume_usd":
|
||||
self._attr_state = f"{stats.estimated_transaction_volume_usd:.2f}"
|
||||
self._attr_native_value = f"{stats.estimated_transaction_volume_usd:.2f}"
|
||||
elif sensor_type == "miners_revenue_btc":
|
||||
self._attr_state = f"{stats.miners_revenue_btc * 0.00000001:.1f}"
|
||||
self._attr_native_value = f"{stats.miners_revenue_btc * 0.00000001:.1f}"
|
||||
elif sensor_type == "market_price_usd":
|
||||
self._attr_state = f"{stats.market_price_usd:.2f}"
|
||||
self._attr_native_value = f"{stats.market_price_usd:.2f}"
|
||||
|
||||
|
||||
class BitcoinData:
|
||||
|
@ -37,7 +37,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||
class BizkaibusSensor(SensorEntity):
|
||||
"""The class for handling the data."""
|
||||
|
||||
_attr_unit_of_measurement = TIME_MINUTES
|
||||
_attr_native_unit_of_measurement = TIME_MINUTES
|
||||
|
||||
def __init__(self, data, name):
|
||||
"""Initialize the sensor."""
|
||||
@ -48,7 +48,7 @@ class BizkaibusSensor(SensorEntity):
|
||||
"""Get the latest data from the webservice."""
|
||||
self.data.update()
|
||||
with suppress(TypeError):
|
||||
self._attr_state = self.data.info[0][ATTR_DUE_IN]
|
||||
self._attr_native_value = self.data.info[0][ATTR_DUE_IN]
|
||||
|
||||
|
||||
class Bizkaibus:
|
||||
|
@ -20,10 +20,10 @@ class BleBoxSensorEntity(BleBoxEntity, SensorEntity):
|
||||
def __init__(self, feature):
|
||||
"""Initialize a BleBox sensor feature."""
|
||||
super().__init__(feature)
|
||||
self._attr_unit_of_measurement = BLEBOX_TO_UNIT_MAP[feature.unit]
|
||||
self._attr_native_unit_of_measurement = BLEBOX_TO_UNIT_MAP[feature.unit]
|
||||
self._attr_device_class = BLEBOX_TO_HASS_DEVICE_CLASSES[feature.device_class]
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def native_value(self):
|
||||
"""Return the state."""
|
||||
return self._feature.current
|
||||
|
@ -44,7 +44,7 @@ class BlinkSensor(SensorEntity):
|
||||
self._attr_device_class = device_class
|
||||
self.data = data
|
||||
self._camera = data.cameras[camera]
|
||||
self._attr_unit_of_measurement = units
|
||||
self._attr_native_unit_of_measurement = units
|
||||
self._attr_unique_id = f"{self._camera.serial}-{sensor_type}"
|
||||
self._sensor_key = (
|
||||
"temperature_calibrated" if sensor_type == "temperature" else sensor_type
|
||||
@ -54,9 +54,9 @@ class BlinkSensor(SensorEntity):
|
||||
"""Retrieve sensor data from the camera."""
|
||||
self.data.refresh()
|
||||
try:
|
||||
self._attr_state = self._camera.attributes[self._sensor_key]
|
||||
self._attr_native_value = self._camera.attributes[self._sensor_key]
|
||||
except KeyError:
|
||||
self._attr_state = None
|
||||
self._attr_native_value = None
|
||||
_LOGGER.error(
|
||||
"%s not a valid camera attribute. Did the API change?", self._sensor_key
|
||||
)
|
||||
|
@ -48,7 +48,7 @@ class BlockchainSensor(SensorEntity):
|
||||
|
||||
_attr_extra_state_attributes = {ATTR_ATTRIBUTION: ATTRIBUTION}
|
||||
_attr_icon = ICON
|
||||
_attr_unit_of_measurement = "BTC"
|
||||
_attr_native_unit_of_measurement = "BTC"
|
||||
|
||||
def __init__(self, name, addresses):
|
||||
"""Initialize the sensor."""
|
||||
@ -57,4 +57,4 @@ class BlockchainSensor(SensorEntity):
|
||||
|
||||
def update(self):
|
||||
"""Get the latest state of the sensor."""
|
||||
self._attr_state = get_balance(self.addresses)
|
||||
self._attr_native_value = get_balance(self.addresses)
|
||||
|
@ -86,9 +86,13 @@ class BloomSkySensor(SensorEntity):
|
||||
self._sensor_name = sensor_name
|
||||
self._attr_name = f"{device['DeviceName']} {sensor_name}"
|
||||
self._attr_unique_id = f"{self._device_id}-{sensor_name}"
|
||||
self._attr_unit_of_measurement = SENSOR_UNITS_IMPERIAL.get(sensor_name, None)
|
||||
self._attr_native_unit_of_measurement = SENSOR_UNITS_IMPERIAL.get(
|
||||
sensor_name, None
|
||||
)
|
||||
if self._bloomsky.is_metric:
|
||||
self._attr_unit_of_measurement = SENSOR_UNITS_METRIC.get(sensor_name, None)
|
||||
self._attr_native_unit_of_measurement = SENSOR_UNITS_METRIC.get(
|
||||
sensor_name, None
|
||||
)
|
||||
|
||||
@property
|
||||
def device_class(self):
|
||||
@ -99,6 +103,6 @@ class BloomSkySensor(SensorEntity):
|
||||
"""Request an update from the BloomSky API."""
|
||||
self._bloomsky.refresh_devices()
|
||||
state = self._bloomsky.devices[self._device_id]["Data"][self._sensor_name]
|
||||
self._attr_state = (
|
||||
self._attr_native_value = (
|
||||
f"{state:.2f}" if self._sensor_name in FORMAT_NUMBERS else state
|
||||
)
|
||||
|
@ -127,11 +127,11 @@ class BME280Sensor(CoordinatorEntity, SensorEntity):
|
||||
self._attr_name = f"{name} {SENSOR_TYPES[sensor_type][0]}"
|
||||
self.temp_unit = temp_unit
|
||||
self.type = sensor_type
|
||||
self._attr_unit_of_measurement = SENSOR_TYPES[sensor_type][1]
|
||||
self._attr_native_unit_of_measurement = SENSOR_TYPES[sensor_type][1]
|
||||
self._attr_device_class = SENSOR_TYPES[sensor_type][2]
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def native_value(self):
|
||||
"""Return the state of the sensor."""
|
||||
if self.type == SENSOR_TEMP:
|
||||
temperature = round(self.coordinator.data.temperature, 1)
|
||||
|
@ -327,25 +327,27 @@ class BME680Sensor(SensorEntity):
|
||||
self.bme680_client = bme680_client
|
||||
self.temp_unit = temp_unit
|
||||
self.type = sensor_type
|
||||
self._attr_unit_of_measurement = SENSOR_TYPES[sensor_type][1]
|
||||
self._attr_native_unit_of_measurement = SENSOR_TYPES[sensor_type][1]
|
||||
self._attr_device_class = SENSOR_TYPES[sensor_type][2]
|
||||
|
||||
async def async_update(self):
|
||||
"""Get the latest data from the BME680 and update the states."""
|
||||
await self.hass.async_add_executor_job(self.bme680_client.update)
|
||||
if self.type == SENSOR_TEMP:
|
||||
self._attr_state = round(self.bme680_client.sensor_data.temperature, 1)
|
||||
self._attr_native_value = round(
|
||||
self.bme680_client.sensor_data.temperature, 1
|
||||
)
|
||||
if self.temp_unit == TEMP_FAHRENHEIT:
|
||||
self._attr_state = round(celsius_to_fahrenheit(self.state), 1)
|
||||
self._attr_native_value = round(celsius_to_fahrenheit(self.state), 1)
|
||||
elif self.type == SENSOR_HUMID:
|
||||
self._attr_state = round(self.bme680_client.sensor_data.humidity, 1)
|
||||
self._attr_native_value = round(self.bme680_client.sensor_data.humidity, 1)
|
||||
elif self.type == SENSOR_PRESS:
|
||||
self._attr_state = round(self.bme680_client.sensor_data.pressure, 1)
|
||||
self._attr_native_value = round(self.bme680_client.sensor_data.pressure, 1)
|
||||
elif self.type == SENSOR_GAS:
|
||||
self._attr_state = int(
|
||||
self._attr_native_value = int(
|
||||
round(self.bme680_client.sensor_data.gas_resistance, 0)
|
||||
)
|
||||
elif self.type == SENSOR_AQ:
|
||||
aq_score = self.bme680_client.sensor_data.air_quality
|
||||
if aq_score is not None:
|
||||
self._attr_state = round(aq_score, 1)
|
||||
self._attr_native_value = round(aq_score, 1)
|
||||
|
@ -78,7 +78,7 @@ class Bmp280Sensor(SensorEntity):
|
||||
"""Initialize the sensor."""
|
||||
self._bmp280 = bmp280
|
||||
self._attr_name = name
|
||||
self._attr_unit_of_measurement = unit_of_measurement
|
||||
self._attr_native_unit_of_measurement = unit_of_measurement
|
||||
|
||||
|
||||
class Bmp280TemperatureSensor(Bmp280Sensor):
|
||||
@ -94,7 +94,7 @@ class Bmp280TemperatureSensor(Bmp280Sensor):
|
||||
def update(self):
|
||||
"""Fetch new state data for the sensor."""
|
||||
try:
|
||||
self._attr_state = round(self._bmp280.temperature, 1)
|
||||
self._attr_native_value = round(self._bmp280.temperature, 1)
|
||||
if not self.available:
|
||||
_LOGGER.warning("Communication restored with temperature sensor")
|
||||
self._attr_available = True
|
||||
@ -119,7 +119,7 @@ class Bmp280PressureSensor(Bmp280Sensor):
|
||||
def update(self):
|
||||
"""Fetch new state data for the sensor."""
|
||||
try:
|
||||
self._attr_state = round(self._bmp280.pressure)
|
||||
self._attr_native_value = round(self._bmp280.pressure)
|
||||
if not self.available:
|
||||
_LOGGER.warning("Communication restored with pressure sensor")
|
||||
self._attr_available = True
|
||||
|
@ -516,7 +516,7 @@ class BMWConnectedDriveSensor(BMWConnectedDriveBaseEntity, SensorEntity):
|
||||
self._attr_device_class = attribute_info.get(
|
||||
attribute, [None, None, None, None]
|
||||
)[1]
|
||||
self._attr_unit_of_measurement = attribute_info.get(
|
||||
self._attr_native_unit_of_measurement = attribute_info.get(
|
||||
attribute, [None, None, None, None]
|
||||
)[2]
|
||||
|
||||
@ -525,24 +525,24 @@ class BMWConnectedDriveSensor(BMWConnectedDriveBaseEntity, SensorEntity):
|
||||
_LOGGER.debug("Updating %s", self._vehicle.name)
|
||||
vehicle_state = self._vehicle.state
|
||||
if self._attribute == "charging_status":
|
||||
self._attr_state = getattr(vehicle_state, self._attribute).value
|
||||
self._attr_native_value = getattr(vehicle_state, self._attribute).value
|
||||
elif self.unit_of_measurement == VOLUME_GALLONS:
|
||||
value = getattr(vehicle_state, self._attribute)
|
||||
value_converted = self.hass.config.units.volume(value, VOLUME_LITERS)
|
||||
self._attr_state = round(value_converted)
|
||||
self._attr_native_value = round(value_converted)
|
||||
elif self.unit_of_measurement == LENGTH_MILES:
|
||||
value = getattr(vehicle_state, self._attribute)
|
||||
value_converted = self.hass.config.units.length(value, LENGTH_KILOMETERS)
|
||||
self._attr_state = round(value_converted)
|
||||
self._attr_native_value = round(value_converted)
|
||||
elif self._service is None:
|
||||
self._attr_state = getattr(vehicle_state, self._attribute)
|
||||
self._attr_native_value = getattr(vehicle_state, self._attribute)
|
||||
elif self._service == SERVICE_LAST_TRIP:
|
||||
vehicle_last_trip = self._vehicle.state.last_trip
|
||||
if self._attribute == "date_utc":
|
||||
date_str = getattr(vehicle_last_trip, "date")
|
||||
self._attr_state = dt_util.parse_datetime(date_str).isoformat()
|
||||
self._attr_native_value = dt_util.parse_datetime(date_str).isoformat()
|
||||
else:
|
||||
self._attr_state = getattr(vehicle_last_trip, self._attribute)
|
||||
self._attr_native_value = getattr(vehicle_last_trip, self._attribute)
|
||||
elif self._service == SERVICE_ALL_TRIPS:
|
||||
vehicle_all_trips = self._vehicle.state.all_trips
|
||||
for attribute in (
|
||||
@ -555,13 +555,13 @@ class BMWConnectedDriveSensor(BMWConnectedDriveBaseEntity, SensorEntity):
|
||||
if self._attribute.startswith(f"{attribute}_"):
|
||||
attr = getattr(vehicle_all_trips, attribute)
|
||||
sub_attr = self._attribute.replace(f"{attribute}_", "")
|
||||
self._attr_state = getattr(attr, sub_attr)
|
||||
self._attr_native_value = getattr(attr, sub_attr)
|
||||
return
|
||||
if self._attribute == "reset_date_utc":
|
||||
date_str = getattr(vehicle_all_trips, "reset_date")
|
||||
self._attr_state = dt_util.parse_datetime(date_str).isoformat()
|
||||
self._attr_native_value = dt_util.parse_datetime(date_str).isoformat()
|
||||
else:
|
||||
self._attr_state = getattr(vehicle_all_trips, self._attribute)
|
||||
self._attr_native_value = getattr(vehicle_all_trips, self._attribute)
|
||||
|
||||
vehicle_state = self._vehicle.state
|
||||
charging_state = vehicle_state.charging_status in [ChargingState.CHARGING]
|
||||
|
@ -147,7 +147,7 @@ class TemperatureSensor(SHCEntity, SensorEntity):
|
||||
"""Representation of an SHC temperature reporting sensor."""
|
||||
|
||||
_attr_device_class = DEVICE_CLASS_TEMPERATURE
|
||||
_attr_unit_of_measurement = TEMP_CELSIUS
|
||||
_attr_native_unit_of_measurement = TEMP_CELSIUS
|
||||
|
||||
def __init__(self, device: SHCDevice, parent_id: str, entry_id: str) -> None:
|
||||
"""Initialize an SHC temperature reporting sensor."""
|
||||
@ -156,7 +156,7 @@ class TemperatureSensor(SHCEntity, SensorEntity):
|
||||
self._attr_unique_id = f"{device.serial}_temperature"
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def native_value(self):
|
||||
"""Return the state of the sensor."""
|
||||
return self._device.temperature
|
||||
|
||||
@ -165,7 +165,7 @@ class HumiditySensor(SHCEntity, SensorEntity):
|
||||
"""Representation of an SHC humidity reporting sensor."""
|
||||
|
||||
_attr_device_class = DEVICE_CLASS_HUMIDITY
|
||||
_attr_unit_of_measurement = PERCENTAGE
|
||||
_attr_native_unit_of_measurement = PERCENTAGE
|
||||
|
||||
def __init__(self, device: SHCDevice, parent_id: str, entry_id: str) -> None:
|
||||
"""Initialize an SHC humidity reporting sensor."""
|
||||
@ -174,7 +174,7 @@ class HumiditySensor(SHCEntity, SensorEntity):
|
||||
self._attr_unique_id = f"{device.serial}_humidity"
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def native_value(self):
|
||||
"""Return the state of the sensor."""
|
||||
return self._device.humidity
|
||||
|
||||
@ -183,7 +183,7 @@ class PuritySensor(SHCEntity, SensorEntity):
|
||||
"""Representation of an SHC purity reporting sensor."""
|
||||
|
||||
_attr_icon = "mdi:molecule-co2"
|
||||
_attr_unit_of_measurement = CONCENTRATION_PARTS_PER_MILLION
|
||||
_attr_native_unit_of_measurement = CONCENTRATION_PARTS_PER_MILLION
|
||||
|
||||
def __init__(self, device: SHCDevice, parent_id: str, entry_id: str) -> None:
|
||||
"""Initialize an SHC purity reporting sensor."""
|
||||
@ -192,7 +192,7 @@ class PuritySensor(SHCEntity, SensorEntity):
|
||||
self._attr_unique_id = f"{device.serial}_purity"
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def native_value(self):
|
||||
"""Return the state of the sensor."""
|
||||
return self._device.purity
|
||||
|
||||
@ -207,7 +207,7 @@ class AirQualitySensor(SHCEntity, SensorEntity):
|
||||
self._attr_unique_id = f"{device.serial}_airquality"
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def native_value(self):
|
||||
"""Return the state of the sensor."""
|
||||
return self._device.combined_rating.name
|
||||
|
||||
@ -229,7 +229,7 @@ class TemperatureRatingSensor(SHCEntity, SensorEntity):
|
||||
self._attr_unique_id = f"{device.serial}_temperature_rating"
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def native_value(self):
|
||||
"""Return the state of the sensor."""
|
||||
return self._device.temperature_rating.name
|
||||
|
||||
@ -244,7 +244,7 @@ class HumidityRatingSensor(SHCEntity, SensorEntity):
|
||||
self._attr_unique_id = f"{device.serial}_humidity_rating"
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def native_value(self):
|
||||
"""Return the state of the sensor."""
|
||||
return self._device.humidity_rating.name
|
||||
|
||||
@ -259,7 +259,7 @@ class PurityRatingSensor(SHCEntity, SensorEntity):
|
||||
self._attr_unique_id = f"{device.serial}_purity_rating"
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def native_value(self):
|
||||
"""Return the state of the sensor."""
|
||||
return self._device.purity_rating.name
|
||||
|
||||
@ -268,7 +268,7 @@ class PowerSensor(SHCEntity, SensorEntity):
|
||||
"""Representation of an SHC power reporting sensor."""
|
||||
|
||||
_attr_device_class = DEVICE_CLASS_POWER
|
||||
_attr_unit_of_measurement = POWER_WATT
|
||||
_attr_native_unit_of_measurement = POWER_WATT
|
||||
|
||||
def __init__(self, device: SHCDevice, parent_id: str, entry_id: str) -> None:
|
||||
"""Initialize an SHC power reporting sensor."""
|
||||
@ -277,7 +277,7 @@ class PowerSensor(SHCEntity, SensorEntity):
|
||||
self._attr_unique_id = f"{device.serial}_power"
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def native_value(self):
|
||||
"""Return the state of the sensor."""
|
||||
return self._device.powerconsumption
|
||||
|
||||
@ -286,7 +286,7 @@ class EnergySensor(SHCEntity, SensorEntity):
|
||||
"""Representation of an SHC energy reporting sensor."""
|
||||
|
||||
_attr_device_class = DEVICE_CLASS_ENERGY
|
||||
_attr_unit_of_measurement = ENERGY_KILO_WATT_HOUR
|
||||
_attr_native_unit_of_measurement = ENERGY_KILO_WATT_HOUR
|
||||
|
||||
def __init__(self, device: SHCDevice, parent_id: str, entry_id: str) -> None:
|
||||
"""Initialize an SHC energy reporting sensor."""
|
||||
@ -295,7 +295,7 @@ class EnergySensor(SHCEntity, SensorEntity):
|
||||
self._attr_unique_id = f"{self._device.serial}_energy"
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def native_value(self):
|
||||
"""Return the state of the sensor."""
|
||||
return self._device.energyconsumption / 1000.0
|
||||
|
||||
@ -304,7 +304,7 @@ class ValveTappetSensor(SHCEntity, SensorEntity):
|
||||
"""Representation of an SHC valve tappet reporting sensor."""
|
||||
|
||||
_attr_icon = "mdi:gauge"
|
||||
_attr_unit_of_measurement = PERCENTAGE
|
||||
_attr_native_unit_of_measurement = PERCENTAGE
|
||||
|
||||
def __init__(self, device: SHCDevice, parent_id: str, entry_id: str) -> None:
|
||||
"""Initialize an SHC valve tappet reporting sensor."""
|
||||
@ -313,7 +313,7 @@ class ValveTappetSensor(SHCEntity, SensorEntity):
|
||||
self._attr_unique_id = f"{device.serial}_valvetappet"
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def native_value(self):
|
||||
"""Return the state of the sensor."""
|
||||
return self._device.position
|
||||
|
||||
|
@ -91,10 +91,10 @@ class BroadlinkSensor(BroadlinkEntity, SensorEntity):
|
||||
self._attr_device_class = SENSOR_TYPES[monitored_condition][2]
|
||||
self._attr_name = f"{device.name} {SENSOR_TYPES[monitored_condition][0]}"
|
||||
self._attr_state_class = SENSOR_TYPES[monitored_condition][3]
|
||||
self._attr_state = self._coordinator.data[monitored_condition]
|
||||
self._attr_native_value = self._coordinator.data[monitored_condition]
|
||||
self._attr_unique_id = f"{device.unique_id}-{monitored_condition}"
|
||||
self._attr_unit_of_measurement = SENSOR_TYPES[monitored_condition][1]
|
||||
self._attr_native_unit_of_measurement = SENSOR_TYPES[monitored_condition][1]
|
||||
|
||||
def _update_state(self, data):
|
||||
"""Update the state of the entity."""
|
||||
self._attr_state = data[self._monitored_condition]
|
||||
self._attr_native_value = data[self._monitored_condition]
|
||||
|
@ -87,154 +87,154 @@ SENSOR_TYPES: Final[tuple[SensorEntityDescription, ...]] = (
|
||||
key=ATTR_PAGE_COUNTER,
|
||||
icon="mdi:file-document-outline",
|
||||
name=ATTR_PAGE_COUNTER.replace("_", " ").title(),
|
||||
unit_of_measurement=UNIT_PAGES,
|
||||
native_unit_of_measurement=UNIT_PAGES,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key=ATTR_BW_COUNTER,
|
||||
icon="mdi:file-document-outline",
|
||||
name=ATTR_BW_COUNTER.replace("_", " ").title(),
|
||||
unit_of_measurement=UNIT_PAGES,
|
||||
native_unit_of_measurement=UNIT_PAGES,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key=ATTR_COLOR_COUNTER,
|
||||
icon="mdi:file-document-outline",
|
||||
name=ATTR_COLOR_COUNTER.replace("_", " ").title(),
|
||||
unit_of_measurement=UNIT_PAGES,
|
||||
native_unit_of_measurement=UNIT_PAGES,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key=ATTR_DUPLEX_COUNTER,
|
||||
icon="mdi:file-document-outline",
|
||||
name=ATTR_DUPLEX_COUNTER.replace("_", " ").title(),
|
||||
unit_of_measurement=UNIT_PAGES,
|
||||
native_unit_of_measurement=UNIT_PAGES,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key=ATTR_DRUM_REMAINING_LIFE,
|
||||
icon="mdi:chart-donut",
|
||||
name=ATTR_DRUM_REMAINING_LIFE.replace("_", " ").title(),
|
||||
unit_of_measurement=PERCENTAGE,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key=ATTR_BLACK_DRUM_REMAINING_LIFE,
|
||||
icon="mdi:chart-donut",
|
||||
name=ATTR_BLACK_DRUM_REMAINING_LIFE.replace("_", " ").title(),
|
||||
unit_of_measurement=PERCENTAGE,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key=ATTR_CYAN_DRUM_REMAINING_LIFE,
|
||||
icon="mdi:chart-donut",
|
||||
name=ATTR_CYAN_DRUM_REMAINING_LIFE.replace("_", " ").title(),
|
||||
unit_of_measurement=PERCENTAGE,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key=ATTR_MAGENTA_DRUM_REMAINING_LIFE,
|
||||
icon="mdi:chart-donut",
|
||||
name=ATTR_MAGENTA_DRUM_REMAINING_LIFE.replace("_", " ").title(),
|
||||
unit_of_measurement=PERCENTAGE,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key=ATTR_YELLOW_DRUM_REMAINING_LIFE,
|
||||
icon="mdi:chart-donut",
|
||||
name=ATTR_YELLOW_DRUM_REMAINING_LIFE.replace("_", " ").title(),
|
||||
unit_of_measurement=PERCENTAGE,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key=ATTR_BELT_UNIT_REMAINING_LIFE,
|
||||
icon="mdi:current-ac",
|
||||
name=ATTR_BELT_UNIT_REMAINING_LIFE.replace("_", " ").title(),
|
||||
unit_of_measurement=PERCENTAGE,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key=ATTR_FUSER_REMAINING_LIFE,
|
||||
icon="mdi:water-outline",
|
||||
name=ATTR_FUSER_REMAINING_LIFE.replace("_", " ").title(),
|
||||
unit_of_measurement=PERCENTAGE,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key=ATTR_LASER_REMAINING_LIFE,
|
||||
icon="mdi:spotlight-beam",
|
||||
name=ATTR_LASER_REMAINING_LIFE.replace("_", " ").title(),
|
||||
unit_of_measurement=PERCENTAGE,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key=ATTR_PF_KIT_1_REMAINING_LIFE,
|
||||
icon="mdi:printer-3d",
|
||||
name=ATTR_PF_KIT_1_REMAINING_LIFE.replace("_", " ").title(),
|
||||
unit_of_measurement=PERCENTAGE,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key=ATTR_PF_KIT_MP_REMAINING_LIFE,
|
||||
icon="mdi:printer-3d",
|
||||
name=ATTR_PF_KIT_MP_REMAINING_LIFE.replace("_", " ").title(),
|
||||
unit_of_measurement=PERCENTAGE,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key=ATTR_BLACK_TONER_REMAINING,
|
||||
icon="mdi:printer-3d-nozzle",
|
||||
name=ATTR_BLACK_TONER_REMAINING.replace("_", " ").title(),
|
||||
unit_of_measurement=PERCENTAGE,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key=ATTR_CYAN_TONER_REMAINING,
|
||||
icon="mdi:printer-3d-nozzle",
|
||||
name=ATTR_CYAN_TONER_REMAINING.replace("_", " ").title(),
|
||||
unit_of_measurement=PERCENTAGE,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key=ATTR_MAGENTA_TONER_REMAINING,
|
||||
icon="mdi:printer-3d-nozzle",
|
||||
name=ATTR_MAGENTA_TONER_REMAINING.replace("_", " ").title(),
|
||||
unit_of_measurement=PERCENTAGE,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key=ATTR_YELLOW_TONER_REMAINING,
|
||||
icon="mdi:printer-3d-nozzle",
|
||||
name=ATTR_YELLOW_TONER_REMAINING.replace("_", " ").title(),
|
||||
unit_of_measurement=PERCENTAGE,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key=ATTR_BLACK_INK_REMAINING,
|
||||
icon="mdi:printer-3d-nozzle",
|
||||
name=ATTR_BLACK_INK_REMAINING.replace("_", " ").title(),
|
||||
unit_of_measurement=PERCENTAGE,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key=ATTR_CYAN_INK_REMAINING,
|
||||
icon="mdi:printer-3d-nozzle",
|
||||
name=ATTR_CYAN_INK_REMAINING.replace("_", " ").title(),
|
||||
unit_of_measurement=PERCENTAGE,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key=ATTR_MAGENTA_INK_REMAINING,
|
||||
icon="mdi:printer-3d-nozzle",
|
||||
name=ATTR_MAGENTA_INK_REMAINING.replace("_", " ").title(),
|
||||
unit_of_measurement=PERCENTAGE,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key=ATTR_YELLOW_INK_REMAINING,
|
||||
icon="mdi:printer-3d-nozzle",
|
||||
name=ATTR_YELLOW_INK_REMAINING.replace("_", " ").title(),
|
||||
unit_of_measurement=PERCENTAGE,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
|
@ -64,7 +64,7 @@ class BrotherPrinterSensor(CoordinatorEntity, SensorEntity):
|
||||
self.entity_description = description
|
||||
|
||||
@property
|
||||
def state(self) -> StateType:
|
||||
def native_value(self) -> StateType:
|
||||
"""Return the state."""
|
||||
if self.entity_description.key == ATTR_UPTIME:
|
||||
return cast(
|
||||
|
@ -103,4 +103,4 @@ class BrottsplatskartanSensor(SensorEntity):
|
||||
ATTR_ATTRIBUTION: brottsplatskartan.ATTRIBUTION
|
||||
}
|
||||
self._attr_extra_state_attributes.update(incident_counts)
|
||||
self._attr_state = len(incidents)
|
||||
self._attr_native_value = len(incidents)
|
||||
|
@ -364,7 +364,7 @@ class BrSensor(SensorEntity):
|
||||
self._attr_name = f"{client_name} {SENSOR_TYPES[sensor_type][0]}"
|
||||
self._attr_icon = SENSOR_TYPES[sensor_type][2]
|
||||
self.type = sensor_type
|
||||
self._attr_unit_of_measurement = SENSOR_TYPES[sensor_type][1]
|
||||
self._attr_native_unit_of_measurement = SENSOR_TYPES[sensor_type][1]
|
||||
self._measured = None
|
||||
self._attr_unique_id = "{:2.6f}{:2.6f}{}".format(
|
||||
coordinates[CONF_LATITUDE], coordinates[CONF_LONGITUDE], sensor_type
|
||||
@ -438,7 +438,7 @@ class BrSensor(SensorEntity):
|
||||
img = condition.get(IMAGE)
|
||||
|
||||
if new_state != self.state or img != self.entity_picture:
|
||||
self._attr_state = new_state
|
||||
self._attr_native_value = new_state
|
||||
self._attr_entity_picture = img
|
||||
return True
|
||||
return False
|
||||
@ -446,9 +446,11 @@ class BrSensor(SensorEntity):
|
||||
if self.type.startswith(WINDSPEED):
|
||||
# hass wants windspeeds in km/h not m/s, so convert:
|
||||
try:
|
||||
self._attr_state = data.get(FORECAST)[fcday].get(self.type[:-3])
|
||||
self._attr_native_value = data.get(FORECAST)[fcday].get(
|
||||
self.type[:-3]
|
||||
)
|
||||
if self.state is not None:
|
||||
self._attr_state = round(self.state * 3.6, 1)
|
||||
self._attr_native_value = round(self.state * 3.6, 1)
|
||||
return True
|
||||
except IndexError:
|
||||
_LOGGER.warning("No forecast for fcday=%s", fcday)
|
||||
@ -456,7 +458,7 @@ class BrSensor(SensorEntity):
|
||||
|
||||
# update all other sensors
|
||||
try:
|
||||
self._attr_state = data.get(FORECAST)[fcday].get(self.type[:-3])
|
||||
self._attr_native_value = data.get(FORECAST)[fcday].get(self.type[:-3])
|
||||
return True
|
||||
except IndexError:
|
||||
_LOGGER.warning("No forecast for fcday=%s", fcday)
|
||||
@ -480,7 +482,7 @@ class BrSensor(SensorEntity):
|
||||
img = condition.get(IMAGE)
|
||||
|
||||
if new_state != self.state or img != self.entity_picture:
|
||||
self._attr_state = new_state
|
||||
self._attr_native_value = new_state
|
||||
self._attr_entity_picture = img
|
||||
return True
|
||||
|
||||
@ -490,25 +492,27 @@ class BrSensor(SensorEntity):
|
||||
# update nested precipitation forecast sensors
|
||||
nested = data.get(PRECIPITATION_FORECAST)
|
||||
self._timeframe = nested.get(TIMEFRAME)
|
||||
self._attr_state = nested.get(self.type[len(PRECIPITATION_FORECAST) + 1 :])
|
||||
self._attr_native_value = nested.get(
|
||||
self.type[len(PRECIPITATION_FORECAST) + 1 :]
|
||||
)
|
||||
return True
|
||||
|
||||
if self.type in [WINDSPEED, WINDGUST]:
|
||||
# hass wants windspeeds in km/h not m/s, so convert:
|
||||
self._attr_state = data.get(self.type)
|
||||
self._attr_native_value = data.get(self.type)
|
||||
if self.state is not None:
|
||||
self._attr_state = round(data.get(self.type) * 3.6, 1)
|
||||
self._attr_native_value = round(data.get(self.type) * 3.6, 1)
|
||||
return True
|
||||
|
||||
if self.type == VISIBILITY:
|
||||
# hass wants visibility in km (not m), so convert:
|
||||
self._attr_state = data.get(self.type)
|
||||
self._attr_native_value = data.get(self.type)
|
||||
if self.state is not None:
|
||||
self._attr_state = round(self.state / 1000, 1)
|
||||
self._attr_native_value = round(self.state / 1000, 1)
|
||||
return True
|
||||
|
||||
# update all other sensors
|
||||
self._attr_state = data.get(self.type)
|
||||
self._attr_native_value = data.get(self.type)
|
||||
if self.type.startswith(PRECIPITATION_FORECAST):
|
||||
result = {ATTR_ATTRIBUTION: data.get(ATTRIBUTION)}
|
||||
if self._timeframe is not None:
|
||||
|
@ -144,7 +144,7 @@ class CanarySensor(CoordinatorEntity, SensorEntity):
|
||||
return None
|
||||
|
||||
@property
|
||||
def state(self) -> float | None:
|
||||
def native_value(self) -> float | None:
|
||||
"""Return the state of the sensor."""
|
||||
return self.reading
|
||||
|
||||
|
@ -85,7 +85,7 @@ class SSLCertificateTimestamp(CertExpiryEntity, SensorEntity):
|
||||
self._attr_unique_id = f"{coordinator.host}:{coordinator.port}-timestamp"
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def native_value(self):
|
||||
"""Return the state of the sensor."""
|
||||
if self.coordinator.data:
|
||||
return self.coordinator.data.isoformat()
|
||||
|
@ -265,7 +265,7 @@ class CityBikesNetwork:
|
||||
class CityBikesStation(SensorEntity):
|
||||
"""CityBikes API Sensor."""
|
||||
|
||||
_attr_unit_of_measurement = "bikes"
|
||||
_attr_native_unit_of_measurement = "bikes"
|
||||
_attr_icon = "mdi:bike"
|
||||
|
||||
def __init__(self, network, station_id, entity_id):
|
||||
@ -281,7 +281,7 @@ class CityBikesStation(SensorEntity):
|
||||
station_data = station
|
||||
break
|
||||
self._attr_name = station_data.get(ATTR_NAME)
|
||||
self._attr_state = station_data.get(ATTR_FREE_BIKES)
|
||||
self._attr_native_value = station_data.get(ATTR_FREE_BIKES)
|
||||
self._attr_extra_state_attributes = (
|
||||
{
|
||||
ATTR_ATTRIBUTION: CITYBIKES_ATTRIBUTION,
|
||||
|
@ -68,7 +68,7 @@ class BaseClimaCellSensorEntity(ClimaCellEntity, SensorEntity):
|
||||
f"{self._config_entry.unique_id}_{slugify(description.name)}"
|
||||
)
|
||||
self._attr_extra_state_attributes = {ATTR_ATTRIBUTION: self.attribution}
|
||||
self._attr_unit_of_measurement = (
|
||||
self._attr_native_unit_of_measurement = (
|
||||
description.unit_metric
|
||||
if hass.config.units.is_metric
|
||||
else description.unit_imperial
|
||||
@ -80,7 +80,7 @@ class BaseClimaCellSensorEntity(ClimaCellEntity, SensorEntity):
|
||||
"""Return the raw state."""
|
||||
|
||||
@property
|
||||
def state(self) -> str | int | float | None:
|
||||
def native_value(self) -> str | int | float | None:
|
||||
"""Return the state."""
|
||||
state = self._state
|
||||
if (
|
||||
|
@ -123,12 +123,12 @@ class CO2Sensor(update_coordinator.CoordinatorEntity[CO2SignalResponse], SensorE
|
||||
)
|
||||
|
||||
@property
|
||||
def state(self) -> StateType:
|
||||
def native_value(self) -> StateType:
|
||||
"""Return sensor state."""
|
||||
return round(self.coordinator.data["data"][self._description.key], 2) # type: ignore[misc]
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self) -> str | None:
|
||||
def native_unit_of_measurement(self) -> str | None:
|
||||
"""Return the unit of measurement."""
|
||||
if self._description.unit_of_measurement:
|
||||
return self._description.unit_of_measurement
|
||||
|
@ -116,12 +116,12 @@ class AccountSensor(SensorEntity):
|
||||
return self._id
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def native_value(self):
|
||||
"""Return the state of the sensor."""
|
||||
return self._state
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self):
|
||||
def native_unit_of_measurement(self):
|
||||
"""Return the unit of measurement this sensor expresses itself in."""
|
||||
return self._unit_of_measurement
|
||||
|
||||
@ -181,12 +181,12 @@ class ExchangeRateSensor(SensorEntity):
|
||||
return self._id
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def native_value(self):
|
||||
"""Return the state of the sensor."""
|
||||
return self._state
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self):
|
||||
def native_unit_of_measurement(self):
|
||||
"""Return the unit of measurement this sensor expresses itself in."""
|
||||
return self._unit_of_measurement
|
||||
|
||||
|
@ -86,12 +86,12 @@ class ComedHourlyPricingSensor(SensorEntity):
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def native_value(self):
|
||||
"""Return the state of the sensor."""
|
||||
return self._state
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self):
|
||||
def native_unit_of_measurement(self):
|
||||
"""Return the unit of measurement of this entity, if any."""
|
||||
return self._unit_of_measurement
|
||||
|
||||
|
@ -297,7 +297,7 @@ class ComfoConnectSensor(SensorEntity):
|
||||
self.schedule_update_ha_state()
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def native_value(self):
|
||||
"""Return the state of the entity."""
|
||||
try:
|
||||
return self._ccb.data[self._sensor_id]
|
||||
@ -325,7 +325,7 @@ class ComfoConnectSensor(SensorEntity):
|
||||
return SENSOR_TYPES[self._sensor_type][ATTR_ICON]
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self):
|
||||
def native_unit_of_measurement(self):
|
||||
"""Return the unit of measurement of this entity."""
|
||||
return SENSOR_TYPES[self._sensor_type][ATTR_UNIT]
|
||||
|
||||
|
@ -84,12 +84,12 @@ class CommandSensor(SensorEntity):
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self):
|
||||
def native_unit_of_measurement(self):
|
||||
"""Return the unit the value is expressed in."""
|
||||
return self._unit_of_measurement
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def native_value(self):
|
||||
"""Return the state of the device."""
|
||||
return self._state
|
||||
|
||||
|
@ -107,7 +107,7 @@ class CompensationSensor(SensorEntity):
|
||||
return False
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def native_value(self):
|
||||
"""Return the state of the sensor."""
|
||||
return self._state
|
||||
|
||||
@ -123,7 +123,7 @@ class CompensationSensor(SensorEntity):
|
||||
return ret
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self):
|
||||
def native_unit_of_measurement(self):
|
||||
"""Return the unit the value is expressed in."""
|
||||
return self._unit_of_measurement
|
||||
|
||||
|
@ -27,7 +27,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
class CoronavirusSensor(CoordinatorEntity, SensorEntity):
|
||||
"""Sensor representing corona virus data."""
|
||||
|
||||
_attr_unit_of_measurement = "people"
|
||||
_attr_native_unit_of_measurement = "people"
|
||||
|
||||
def __init__(self, coordinator, country, info_type):
|
||||
"""Initialize coronavirus sensor."""
|
||||
@ -53,7 +53,7 @@ class CoronavirusSensor(CoordinatorEntity, SensorEntity):
|
||||
)
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def native_value(self):
|
||||
"""State of the sensor."""
|
||||
if self.country == OPTION_WORLDWIDE:
|
||||
sum_cases = 0
|
||||
|
@ -43,12 +43,12 @@ class CpuSpeedSensor(SensorEntity):
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def native_value(self):
|
||||
"""Return the state of the sensor."""
|
||||
return self._state
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self):
|
||||
def native_unit_of_measurement(self):
|
||||
"""Return the unit the value is expressed in."""
|
||||
return FREQUENCY_GIGAHERTZ
|
||||
|
||||
|
@ -111,7 +111,7 @@ class CupsSensor(SensorEntity):
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def native_value(self):
|
||||
"""Return the state of the sensor."""
|
||||
if self._printer is None:
|
||||
return None
|
||||
@ -183,7 +183,7 @@ class IPPSensor(SensorEntity):
|
||||
return self._available
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def native_value(self):
|
||||
"""Return the state of the sensor."""
|
||||
if self._attributes is None:
|
||||
return None
|
||||
@ -257,7 +257,7 @@ class MarkerSensor(SensorEntity):
|
||||
return ICON_MARKER
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def native_value(self):
|
||||
"""Return the state of the sensor."""
|
||||
if self._attributes is None:
|
||||
return None
|
||||
@ -265,7 +265,7 @@ class MarkerSensor(SensorEntity):
|
||||
return self._attributes[self._printer]["marker-levels"][self._index]
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self):
|
||||
def native_unit_of_measurement(self):
|
||||
"""Return the unit of measurement."""
|
||||
return PERCENTAGE
|
||||
|
||||
|
@ -65,7 +65,7 @@ class CurrencylayerSensor(SensorEntity):
|
||||
self._state = None
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self):
|
||||
def native_unit_of_measurement(self):
|
||||
"""Return the unit of measurement of this entity, if any."""
|
||||
return self._quote
|
||||
|
||||
@ -80,7 +80,7 @@ class CurrencylayerSensor(SensorEntity):
|
||||
return ICON
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
def native_value(self):
|
||||
"""Return the state of the sensor."""
|
||||
return self._state
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Mapping
|
||||
from contextlib import suppress
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime, timedelta
|
||||
import logging
|
||||
@ -26,6 +27,8 @@ from homeassistant.const import (
|
||||
DEVICE_CLASS_TEMPERATURE,
|
||||
DEVICE_CLASS_TIMESTAMP,
|
||||
DEVICE_CLASS_VOLTAGE,
|
||||
TEMP_CELSIUS,
|
||||
TEMP_FAHRENHEIT,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.config_validation import ( # noqa: F401
|
||||
@ -34,7 +37,7 @@ from homeassistant.helpers.config_validation import ( # noqa: F401
|
||||
)
|
||||
from homeassistant.helpers.entity import Entity, EntityDescription
|
||||
from homeassistant.helpers.entity_component import EntityComponent
|
||||
from homeassistant.helpers.typing import ConfigType
|
||||
from homeassistant.helpers.typing import ConfigType, StateType
|
||||
|
||||
_LOGGER: Final = logging.getLogger(__name__)
|
||||
|
||||
@ -102,14 +105,18 @@ class SensorEntityDescription(EntityDescription):
|
||||
|
||||
state_class: str | None = None
|
||||
last_reset: datetime | None = None
|
||||
native_unit_of_measurement: str | None = None
|
||||
|
||||
|
||||
class SensorEntity(Entity):
|
||||
"""Base class for sensor entities."""
|
||||
|
||||
entity_description: SensorEntityDescription
|
||||
_attr_state_class: str | None
|
||||
_attr_last_reset: datetime | None
|
||||
_attr_native_unit_of_measurement: str | None
|
||||
_attr_native_value: StateType = None
|
||||
_attr_state_class: str | None
|
||||
_temperature_conversion_reported = False
|
||||
|
||||
@property
|
||||
def state_class(self) -> str | None:
|
||||
@ -145,3 +152,94 @@ class SensorEntity(Entity):
|
||||
return {ATTR_LAST_RESET: last_reset.isoformat()}
|
||||
|
||||
return None
|
||||
|
||||
@property
|
||||
def native_value(self) -> StateType:
|
||||
"""Return the value reported by the sensor."""
|
||||
return self._attr_native_value
|
||||
|
||||
@property
|
||||
def native_unit_of_measurement(self) -> str | None:
|
||||
"""Return the unit of measurement of the sensor, if any."""
|
||||
if hasattr(self, "_attr_native_unit_of_measurement"):
|
||||
return self._attr_native_unit_of_measurement
|
||||
if hasattr(self, "entity_description"):
|
||||
return self.entity_description.native_unit_of_measurement
|
||||
return None
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self) -> str | None:
|
||||
"""Return the unit of measurement of the entity, after unit conversion."""
|
||||
if (
|
||||
hasattr(self, "_attr_unit_of_measurement")
|
||||
and self._attr_unit_of_measurement is not None
|
||||
):
|
||||
return self._attr_unit_of_measurement
|
||||
if (
|
||||
hasattr(self, "entity_description")
|
||||
and self.entity_description.unit_of_measurement is not None
|
||||
):
|
||||
return self.entity_description.unit_of_measurement
|
||||
|
||||
native_unit_of_measurement = self.native_unit_of_measurement
|
||||
|
||||
if native_unit_of_measurement in (TEMP_CELSIUS, TEMP_FAHRENHEIT):
|
||||
return self.hass.config.units.temperature_unit
|
||||
|
||||
return native_unit_of_measurement
|
||||
|
||||
@property
|
||||
def state(self) -> Any:
|
||||
"""Return the state of the sensor and perform unit conversions, if needed."""
|
||||
# Test if _attr_state has been set in this instance
|
||||
if "_attr_state" in self.__dict__:
|
||||
return self._attr_state
|
||||
|
||||
unit_of_measurement = self.native_unit_of_measurement
|
||||
value = self.native_value
|
||||
|
||||
units = self.hass.config.units
|
||||
if (
|
||||
value is not None
|
||||
and unit_of_measurement in (TEMP_CELSIUS, TEMP_FAHRENHEIT)
|
||||
and unit_of_measurement != units.temperature_unit
|
||||
):
|
||||
if (
|
||||
self.device_class != DEVICE_CLASS_TEMPERATURE
|
||||
and not self._temperature_conversion_reported
|
||||
):
|
||||
self._temperature_conversion_reported = True
|
||||
report_issue = self._suggest_report_issue()
|
||||
_LOGGER.warning(
|
||||
"Entity %s (%s) with device_class %s reports a temperature in "
|
||||
"%s which will be converted to %s. Temperature conversion for "
|
||||
"entities without correct device_class is deprecated and will"
|
||||
" be removed from Home Assistant Core 2022.3. Please update "
|
||||
"your configuration if device_class is manually configured, "
|
||||
"otherwise %s",
|
||||
self.entity_id,
|
||||
type(self),
|
||||
self.device_class,
|
||||
unit_of_measurement,
|
||||
units.temperature_unit,
|
||||
report_issue,
|
||||
)
|
||||
value_s = str(value)
|
||||
prec = len(value_s) - value_s.index(".") - 1 if "." in value_s else 0
|
||||
# Suppress ValueError (Could not convert sensor_value to float)
|
||||
with suppress(ValueError):
|
||||
temp = units.temperature(float(value), unit_of_measurement)
|
||||
value = str(round(temp) if prec == 0 else round(temp, prec))
|
||||
|
||||
return value
|
||||
|
||||
def __repr__(self) -> str:
|
||||
"""Return the representation.
|
||||
|
||||
Entity.__repr__ includes the state in the generated string, this fails if we're
|
||||
called before self.hass is set.
|
||||
"""
|
||||
if not self.hass:
|
||||
return f"<Entity {self.name}>"
|
||||
|
||||
return super().__repr__()
|
||||
|
@ -539,25 +539,13 @@ class Entity(ABC):
|
||||
|
||||
if end - start > 0.4 and not self._slow_reported:
|
||||
self._slow_reported = True
|
||||
extra = ""
|
||||
if "custom_components" in type(self).__module__:
|
||||
extra = "Please report it to the custom component author."
|
||||
else:
|
||||
extra = (
|
||||
"Please create a bug report at "
|
||||
"https://github.com/home-assistant/core/issues?q=is%3Aopen+is%3Aissue"
|
||||
)
|
||||
if self.platform:
|
||||
extra += (
|
||||
f"+label%3A%22integration%3A+{self.platform.platform_name}%22"
|
||||
)
|
||||
|
||||
report_issue = self._suggest_report_issue()
|
||||
_LOGGER.warning(
|
||||
"Updating state for %s (%s) took %.3f seconds. %s",
|
||||
"Updating state for %s (%s) took %.3f seconds. Please %s",
|
||||
self.entity_id,
|
||||
type(self),
|
||||
end - start,
|
||||
extra,
|
||||
report_issue,
|
||||
)
|
||||
|
||||
# Overwrite properties that have been set in the config file.
|
||||
@ -858,6 +846,23 @@ class Entity(ABC):
|
||||
if self.parallel_updates:
|
||||
self.parallel_updates.release()
|
||||
|
||||
def _suggest_report_issue(self) -> str:
|
||||
"""Suggest to report an issue."""
|
||||
report_issue = ""
|
||||
if "custom_components" in type(self).__module__:
|
||||
report_issue = "report it to the custom component author."
|
||||
else:
|
||||
report_issue = (
|
||||
"create a bug report at "
|
||||
"https://github.com/home-assistant/core/issues?q=is%3Aopen+is%3Aissue"
|
||||
)
|
||||
if self.platform:
|
||||
report_issue += (
|
||||
f"+label%3A%22integration%3A+{self.platform.platform_name}%22"
|
||||
)
|
||||
|
||||
return report_issue
|
||||
|
||||
|
||||
@dataclass
|
||||
class ToggleEntityDescription(EntityDescription):
|
||||
|
@ -19,53 +19,55 @@ def _get_named_tuple(input_dict):
|
||||
return namedtuple("Struct", input_dict.keys())(*input_dict.values())
|
||||
|
||||
|
||||
def _get_sensor(name="Last", sensor_type="last_capture", data=None):
|
||||
def _get_sensor(hass, name="Last", sensor_type="last_capture", data=None):
|
||||
if data is None:
|
||||
data = {}
|
||||
sensor_entry = next(
|
||||
sensor_entry for sensor_entry in SENSOR_TYPES if sensor_entry.key == sensor_type
|
||||
)
|
||||
sensor_entry.name = name
|
||||
return arlo.ArloSensor(data, sensor_entry)
|
||||
sensor = arlo.ArloSensor(data, sensor_entry)
|
||||
sensor.hass = hass
|
||||
return sensor
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def default_sensor():
|
||||
def default_sensor(hass):
|
||||
"""Create an ArloSensor with default values."""
|
||||
return _get_sensor()
|
||||
return _get_sensor(hass)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def battery_sensor():
|
||||
def battery_sensor(hass):
|
||||
"""Create an ArloSensor with battery data."""
|
||||
data = _get_named_tuple({"battery_level": 50})
|
||||
return _get_sensor("Battery Level", "battery_level", data)
|
||||
return _get_sensor(hass, "Battery Level", "battery_level", data)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def temperature_sensor():
|
||||
def temperature_sensor(hass):
|
||||
"""Create a temperature ArloSensor."""
|
||||
return _get_sensor("Temperature", "temperature")
|
||||
return _get_sensor(hass, "Temperature", "temperature")
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def humidity_sensor():
|
||||
def humidity_sensor(hass):
|
||||
"""Create a humidity ArloSensor."""
|
||||
return _get_sensor("Humidity", "humidity")
|
||||
return _get_sensor(hass, "Humidity", "humidity")
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def cameras_sensor():
|
||||
def cameras_sensor(hass):
|
||||
"""Create a total cameras ArloSensor."""
|
||||
data = _get_named_tuple({"cameras": [0, 0]})
|
||||
return _get_sensor("Arlo Cameras", "total_cameras", data)
|
||||
return _get_sensor(hass, "Arlo Cameras", "total_cameras", data)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def captured_sensor():
|
||||
def captured_sensor(hass):
|
||||
"""Create a captured today ArloSensor."""
|
||||
data = _get_named_tuple({"captured_today": [0, 0, 0, 0, 0]})
|
||||
return _get_sensor("Captured Today", "captured_today", data)
|
||||
return _get_sensor(hass, "Captured Today", "captured_today", data)
|
||||
|
||||
|
||||
class PlatformSetupFixture:
|
||||
@ -88,14 +90,6 @@ def platform_setup():
|
||||
return PlatformSetupFixture()
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def sensor_with_hass_data(default_sensor, hass):
|
||||
"""Create a sensor with async_dispatcher_connected mocked."""
|
||||
hass.data = {}
|
||||
default_sensor.hass = hass
|
||||
return default_sensor
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def mock_dispatch():
|
||||
"""Mock the dispatcher connect method."""
|
||||
@ -145,14 +139,14 @@ def test_sensor_name(default_sensor):
|
||||
assert default_sensor.name == "Last"
|
||||
|
||||
|
||||
async def test_async_added_to_hass(sensor_with_hass_data, mock_dispatch):
|
||||
async def test_async_added_to_hass(default_sensor, mock_dispatch):
|
||||
"""Test dispatcher called when added."""
|
||||
await sensor_with_hass_data.async_added_to_hass()
|
||||
await default_sensor.async_added_to_hass()
|
||||
assert len(mock_dispatch.mock_calls) == 1
|
||||
kall = mock_dispatch.call_args
|
||||
args, kwargs = kall
|
||||
assert len(args) == 3
|
||||
assert args[0] == sensor_with_hass_data.hass
|
||||
assert args[0] == default_sensor.hass
|
||||
assert args[1] == "arlo_update"
|
||||
assert not kwargs
|
||||
|
||||
@ -197,22 +191,22 @@ def test_update_captured_today(captured_sensor):
|
||||
assert captured_sensor.state == 5
|
||||
|
||||
|
||||
def _test_attributes(sensor_type):
|
||||
def _test_attributes(hass, sensor_type):
|
||||
data = _get_named_tuple({"model_id": "TEST123"})
|
||||
sensor = _get_sensor("test", sensor_type, data)
|
||||
sensor = _get_sensor(hass, "test", sensor_type, data)
|
||||
attrs = sensor.extra_state_attributes
|
||||
assert attrs.get(ATTR_ATTRIBUTION) == "Data provided by arlo.netgear.com"
|
||||
assert attrs.get("brand") == "Netgear Arlo"
|
||||
assert attrs.get("model") == "TEST123"
|
||||
|
||||
|
||||
def test_state_attributes():
|
||||
def test_state_attributes(hass):
|
||||
"""Test attributes for camera sensor types."""
|
||||
_test_attributes("battery_level")
|
||||
_test_attributes("signal_strength")
|
||||
_test_attributes("temperature")
|
||||
_test_attributes("humidity")
|
||||
_test_attributes("air_quality")
|
||||
_test_attributes(hass, "battery_level")
|
||||
_test_attributes(hass, "signal_strength")
|
||||
_test_attributes(hass, "temperature")
|
||||
_test_attributes(hass, "humidity")
|
||||
_test_attributes(hass, "air_quality")
|
||||
|
||||
|
||||
def test_attributes_total_cameras(cameras_sensor):
|
||||
@ -223,17 +217,17 @@ def test_attributes_total_cameras(cameras_sensor):
|
||||
assert attrs.get("model") is None
|
||||
|
||||
|
||||
def _test_update(sensor_type, key, value):
|
||||
def _test_update(hass, sensor_type, key, value):
|
||||
data = _get_named_tuple({key: value})
|
||||
sensor = _get_sensor("test", sensor_type, data)
|
||||
sensor = _get_sensor(hass, "test", sensor_type, data)
|
||||
sensor.update()
|
||||
assert sensor.state == value
|
||||
|
||||
|
||||
def test_update():
|
||||
def test_update(hass):
|
||||
"""Test update method for direct transcription sensor types."""
|
||||
_test_update("battery_level", "battery_level", 100)
|
||||
_test_update("signal_strength", "signal_strength", 100)
|
||||
_test_update("temperature", "ambient_temperature", 21.4)
|
||||
_test_update("humidity", "ambient_humidity", 45.1)
|
||||
_test_update("air_quality", "ambient_air_quality", 14.2)
|
||||
_test_update(hass, "battery_level", "battery_level", 100)
|
||||
_test_update(hass, "signal_strength", "signal_strength", 100)
|
||||
_test_update(hass, "temperature", "ambient_temperature", 21.4)
|
||||
_test_update(hass, "humidity", "ambient_humidity", 45.1)
|
||||
_test_update(hass, "air_quality", "ambient_air_quality", 14.2)
|
||||
|
30
tests/components/sensor/test_init.py
Normal file
30
tests/components/sensor/test_init.py
Normal file
@ -0,0 +1,30 @@
|
||||
"""The test for sensor device automation."""
|
||||
from homeassistant.const import ATTR_UNIT_OF_MEASUREMENT, TEMP_CELSIUS, TEMP_FAHRENHEIT
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
|
||||
async def test_deprecated_temperature_conversion(
|
||||
hass, caplog, enable_custom_integrations
|
||||
):
|
||||
"""Test warning on deprecated temperature conversion."""
|
||||
platform = getattr(hass.components, "test.sensor")
|
||||
platform.init(empty=True)
|
||||
platform.ENTITIES["0"] = platform.MockSensor(
|
||||
name="Test", native_value="0.0", native_unit_of_measurement=TEMP_FAHRENHEIT
|
||||
)
|
||||
|
||||
entity0 = platform.ENTITIES["0"]
|
||||
assert await async_setup_component(hass, "sensor", {"sensor": {"platform": "test"}})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(entity0.entity_id)
|
||||
assert state.state == "-17.8"
|
||||
assert state.attributes[ATTR_UNIT_OF_MEASUREMENT] == TEMP_CELSIUS
|
||||
assert (
|
||||
"Entity sensor.test (<class 'custom_components.test.sensor.MockSensor'>) "
|
||||
"with device_class None reports a temperature in °F which will be converted to "
|
||||
"°C. Temperature conversion for entities without correct device_class is "
|
||||
"deprecated and will be removed from Home Assistant Core 2022.3. Please update "
|
||||
"your configuration if device_class is manually configured, otherwise report it "
|
||||
"to the custom component author."
|
||||
) in caplog.text
|
@ -61,7 +61,7 @@ async def async_setup_platform(
|
||||
async_add_entities_callback(list(ENTITIES.values()))
|
||||
|
||||
|
||||
class MockSensor(MockEntity):
|
||||
class MockSensor(MockEntity, sensor.SensorEntity):
|
||||
"""Mock Sensor class."""
|
||||
|
||||
@property
|
||||
@ -70,6 +70,11 @@ class MockSensor(MockEntity):
|
||||
return self._handle("device_class")
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self):
|
||||
"""Return the unit_of_measurement of this sensor."""
|
||||
return self._handle("unit_of_measurement")
|
||||
def native_unit_of_measurement(self):
|
||||
"""Return the native unit_of_measurement of this sensor."""
|
||||
return self._handle("native_unit_of_measurement")
|
||||
|
||||
@property
|
||||
def native_value(self):
|
||||
"""Return the native value of this sensor."""
|
||||
return self._handle("native_value")
|
||||
|
Loading…
x
Reference in New Issue
Block a user