test_saswell_c16_thermostat.py 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. from homeassistant.components.climate.const import (
  2. ClimateEntityFeature,
  3. HVACAction,
  4. HVACMode,
  5. PRESET_AWAY,
  6. PRESET_HOME,
  7. )
  8. from homeassistant.components.sensor import SensorDeviceClass
  9. from homeassistant.const import UnitOfPower, UnitOfTemperature
  10. from ..const import SASWELL_C16_THERMOSTAT_PAYLOAD
  11. from ..helpers import assert_device_properties_set
  12. from ..mixins.climate import TargetTemperatureTests
  13. from ..mixins.lock import BasicLockTests
  14. from ..mixins.number import MultiNumberTests
  15. from ..mixins.select import MultiSelectTests
  16. from ..mixins.sensor import BasicSensorTests
  17. from ..mixins.switch import BasicSwitchTests
  18. from .base_device_tests import TuyaDeviceTestCase
  19. TEMPERATURE_DPS = "2"
  20. PRESET_DPS = "3"
  21. UNKNOWN4_DPS = "4"
  22. CURRENTTEMP_DPS = "5"
  23. FLOORTEMPLIMIT_DPS = "6"
  24. INSTALL_DPS = "7"
  25. FLOORTEMP_DPS = "8"
  26. HVACMODE_DPS = "9"
  27. ADAPTIVE_DPS = "10"
  28. LOCK_DPS = "11"
  29. SCHED_DPS = "12"
  30. SENSOR_DPS = "14"
  31. ROOMCALIB_DPS = "15"
  32. FLOORCALIB_DPS = "17"
  33. UNKNOWN21_DPS = "21"
  34. POWERRATING_DPS = "22"
  35. UNKNOWN23_DPS = "23"
  36. HVACACTION_DPS = "24"
  37. UNKNOWN26_DPS = "26"
  38. class TestSaswellC16Thermostat(
  39. BasicLockTests,
  40. BasicSensorTests,
  41. BasicSwitchTests,
  42. MultiNumberTests,
  43. MultiSelectTests,
  44. TargetTemperatureTests,
  45. TuyaDeviceTestCase,
  46. ):
  47. __test__ = True
  48. def setUp(self):
  49. self.setUpForConfig(
  50. "saswell_c16_thermostat.yaml", SASWELL_C16_THERMOSTAT_PAYLOAD
  51. )
  52. self.subject = self.entities.get("climate")
  53. self.setUpTargetTemperature(
  54. TEMPERATURE_DPS,
  55. self.subject,
  56. min=5.0,
  57. max=40.0,
  58. scale=10,
  59. step=5,
  60. )
  61. self.setUpBasicLock(LOCK_DPS, self.entities.get("lock_child_lock"))
  62. self.setUpBasicSensor(
  63. FLOORTEMP_DPS,
  64. self.entities.get("sensor_floor_temperature"),
  65. device_class=SensorDeviceClass.TEMPERATURE,
  66. state_class="measurement",
  67. unit=UnitOfTemperature.CELSIUS,
  68. testdata=(218, 21.8),
  69. )
  70. self.setUpBasicSwitch(ADAPTIVE_DPS, self.entities.get("switch_adaptive"))
  71. self.setUpMultiNumber(
  72. [
  73. {
  74. "name": "number_floor_temperature_limit",
  75. "dps": FLOORTEMPLIMIT_DPS,
  76. "min": 20.0,
  77. "max": 50.0,
  78. "scale": 10,
  79. "step": 0.5,
  80. "unit": UnitOfTemperature.CELSIUS,
  81. },
  82. {
  83. "name": "number_power_rating",
  84. "dps": POWERRATING_DPS,
  85. "max": 3500,
  86. "unit": UnitOfPower.WATT,
  87. },
  88. {
  89. "name": "number_room_temperature_calibration",
  90. "dps": ROOMCALIB_DPS,
  91. "min": -5.0,
  92. "max": 5.0,
  93. "scale": 10,
  94. "step": 0.5,
  95. "unit": UnitOfTemperature.CELSIUS,
  96. },
  97. {
  98. "name": "number_floor_temperature_calibration",
  99. "dps": FLOORCALIB_DPS,
  100. "min": -5.0,
  101. "max": 5.0,
  102. "scale": 10,
  103. "step": 0.5,
  104. "unit": UnitOfTemperature.CELSIUS,
  105. },
  106. ]
  107. )
  108. self.setUpMultiSelect(
  109. [
  110. {
  111. "name": "select_installation",
  112. "dps": INSTALL_DPS,
  113. "options": {
  114. True: "Office",
  115. False: "Home",
  116. },
  117. },
  118. {
  119. "name": "select_schedule",
  120. "dps": SCHED_DPS,
  121. "options": {
  122. "5_1_1": "Weekdays+Sat+Sun",
  123. "7": "Daily",
  124. },
  125. },
  126. {
  127. "name": "select_sensor_select",
  128. "dps": SENSOR_DPS,
  129. "options": {
  130. "0": "Floor sensor",
  131. "1": "Room sensor",
  132. "2": "Room sensor with floor sensor limit",
  133. "3": "External room sensor",
  134. "4": "External room sensor with floor sensor limit",
  135. },
  136. },
  137. ]
  138. )
  139. self.mark_secondary(
  140. [
  141. "lock_child_lock",
  142. "sensor_floor_temperature",
  143. "switch_adaptive",
  144. "number_floor_temperature_calibration",
  145. "number_floor_temperature_limit",
  146. "number_power_rating",
  147. "number_room_temperature_calibration",
  148. "select_installation",
  149. "select_schedule",
  150. "select_sensor_select",
  151. ]
  152. )
  153. def test_supported_features(self):
  154. self.assertEqual(
  155. self.subject.supported_features,
  156. (
  157. ClimateEntityFeature.TARGET_TEMPERATURE
  158. | ClimateEntityFeature.PRESET_MODE
  159. ),
  160. )
  161. def test_icon(self):
  162. self.dps[PRESET_DPS] = "Smart"
  163. self.assertEqual(self.subject.icon, "mdi:home-thermometer")
  164. self.dps[PRESET_DPS] = "Manual"
  165. self.assertEqual(self.subject.icon, "mdi:cursor-pointer")
  166. self.dps[PRESET_DPS] = "Anti_frozen"
  167. self.assertEqual(self.subject.icon, "mdi:snowflake-melt")
  168. self.dps[LOCK_DPS] = True
  169. self.assertEqual(self.basicLock.icon, "mdi:hand-back-right-off")
  170. self.dps[LOCK_DPS] = False
  171. self.assertEqual(self.basicLock.icon, "mdi:hand-back-right")
  172. def test_temperature_unit(self):
  173. self.assertEqual(
  174. self.subject.temperature_unit,
  175. self.subject._device.temperature_unit,
  176. )
  177. def test_current_temperature(self):
  178. self.dps[CURRENTTEMP_DPS] = 250
  179. self.assertEqual(self.subject.current_temperature, 25.0)
  180. def test_hvac_mode(self):
  181. self.dps[HVACMODE_DPS] = True
  182. self.assertEqual(self.subject.hvac_mode, HVACMode.COOL)
  183. self.dps[HVACMODE_DPS] = False
  184. self.assertEqual(self.subject.hvac_mode, HVACMode.HEAT)
  185. def test_hvac_modes(self):
  186. self.assertCountEqual(
  187. self.subject.hvac_modes,
  188. [HVACMode.COOL, HVACMode.HEAT],
  189. )
  190. async def test_set_hvac_mode_cool(self):
  191. with self.assertRaises(TypeError):
  192. await self.subject.async_set_hvac_mode(HVACMode.COOL)
  193. async def test_set_hvac_mode_heat(self):
  194. with self.assertRaises(TypeError):
  195. await self.subject.async_set_hvac_mode(HVACMode.HEAT)
  196. def test_hvac_action(self):
  197. self.dps[HVACACTION_DPS] = "Cooling"
  198. self.assertEqual(self.subject.hvac_action, HVACAction.COOLING)
  199. self.dps[HVACACTION_DPS] = "Heating"
  200. self.assertEqual(self.subject.hvac_action, HVACAction.HEATING)
  201. self.dps[HVACACTION_DPS] = "Standby"
  202. self.assertEqual(self.subject.hvac_action, HVACAction.IDLE)
  203. def test_preset_mode(self):
  204. self.dps[PRESET_DPS] = "Smart"
  205. self.assertEqual(self.subject.preset_mode, PRESET_HOME)
  206. self.dps[PRESET_DPS] = "Manual"
  207. self.assertEqual(self.subject.preset_mode, "manual")
  208. self.dps[PRESET_DPS] = "Anti_frozen"
  209. self.assertEqual(self.subject.preset_mode, PRESET_AWAY)
  210. def test_preset_modes(self):
  211. self.assertCountEqual(
  212. self.subject.preset_modes,
  213. [PRESET_HOME, PRESET_AWAY, "manual"],
  214. )
  215. async def test_set_preset_to_away(self):
  216. async with assert_device_properties_set(
  217. self.subject._device,
  218. {PRESET_DPS: "Anti_frozen"},
  219. ):
  220. await self.subject.async_set_preset_mode(PRESET_AWAY)
  221. async def test_set_preset_to_home(self):
  222. async with assert_device_properties_set(
  223. self.subject._device,
  224. {PRESET_DPS: "Smart"},
  225. ):
  226. await self.subject.async_set_preset_mode(PRESET_HOME)
  227. async def test_set_preset_to_manual(self):
  228. async with assert_device_properties_set(
  229. self.subject._device,
  230. {PRESET_DPS: "Manual"},
  231. ):
  232. await self.subject.async_set_preset_mode("manual")
  233. def test_extra_state_attributes(self):
  234. self.dps[UNKNOWN4_DPS] = 4
  235. self.dps[FLOORTEMPLIMIT_DPS] = 355
  236. self.dps[INSTALL_DPS] = True
  237. self.dps[FLOORTEMP_DPS] = 251
  238. self.dps[ADAPTIVE_DPS] = False
  239. self.dps[SCHED_DPS] = "5_1_1"
  240. self.dps[UNKNOWN21_DPS] = True
  241. self.dps[POWERRATING_DPS] = 2000
  242. self.dps[UNKNOWN23_DPS] = 23
  243. self.dps[UNKNOWN26_DPS] = 26
  244. self.assertDictEqual(
  245. self.subject.extra_state_attributes,
  246. {
  247. "unknown_4": 4,
  248. "floor_temp_limit": 35.5,
  249. "installation": "Office",
  250. "floor_temperature": 25.1,
  251. "adaptive": False,
  252. "schedule": "5_1_1",
  253. "unknown_21": True,
  254. "power_rating": 2000,
  255. "unknown_23": 23,
  256. "unknown_26": 26,
  257. },
  258. )