test_vacuum.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. from unittest.mock import AsyncMock
  2. import pytest
  3. from bleak.backends.device import BLEDevice
  4. from switchbot import SwitchBotAdvertisement
  5. from switchbot.adv_parser import SUPPORTED_TYPES
  6. from switchbot.devices import vacuum
  7. from .test_adv_parser import generate_ble_device
  8. common_params = [
  9. (b".\x00d", ".", 2),
  10. (b"z\x00\x00", ".", 2),
  11. (b"3\x00\x00", ".", 2),
  12. (b"(\x00", "(", 1),
  13. (b"}\x00", "(", 1),
  14. (b"\x00\x00M\x00\x10\xfb\xa8", b"\x00\x10\xfb\xa8", 2),
  15. (b"\x00\x00d\x00\x10\xe0P", b"\x00\x10\xe0P", 2),
  16. ]
  17. def create_device_for_command_testing(
  18. protocol_version: int, rawAdvData: bytes, model: str
  19. ):
  20. ble_device = generate_ble_device("aa:bb:cc:dd:ee:ff", "any")
  21. device = vacuum.SwitchbotVacuum(ble_device)
  22. device.update_from_advertisement(
  23. make_advertisement_data(ble_device, protocol_version, rawAdvData, model)
  24. )
  25. device._send_command = AsyncMock()
  26. device.update = AsyncMock()
  27. return device
  28. def make_advertisement_data(
  29. ble_device: BLEDevice, protocol_version: int, rawAdvData: bytes, model: str
  30. ):
  31. """Set advertisement data with defaults."""
  32. if protocol_version == 1:
  33. return SwitchBotAdvertisement(
  34. address="aa:bb:cc:dd:ee:ff",
  35. data={
  36. "rawAdvData": rawAdvData,
  37. "data": {
  38. "sequence_number": 2,
  39. "dusbin_connected": False,
  40. "dustbin_bound": False,
  41. "network_connected": True,
  42. "battery": 100,
  43. "work_status": 0,
  44. },
  45. "isEncrypted": False,
  46. "model": model,
  47. "modelFriendlyName": SUPPORTED_TYPES[model]["modelFriendlyName"],
  48. "modelName": SUPPORTED_TYPES[model]["modelName"],
  49. },
  50. device=ble_device,
  51. rssi=-97,
  52. active=True,
  53. )
  54. return SwitchBotAdvertisement(
  55. address="aa:bb:cc:dd:ee:ff",
  56. data={
  57. "rawAdvData": rawAdvData,
  58. "data": {
  59. "soc_version": "1.1.083",
  60. "step": 0,
  61. "mqtt_connected": True,
  62. "battery": 100,
  63. "work_status": 15,
  64. },
  65. "isEncrypted": False,
  66. "model": model,
  67. "modelFriendlyName": SUPPORTED_TYPES[model]["modelFriendlyName"],
  68. "modelName": SUPPORTED_TYPES[model]["modelName"],
  69. },
  70. device=ble_device,
  71. rssi=-97,
  72. active=True,
  73. )
  74. @pytest.mark.asyncio
  75. @pytest.mark.parametrize(
  76. ("rawAdvData", "model"),
  77. [
  78. (b".\x00d", "."),
  79. (b"z\x00\x00", "z"),
  80. (b"3\x00\x00", "3"),
  81. (b"\x00\x00M\x00\x10\xfb\xa8", b"\x00\x10\xfb\xa8"),
  82. (b"\x00\x00d\x00\x10\xe0P", b"\x00\x10\xe0P"),
  83. ],
  84. )
  85. async def test_status_from_proceess_adv(rawAdvData: bytes, model: str) -> None:
  86. protocol_version = 2
  87. device = create_device_for_command_testing(protocol_version, rawAdvData, model)
  88. assert device.get_soc_version() == "1.1.083"
  89. assert device.get_last_step() == 0
  90. assert device.get_mqtt_connnect_status() is True
  91. assert device.get_battery() == 100
  92. assert device.get_work_status() == 15
  93. @pytest.mark.asyncio
  94. @pytest.mark.parametrize(("rawAdvData", "model"), [(b"(\x00", "("), (b"}\x00", "}")])
  95. async def test_status_from_proceess_adv_k(rawAdvData: bytes, model: str) -> None:
  96. protocol_version = 1
  97. device = create_device_for_command_testing(protocol_version, rawAdvData, model)
  98. assert device.get_dustbin_bound_status() is False
  99. assert device.get_dustbin_connnected_status() is False
  100. assert device.get_network_connected_status() is True
  101. assert device.get_battery() == 100
  102. assert device.get_work_status() == 0
  103. @pytest.mark.asyncio
  104. @pytest.mark.parametrize(("rawAdvData", "model", "protocol_version"), common_params)
  105. async def test_clean_up(rawAdvData, model, protocol_version):
  106. device = create_device_for_command_testing(protocol_version, rawAdvData, model)
  107. await device.clean_up(protocol_version)
  108. device._send_command.assert_awaited_once_with(
  109. vacuum.COMMAND_CLEAN_UP[protocol_version]
  110. )
  111. @pytest.mark.asyncio
  112. @pytest.mark.parametrize(("rawAdvData", "model", "protocol_version"), common_params)
  113. async def test_return_to_dock(rawAdvData, model, protocol_version):
  114. device = create_device_for_command_testing(protocol_version, rawAdvData, model)
  115. await device.return_to_dock(protocol_version)
  116. device._send_command.assert_awaited_once_with(
  117. vacuum.COMMAND_RETURN_DOCK[protocol_version]
  118. )
  119. @pytest.mark.asyncio
  120. @pytest.mark.parametrize(("rawAdvData", "model", "protocol_version"), common_params)
  121. async def test_get_basic_info_returns_none_when_no_data(
  122. rawAdvData, model, protocol_version
  123. ):
  124. device = create_device_for_command_testing(protocol_version, rawAdvData, model)
  125. device._get_basic_info = AsyncMock(return_value=None)
  126. assert await device.get_basic_info() is None