climate.py 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. """
  2. Goldair WiFi Dehumidifier device.
  3. """
  4. from homeassistant.components.climate import ClimateDevice
  5. from homeassistant.components.climate.const import (
  6. ATTR_FAN_MODE,
  7. ATTR_HUMIDITY,
  8. ATTR_HVAC_MODE,
  9. ATTR_PRESET_MODE,
  10. FAN_HIGH,
  11. FAN_LOW,
  12. SUPPORT_FAN_MODE,
  13. SUPPORT_PRESET_MODE,
  14. SUPPORT_TARGET_HUMIDITY,
  15. )
  16. from homeassistant.const import ATTR_TEMPERATURE, STATE_UNAVAILABLE
  17. from ..device import GoldairTuyaDevice
  18. from .const import (
  19. ATTR_AIR_CLEAN_ON,
  20. ATTR_DEFROSTING,
  21. ATTR_ERROR,
  22. ATTR_TARGET_HUMIDITY,
  23. ERROR_CODE_TO_DPS_CODE,
  24. FAN_MODE_TO_DPS_MODE,
  25. HVAC_MODE_TO_DPS_MODE,
  26. PRESET_AIR_CLEAN,
  27. PRESET_DRY_CLOTHES,
  28. PRESET_HIGH,
  29. PRESET_LOW,
  30. PRESET_MODE_TO_DPS_MODE,
  31. PRESET_NORMAL,
  32. PROPERTY_TO_DPS_ID,
  33. )
  34. SUPPORT_FLAGS = SUPPORT_TARGET_HUMIDITY | SUPPORT_PRESET_MODE | SUPPORT_FAN_MODE
  35. class GoldairDehumidifier(ClimateDevice):
  36. """Representation of a Goldair WiFi dehumidifier."""
  37. def __init__(self, device):
  38. """Initialize the dehumidifier.
  39. Args:
  40. name (str): The device's name.
  41. device (GoldairTuyaDevice): The device API instance."""
  42. self._device = device
  43. self._support_flags = SUPPORT_FLAGS
  44. self._HUMIDITY_STEP = 5
  45. self._HUMIDITY_LIMITS = {"min": 30, "max": 80}
  46. @property
  47. def supported_features(self):
  48. """Return the list of supported features."""
  49. return self._support_flags
  50. @property
  51. def should_poll(self):
  52. """Return the polling state."""
  53. return True
  54. @property
  55. def name(self):
  56. """Return the name of the climate device."""
  57. return self._device.name
  58. @property
  59. def unique_id(self):
  60. """Return the unique id for this dehumidifier."""
  61. return self._device.unique_id
  62. @property
  63. def device_info(self):
  64. """Return device information about this dehumidifier."""
  65. return self._device.device_info
  66. @property
  67. def current_humidity(self):
  68. """Return the current reading of the humidity sensor."""
  69. return self._device.get_property(PROPERTY_TO_DPS_ID[ATTR_HUMIDITY])
  70. @property
  71. def min_humidity(self):
  72. """Return the minimum humidity setting."""
  73. return self._HUMIDITY_LIMITS["min"]
  74. @property
  75. def max_humidity(self):
  76. """Return the maximum humidity setting."""
  77. return self._HUMIDITY_LIMITS["max"]
  78. @property
  79. def target_humidity(self):
  80. """Return the current target humidity."""
  81. return self._device.get_property(PROPERTY_TO_DPS_ID[ATTR_TARGET_HUMIDITY])
  82. async def async_set_humidity(self, humidity):
  83. """Set the device's target humidity."""
  84. if self.preset_mode in [PRESET_AIR_CLEAN, PRESET_DRY_CLOTHES]:
  85. raise ValueError(
  86. "Humidity can only be changed while in Normal, Low or High preset modes."
  87. )
  88. humidity = int(
  89. self._HUMIDITY_STEP * round(float(humidity) / self._HUMIDITY_STEP)
  90. )
  91. await self._device.async_set_property(
  92. PROPERTY_TO_DPS_ID[ATTR_TARGET_HUMIDITY], humidity
  93. )
  94. @property
  95. def temperature_unit(self):
  96. """Return the unit of measurement."""
  97. return self._device.temperature_unit
  98. @property
  99. def min_temp(self):
  100. """Return the minimum temperature setting."""
  101. return None
  102. @property
  103. def max_temp(self):
  104. """Return the maximum temperature setting."""
  105. return None
  106. @property
  107. def current_temperature(self):
  108. """Return the current temperature."""
  109. return self._device.get_property(PROPERTY_TO_DPS_ID[ATTR_TEMPERATURE])
  110. @property
  111. def hvac_mode(self):
  112. """Return current HVAC mode, ie Dry or Off."""
  113. dps_mode = self._device.get_property(PROPERTY_TO_DPS_ID[ATTR_HVAC_MODE])
  114. if dps_mode is not None:
  115. return GoldairTuyaDevice.get_key_for_value(HVAC_MODE_TO_DPS_MODE, dps_mode)
  116. else:
  117. return STATE_UNAVAILABLE
  118. @property
  119. def hvac_modes(self):
  120. """Return the list of available HVAC modes."""
  121. return list(HVAC_MODE_TO_DPS_MODE.keys())
  122. async def async_set_hvac_mode(self, hvac_mode):
  123. """Set new HVAC mode."""
  124. dps_mode = HVAC_MODE_TO_DPS_MODE[hvac_mode]
  125. await self._device.async_set_property(
  126. PROPERTY_TO_DPS_ID[ATTR_HVAC_MODE], dps_mode
  127. )
  128. @property
  129. def preset_mode(self):
  130. """Return current preset mode, ie Normal, Low, High, Dry Clothes, or Air Clean."""
  131. air_clean_on = self._device.get_property(PROPERTY_TO_DPS_ID[ATTR_AIR_CLEAN_ON])
  132. dps_mode = self._device.get_property(PROPERTY_TO_DPS_ID[ATTR_PRESET_MODE])
  133. if air_clean_on:
  134. return PRESET_AIR_CLEAN
  135. elif dps_mode is not None:
  136. return GoldairTuyaDevice.get_key_for_value(
  137. PRESET_MODE_TO_DPS_MODE, dps_mode
  138. )
  139. else:
  140. return None
  141. @property
  142. def preset_modes(self):
  143. """Return the list of available preset modes."""
  144. return list(PRESET_MODE_TO_DPS_MODE.keys()) + [PRESET_AIR_CLEAN]
  145. async def async_set_preset_mode(self, preset_mode):
  146. """Set new preset mode."""
  147. if preset_mode == PRESET_AIR_CLEAN:
  148. await self._device.async_set_property(
  149. PROPERTY_TO_DPS_ID[ATTR_AIR_CLEAN_ON], True
  150. )
  151. self._device.anticipate_property_value(
  152. PROPERTY_TO_DPS_ID[ATTR_FAN_MODE], FAN_HIGH
  153. )
  154. else:
  155. dps_mode = PRESET_MODE_TO_DPS_MODE[preset_mode]
  156. await self._device.async_set_property(
  157. PROPERTY_TO_DPS_ID[ATTR_AIR_CLEAN_ON], False
  158. )
  159. await self._device.async_set_property(
  160. PROPERTY_TO_DPS_ID[ATTR_PRESET_MODE], dps_mode
  161. )
  162. if preset_mode == PRESET_LOW:
  163. self._device.anticipate_property_value(
  164. PROPERTY_TO_DPS_ID[ATTR_FAN_MODE], FAN_LOW
  165. )
  166. elif preset_mode in [PRESET_HIGH, PRESET_DRY_CLOTHES]:
  167. self._device.anticipate_property_value(
  168. PROPERTY_TO_DPS_ID[ATTR_FAN_MODE], FAN_HIGH
  169. )
  170. @property
  171. def fan_mode(self):
  172. """Return the fan mode."""
  173. preset = self.preset_mode
  174. if preset in [PRESET_HIGH, PRESET_DRY_CLOTHES, PRESET_AIR_CLEAN]:
  175. return FAN_HIGH
  176. elif preset == PRESET_LOW:
  177. return FAN_LOW
  178. else:
  179. dps_mode = self._device.get_property(PROPERTY_TO_DPS_ID[ATTR_FAN_MODE])
  180. if dps_mode is not None:
  181. return GoldairTuyaDevice.get_key_for_value(
  182. FAN_MODE_TO_DPS_MODE, dps_mode
  183. )
  184. else:
  185. return None
  186. @property
  187. def fan_modes(self):
  188. """List of fan modes."""
  189. preset = self.preset_mode
  190. if preset in [PRESET_HIGH, PRESET_DRY_CLOTHES, PRESET_AIR_CLEAN]:
  191. return [FAN_HIGH]
  192. elif preset == PRESET_LOW:
  193. return [FAN_LOW]
  194. elif preset == PRESET_NORMAL:
  195. return list(FAN_MODE_TO_DPS_MODE.keys())
  196. else:
  197. return []
  198. async def async_set_fan_mode(self, fan_mode):
  199. """Set new fan mode."""
  200. if self.preset_mode != PRESET_NORMAL:
  201. raise ValueError(
  202. "Fan mode can only be changed while in Normal preset mode."
  203. )
  204. if fan_mode not in FAN_MODE_TO_DPS_MODE.keys():
  205. raise ValueError(f"Invalid fan mode: {fan_mode}")
  206. dps_mode = FAN_MODE_TO_DPS_MODE[fan_mode]
  207. await self._device.async_set_property(
  208. PROPERTY_TO_DPS_ID[ATTR_FAN_MODE], dps_mode
  209. )
  210. @property
  211. def device_state_attributes(self):
  212. """Get additional attributes that HA doesn't naturally support."""
  213. error = self._device.get_property(PROPERTY_TO_DPS_ID[ATTR_ERROR])
  214. if error:
  215. error = GoldairTuyaDevice.get_key_for_value(
  216. ERROR_CODE_TO_DPS_CODE, error, error
  217. )
  218. defrosting = self._device.get_property(PROPERTY_TO_DPS_ID[ATTR_DEFROSTING])
  219. return {ATTR_ERROR: error or None, ATTR_DEFROSTING: defrosting}
  220. async def async_update(self):
  221. await self._device.async_refresh()