mirror of
https://github.com/home-assistant/core.git
synced 2025-07-03 11:27:05 +00:00
795 lines
27 KiB
Python
795 lines
27 KiB
Python
"""Support for sensors through the SmartThings cloud API."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from collections.abc import Callable, Mapping, Sequence
|
|
from dataclasses import dataclass
|
|
from datetime import datetime
|
|
from typing import Any
|
|
|
|
from pysmartthings import Attribute, Capability
|
|
from pysmartthings.device import DeviceEntity, DeviceStatus
|
|
|
|
from homeassistant.components.sensor import (
|
|
SensorDeviceClass,
|
|
SensorEntity,
|
|
SensorEntityDescription,
|
|
SensorStateClass,
|
|
)
|
|
from homeassistant.config_entries import ConfigEntry
|
|
from homeassistant.const import (
|
|
CONCENTRATION_PARTS_PER_MILLION,
|
|
LIGHT_LUX,
|
|
PERCENTAGE,
|
|
EntityCategory,
|
|
UnitOfArea,
|
|
UnitOfElectricPotential,
|
|
UnitOfEnergy,
|
|
UnitOfMass,
|
|
UnitOfPower,
|
|
UnitOfTemperature,
|
|
UnitOfVolume,
|
|
)
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
|
from homeassistant.util import dt as dt_util
|
|
|
|
from .const import DATA_BROKERS, DOMAIN
|
|
from .entity import SmartThingsEntity
|
|
|
|
|
|
def power_attributes(status: DeviceStatus) -> dict[str, Any]:
|
|
"""Return the power attributes."""
|
|
state = {}
|
|
for attribute in ("power_consumption_start", "power_consumption_end"):
|
|
value = getattr(status, attribute)
|
|
if value is not None:
|
|
state[attribute] = value
|
|
return state
|
|
|
|
|
|
@dataclass(frozen=True, kw_only=True)
|
|
class SmartThingsSensorEntityDescription(SensorEntityDescription):
|
|
"""Describe a SmartThings sensor entity."""
|
|
|
|
value_fn: Callable[[Any], str | float | int | datetime | None] = lambda value: value
|
|
extra_state_attributes_fn: Callable[[DeviceStatus], dict[str, Any]] | None = None
|
|
unique_id_separator: str = "."
|
|
|
|
|
|
CAPABILITY_TO_SENSORS: dict[
|
|
str, dict[str, list[SmartThingsSensorEntityDescription]]
|
|
] = {
|
|
Capability.activity_lighting_mode: {
|
|
Attribute.lighting_mode: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.lighting_mode,
|
|
name="Activity Lighting Mode",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
)
|
|
]
|
|
},
|
|
Capability.air_conditioner_mode: {
|
|
Attribute.air_conditioner_mode: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.air_conditioner_mode,
|
|
name="Air Conditioner Mode",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
)
|
|
]
|
|
},
|
|
Capability.air_quality_sensor: {
|
|
Attribute.air_quality: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.air_quality,
|
|
name="Air Quality",
|
|
native_unit_of_measurement="CAQI",
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
)
|
|
]
|
|
},
|
|
Capability.alarm: {
|
|
Attribute.alarm: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.alarm,
|
|
name="Alarm",
|
|
)
|
|
]
|
|
},
|
|
Capability.audio_volume: {
|
|
Attribute.volume: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.volume,
|
|
name="Volume",
|
|
native_unit_of_measurement=PERCENTAGE,
|
|
)
|
|
]
|
|
},
|
|
Capability.battery: {
|
|
Attribute.battery: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.battery,
|
|
name="Battery",
|
|
native_unit_of_measurement=PERCENTAGE,
|
|
device_class=SensorDeviceClass.BATTERY,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
)
|
|
]
|
|
},
|
|
Capability.body_mass_index_measurement: {
|
|
Attribute.bmi_measurement: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.bmi_measurement,
|
|
name="Body Mass Index",
|
|
native_unit_of_measurement=f"{UnitOfMass.KILOGRAMS}/{UnitOfArea.SQUARE_METERS}",
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
)
|
|
]
|
|
},
|
|
Capability.body_weight_measurement: {
|
|
Attribute.body_weight_measurement: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.body_weight_measurement,
|
|
name="Body Weight",
|
|
native_unit_of_measurement=UnitOfMass.KILOGRAMS,
|
|
device_class=SensorDeviceClass.WEIGHT,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
)
|
|
]
|
|
},
|
|
Capability.carbon_dioxide_measurement: {
|
|
Attribute.carbon_dioxide: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.carbon_dioxide,
|
|
name="Carbon Dioxide",
|
|
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
|
|
device_class=SensorDeviceClass.CO2,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
)
|
|
]
|
|
},
|
|
Capability.carbon_monoxide_detector: {
|
|
Attribute.carbon_monoxide: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.carbon_monoxide,
|
|
name="Carbon Monoxide Detector",
|
|
)
|
|
]
|
|
},
|
|
Capability.carbon_monoxide_measurement: {
|
|
Attribute.carbon_monoxide_level: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.carbon_monoxide_level,
|
|
name="Carbon Monoxide Level",
|
|
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
|
|
device_class=SensorDeviceClass.CO,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
)
|
|
]
|
|
},
|
|
Capability.dishwasher_operating_state: {
|
|
Attribute.machine_state: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.machine_state,
|
|
name="Dishwasher Machine State",
|
|
)
|
|
],
|
|
Attribute.dishwasher_job_state: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.dishwasher_job_state,
|
|
name="Dishwasher Job State",
|
|
)
|
|
],
|
|
Attribute.completion_time: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.completion_time,
|
|
name="Dishwasher Completion Time",
|
|
device_class=SensorDeviceClass.TIMESTAMP,
|
|
value_fn=dt_util.parse_datetime,
|
|
)
|
|
],
|
|
},
|
|
Capability.dryer_mode: {
|
|
Attribute.dryer_mode: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.dryer_mode,
|
|
name="Dryer Mode",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
)
|
|
]
|
|
},
|
|
Capability.dryer_operating_state: {
|
|
Attribute.machine_state: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.machine_state,
|
|
name="Dryer Machine State",
|
|
)
|
|
],
|
|
Attribute.dryer_job_state: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.dryer_job_state,
|
|
name="Dryer Job State",
|
|
)
|
|
],
|
|
Attribute.completion_time: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.completion_time,
|
|
name="Dryer Completion Time",
|
|
device_class=SensorDeviceClass.TIMESTAMP,
|
|
value_fn=dt_util.parse_datetime,
|
|
)
|
|
],
|
|
},
|
|
Capability.dust_sensor: {
|
|
Attribute.fine_dust_level: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.fine_dust_level,
|
|
name="Fine Dust Level",
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
)
|
|
],
|
|
Attribute.dust_level: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.dust_level,
|
|
name="Dust Level",
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
)
|
|
],
|
|
},
|
|
Capability.energy_meter: {
|
|
Attribute.energy: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.energy,
|
|
name="Energy Meter",
|
|
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
|
device_class=SensorDeviceClass.ENERGY,
|
|
state_class=SensorStateClass.TOTAL_INCREASING,
|
|
)
|
|
]
|
|
},
|
|
Capability.equivalent_carbon_dioxide_measurement: {
|
|
Attribute.equivalent_carbon_dioxide_measurement: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.equivalent_carbon_dioxide_measurement,
|
|
name="Equivalent Carbon Dioxide Measurement",
|
|
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
|
|
device_class=SensorDeviceClass.CO2,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
)
|
|
]
|
|
},
|
|
Capability.formaldehyde_measurement: {
|
|
Attribute.formaldehyde_level: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.formaldehyde_level,
|
|
name="Formaldehyde Measurement",
|
|
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
)
|
|
]
|
|
},
|
|
Capability.gas_meter: {
|
|
Attribute.gas_meter: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.gas_meter,
|
|
name="Gas Meter",
|
|
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
|
device_class=SensorDeviceClass.ENERGY,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
)
|
|
],
|
|
Attribute.gas_meter_calorific: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.gas_meter_calorific,
|
|
name="Gas Meter Calorific",
|
|
)
|
|
],
|
|
Attribute.gas_meter_time: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.gas_meter_time,
|
|
name="Gas Meter Time",
|
|
device_class=SensorDeviceClass.TIMESTAMP,
|
|
value_fn=dt_util.parse_datetime,
|
|
)
|
|
],
|
|
Attribute.gas_meter_volume: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.gas_meter_volume,
|
|
name="Gas Meter Volume",
|
|
native_unit_of_measurement=UnitOfVolume.CUBIC_METERS,
|
|
device_class=SensorDeviceClass.GAS,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
)
|
|
],
|
|
},
|
|
Capability.illuminance_measurement: {
|
|
Attribute.illuminance: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.illuminance,
|
|
name="Illuminance",
|
|
native_unit_of_measurement=LIGHT_LUX,
|
|
device_class=SensorDeviceClass.ILLUMINANCE,
|
|
)
|
|
]
|
|
},
|
|
Capability.infrared_level: {
|
|
Attribute.infrared_level: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.infrared_level,
|
|
name="Infrared Level",
|
|
native_unit_of_measurement=PERCENTAGE,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
)
|
|
]
|
|
},
|
|
Capability.media_input_source: {
|
|
Attribute.input_source: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.input_source,
|
|
name="Media Input Source",
|
|
)
|
|
]
|
|
},
|
|
Capability.media_playback_repeat: {
|
|
Attribute.playback_repeat_mode: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.playback_repeat_mode,
|
|
name="Media Playback Repeat",
|
|
)
|
|
]
|
|
},
|
|
Capability.media_playback_shuffle: {
|
|
Attribute.playback_shuffle: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.playback_shuffle,
|
|
name="Media Playback Shuffle",
|
|
)
|
|
]
|
|
},
|
|
Capability.media_playback: {
|
|
Attribute.playback_status: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.playback_status,
|
|
name="Media Playback Status",
|
|
)
|
|
]
|
|
},
|
|
Capability.odor_sensor: {
|
|
Attribute.odor_level: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.odor_level,
|
|
name="Odor Sensor",
|
|
)
|
|
]
|
|
},
|
|
Capability.oven_mode: {
|
|
Attribute.oven_mode: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.oven_mode,
|
|
name="Oven Mode",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
)
|
|
]
|
|
},
|
|
Capability.oven_operating_state: {
|
|
Attribute.machine_state: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.machine_state,
|
|
name="Oven Machine State",
|
|
)
|
|
],
|
|
Attribute.oven_job_state: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.oven_job_state,
|
|
name="Oven Job State",
|
|
)
|
|
],
|
|
Attribute.completion_time: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.completion_time,
|
|
name="Oven Completion Time",
|
|
)
|
|
],
|
|
},
|
|
Capability.oven_setpoint: {
|
|
Attribute.oven_setpoint: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.oven_setpoint,
|
|
name="Oven Set Point",
|
|
)
|
|
]
|
|
},
|
|
Capability.power_consumption_report: {
|
|
Attribute.power_consumption: [
|
|
SmartThingsSensorEntityDescription(
|
|
key="energy_meter",
|
|
name="energy",
|
|
state_class=SensorStateClass.TOTAL_INCREASING,
|
|
device_class=SensorDeviceClass.ENERGY,
|
|
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
|
value_fn=lambda value: (
|
|
val / 1000 if (val := value.get("energy")) is not None else None
|
|
),
|
|
),
|
|
SmartThingsSensorEntityDescription(
|
|
key="power_meter",
|
|
name="power",
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
device_class=SensorDeviceClass.POWER,
|
|
native_unit_of_measurement=UnitOfPower.WATT,
|
|
value_fn=lambda value: value.get("power"),
|
|
extra_state_attributes_fn=power_attributes,
|
|
),
|
|
SmartThingsSensorEntityDescription(
|
|
key="deltaEnergy_meter",
|
|
name="deltaEnergy",
|
|
state_class=SensorStateClass.TOTAL_INCREASING,
|
|
device_class=SensorDeviceClass.ENERGY,
|
|
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
|
value_fn=lambda value: (
|
|
val / 1000
|
|
if (val := value.get("deltaEnergy")) is not None
|
|
else None
|
|
),
|
|
),
|
|
SmartThingsSensorEntityDescription(
|
|
key="powerEnergy_meter",
|
|
name="powerEnergy",
|
|
state_class=SensorStateClass.TOTAL_INCREASING,
|
|
device_class=SensorDeviceClass.ENERGY,
|
|
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
|
value_fn=lambda value: (
|
|
val / 1000
|
|
if (val := value.get("powerEnergy")) is not None
|
|
else None
|
|
),
|
|
),
|
|
SmartThingsSensorEntityDescription(
|
|
key="energySaved_meter",
|
|
name="energySaved",
|
|
state_class=SensorStateClass.TOTAL_INCREASING,
|
|
device_class=SensorDeviceClass.ENERGY,
|
|
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
|
value_fn=lambda value: (
|
|
val / 1000
|
|
if (val := value.get("energySaved")) is not None
|
|
else None
|
|
),
|
|
),
|
|
]
|
|
},
|
|
Capability.power_meter: {
|
|
Attribute.power: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.power,
|
|
name="Power Meter",
|
|
native_unit_of_measurement=UnitOfPower.WATT,
|
|
device_class=SensorDeviceClass.POWER,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
)
|
|
]
|
|
},
|
|
Capability.power_source: {
|
|
Attribute.power_source: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.power_source,
|
|
name="Power Source",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
)
|
|
]
|
|
},
|
|
Capability.refrigeration_setpoint: {
|
|
Attribute.refrigeration_setpoint: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.refrigeration_setpoint,
|
|
name="Refrigeration Setpoint",
|
|
)
|
|
]
|
|
},
|
|
Capability.relative_humidity_measurement: {
|
|
Attribute.humidity: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.humidity,
|
|
name="Relative Humidity",
|
|
native_unit_of_measurement=PERCENTAGE,
|
|
device_class=SensorDeviceClass.HUMIDITY,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
)
|
|
]
|
|
},
|
|
Capability.robot_cleaner_cleaning_mode: {
|
|
Attribute.robot_cleaner_cleaning_mode: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.robot_cleaner_cleaning_mode,
|
|
name="Robot Cleaner Cleaning Mode",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
)
|
|
]
|
|
},
|
|
Capability.robot_cleaner_movement: {
|
|
Attribute.robot_cleaner_movement: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.robot_cleaner_movement,
|
|
name="Robot Cleaner Movement",
|
|
)
|
|
]
|
|
},
|
|
Capability.robot_cleaner_turbo_mode: {
|
|
Attribute.robot_cleaner_turbo_mode: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.robot_cleaner_turbo_mode,
|
|
name="Robot Cleaner Turbo Mode",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
)
|
|
]
|
|
},
|
|
Capability.signal_strength: {
|
|
Attribute.lqi: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.lqi,
|
|
name="LQI Signal Strength",
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
)
|
|
],
|
|
Attribute.rssi: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.rssi,
|
|
name="RSSI Signal Strength",
|
|
device_class=SensorDeviceClass.SIGNAL_STRENGTH,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
)
|
|
],
|
|
},
|
|
Capability.smoke_detector: {
|
|
Attribute.smoke: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.smoke,
|
|
name="Smoke Detector",
|
|
)
|
|
]
|
|
},
|
|
Capability.temperature_measurement: {
|
|
Attribute.temperature: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.temperature,
|
|
name="Temperature Measurement",
|
|
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
|
device_class=SensorDeviceClass.TEMPERATURE,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
)
|
|
]
|
|
},
|
|
Capability.thermostat_cooling_setpoint: {
|
|
Attribute.cooling_setpoint: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.cooling_setpoint,
|
|
name="Thermostat Cooling Setpoint",
|
|
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
|
device_class=SensorDeviceClass.TEMPERATURE,
|
|
)
|
|
]
|
|
},
|
|
Capability.thermostat_fan_mode: {
|
|
Attribute.thermostat_fan_mode: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.thermostat_fan_mode,
|
|
name="Thermostat Fan Mode",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
)
|
|
]
|
|
},
|
|
Capability.thermostat_heating_setpoint: {
|
|
Attribute.heating_setpoint: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.heating_setpoint,
|
|
name="Thermostat Heating Setpoint",
|
|
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
|
device_class=SensorDeviceClass.TEMPERATURE,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
)
|
|
]
|
|
},
|
|
Capability.thermostat_mode: {
|
|
Attribute.thermostat_mode: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.thermostat_mode,
|
|
name="Thermostat Mode",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
)
|
|
]
|
|
},
|
|
Capability.thermostat_operating_state: {
|
|
Attribute.thermostat_operating_state: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.thermostat_operating_state,
|
|
name="Thermostat Operating State",
|
|
)
|
|
]
|
|
},
|
|
Capability.thermostat_setpoint: {
|
|
Attribute.thermostat_setpoint: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.thermostat_setpoint,
|
|
name="Thermostat Setpoint",
|
|
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
|
device_class=SensorDeviceClass.TEMPERATURE,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
)
|
|
]
|
|
},
|
|
Capability.three_axis: {
|
|
Attribute.three_axis: [
|
|
SmartThingsSensorEntityDescription(
|
|
key="X Coordinate",
|
|
name="X Coordinate",
|
|
unique_id_separator=" ",
|
|
value_fn=lambda value: value[0],
|
|
),
|
|
SmartThingsSensorEntityDescription(
|
|
key="Y Coordinate",
|
|
name="Y Coordinate",
|
|
unique_id_separator=" ",
|
|
value_fn=lambda value: value[1],
|
|
),
|
|
SmartThingsSensorEntityDescription(
|
|
key="Z Coordinate",
|
|
name="Z Coordinate",
|
|
unique_id_separator=" ",
|
|
value_fn=lambda value: value[2],
|
|
),
|
|
]
|
|
},
|
|
Capability.tv_channel: {
|
|
Attribute.tv_channel: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.tv_channel,
|
|
name="Tv Channel",
|
|
)
|
|
],
|
|
Attribute.tv_channel_name: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.tv_channel_name,
|
|
name="Tv Channel Name",
|
|
)
|
|
],
|
|
},
|
|
Capability.tvoc_measurement: {
|
|
Attribute.tvoc_level: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.tvoc_level,
|
|
name="Tvoc Measurement",
|
|
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
)
|
|
]
|
|
},
|
|
Capability.ultraviolet_index: {
|
|
Attribute.ultraviolet_index: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.ultraviolet_index,
|
|
name="Ultraviolet Index",
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
)
|
|
]
|
|
},
|
|
Capability.voltage_measurement: {
|
|
Attribute.voltage: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.voltage,
|
|
name="Voltage Measurement",
|
|
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
|
|
device_class=SensorDeviceClass.VOLTAGE,
|
|
state_class=SensorStateClass.MEASUREMENT,
|
|
)
|
|
]
|
|
},
|
|
Capability.washer_mode: {
|
|
Attribute.washer_mode: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.washer_mode,
|
|
name="Washer Mode",
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
)
|
|
]
|
|
},
|
|
Capability.washer_operating_state: {
|
|
Attribute.machine_state: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.machine_state,
|
|
name="Washer Machine State",
|
|
)
|
|
],
|
|
Attribute.washer_job_state: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.washer_job_state,
|
|
name="Washer Job State",
|
|
)
|
|
],
|
|
Attribute.completion_time: [
|
|
SmartThingsSensorEntityDescription(
|
|
key=Attribute.completion_time,
|
|
name="Washer Completion Time",
|
|
device_class=SensorDeviceClass.TIMESTAMP,
|
|
value_fn=dt_util.parse_datetime,
|
|
)
|
|
],
|
|
},
|
|
}
|
|
|
|
UNITS = {
|
|
"C": UnitOfTemperature.CELSIUS,
|
|
"F": UnitOfTemperature.FAHRENHEIT,
|
|
"lux": LIGHT_LUX,
|
|
"mG": None, # Three axis sensors never had a unit, so this removes it for now
|
|
}
|
|
|
|
|
|
async def async_setup_entry(
|
|
hass: HomeAssistant,
|
|
config_entry: ConfigEntry,
|
|
async_add_entities: AddConfigEntryEntitiesCallback,
|
|
) -> None:
|
|
"""Add sensors for a config entry."""
|
|
broker = hass.data[DOMAIN][DATA_BROKERS][config_entry.entry_id]
|
|
async_add_entities(
|
|
SmartThingsSensor(device, attribute, description)
|
|
for device in broker.devices.values()
|
|
for capability in broker.get_assigned(device.device_id, "sensor")
|
|
for attribute, descriptions in CAPABILITY_TO_SENSORS[capability].items()
|
|
for description in descriptions
|
|
)
|
|
|
|
|
|
def get_capabilities(capabilities: Sequence[str]) -> Sequence[str] | None:
|
|
"""Return all capabilities supported if minimum required are present."""
|
|
return [
|
|
capability for capability in CAPABILITY_TO_SENSORS if capability in capabilities
|
|
]
|
|
|
|
|
|
class SmartThingsSensor(SmartThingsEntity, SensorEntity):
|
|
"""Define a SmartThings Sensor."""
|
|
|
|
entity_description: SmartThingsSensorEntityDescription
|
|
|
|
def __init__(
|
|
self,
|
|
device: DeviceEntity,
|
|
attribute: str,
|
|
entity_description: SmartThingsSensorEntityDescription,
|
|
) -> None:
|
|
"""Init the class."""
|
|
super().__init__(device)
|
|
self._attribute = attribute
|
|
self._attr_name = f"{device.label} {entity_description.name}"
|
|
self._attr_unique_id = f"{device.device_id}{entity_description.unique_id_separator}{entity_description.key}"
|
|
self.entity_description = entity_description
|
|
|
|
@property
|
|
def native_value(self) -> str | float | int | datetime | None:
|
|
"""Return the state of the sensor."""
|
|
return self.entity_description.value_fn(
|
|
self._device.status.attributes[self._attribute].value
|
|
)
|
|
|
|
@property
|
|
def native_unit_of_measurement(self):
|
|
"""Return the unit this state is expressed in."""
|
|
unit = self._device.status.attributes[self._attribute].unit
|
|
return (
|
|
UNITS.get(unit, unit)
|
|
if unit
|
|
else self.entity_description.native_unit_of_measurement
|
|
)
|
|
|
|
@property
|
|
def extra_state_attributes(self) -> Mapping[str, Any] | None:
|
|
"""Return the state attributes."""
|
|
if self.entity_description.extra_state_attributes_fn:
|
|
return self.entity_description.extra_state_attributes_fn(
|
|
self._device.status
|
|
)
|
|
return None
|