mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 03:07:37 +00:00
Add Dryer Wrinkle Prevent switch to SmartThings (#141085)
* Add Dryer Wrinkle Prevent switch to SmartThings * Fix
This commit is contained in:
parent
4b4d75063c
commit
c56b087d0c
@ -27,6 +27,14 @@
|
||||
"stop": "mdi:stop"
|
||||
}
|
||||
}
|
||||
},
|
||||
"switch": {
|
||||
"wrinkle_prevent": {
|
||||
"default": "mdi:tumble-dryer",
|
||||
"state": {
|
||||
"off": "mdi:tumble-dryer-off"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -442,6 +442,11 @@
|
||||
"freeze_protection": "Freeze protection"
|
||||
}
|
||||
}
|
||||
},
|
||||
"switch": {
|
||||
"wrinkle_prevent": {
|
||||
"name": "Wrinkle prevent"
|
||||
}
|
||||
}
|
||||
},
|
||||
"issues": {
|
||||
|
@ -2,15 +2,16 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import Any
|
||||
|
||||
from pysmartthings import Attribute, Capability, Command
|
||||
from pysmartthings import Attribute, Capability, Command, SmartThings
|
||||
|
||||
from homeassistant.components.switch import SwitchEntity
|
||||
from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from . import SmartThingsConfigEntry
|
||||
from . import FullDevice, SmartThingsConfigEntry
|
||||
from .const import MAIN
|
||||
from .entity import SmartThingsEntity
|
||||
|
||||
@ -29,6 +30,37 @@ AC_CAPABILITIES = (
|
||||
)
|
||||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
class SmartThingsSwitchEntityDescription(SwitchEntityDescription):
|
||||
"""Describe a SmartThings switch entity."""
|
||||
|
||||
status_attribute: Attribute
|
||||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
class SmartThingsCommandSwitchEntityDescription(SmartThingsSwitchEntityDescription):
|
||||
"""Describe a SmartThings switch entity."""
|
||||
|
||||
command: Command
|
||||
|
||||
|
||||
SWITCH = SmartThingsSwitchEntityDescription(
|
||||
key=Capability.SWITCH,
|
||||
status_attribute=Attribute.SWITCH,
|
||||
name=None,
|
||||
)
|
||||
CAPABILITY_TO_COMMAND_SWITCHES: dict[
|
||||
Capability | str, SmartThingsCommandSwitchEntityDescription
|
||||
] = {
|
||||
Capability.CUSTOM_DRYER_WRINKLE_PREVENT: SmartThingsCommandSwitchEntityDescription(
|
||||
key=Capability.CUSTOM_DRYER_WRINKLE_PREVENT,
|
||||
translation_key="wrinkle_prevent",
|
||||
status_attribute=Attribute.DRYER_WRINKLE_PREVENT,
|
||||
command=Command.SET_DRYER_WRINKLE_PREVENT,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
entry: SmartThingsConfigEntry,
|
||||
@ -36,35 +68,89 @@ async def async_setup_entry(
|
||||
) -> None:
|
||||
"""Add switches for a config entry."""
|
||||
entry_data = entry.runtime_data
|
||||
async_add_entities(
|
||||
SmartThingsSwitch(entry_data.client, device, {Capability.SWITCH})
|
||||
entities: list[SmartThingsEntity] = [
|
||||
SmartThingsSwitch(entry_data.client, device, SWITCH, Capability.SWITCH)
|
||||
for device in entry_data.devices.values()
|
||||
if Capability.SWITCH in device.status[MAIN]
|
||||
and not any(capability in device.status[MAIN] for capability in CAPABILITIES)
|
||||
and not all(capability in device.status[MAIN] for capability in AC_CAPABILITIES)
|
||||
]
|
||||
entities.extend(
|
||||
SmartThingsCommandSwitch(
|
||||
entry_data.client,
|
||||
device,
|
||||
description,
|
||||
Capability(capability),
|
||||
)
|
||||
for device in entry_data.devices.values()
|
||||
for capability, description in CAPABILITY_TO_COMMAND_SWITCHES.items()
|
||||
if capability in device.status[MAIN]
|
||||
)
|
||||
async_add_entities(entities)
|
||||
|
||||
|
||||
class SmartThingsSwitch(SmartThingsEntity, SwitchEntity):
|
||||
"""Define a SmartThings switch."""
|
||||
|
||||
_attr_name = None
|
||||
entity_description: SmartThingsSwitchEntityDescription
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
client: SmartThings,
|
||||
device: FullDevice,
|
||||
entity_description: SmartThingsSwitchEntityDescription,
|
||||
capability: Capability,
|
||||
) -> None:
|
||||
"""Initialize the switch."""
|
||||
super().__init__(client, device, {capability})
|
||||
self.entity_description = entity_description
|
||||
self.switch_capability = capability
|
||||
self._attr_unique_id = device.device.device_id
|
||||
if capability is not Capability.SWITCH:
|
||||
self._attr_unique_id = f"{device.device.device_id}_{MAIN}_{capability}"
|
||||
|
||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn the switch off."""
|
||||
await self.execute_device_command(
|
||||
Capability.SWITCH,
|
||||
self.switch_capability,
|
||||
Command.OFF,
|
||||
)
|
||||
|
||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||
"""Turn the switch on."""
|
||||
await self.execute_device_command(
|
||||
Capability.SWITCH,
|
||||
self.switch_capability,
|
||||
Command.ON,
|
||||
)
|
||||
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""Return true if light is on."""
|
||||
return self.get_attribute_value(Capability.SWITCH, Attribute.SWITCH) == "on"
|
||||
"""Return true if switch is on."""
|
||||
return (
|
||||
self.get_attribute_value(
|
||||
self.switch_capability, self.entity_description.status_attribute
|
||||
)
|
||||
== "on"
|
||||
)
|
||||
|
||||
|
||||
class SmartThingsCommandSwitch(SmartThingsSwitch):
|
||||
"""Define a SmartThings command switch."""
|
||||
|
||||
entity_description: SmartThingsCommandSwitchEntityDescription
|
||||
|
||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn the switch off."""
|
||||
await self.execute_device_command(
|
||||
self.switch_capability,
|
||||
self.entity_description.command,
|
||||
"off",
|
||||
)
|
||||
|
||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||
"""Turn the switch on."""
|
||||
await self.execute_device_command(
|
||||
self.switch_capability,
|
||||
self.entity_description.command,
|
||||
"on",
|
||||
)
|
||||
|
@ -281,6 +281,53 @@
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_wm_wd_000001][switch.dryer_wrinkle_prevent-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'switch',
|
||||
'entity_category': None,
|
||||
'entity_id': 'switch.dryer_wrinkle_prevent',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Wrinkle prevent',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'wrinkle_prevent',
|
||||
'unique_id': '02f7256e-8353-5bdd-547f-bd5b1647e01b_main_custom.dryerWrinklePrevent',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_wm_wd_000001][switch.dryer_wrinkle_prevent-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Dryer Wrinkle prevent',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'switch.dryer_wrinkle_prevent',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_wm_wd_000001_1][switch.seca_roupa-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
@ -328,6 +375,53 @@
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_wm_wd_000001_1][switch.seca_roupa_wrinkle_prevent-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'switch',
|
||||
'entity_category': None,
|
||||
'entity_id': 'switch.seca_roupa_wrinkle_prevent',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Wrinkle prevent',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'wrinkle_prevent',
|
||||
'unique_id': '3a6c4e05-811d-5041-e956-3d04c424cbcd_main_custom.dryerWrinklePrevent',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_wm_wd_000001_1][switch.seca_roupa_wrinkle_prevent-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Seca-Roupa Wrinkle prevent',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'switch.seca_roupa_wrinkle_prevent',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_wm_wm_000001][switch.washer-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
|
@ -66,6 +66,39 @@ async def test_switch_turn_on_off(
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("device_fixture", ["da_wm_wd_000001"])
|
||||
@pytest.mark.parametrize(
|
||||
("action", "argument"),
|
||||
[
|
||||
(SERVICE_TURN_ON, "on"),
|
||||
(SERVICE_TURN_OFF, "off"),
|
||||
],
|
||||
)
|
||||
async def test_command_switch_turn_on_off(
|
||||
hass: HomeAssistant,
|
||||
devices: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
action: str,
|
||||
argument: str,
|
||||
) -> None:
|
||||
"""Test switch turn on and off command."""
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
await hass.services.async_call(
|
||||
SWITCH_DOMAIN,
|
||||
action,
|
||||
{ATTR_ENTITY_ID: "switch.dryer_wrinkle_prevent"},
|
||||
blocking=True,
|
||||
)
|
||||
devices.execute_device_command.assert_called_once_with(
|
||||
"02f7256e-8353-5bdd-547f-bd5b1647e01b",
|
||||
Capability.CUSTOM_DRYER_WRINKLE_PREVENT,
|
||||
Command.SET_DRYER_WRINKLE_PREVENT,
|
||||
MAIN,
|
||||
argument,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("device_fixture", ["c2c_arlo_pro_3_switch"])
|
||||
async def test_state_update(
|
||||
hass: HomeAssistant,
|
||||
|
Loading…
x
Reference in New Issue
Block a user