test_saswell_c16_thermostat.py 9.6 KB

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