Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add siren platform to Tuya #57780

Merged
merged 2 commits into from Oct 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .coveragerc
Expand Up @@ -1120,6 +1120,7 @@ omit =
homeassistant/components/tuya/scene.py
homeassistant/components/tuya/select.py
homeassistant/components/tuya/sensor.py
homeassistant/components/tuya/siren.py
homeassistant/components/tuya/switch.py
homeassistant/components/twentemilieu/const.py
homeassistant/components/twentemilieu/sensor.py
Expand Down
7 changes: 7 additions & 0 deletions homeassistant/components/tuya/const.py
Expand Up @@ -46,6 +46,7 @@
"pir", # PIR Detector
"qn", # Heater
"sos", # SOS Button
"sgbj", # Siren Alarm
"wk", # Thermostat
"xdd", # Ceiling Light
"xxj", # Diffuser
Expand All @@ -63,6 +64,7 @@
"scene",
"select",
"sensor",
"siren",
"switch",
]

Expand All @@ -73,9 +75,13 @@ class DPCode(str, Enum):
https://developer.tuya.com/en/docs/iot/standarddescription?id=K9i5ql6waswzq
"""

ALARM_SWITCH = "alarm_switch" # Alarm switch
ALARM_TIME = "alarm_time" # Alarm time
ALARM_VOLUME = "alarm_volume" # Alarm volume
ANION = "anion" # Ionizer unit
BATTERY_PERCENTAGE = "battery_percentage" # Battery percentage
BATTERY_STATE = "battery_state" # Battery state
BRIGHT_STATE = "Brightness" # Brightness
BRIGHT_VALUE = "bright_value" # Brightness
C_F = "c_f" # Temperature unit switching
CHILD_LOCK = "child_lock" # Child lock
Expand All @@ -98,6 +104,7 @@ class DPCode(str, Enum):
MATERIAL = "material" # Material
MODE = "mode" # Working mode / Mode
PIR = "pir" # Motion sensor
MUFFLING = "muffling" # Muffling
POWDER_SET = "powder_set" # Powder
PUMP_RESET = "pump_reset" # Water pump reset
SHAKE = "shake" # Oscillating
Expand Down
10 changes: 10 additions & 0 deletions homeassistant/components/tuya/number.py
Expand Up @@ -8,6 +8,7 @@

from homeassistant.components.number import NumberEntity, NumberEntityDescription
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ENTITY_CATEGORY_CONFIG
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_platform import AddEntitiesCallback
Expand Down Expand Up @@ -47,6 +48,15 @@
entity_registry_enabled_default=False,
),
),
# Siren Alarm
# https://developer.tuya.com/en/docs/iot/categorysgbj?id=Kaiuz37tlpbnu
"sgbj": (
NumberEntityDescription(
key=DPCode.ALARM_TIME,
name="Time",
entity_category=ENTITY_CATEGORY_CONFIG,
),
),
}


Expand Down
15 changes: 15 additions & 0 deletions homeassistant/components/tuya/select.py
Expand Up @@ -8,6 +8,7 @@

from homeassistant.components.select import SelectEntity, SelectEntityDescription
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ENTITY_CATEGORY_CONFIG
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_platform import AddEntitiesCallback
Expand Down Expand Up @@ -42,6 +43,20 @@
name="Mode",
),
),
# Siren Alarm
# https://developer.tuya.com/en/docs/iot/categorysgbj?id=Kaiuz37tlpbnu
"sgbj": (
SelectEntityDescription(
key=DPCode.ALARM_VOLUME,
name="Volume",
entity_category=ENTITY_CATEGORY_CONFIG,
),
SelectEntityDescription(
key=DPCode.BRIGHT_STATE,
name="Brightness",
entity_category=ENTITY_CATEGORY_CONFIG,
),
),
}


Expand Down
92 changes: 92 additions & 0 deletions homeassistant/components/tuya/siren.py
@@ -0,0 +1,92 @@
"""Support for Tuya siren."""
from __future__ import annotations

from typing import Any

from tuya_iot import TuyaDevice, TuyaDeviceManager

from homeassistant.components.siren import SirenEntity, SirenEntityDescription
from homeassistant.components.siren.const import SUPPORT_TURN_OFF, SUPPORT_TURN_ON
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_platform import AddEntitiesCallback

from . import HomeAssistantTuyaData
from .base import TuyaEntity
from .const import DOMAIN, TUYA_DISCOVERY_NEW, DPCode

# All descriptions can be found here:
# https://developer.tuya.com/en/docs/iot/standarddescription?id=K9i5ql6waswzq
SIRENS: dict[str, tuple[SirenEntityDescription, ...]] = {
# Siren Alarm
# https://developer.tuya.com/en/docs/iot/categorysgbj?id=Kaiuz37tlpbnu
"sgbj": (
SirenEntityDescription(
key=DPCode.ALARM_SWITCH,
name="Siren",
),
),
}


async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
"""Set up Tuya siren dynamically through Tuya discovery."""
hass_data: HomeAssistantTuyaData = hass.data[DOMAIN][entry.entry_id]

@callback
def async_discover_device(device_ids: list[str]) -> None:
"""Discover and add a discovered Tuya siren."""
entities: list[TuyaSirenEntity] = []
for device_id in device_ids:
device = hass_data.device_manager.device_map[device_id]
if descriptions := SIRENS.get(device.category):
for description in descriptions:
if (
description.key in device.function
or description.key in device.status
):
entities.append(
TuyaSirenEntity(
device, hass_data.device_manager, description
)
)

async_add_entities(entities)

async_discover_device([*hass_data.device_manager.device_map])

entry.async_on_unload(
async_dispatcher_connect(hass, TUYA_DISCOVERY_NEW, async_discover_device)
)


class TuyaSirenEntity(TuyaEntity, SirenEntity):
"""Tuya Siren Entity."""

def __init__(
self,
device: TuyaDevice,
device_manager: TuyaDeviceManager,
description: SirenEntityDescription,
) -> None:
"""Init Tuya Siren."""
super().__init__(device, device_manager)
self.entity_description = description
self._attr_unique_id = f"{super().unique_id}{description.key}"
self._attr_supported_features = SUPPORT_TURN_ON | SUPPORT_TURN_OFF

@property
def is_on(self) -> bool:
"""Return true if siren is on."""
return self.device.status.get(self.entity_description.key, False)

def turn_on(self, **kwargs: Any) -> None:
"""Turn the siren on."""
self._send_command([{"code": self.entity_description.key, "value": True}])

def turn_off(self, **kwargs: Any) -> None:
"""Turn the siren off."""
self._send_command([{"code": self.entity_description.key, "value": False}])
10 changes: 10 additions & 0 deletions homeassistant/components/tuya/switch.py
Expand Up @@ -11,6 +11,7 @@
SwitchEntityDescription,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ENTITY_CATEGORY_CONFIG
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_platform import AddEntitiesCallback
Expand Down Expand Up @@ -237,6 +238,15 @@
device_class=DEVICE_CLASS_OUTLET,
),
),
# Siren Alarm
# https://developer.tuya.com/en/docs/iot/categorysgbj?id=Kaiuz37tlpbnu
"sgbj": (
SwitchEntityDescription(
key=DPCode.MUFFLING,
name="Muffling",
entity_category=ENTITY_CATEGORY_CONFIG,
),
),
# Diffuser
"xxj": (
SwitchEntityDescription(
Expand Down