siren.py 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. """
  2. Platform to control Tuya sirens.
  3. """
  4. from homeassistant.components.siren import (
  5. SirenEntity,
  6. SirenEntityDescription,
  7. SirenEntityFeature,
  8. )
  9. from ..device import TuyaLocalDevice
  10. from ..helpers.device_config import TuyaEntityConfig
  11. from ..helpers.mixin import TuyaLocalEntity
  12. class TuyaLocalSiren(TuyaLocalEntity, SirenEntity):
  13. """Representation of a Tuya siren"""
  14. def __init__(self, device: TuyaLocalDevice, config: TuyaEntityConfig):
  15. """
  16. Initialize the siren.
  17. Args:
  18. device (TuyaLocalDevice): The device API instance.
  19. config (TuyaEntityConfig): The config for this entity.
  20. """
  21. dps_map = self._init_begin(device, config)
  22. self._tone_dp = dps_map.get("tone", None)
  23. self._volume_dp = dps_map.get("volume_level", None)
  24. self._duration_dp = dps_map.get("duration", None)
  25. self._init_end(dps_map)
  26. # All control of features is through the turn_on service, so we need to
  27. # support that, even if the siren does not support direct control
  28. support = SirenEntityFeature.TURN_ON
  29. if self._tone_dp:
  30. support |= SirenEntityFeature.TONES
  31. self.entity_description = SirenEntityDescription
  32. self.entity_description.available_tones = self._tone_dp.values(device)
  33. if self._volume_dp:
  34. support |= SirenEntityFeature.VOLUME_SET
  35. if self._duration_dp:
  36. support |= SirenEntityFeature.DURATION
  37. self._attr_supported_features = support
  38. async def async_turn_on(self, **kwargs) -> None:
  39. tone = kwargs.get("tone", None)
  40. duration = kwargs.get("duration", None)
  41. volume = kwargs.get("volume", None)
  42. set_dps = {}
  43. if tone is not None and self._tone_dp:
  44. set_dps = {
  45. **set_dps,
  46. **self._tone_dp.get_values_to_set(self._device, tone),
  47. }
  48. if duration is not None and self._duration_dp:
  49. set_dps = {
  50. **set_dps,
  51. **self._duration_dp.get_values_to_set(self._device, duration),
  52. }
  53. if volume is not None and self._volume_dp:
  54. # Volume is a float, range 0.0-1.0 in Home Assistant
  55. # In tuya it is likely an integer or a fixed list of values.
  56. # For integer, expect scale and step to do the conversion,
  57. # for fixed values, we need to snap to closest value.
  58. if self._volume_dp.values(self._device) is not None:
  59. volume = min(
  60. self._volume_dp.values(self._device), key=lambda x: abs(x - volume)
  61. )
  62. set_dps = {
  63. **set_dps,
  64. **self._volume_dp.get_values_to_set(self._device, volume),
  65. }
  66. await self._device.async_set_properties(set_dps)