valve.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  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 .entity import TuyaLocalEntity
  12. from .helpers.config import async_tuya_setup_platform
  13. from .helpers.device_config import TuyaEntityConfig
  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 or (
  40. self._valve_dp.values(device)
  41. and self._valve_dp.values(device)[0] is int
  42. ):
  43. self._attr_supported_features |= ValveEntityFeature.SET_POSITION
  44. @property
  45. def device_class(self):
  46. """Return the class of this device"""
  47. dclass = self._config.device_class
  48. try:
  49. return ValveDeviceClass(dclass)
  50. except ValueError:
  51. if dclass:
  52. _LOGGER.warning(
  53. "%s/%s: Unrecognised valve device class of %s ignored",
  54. self._config._device.config,
  55. self.name or "valve",
  56. dclass,
  57. )
  58. @property
  59. def reports_position(self):
  60. """If the valve is an integer, it reports position."""
  61. return self._valve_dp.type is int or (
  62. self._valve_dp.values(self._device)
  63. and self._valve_dp.values(self._device)[0] is int
  64. )
  65. @property
  66. def current_position(self):
  67. """Report the position of the valve."""
  68. pos = self._valve_dp.get_value(self._device)
  69. if isinstance(pos, int):
  70. return pos
  71. @property
  72. def is_closed(self):
  73. """Report whether the valve is closed."""
  74. pos = self._valve_dp.get_value(self._device)
  75. return not pos
  76. async def async_open_valve(self):
  77. """Open the valve."""
  78. await self._valve_dp.async_set_value(
  79. self._device,
  80. 100 if self.reports_position else True,
  81. )
  82. async def async_close_valve(self):
  83. """Close the valve"""
  84. await self._valve_dp.async_set_value(
  85. self._device,
  86. 0 if self.reports_position else False,
  87. )
  88. async def async_set_valve_position(self, position):
  89. """Set the position of the valve"""
  90. if not self.reports_position:
  91. raise NotImplementedError()
  92. await self._valve_dp.async_set_value(self._device, position)