Skip to content

Commit

Permalink
Added Button Entity and Fixed bugs
Browse files Browse the repository at this point in the history
Fixed bugs and added button entity
  • Loading branch information
veista committed Jan 3, 2022
1 parent e50f6a9 commit 18bda8c
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 70 deletions.
122 changes: 122 additions & 0 deletions custom_components/smartthings/button.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
"""Support for buttons through the SmartThings cloud API."""
from __future__ import annotations

from collections import namedtuple
from collections.abc import Sequence

from pysmartthings.device import DeviceEntity

from homeassistant.components.button import ButtonEntity

from . import SmartThingsEntity
from .const import DATA_BROKERS, DOMAIN

Map = namedtuple(
"map",
"button_command name icon device_class extra_state_attributes",
)

CAPABILITY_TO_BUTTON = {
"custom.dustFilter": [
Map(
"resetDustFilter",
"Reset Dust Filter",
"mdi:air-filter",
None,
[
"dustFilterUsageStep",
"dustFilterUsage",
"dustFilterLastResetDate",
"dustFilterStatus",
"dustFilterCapacity",
"dustFilterResetType",
],
)
],
}


async def async_setup_entry(hass, config_entry, async_add_entities):
"""Add switches for a config entry."""
broker = hass.data[DOMAIN][DATA_BROKERS][config_entry.entry_id]
buttons = []
for device in broker.devices.values():
for capability in broker.get_assigned(device.device_id, "button"):
maps = CAPABILITY_TO_BUTTON[capability]
buttons.extend(
[
SmartThingsButton(
device,
capability,
m.button_command,
m.name,
m.icon,
m.device_class,
m.extra_state_attributes,
)
for m in maps
]
)

async_add_entities(buttons)


def get_capabilities(capabilities: Sequence[str]) -> Sequence[str] | None:
"""Return all capabilities supported if minimum required are present."""
# Must be able to be turned on.
return [
capability for capability in CAPABILITY_TO_BUTTON if capability in capabilities
]


class SmartThingsButton(SmartThingsEntity, ButtonEntity):
"""Define a SmartThings button."""

def __init__(
self,
device: DeviceEntity,
capability: str,
button_command: str | None,
name: str,
icon: str | None,
device_class: str | None,
extra_state_attributes: str | None,
) -> None:
"""Init the class."""
super().__init__(device)
self._capability = capability
self._button_command = button_command
self._name = name
self._icon = icon
self._attr_device_class = device_class
self._extra_state_attributes = extra_state_attributes

async def async_press(self) -> None:
"""Handle the button press."""
await self._device.command("main", self._capability, self._button_command, [])

@property
def name(self) -> str:
"""Return the name of the switch."""
return f"{self._device.label} {self._name}"

@property
def unique_id(self) -> str:
"""Return a unique ID."""
return f"{self._device.device_id}.{self._name}"

@property
def icon(self) -> str | None:
return self._icon

@property
def extra_state_attributes(self):
"""Return device specific state attributes."""
state_attributes = {}
if self._extra_state_attributes is not None:
attributes = self._extra_state_attributes
for attribute in attributes:
value = self._device.status.attributes[attribute].value
if value is not None:
state_attributes[attribute] = value
return state_attributes
1 change: 1 addition & 0 deletions custom_components/smartthings/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"cover",
"number",
"select",
"button",
"switch",
"binary_sensor",
"sensor",
Expand Down
9 changes: 3 additions & 6 deletions custom_components/smartthings/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -698,13 +698,10 @@ def __init__(
"""Init the class."""
super().__init__(device)
self.report_name = report_name
self._attr_state_class = STATE_CLASS_MEASUREMENT
if (
self.report_name != "power"
or self.report_name != "deltaEnergy"
or self.report_name != "powerEnergy"
):
if self.report_name in ("energy", "energySaved"):
self._attr_state_class = STATE_CLASS_TOTAL_INCREASING
else:
self._attr_state_class = STATE_CLASS_MEASUREMENT

@property
def name(self) -> str:
Expand Down
2 changes: 2 additions & 0 deletions custom_components/smartthings/smartapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,8 @@ async def delete_subscription(sub: SubscriptionEntity):
if disabled_capability in new_capabilities:
new_capabilities.remove(disabled_capability)
capabilities.update(new_capabilities)
else:
capabilities.update(device.capabilities)

# Remove unused capabilities
capabilities.difference_update(IGNORED_CAPABILITIES)
Expand Down
82 changes: 20 additions & 62 deletions custom_components/smartthings/switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,25 +45,6 @@
None,
)
],
"custom.dustFilter": [
Map(
None,
"resetDustFilter",
None,
None,
None,
"Reset Dust Filter",
"mdi:air-filter",
[
"dustFilterUsageStep",
"dustFilterUsage",
"dustFilterLastResetDate",
"dustFilterStatus",
"dustFilterCapacity",
"dustFilterResetType",
],
)
],
}


