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