climate.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. """
  2. Goldair GPCV WiFi Heater device.
  3. """
  4. try:
  5. from homeassistant.components.climate import ClimateEntity
  6. except ImportError:
  7. from homeassistant.components.climate import ClimateDevice as ClimateEntity
  8. from homeassistant.components.climate.const import (
  9. ATTR_HVAC_MODE,
  10. ATTR_PRESET_MODE,
  11. HVAC_MODE_HEAT,
  12. SUPPORT_PRESET_MODE,
  13. SUPPORT_TARGET_TEMPERATURE,
  14. )
  15. from homeassistant.const import ATTR_TEMPERATURE, STATE_UNAVAILABLE
  16. from ..device import TuyaLocalDevice
  17. from .const import (
  18. ATTR_ERROR,
  19. ATTR_TARGET_TEMPERATURE,
  20. HVAC_MODE_TO_DPS_MODE,
  21. PRESET_MODE_TO_DPS_MODE,
  22. PROPERTY_TO_DPS_ID,
  23. )
  24. SUPPORT_FLAGS = SUPPORT_TARGET_TEMPERATURE | SUPPORT_PRESET_MODE
  25. class GoldairGPCVHeater(ClimateEntity):
  26. """Representation of a Goldair GPCV WiFi heater."""
  27. def __init__(self, device):
  28. """Initialize the heater.
  29. Args:
  30. device (TuyaLocalDevice): The device API instance."""
  31. self._device = device
  32. self._support_flags = SUPPORT_FLAGS
  33. self._TEMPERATURE_STEP = 1
  34. self._TEMPERATURE_LIMITS = {"min": 15, "max": 35}
  35. @property
  36. def supported_features(self):
  37. """Return the list of supported features."""
  38. return self._support_flags
  39. @property
  40. def should_poll(self):
  41. """Return the polling state."""
  42. return True
  43. @property
  44. def name(self):
  45. """Return the name of the climate device."""
  46. return self._device.name
  47. @property
  48. def unique_id(self):
  49. """Return the unique id for this heater."""
  50. return self._device.unique_id
  51. @property
  52. def device_info(self):
  53. """Return device information about this heater."""
  54. return self._device.device_info
  55. @property
  56. def icon(self):
  57. """Return the icon to use in the frontend for this device."""
  58. hvac_mode = self.hvac_mode
  59. if hvac_mode == HVAC_MODE_HEAT:
  60. return "mdi:radiator"
  61. else:
  62. return "mdi:radiator-disabled"
  63. @property
  64. def temperature_unit(self):
  65. """Return the unit of measurement."""
  66. return self._device.temperature_unit
  67. @property
  68. def target_temperature(self):
  69. """Return the temperature we try to reach."""
  70. return self._device.get_property(PROPERTY_TO_DPS_ID[ATTR_TARGET_TEMPERATURE])
  71. @property
  72. def target_temperature_step(self):
  73. """Return the supported step of target temperature."""
  74. return self._TEMPERATURE_STEP
  75. @property
  76. def min_temp(self):
  77. """Return the minimum temperature."""
  78. return self._TEMPERATURE_LIMITS["min"]
  79. @property
  80. def max_temp(self):
  81. """Return the maximum temperature."""
  82. return self._TEMPERATURE_LIMITS["max"]
  83. async def async_set_temperature(self, **kwargs):
  84. """Set new target temperatures."""
  85. if kwargs.get(ATTR_PRESET_MODE) is not None:
  86. await self.async_set_preset_mode(kwargs.get(ATTR_PRESET_MODE))
  87. if kwargs.get(ATTR_TEMPERATURE) is not None:
  88. await self.async_set_target_temperature(kwargs.get(ATTR_TEMPERATURE))
  89. async def async_set_target_temperature(self, target_temperature):
  90. target_temperature = int(round(target_temperature))
  91. limits = self._TEMPERATURE_LIMITS
  92. if not limits["min"] <= target_temperature <= limits["max"]:
  93. raise ValueError(
  94. f"Target temperature ({target_temperature}) must be between "
  95. f'{limits["min"]} and {limits["max"]}'
  96. )
  97. await self._device.async_set_property(
  98. PROPERTY_TO_DPS_ID[ATTR_TARGET_TEMPERATURE], target_temperature
  99. )
  100. @property
  101. def current_temperature(self):
  102. """Return the current temperature."""
  103. return self._device.get_property(PROPERTY_TO_DPS_ID[ATTR_TEMPERATURE])
  104. @property
  105. def hvac_mode(self):
  106. """Return current HVAC mode, ie Heat or Off."""
  107. dps_mode = self._device.get_property(PROPERTY_TO_DPS_ID[ATTR_HVAC_MODE])
  108. if dps_mode is not None:
  109. return TuyaLocalDevice.get_key_for_value(HVAC_MODE_TO_DPS_MODE, dps_mode)
  110. else:
  111. return STATE_UNAVAILABLE
  112. @property
  113. def hvac_modes(self):
  114. """Return the list of available HVAC modes."""
  115. return list(HVAC_MODE_TO_DPS_MODE.keys())
  116. async def async_set_hvac_mode(self, hvac_mode):
  117. """Set new HVAC mode."""
  118. dps_mode = HVAC_MODE_TO_DPS_MODE[hvac_mode]
  119. await self._device.async_set_property(
  120. PROPERTY_TO_DPS_ID[ATTR_HVAC_MODE], dps_mode
  121. )
  122. @property
  123. def preset_mode(self):
  124. """Return current preset mode, ie Comfort, Eco, Anti-freeze."""
  125. dps_mode = self._device.get_property(PROPERTY_TO_DPS_ID[ATTR_PRESET_MODE])
  126. if dps_mode is not None:
  127. return TuyaLocalDevice.get_key_for_value(PRESET_MODE_TO_DPS_MODE, dps_mode)
  128. else:
  129. return None
  130. @property
  131. def preset_modes(self):
  132. """Return the list of available preset modes."""
  133. return list(PRESET_MODE_TO_DPS_MODE.keys())
  134. async def async_set_preset_mode(self, preset_mode):
  135. """Set new preset mode."""
  136. dps_mode = PRESET_MODE_TO_DPS_MODE[preset_mode]
  137. await self._device.async_set_property(
  138. PROPERTY_TO_DPS_ID[ATTR_PRESET_MODE], dps_mode
  139. )
  140. @property
  141. def device_state_attributes(self):
  142. """Get additional attributes that HA doesn't naturally support."""
  143. error = self._device.get_property(PROPERTY_TO_DPS_ID[ATTR_ERROR])
  144. return {ATTR_ERROR: error or None}
  145. async def async_update(self):
  146. await self._device.async_refresh()