time.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  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. self._hms_dps = dps_map.pop("hms", None)
  38. if (
  39. self._hour_dps is None
  40. and self._minute_dps is None
  41. and self._second_dps is None
  42. and self._hms_dps is None
  43. ):
  44. raise AttributeError(
  45. f"{config.config_id} is missing an hour, minute or second dp"
  46. )
  47. self._init_end(dps_map)
  48. @property
  49. def native_value(self):
  50. """Return the current value of the time."""
  51. hours = minutes = seconds = None
  52. if self._hour_dps:
  53. hours = self._hour_dps.get_value(self._device)
  54. if self._minute_dps:
  55. minutes = self._minute_dps.get_value(self._device)
  56. if self._second_dps:
  57. seconds = self._second_dps.get_value(self._device)
  58. if self._hms_dps:
  59. hms = self._hms_dps.get_value(self._device)
  60. if hms is not None and isinstance(hms, str):
  61. parts = hms.split(":")
  62. if len(parts) == 3:
  63. hours = int(parts[0])
  64. minutes = int(parts[1])
  65. seconds = int(parts[2])
  66. elif len(parts) == 2:
  67. hours = int(parts[0])
  68. minutes = int(parts[1])
  69. seconds = 0
  70. elif len(parts) == 1:
  71. if len(hms) <= 2:
  72. hours = hms
  73. elif len(hms) <= 4:
  74. hours = hms[0 : len(hms) - 2]
  75. minutes = hms[len(hms) - 2 :]
  76. else:
  77. hours = hms.substring(0, len(hms) - 4)
  78. minutes = hms.substring(len(hms) - 4, len(hms) - 2)
  79. seconds = hms.substring(len(hms) - 2)
  80. if hours is None and minutes is None and seconds is None:
  81. return None
  82. hours = hours or 0
  83. minutes = minutes or 0
  84. seconds = seconds or 0
  85. delta = timedelta(hours=int(hours), minutes=int(minutes), seconds=int(seconds))
  86. return (MIDNIGHT + delta).time()
  87. async def async_set_value(self, value: time):
  88. """Set the number."""
  89. settings = {}
  90. hours = value.hour
  91. minutes = value.minute
  92. seconds = value.second
  93. if self._hour_dps:
  94. settings.update(
  95. self._hour_dps.get_values_to_set(self._device, hours, settings)
  96. )
  97. else:
  98. minutes = minutes + hours * 60
  99. if self._minute_dps:
  100. settings.update(
  101. self._minute_dps.get_values_to_set(self._device, minutes, settings)
  102. )
  103. else:
  104. seconds = seconds + minutes * 60
  105. if self._second_dps:
  106. settings.update(
  107. self._second_dps.get_values_to_set(self._device, seconds, settings)
  108. )
  109. else:
  110. _LOGGER.debug(
  111. "%s: Discarding unused precision: %d seconds",
  112. self.name,
  113. seconds,
  114. )
  115. await self._device.async_set_properties(settings)