valve.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. """
  2. Support for Tuya valve devices
  3. """
  4. import logging
  5. from homeassistant.components.valve import (
  6. ValveDeviceClass,
  7. ValveEntity,
  8. ValveEntityFeature,
  9. )
  10. from .device import TuyaLocalDevice
  11. from .helpers.config import async_tuya_setup_platform
  12. from .helpers.device_config import TuyaEntityConfig
  13. from .helpers.mixin import TuyaLocalEntity
  14. _LOGGER = logging.getLogger(__name__)
  15. async def async_setup_entry(hass, config_entry, async_add_entities):
  16. config = {**config_entry.data, **config_entry.options}
  17. await async_tuya_setup_platform(
  18. hass,
  19. async_add_entities,
  20. config,
  21. "valve",
  22. TuyaLocalValve,
  23. )
  24. class TuyaLocalValve(TuyaLocalEntity, ValveEntity):
  25. """Representation of a Tuya Valve"""
  26. def __init__(self, device: TuyaLocalDevice, config: TuyaEntityConfig):
  27. """
  28. Initialise the valve.
  29. Args:
  30. device (TuyaLocalDevice): The device API instance.
  31. """
  32. super().__init__()
  33. dps_map = self._init_begin(device, config)
  34. self._valve_dp = dps_map.pop("valve")
  35. self._init_end(dps_map)
  36. if not self._valve_dp.readonly:
  37. self._attr_supported_features |= ValveEntityFeature.OPEN
  38. self._attr_supported_features |= ValveEntityFeature.CLOSE
  39. if self._valve_dp.type is int:
  40. self._attr_supported_features |= ValveEntityFeature.SET_POSITION
  41. @property
  42. def device_class(self):
  43. """Return the class of this device"""
  44. dclass = self._config.device_class
  45. try:
  46. return ValveDeviceClass(dclass)
  47. except ValueError:
  48. if dclass:
  49. _LOGGER.warning(
  50. "%s/%s: Unrecognised valve device class of %s ignored",
  51. self._config._device.config,
  52. self.name or "valve",
  53. dclass,
  54. )
  55. @property
  56. def reports_position(self):
  57. """If the valve is an integer, it reports position."""
  58. return self._valve_dp.type is int
  59. @property
  60. def current_position(self):
  61. """Report the position of the valve."""
  62. pos = self._valve_dp.get_value(self._device)
  63. if isinstance(pos, int):
  64. return pos
  65. @property
  66. def is_closed(self):
  67. """Report whether the valve is closed."""
  68. pos = self._valve_dp.get_value(self._device)
  69. return not pos
  70. async def async_open_valve(self):
  71. """Open the valve."""
  72. await self._valve_dp.async_set_value(
  73. self._device,
  74. 100 if self.reports_position else True,
  75. )
  76. async def async_close_valve(self):
  77. """Close the valve"""
  78. await self._valve_dp.async_set_value(
  79. self._device,
  80. 0 if self.reports_position else False,
  81. )
  82. async def async_set_valve_position(self, position):
  83. """Set the position of the valve"""
  84. if not self.reports_position:
  85. raise NotImplementedError()
  86. await self._valve_dp.async_set_value(self._device, position)