Expand All @@ -74,10 +55,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
for device in broker.devices.values():
for capability in broker.get_assigned(device.device_id, "switch"):
maps = CAPABILITY_TO_SWITCH[capability]
if (
capability == "custom.autoCleaningMode"
or capability == "custom.dustFilter"
):
if capability == "custom.autoCleaningMode":
switches.extend(
[
SmartThingsCustomSwitch(
Expand Down Expand Up @@ -133,9 +111,9 @@ class SmartThingsSwitch(SmartThingsEntity, SwitchEntity):
def __init__(
self,
device: DeviceEntity,
attribute: str | None,
on_command: str | None,
off_command: str | None,
attribute: str,
on_command: str,
off_command: str,
on_value: str | int | None,
off_value: str | int | None,
name: str,
Expand Down Expand Up @@ -175,9 +153,7 @@ def name(self) -> str:
@property
def unique_id(self) -> str:
"""Return a unique ID."""
if self._attribute is not None:
return f"{self._device.device_id}.{self._attribute}"
return f"{self._device.device_id}.{self._name}"
return f"{self._device.device_id}.{self._attribute}"

@property
def is_on(self) -> bool:
Expand Down Expand Up @@ -208,9 +184,9 @@ def __init__(
self,
device: DeviceEntity,
capability: str,
attribute: str | None,
on_command: str | None,
off_command: str | None,
attribute: str,
on_command: str,
off_command: str,
on_value: str | int | None,
off_value: str | int | None,
name: str,
Expand All @@ -231,38 +207,22 @@ def __init__(

async def async_turn_off(self, **kwargs) -> None:
"""Turn the switch off."""
if self._off_command is not None:
if self._on_value is not None:
result = await self._device.command(
"main", self._capability, self._off_command, [self._off_value]
)
if result:
self._device.status.update_attribute_value(
self._attribute, self._off_value
)
else:
await self._device.command(
"main", self._capability, self._off_command, []
)
result = await self._device.command(
"main", self._capability, self._off_command, [self._off_value]
)
if result:
self._device.status.update_attribute_value(self._attribute, self._off_value)
# State is set optimistically in the command above, therefore update
# the entity state ahead of receiving the confirming push updates
self.async_write_ha_state()

async def async_turn_on(self, **kwargs) -> None:
"""Turn the switch on."""
if self._on_command is not None:
if self._on_value is not None:
result = await self._device.command(
"main", self._capability, self._on_command, [self._on_value]
)
if result:
self._device.status.update_attribute_value(
self._attribute, self._on_value
)
else:
await self._device.command(
"main", self._capability, self._on_command, []
)
result = await self._device.command(
"main", self._capability, self._on_command, [self._on_value]
)
if result:
self._device.status.update_attribute_value(self._attribute, self._on_value)

# State is set optimistically in the command above, therefore update
# the entity state ahead of receiving the confirming push updates
Expand All @@ -276,9 +236,7 @@ def name(self) -> str:
@property
def unique_id(self) -> str:
"""Return a unique ID."""
if self._attribute is not None:
return f"{self._device.device_id}.{self._attribute}"
return f"{self._device.device_id}.{self._name}"
return f"{self._device.device_id}.{self._attribute}"

@property
def is_on(self) -> bool:
Expand Down Expand Up @@ -356,4 +314,4 @@ def is_on(self) -> bool:

@property
def icon(self) -> str | None:
return "mdi:led-on"
return "mdi:led-on"
4 changes: 2 additions & 2 deletions hacs.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "SmartThings Custom",
"domains": ["binary_sensor","climate", "cover", "fan", "light", "lock", "select", "sensor", "switch", "number"],
"homeassistant": "2021.12.0",
"domains": ["binary_sensor","climate", "cover", "fan", "light", "lock", "select", "sensor", "switch", "number", "button"],
"homeassistant": "2021.12.7",
"render_readme": true,
"content_in_root": false,
"iot_class": "cloud_push"
Expand Down

0 comments on commit 18bda8c

Please sign in to comment.