test_kyvol_e30_vacuum.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. from homeassistant.components.button import ButtonDeviceClass
  2. from homeassistant.components.sensor import SensorDeviceClass
  3. from homeassistant.components.vacuum import (
  4. STATE_CLEANING,
  5. STATE_DOCKED,
  6. STATE_ERROR,
  7. STATE_IDLE,
  8. STATE_RETURNING,
  9. VacuumEntityFeature,
  10. )
  11. from homeassistant.const import (
  12. AREA_SQUARE_METERS,
  13. UnitOfTime,
  14. PERCENTAGE,
  15. )
  16. from ..const import KYVOL_E30_VACUUM_PAYLOAD
  17. from ..helpers import assert_device_properties_set
  18. from ..mixins.button import MultiButtonTests
  19. from ..mixins.sensor import MultiSensorTests
  20. from .base_device_tests import TuyaDeviceTestCase
  21. POWER_DPS = "1"
  22. SWITCH_DPS = "2"
  23. COMMAND_DPS = "3"
  24. DIRECTION_DPS = "4"
  25. STATUS_DPS = "5"
  26. BATTERY_DPS = "6"
  27. EDGE_DPS = "7"
  28. ROLL_DPS = "8"
  29. FILTER_DPS = "9"
  30. RSTEDGE_DPS = "10"
  31. RSTROLL_DPS = "11"
  32. RSTFILTER_DPS = "12"
  33. LOCATE_DPS = "13"
  34. FAN_DPS = "14"
  35. AREA_DPS = "16"
  36. TIME_DPS = "17"
  37. ERROR_DPS = "18"
  38. WATER_DPS = "101"
  39. MODEL_DPS = "102"
  40. MODE_DPS = "104"
  41. CARPET_DPS = "107"
  42. class TestKyvolE30Vacuum(MultiButtonTests, MultiSensorTests, TuyaDeviceTestCase):
  43. __test__ = True
  44. def setUp(self):
  45. self.setUpForConfig("kyvol_e30_vacuum.yaml", KYVOL_E30_VACUUM_PAYLOAD)
  46. self.subject = self.entities.get("vacuum")
  47. self.setUpMultiButtons(
  48. [
  49. {
  50. "dps": RSTEDGE_DPS,
  51. "name": "button_edge_brush_reset",
  52. "device_class": ButtonDeviceClass.RESTART,
  53. },
  54. {
  55. "dps": RSTROLL_DPS,
  56. "name": "button_roll_brush_reset",
  57. "device_class": ButtonDeviceClass.RESTART,
  58. },
  59. {
  60. "dps": RSTFILTER_DPS,
  61. "name": "button_filter_reset",
  62. "device_class": ButtonDeviceClass.RESTART,
  63. },
  64. ]
  65. )
  66. self.setUpMultiSensors(
  67. [
  68. {
  69. "dps": AREA_DPS,
  70. "name": "sensor_clean_area",
  71. "unit": AREA_SQUARE_METERS,
  72. "testdata": (30, 3.0),
  73. },
  74. {
  75. "dps": TIME_DPS,
  76. "name": "sensor_clean_time",
  77. "unit": UnitOfTime.MINUTES,
  78. "device_class": SensorDeviceClass.DURATION,
  79. },
  80. {
  81. "dps": EDGE_DPS,
  82. "name": "sensor_edge_brush",
  83. "unit": PERCENTAGE,
  84. },
  85. {
  86. "dps": ROLL_DPS,
  87. "name": "sensor_roll_brush",
  88. "unit": PERCENTAGE,
  89. },
  90. {
  91. "dps": FILTER_DPS,
  92. "name": "sensor_filter",
  93. "unit": PERCENTAGE,
  94. },
  95. {
  96. "dps": STATUS_DPS,
  97. "name": "sensor_status",
  98. },
  99. ],
  100. )
  101. self.mark_secondary(
  102. [
  103. "button_edge_brush_reset",
  104. "button_roll_brush_reset",
  105. "button_filter_reset",
  106. "sensor_clean_area",
  107. "sensor_clean_time",
  108. "sensor_edge_brush",
  109. "sensor_roll_brush",
  110. "sensor_filter",
  111. "sensor_status",
  112. ]
  113. )
  114. def test_supported_features(self):
  115. self.assertEqual(
  116. self.subject.supported_features,
  117. (
  118. VacuumEntityFeature.STATE
  119. | VacuumEntityFeature.STATUS
  120. | VacuumEntityFeature.SEND_COMMAND
  121. | VacuumEntityFeature.BATTERY
  122. | VacuumEntityFeature.FAN_SPEED
  123. | VacuumEntityFeature.TURN_ON
  124. | VacuumEntityFeature.TURN_OFF
  125. | VacuumEntityFeature.START
  126. | VacuumEntityFeature.PAUSE
  127. | VacuumEntityFeature.LOCATE
  128. | VacuumEntityFeature.RETURN_HOME
  129. | VacuumEntityFeature.CLEAN_SPOT
  130. ),
  131. )
  132. def test_battery_level(self):
  133. self.dps[BATTERY_DPS] = 50
  134. self.assertEqual(self.subject.battery_level, 50)
  135. def test_status(self):
  136. self.dps[COMMAND_DPS] = "standby"
  137. self.assertEqual(self.subject.status, "standby")
  138. self.dps[COMMAND_DPS] = "smart"
  139. self.assertEqual(self.subject.status, "smart")
  140. self.dps[COMMAND_DPS] = "chargego"
  141. self.assertEqual(self.subject.status, "return_to_base")
  142. self.dps[COMMAND_DPS] = "random"
  143. self.assertEqual(self.subject.status, "random")
  144. self.dps[COMMAND_DPS] = "wall_follow"
  145. self.assertEqual(self.subject.status, "wall_follow")
  146. self.dps[COMMAND_DPS] = "spiral"
  147. self.assertEqual(self.subject.status, "clean_spot")
  148. def test_state(self):
  149. self.dps[POWER_DPS] = True
  150. self.dps[SWITCH_DPS] = True
  151. self.dps[ERROR_DPS] = 0
  152. self.dps[COMMAND_DPS] = "return_to_base"
  153. self.assertEqual(self.subject.state, STATE_RETURNING)
  154. self.dps[COMMAND_DPS] = "standby"
  155. self.assertEqual(self.subject.state, STATE_IDLE)
  156. self.dps[COMMAND_DPS] = "random"
  157. self.assertEqual(self.subject.state, STATE_CLEANING)
  158. self.dps[POWER_DPS] = False
  159. self.assertEqual(self.subject.state, STATE_DOCKED)
  160. self.dps[POWER_DPS] = True
  161. self.dps[SWITCH_DPS] = False
  162. self.assertEqual(self.subject.state, STATE_DOCKED)
  163. self.dps[ERROR_DPS] = 1
  164. self.assertEqual(self.subject.state, STATE_ERROR)
  165. async def test_async_turn_on(self):
  166. async with assert_device_properties_set(
  167. self.subject._device,
  168. {POWER_DPS: True},
  169. ):
  170. await self.subject.async_turn_on()
  171. async def test_async_turn_off(self):
  172. async with assert_device_properties_set(
  173. self.subject._device,
  174. {POWER_DPS: False},
  175. ):
  176. await self.subject.async_turn_off()
  177. async def test_async_toggle(self):
  178. self.dps[POWER_DPS] = False
  179. async with assert_device_properties_set(
  180. self.subject._device,
  181. {POWER_DPS: True},
  182. ):
  183. await self.subject.async_toggle()
  184. async def test_async_start(self):
  185. async with assert_device_properties_set(
  186. self.subject._device,
  187. {SWITCH_DPS: True},
  188. ):
  189. await self.subject.async_start()
  190. async def test_async_pause(self):
  191. async with assert_device_properties_set(
  192. self.subject._device,
  193. {SWITCH_DPS: False},
  194. ):
  195. await self.subject.async_pause()
  196. async def test_async_return_to_base(self):
  197. async with assert_device_properties_set(
  198. self.subject._device,
  199. {COMMAND_DPS: "chargego"},
  200. ):
  201. await self.subject.async_return_to_base()
  202. async def test_async_clean_spot(self):
  203. async with assert_device_properties_set(
  204. self.subject._device,
  205. {COMMAND_DPS: "spiral"},
  206. ):
  207. await self.subject.async_clean_spot()
  208. async def test_async_locate(self):
  209. async with assert_device_properties_set(
  210. self.subject._device,
  211. {LOCATE_DPS: True},
  212. ):
  213. await self.subject.async_locate()
  214. async def test_async_send_standby_command(self):
  215. async with assert_device_properties_set(
  216. self.subject._device,
  217. {COMMAND_DPS: "standby"},
  218. ):
  219. await self.subject.async_send_command("standby")
  220. async def test_async_send_smart_command(self):
  221. async with assert_device_properties_set(
  222. self.subject._device,
  223. {COMMAND_DPS: "smart"},
  224. ):
  225. await self.subject.async_send_command("smart")
  226. async def test_async_send_random_command(self):
  227. async with assert_device_properties_set(
  228. self.subject._device,
  229. {COMMAND_DPS: "random"},
  230. ):
  231. await self.subject.async_send_command("random")
  232. async def test_async_send_wall_follow_command(self):
  233. async with assert_device_properties_set(
  234. self.subject._device,
  235. {COMMAND_DPS: "wall_follow"},
  236. ):
  237. await self.subject.async_send_command("wall_follow")
  238. async def test_async_send_reverse_command(self):
  239. async with assert_device_properties_set(
  240. self.subject._device,
  241. {DIRECTION_DPS: "backward"},
  242. ):
  243. await self.subject.async_send_command("reverse")
  244. async def test_async_send_left_command(self):
  245. async with assert_device_properties_set(
  246. self.subject._device,
  247. {DIRECTION_DPS: "turn_left"},
  248. ):
  249. await self.subject.async_send_command("left")
  250. async def test_async_send_right_command(self):
  251. async with assert_device_properties_set(
  252. self.subject._device,
  253. {DIRECTION_DPS: "turn_right"},
  254. ):
  255. await self.subject.async_send_command("right")
  256. async def test_async_send_stop_command(self):
  257. async with assert_device_properties_set(
  258. self.subject._device,
  259. {DIRECTION_DPS: "stop"},
  260. ):
  261. await self.subject.async_send_command("stop")
  262. def test_fan_speed(self):
  263. self.dps[FAN_DPS] = "2"
  264. self.assertEqual(self.subject.fan_speed, "quiet")
  265. def test_fan_speed_list(self):
  266. self.assertCountEqual(
  267. self.subject.fan_speed_list,
  268. [
  269. "strong",
  270. "normal",
  271. "quiet",
  272. "gentle",
  273. "closed",
  274. ],
  275. )
  276. async def test_async_set_fan_speed(self):
  277. async with assert_device_properties_set(self.subject._device, {FAN_DPS: "3"}):
  278. await self.subject.async_set_fan_speed(fan_speed="gentle")