time.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. """
  2. Setup for Tuya time entities
  3. """
  4. import logging
  5. from datetime import datetime, time, timedelta
  6. from homeassistant.components.time import TimeEntity
  7. from .device import TuyaLocalDevice
  8. from .entity import TuyaLocalEntity
  9. from .helpers.config import async_tuya_setup_platform
  10. from .helpers.device_config import TuyaEntityConfig
  11. _LOGGER = logging.getLogger(__name__)
  12. MODE_AUTO = "auto"
  13. MIDNIGHT = datetime.combine(datetime.today(), time(0, 0, 0))
  14. async def async_setup_entry(hass, config_entry, async_add_entities):
  15. config = {**config_entry.data, **config_entry.options}
  16. await async_tuya_setup_platform(
  17. hass,
  18. async_add_entities,
  19. config,
  20. "time",
  21. TuyaLocalTime,
  22. )
  23. class TuyaLocalTime(TuyaLocalEntity, TimeEntity):
  24. """Representation of a Tuya Time"""
  25. def __init__(self, device: TuyaLocalDevice, config: TuyaEntityConfig):
  26. """
  27. Initialise the time entity.
  28. Args:
  29. device (TuyaLocalDevice): the device API instance
  30. config (TuyaEntityConfig): the configuration for this entity
  31. """
  32. super().__init__()
  33. dps_map = self._init_begin(device, config)
  34. self._hour_dps = dps_map.pop("hour", None)
  35. self._minute_dps = dps_map.pop("minute", None)
  36. self._second_dps = dps_map.pop("second", None)
  37. if (
  38. self._hour_dps is None
  39. and self._minute_dps is None
  40. and self._second_dps is None
  41. ):
  42. raise AttributeError(
  43. f"{config.config_id} is missing an hour, minute or second dp"
  44. )
  45. self._init_end(dps_map)
  46. @property
  47. def native_value(self):
  48. """Return the current value of the time."""
  49. hours = minutes = seconds = None
  50. if self._hour_dps:
  51. hours = self._hour_dps.get_value(self._device)
  52. if self._minute_dps:
  53. minutes = self._minute_dps.get_value(self._device)
  54. if self._second_dps:
  55. seconds = self._second_dps.get_value(self._device)
  56. if hours is None and minutes is None and seconds is None:
  57. return None
  58. hours = hours or 0
  59. minutes = minutes or 0
  60. seconds = seconds or 0
  61. delta = timedelta(hours=hours, minutes=minutes, seconds=seconds)
  62. return (MIDNIGHT + delta).time()
  63. async def async_set_value(self, value: time):
  64. """Set the number."""
  65. settings = {}
  66. hours = value.hour
  67. minutes = value.minute
  68. seconds = value.second
  69. if self._hour_dps:
  70. settings.update(self._hour_dps.get_values_to_set(self._device, hours))
  71. else:
  72. minutes = minutes + hours * 60
  73. if self._minute_dps:
  74. settings.update(self._minute_dps.get_values_to_set(self._device, minutes))
  75. else:
  76. seconds = seconds + minutes * 60
  77. if self._second_dps:
  78. settings.update(self._second_dps.get_values_to_set(self._device, seconds))
  79. else:
  80. _LOGGER.debug(
  81. "%s: Discarding unused precision: %d seconds",
  82. self.name,
  83. seconds,
  84. )
  85. await self._device.async_set_properties(settings)