Use shorthand attributes in Smartthings (#100215)
This commit is contained in:
parent
e84a4661b0
commit
a09372590f
7 changed files with 59 additions and 175 deletions
|
@ -429,6 +429,17 @@ class SmartThingsEntity(Entity):
|
||||||
"""Initialize the instance."""
|
"""Initialize the instance."""
|
||||||
self._device = device
|
self._device = device
|
||||||
self._dispatcher_remove = None
|
self._dispatcher_remove = None
|
||||||
|
self._attr_name = device.label
|
||||||
|
self._attr_unique_id = device.device_id
|
||||||
|
self._attr_device_info = DeviceInfo(
|
||||||
|
configuration_url="https://account.smartthings.com",
|
||||||
|
identifiers={(DOMAIN, device.device_id)},
|
||||||
|
manufacturer=device.status.ocf_manufacturer_name,
|
||||||
|
model=device.status.ocf_model_number,
|
||||||
|
name=device.label,
|
||||||
|
hw_version=device.status.ocf_hardware_version,
|
||||||
|
sw_version=device.status.ocf_firmware_version,
|
||||||
|
)
|
||||||
|
|
||||||
async def async_added_to_hass(self):
|
async def async_added_to_hass(self):
|
||||||
"""Device added to hass."""
|
"""Device added to hass."""
|
||||||
|
@ -446,26 +457,3 @@ class SmartThingsEntity(Entity):
|
||||||
"""Disconnect the device when removed."""
|
"""Disconnect the device when removed."""
|
||||||
if self._dispatcher_remove:
|
if self._dispatcher_remove:
|
||||||
self._dispatcher_remove()
|
self._dispatcher_remove()
|
||||||
|
|
||||||
@property
|
|
||||||
def device_info(self) -> DeviceInfo:
|
|
||||||
"""Get attributes about the device."""
|
|
||||||
return DeviceInfo(
|
|
||||||
configuration_url="https://account.smartthings.com",
|
|
||||||
identifiers={(DOMAIN, self._device.device_id)},
|
|
||||||
manufacturer=self._device.status.ocf_manufacturer_name,
|
|
||||||
model=self._device.status.ocf_model_number,
|
|
||||||
name=self._device.label,
|
|
||||||
hw_version=self._device.status.ocf_hardware_version,
|
|
||||||
sw_version=self._device.status.ocf_firmware_version,
|
|
||||||
)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def name(self) -> str:
|
|
||||||
"""Return the name of the device."""
|
|
||||||
return self._device.label
|
|
||||||
|
|
||||||
@property
|
|
||||||
def unique_id(self) -> str:
|
|
||||||
"""Return a unique ID."""
|
|
||||||
return self._device.device_id
|
|
||||||
|
|
|
@ -73,28 +73,12 @@ class SmartThingsBinarySensor(SmartThingsEntity, BinarySensorEntity):
|
||||||
"""Init the class."""
|
"""Init the class."""
|
||||||
super().__init__(device)
|
super().__init__(device)
|
||||||
self._attribute = attribute
|
self._attribute = attribute
|
||||||
|
self._attr_name = f"{device.label} {attribute}"
|
||||||
@property
|
self._attr_unique_id = f"{device.device_id}.{attribute}"
|
||||||
def name(self) -> str:
|
self._attr_device_class = ATTRIB_TO_CLASS[attribute]
|
||||||
"""Return the name of the binary sensor."""
|
self._attr_entity_category = ATTRIB_TO_ENTTIY_CATEGORY.get(attribute)
|
||||||
return f"{self._device.label} {self._attribute}"
|
|
||||||
|
|
||||||
@property
|
|
||||||
def unique_id(self) -> str:
|
|
||||||
"""Return a unique ID."""
|
|
||||||
return f"{self._device.device_id}.{self._attribute}"
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_on(self):
|
def is_on(self):
|
||||||
"""Return true if the binary sensor is on."""
|
"""Return true if the binary sensor is on."""
|
||||||
return self._device.status.is_on(self._attribute)
|
return self._device.status.is_on(self._attribute)
|
||||||
|
|
||||||
@property
|
|
||||||
def device_class(self):
|
|
||||||
"""Return the class of this device."""
|
|
||||||
return ATTRIB_TO_CLASS[self._attribute]
|
|
||||||
|
|
||||||
@property
|
|
||||||
def entity_category(self):
|
|
||||||
"""Return the entity category of this device."""
|
|
||||||
return ATTRIB_TO_ENTTIY_CATEGORY.get(self._attribute)
|
|
||||||
|
|
|
@ -77,10 +77,8 @@ class SmartThingsCover(SmartThingsEntity, CoverEntity):
|
||||||
def __init__(self, device):
|
def __init__(self, device):
|
||||||
"""Initialize the cover class."""
|
"""Initialize the cover class."""
|
||||||
super().__init__(device)
|
super().__init__(device)
|
||||||
self._device_class = None
|
|
||||||
self._current_cover_position = None
|
self._current_cover_position = None
|
||||||
self._state = None
|
self._state = None
|
||||||
self._state_attrs = None
|
|
||||||
self._attr_supported_features = (
|
self._attr_supported_features = (
|
||||||
CoverEntityFeature.OPEN | CoverEntityFeature.CLOSE
|
CoverEntityFeature.OPEN | CoverEntityFeature.CLOSE
|
||||||
)
|
)
|
||||||
|
@ -90,6 +88,13 @@ class SmartThingsCover(SmartThingsEntity, CoverEntity):
|
||||||
):
|
):
|
||||||
self._attr_supported_features |= CoverEntityFeature.SET_POSITION
|
self._attr_supported_features |= CoverEntityFeature.SET_POSITION
|
||||||
|
|
||||||
|
if Capability.door_control in device.capabilities:
|
||||||
|
self._attr_device_class = CoverDeviceClass.DOOR
|
||||||
|
elif Capability.window_shade in device.capabilities:
|
||||||
|
self._attr_device_class = CoverDeviceClass.SHADE
|
||||||
|
elif Capability.garage_door_control in device.capabilities:
|
||||||
|
self._attr_device_class = CoverDeviceClass.GARAGE
|
||||||
|
|
||||||
async def async_close_cover(self, **kwargs: Any) -> None:
|
async def async_close_cover(self, **kwargs: Any) -> None:
|
||||||
"""Close cover."""
|
"""Close cover."""
|
||||||
# Same command for all 3 supported capabilities
|
# Same command for all 3 supported capabilities
|
||||||
|
@ -121,24 +126,21 @@ class SmartThingsCover(SmartThingsEntity, CoverEntity):
|
||||||
async def async_update(self) -> None:
|
async def async_update(self) -> None:
|
||||||
"""Update the attrs of the cover."""
|
"""Update the attrs of the cover."""
|
||||||
if Capability.door_control in self._device.capabilities:
|
if Capability.door_control in self._device.capabilities:
|
||||||
self._device_class = CoverDeviceClass.DOOR
|
|
||||||
self._state = VALUE_TO_STATE.get(self._device.status.door)
|
self._state = VALUE_TO_STATE.get(self._device.status.door)
|
||||||
elif Capability.window_shade in self._device.capabilities:
|
elif Capability.window_shade in self._device.capabilities:
|
||||||
self._device_class = CoverDeviceClass.SHADE
|
|
||||||
self._state = VALUE_TO_STATE.get(self._device.status.window_shade)
|
self._state = VALUE_TO_STATE.get(self._device.status.window_shade)
|
||||||
elif Capability.garage_door_control in self._device.capabilities:
|
elif Capability.garage_door_control in self._device.capabilities:
|
||||||
self._device_class = CoverDeviceClass.GARAGE
|
|
||||||
self._state = VALUE_TO_STATE.get(self._device.status.door)
|
self._state = VALUE_TO_STATE.get(self._device.status.door)
|
||||||
|
|
||||||
if Capability.window_shade_level in self._device.capabilities:
|
if Capability.window_shade_level in self._device.capabilities:
|
||||||
self._current_cover_position = self._device.status.shade_level
|
self._attr_current_cover_position = self._device.status.shade_level
|
||||||
elif Capability.switch_level in self._device.capabilities:
|
elif Capability.switch_level in self._device.capabilities:
|
||||||
self._current_cover_position = self._device.status.level
|
self._attr_current_cover_position = self._device.status.level
|
||||||
|
|
||||||
self._state_attrs = {}
|
self._attr_extra_state_attributes = {}
|
||||||
battery = self._device.status.attributes[Attribute.battery].value
|
battery = self._device.status.attributes[Attribute.battery].value
|
||||||
if battery is not None:
|
if battery is not None:
|
||||||
self._state_attrs[ATTR_BATTERY_LEVEL] = battery
|
self._attr_extra_state_attributes[ATTR_BATTERY_LEVEL] = battery
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_opening(self) -> bool:
|
def is_opening(self) -> bool:
|
||||||
|
@ -156,18 +158,3 @@ class SmartThingsCover(SmartThingsEntity, CoverEntity):
|
||||||
if self._state == STATE_CLOSED:
|
if self._state == STATE_CLOSED:
|
||||||
return True
|
return True
|
||||||
return None if self._state is None else False
|
return None if self._state is None else False
|
||||||
|
|
||||||
@property
|
|
||||||
def current_cover_position(self) -> int | None:
|
|
||||||
"""Return current position of cover."""
|
|
||||||
return self._current_cover_position
|
|
||||||
|
|
||||||
@property
|
|
||||||
def device_class(self) -> CoverDeviceClass | None:
|
|
||||||
"""Define this cover as a garage door."""
|
|
||||||
return self._device_class
|
|
||||||
|
|
||||||
@property
|
|
||||||
def extra_state_attributes(self) -> dict[str, Any]:
|
|
||||||
"""Get additional state attributes."""
|
|
||||||
return self._state_attrs
|
|
||||||
|
|
|
@ -52,6 +52,7 @@ class SmartThingsFan(SmartThingsEntity, FanEntity):
|
||||||
"""Define a SmartThings Fan."""
|
"""Define a SmartThings Fan."""
|
||||||
|
|
||||||
_attr_supported_features = FanEntityFeature.SET_SPEED
|
_attr_supported_features = FanEntityFeature.SET_SPEED
|
||||||
|
_attr_speed_count = int_states_in_range(SPEED_RANGE)
|
||||||
|
|
||||||
async def async_set_percentage(self, percentage: int) -> None:
|
async def async_set_percentage(self, percentage: int) -> None:
|
||||||
"""Set the speed percentage of the fan."""
|
"""Set the speed percentage of the fan."""
|
||||||
|
@ -94,8 +95,3 @@ class SmartThingsFan(SmartThingsEntity, FanEntity):
|
||||||
def percentage(self) -> int:
|
def percentage(self) -> int:
|
||||||
"""Return the current speed percentage."""
|
"""Return the current speed percentage."""
|
||||||
return ranged_value_to_percentage(SPEED_RANGE, self._device.status.fan_speed)
|
return ranged_value_to_percentage(SPEED_RANGE, self._device.status.fan_speed)
|
||||||
|
|
||||||
@property
|
|
||||||
def speed_count(self) -> int:
|
|
||||||
"""Return the number of speeds the fan supports."""
|
|
||||||
return int_states_in_range(SPEED_RANGE)
|
|
||||||
|
|
|
@ -75,12 +75,19 @@ class SmartThingsLight(SmartThingsEntity, LightEntity):
|
||||||
|
|
||||||
_attr_supported_color_modes: set[ColorMode]
|
_attr_supported_color_modes: set[ColorMode]
|
||||||
|
|
||||||
|
# SmartThings does not expose this attribute, instead it's
|
||||||
|
# implemented within each device-type handler. This value is the
|
||||||
|
# lowest kelvin found supported across 20+ handlers.
|
||||||
|
_attr_max_mireds = 500 # 2000K
|
||||||
|
|
||||||
|
# SmartThings does not expose this attribute, instead it's
|
||||||
|
# implemented within each device-type handler. This value is the
|
||||||
|
# highest kelvin found supported across 20+ handlers.
|
||||||
|
_attr_min_mireds = 111 # 9000K
|
||||||
|
|
||||||
def __init__(self, device):
|
def __init__(self, device):
|
||||||
"""Initialize a SmartThingsLight."""
|
"""Initialize a SmartThingsLight."""
|
||||||
super().__init__(device)
|
super().__init__(device)
|
||||||
self._brightness = None
|
|
||||||
self._color_temp = None
|
|
||||||
self._hs_color = None
|
|
||||||
self._attr_supported_color_modes = self._determine_color_modes()
|
self._attr_supported_color_modes = self._determine_color_modes()
|
||||||
self._attr_supported_features = self._determine_features()
|
self._attr_supported_features = self._determine_features()
|
||||||
|
|
||||||
|
@ -151,17 +158,17 @@ class SmartThingsLight(SmartThingsEntity, LightEntity):
|
||||||
"""Update entity attributes when the device status has changed."""
|
"""Update entity attributes when the device status has changed."""
|
||||||
# Brightness and transition
|
# Brightness and transition
|
||||||
if brightness_supported(self._attr_supported_color_modes):
|
if brightness_supported(self._attr_supported_color_modes):
|
||||||
self._brightness = int(
|
self._attr_brightness = int(
|
||||||
convert_scale(self._device.status.level, 100, 255, 0)
|
convert_scale(self._device.status.level, 100, 255, 0)
|
||||||
)
|
)
|
||||||
# Color Temperature
|
# Color Temperature
|
||||||
if ColorMode.COLOR_TEMP in self._attr_supported_color_modes:
|
if ColorMode.COLOR_TEMP in self._attr_supported_color_modes:
|
||||||
self._color_temp = color_util.color_temperature_kelvin_to_mired(
|
self._attr_color_temp = color_util.color_temperature_kelvin_to_mired(
|
||||||
self._device.status.color_temperature
|
self._device.status.color_temperature
|
||||||
)
|
)
|
||||||
# Color
|
# Color
|
||||||
if ColorMode.HS in self._attr_supported_color_modes:
|
if ColorMode.HS in self._attr_supported_color_modes:
|
||||||
self._hs_color = (
|
self._attr_hs_color = (
|
||||||
convert_scale(self._device.status.hue, 100, 360),
|
convert_scale(self._device.status.hue, 100, 360),
|
||||||
self._device.status.saturation,
|
self._device.status.saturation,
|
||||||
)
|
)
|
||||||
|
@ -197,42 +204,11 @@ class SmartThingsLight(SmartThingsEntity, LightEntity):
|
||||||
return list(self._attr_supported_color_modes)[0]
|
return list(self._attr_supported_color_modes)[0]
|
||||||
|
|
||||||
# The light supports hs + color temp, determine which one it is
|
# The light supports hs + color temp, determine which one it is
|
||||||
if self._hs_color and self._hs_color[1]:
|
if self._attr_hs_color and self._attr_hs_color[1]:
|
||||||
return ColorMode.HS
|
return ColorMode.HS
|
||||||
return ColorMode.COLOR_TEMP
|
return ColorMode.COLOR_TEMP
|
||||||
|
|
||||||
@property
|
|
||||||
def brightness(self):
|
|
||||||
"""Return the brightness of this light between 0..255."""
|
|
||||||
return self._brightness
|
|
||||||
|
|
||||||
@property
|
|
||||||
def color_temp(self):
|
|
||||||
"""Return the CT color value in mireds."""
|
|
||||||
return self._color_temp
|
|
||||||
|
|
||||||
@property
|
|
||||||
def hs_color(self):
|
|
||||||
"""Return the hue and saturation color value [float, float]."""
|
|
||||||
return self._hs_color
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_on(self) -> bool:
|
def is_on(self) -> bool:
|
||||||
"""Return true if light is on."""
|
"""Return true if light is on."""
|
||||||
return self._device.status.switch
|
return self._device.status.switch
|
||||||
|
|
||||||
@property
|
|
||||||
def max_mireds(self):
|
|
||||||
"""Return the warmest color_temp that this light supports."""
|
|
||||||
# SmartThings does not expose this attribute, instead it's
|
|
||||||
# implemented within each device-type handler. This value is the
|
|
||||||
# lowest kelvin found supported across 20+ handlers.
|
|
||||||
return 500 # 2000K
|
|
||||||
|
|
||||||
@property
|
|
||||||
def min_mireds(self):
|
|
||||||
"""Return the coldest color_temp that this light supports."""
|
|
||||||
# SmartThings does not expose this attribute, instead it's
|
|
||||||
# implemented within each device-type handler. This value is the
|
|
||||||
# highest kelvin found supported across 20+ handlers.
|
|
||||||
return 111 # 9000K
|
|
||||||
|
|
|
@ -25,6 +25,8 @@ class SmartThingsScene(Scene):
|
||||||
def __init__(self, scene):
|
def __init__(self, scene):
|
||||||
"""Init the scene class."""
|
"""Init the scene class."""
|
||||||
self._scene = scene
|
self._scene = scene
|
||||||
|
self._attr_name = scene.name
|
||||||
|
self._attr_unique_id = scene.scene_id
|
||||||
|
|
||||||
async def async_activate(self, **kwargs: Any) -> None:
|
async def async_activate(self, **kwargs: Any) -> None:
|
||||||
"""Activate scene."""
|
"""Activate scene."""
|
||||||
|
@ -38,13 +40,3 @@ class SmartThingsScene(Scene):
|
||||||
"color": self._scene.color,
|
"color": self._scene.color,
|
||||||
"location_id": self._scene.location_id,
|
"location_id": self._scene.location_id,
|
||||||
}
|
}
|
||||||
|
|
||||||
@property
|
|
||||||
def name(self) -> str:
|
|
||||||
"""Return the name of the device."""
|
|
||||||
return self._scene.name
|
|
||||||
|
|
||||||
@property
|
|
||||||
def unique_id(self) -> str:
|
|
||||||
"""Return a unique ID."""
|
|
||||||
return self._scene.scene_id
|
|
||||||
|
|
|
@ -629,44 +629,30 @@ class SmartThingsSensor(SmartThingsEntity, SensorEntity):
|
||||||
attribute: str,
|
attribute: str,
|
||||||
name: str,
|
name: str,
|
||||||
default_unit: str,
|
default_unit: str,
|
||||||
device_class: str,
|
device_class: SensorDeviceClass,
|
||||||
state_class: str | None,
|
state_class: str | None,
|
||||||
entity_category: EntityCategory | None,
|
entity_category: EntityCategory | None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Init the class."""
|
"""Init the class."""
|
||||||
super().__init__(device)
|
super().__init__(device)
|
||||||
self._attribute = attribute
|
self._attribute = attribute
|
||||||
self._name = name
|
self._attr_name = f"{device.label} {name}"
|
||||||
self._device_class = device_class
|
self._attr_unique_id = f"{device.device_id}.{attribute}"
|
||||||
|
self._attr_device_class = device_class
|
||||||
self._default_unit = default_unit
|
self._default_unit = default_unit
|
||||||
self._attr_state_class = state_class
|
self._attr_state_class = state_class
|
||||||
self._attr_entity_category = entity_category
|
self._attr_entity_category = entity_category
|
||||||
|
|
||||||
@property
|
|
||||||
def name(self) -> str:
|
|
||||||
"""Return the name of the sensor."""
|
|
||||||
return f"{self._device.label} {self._name}"
|
|
||||||
|
|
||||||
@property
|
|
||||||
def unique_id(self) -> str:
|
|
||||||
"""Return a unique ID."""
|
|
||||||
return f"{self._device.device_id}.{self._attribute}"
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def native_value(self):
|
def native_value(self):
|
||||||
"""Return the state of the sensor."""
|
"""Return the state of the sensor."""
|
||||||
value = self._device.status.attributes[self._attribute].value
|
value = self._device.status.attributes[self._attribute].value
|
||||||
|
|
||||||
if self._device_class != SensorDeviceClass.TIMESTAMP:
|
if self.device_class != SensorDeviceClass.TIMESTAMP:
|
||||||
return value
|
return value
|
||||||
|
|
||||||
return dt_util.parse_datetime(value)
|
return dt_util.parse_datetime(value)
|
||||||
|
|
||||||
@property
|
|
||||||
def device_class(self):
|
|
||||||
"""Return the device class of the sensor."""
|
|
||||||
return self._device_class
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def native_unit_of_measurement(self):
|
def native_unit_of_measurement(self):
|
||||||
"""Return the unit this state is expressed in."""
|
"""Return the unit this state is expressed in."""
|
||||||
|
@ -681,16 +667,8 @@ class SmartThingsThreeAxisSensor(SmartThingsEntity, SensorEntity):
|
||||||
"""Init the class."""
|
"""Init the class."""
|
||||||
super().__init__(device)
|
super().__init__(device)
|
||||||
self._index = index
|
self._index = index
|
||||||
|
self._attr_name = f"{device.label} {THREE_AXIS_NAMES[index]}"
|
||||||
@property
|
self._attr_unique_id = f"{device.device_id} {THREE_AXIS_NAMES[index]}"
|
||||||
def name(self) -> str:
|
|
||||||
"""Return the name of the sensor."""
|
|
||||||
return f"{self._device.label} {THREE_AXIS_NAMES[self._index]}"
|
|
||||||
|
|
||||||
@property
|
|
||||||
def unique_id(self) -> str:
|
|
||||||
"""Return a unique ID."""
|
|
||||||
return f"{self._device.device_id}.{THREE_AXIS_NAMES[self._index]}"
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def native_value(self):
|
def native_value(self):
|
||||||
|
@ -713,19 +691,16 @@ class SmartThingsPowerConsumptionSensor(SmartThingsEntity, SensorEntity):
|
||||||
"""Init the class."""
|
"""Init the class."""
|
||||||
super().__init__(device)
|
super().__init__(device)
|
||||||
self.report_name = report_name
|
self.report_name = report_name
|
||||||
self._attr_state_class = SensorStateClass.MEASUREMENT
|
self._attr_name = f"{device.label} {report_name}"
|
||||||
if self.report_name != "power":
|
self._attr_unique_id = f"{device.device_id}.{report_name}_meter"
|
||||||
|
if self.report_name == "power":
|
||||||
|
self._attr_state_class = SensorStateClass.MEASUREMENT
|
||||||
|
self._attr_device_class = SensorDeviceClass.POWER
|
||||||
|
self._attr_native_unit_of_measurement = UnitOfPower.WATT
|
||||||
|
else:
|
||||||
self._attr_state_class = SensorStateClass.TOTAL_INCREASING
|
self._attr_state_class = SensorStateClass.TOTAL_INCREASING
|
||||||
|
self._attr_device_class = SensorDeviceClass.ENERGY
|
||||||
@property
|
self._attr_native_unit_of_measurement = UnitOfEnergy.KILO_WATT_HOUR
|
||||||
def name(self) -> str:
|
|
||||||
"""Return the name of the sensor."""
|
|
||||||
return f"{self._device.label} {self.report_name}"
|
|
||||||
|
|
||||||
@property
|
|
||||||
def unique_id(self) -> str:
|
|
||||||
"""Return a unique ID."""
|
|
||||||
return f"{self._device.device_id}.{self.report_name}_meter"
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def native_value(self):
|
def native_value(self):
|
||||||
|
@ -737,20 +712,6 @@ class SmartThingsPowerConsumptionSensor(SmartThingsEntity, SensorEntity):
|
||||||
return value[self.report_name]
|
return value[self.report_name]
|
||||||
return value[self.report_name] / 1000
|
return value[self.report_name] / 1000
|
||||||
|
|
||||||
@property
|
|
||||||
def device_class(self):
|
|
||||||
"""Return the device class of the sensor."""
|
|
||||||
if self.report_name == "power":
|
|
||||||
return SensorDeviceClass.POWER
|
|
||||||
return SensorDeviceClass.ENERGY
|
|
||||||
|
|
||||||
@property
|
|
||||||
def native_unit_of_measurement(self):
|
|
||||||
"""Return the unit this state is expressed in."""
|
|
||||||
if self.report_name == "power":
|
|
||||||
return UnitOfPower.WATT
|
|
||||||
return UnitOfEnergy.KILO_WATT_HOUR
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def extra_state_attributes(self):
|
def extra_state_attributes(self):
|
||||||
"""Return specific state attributes."""
|
"""Return specific state attributes."""
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue