Browse Source

loosen version constraint to support PySwitchbot v0.11.0; update dev env & adapt tests for new PySwitchbot version

https://github.com/Danielhiversen/pySwitchbot/compare/0.10.1...0.11.0

https://github.com/fphammerle/switchbot-mqtt/issues/55#issuecomment-955401095
Fabian Peter Hammerle 2 years ago
parent
commit
5c7d230a80

+ 3 - 0
CHANGELOG.md

@@ -5,6 +5,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
 ## [Unreleased]
+### Added
+- support `PySwitchbot` `v0.11.0`
+
 ### Removed
 - compatibility with `python3.6`
 

+ 3 - 3
Pipfile.lock

@@ -30,10 +30,10 @@
         },
         "pyswitchbot": {
             "hashes": [
-                "sha256:392f99abe7c1861c5edbefb5430100941714be127dff03677722496c24ea7d96",
-                "sha256:5a32811423e5ba34e0d1a914ea19442a19c977d2bdd140094eb7413701d85f85"
+                "sha256:32c071a484750b71c2128c5e1169274f80e9ad055a7bd6c3d2da45732c292ffc",
+                "sha256:d20e8b634c662f9a400f354e3b1b12af76781a3d4b5867221f99e558c3aa215d"
             ],
-            "version": "==0.10.1"
+            "version": "==0.11.0"
         },
         "switchbot-mqtt": {
             "editable": true,

+ 1 - 1
setup.py

@@ -81,7 +81,7 @@ setuptools.setup(
         # https://github.com/IanHarvey/bluepy/tree/v/1.3.0#release-notes
         "bluepy>=1.3.0,<2",
         # >=0.10.0 for SwitchbotCurtain.{update,get_position}
-        "PySwitchbot>=0.10.0,<0.11",
+        "PySwitchbot>=0.10.0,<0.12",
         "paho-mqtt<2",
     ],
     setup_requires=["setuptools_scm"],

+ 1 - 0
switchbot_mqtt/_actors/_base.py

@@ -85,6 +85,7 @@ class _MQTTControlledActor(abc.ABC):
             self._get_device().update()
             # pySwitchbot>=v0.10.1 catches bluepy.btle.BTLEManagementError :(
             # https://github.com/Danielhiversen/pySwitchbot/blob/0.10.1/switchbot/__init__.py#L141
+            # pySwitchbot<0.11.0 WARNING, >=0.11.0 ERROR
             while not log_queue.empty():
                 log_record = log_queue.get()
                 if log_record.exc_info:

+ 7 - 3
tests/test_actor_base_device_info.py

@@ -43,11 +43,13 @@ _LE_ON_PERMISSION_DENIED_ERROR = bluepy.btle.BTLEManagementError(
 def test__update_device_info_le_on_permission_denied_log(
     actor_class,
 ):  # pySwitchbot>=v0.10.0
-    actor = actor_class(mac_address="dummy", retry_count=21, password=None)
+    actor = actor_class(mac_address="dummy", retry_count=0, password=None)
     with unittest.mock.patch(
         "bluepy.btle.Scanner.scan",
         side_effect=_LE_ON_PERMISSION_DENIED_ERROR,
-    ), pytest.raises(PermissionError) as exc_info:
+    ), pytest.raises(
+        PermissionError, match=r"^bluepy-helper failed to enable low energy mode "
+    ) as exc_info:
         actor._update_device_info()
     assert "sudo setcap cap_net_admin+ep /" in exc_info.exconly()
     assert exc_info.value.__cause__ == _LE_ON_PERMISSION_DENIED_ERROR
@@ -64,7 +66,9 @@ def test__update_device_info_le_on_permission_denied_exc(
         actor._get_device(),
         "update",
         side_effect=_LE_ON_PERMISSION_DENIED_ERROR,
-    ) as update_mock, pytest.raises(PermissionError) as exc_info:
+    ) as update_mock, pytest.raises(
+        PermissionError, match=r"^bluepy-helper failed to enable low energy mode "
+    ) as exc_info:
         actor._update_device_info()
     update_mock.assert_called_once_with()
     assert os.path.isfile(

+ 14 - 14
tests/test_switchbot_button_automator.py

@@ -42,7 +42,7 @@ def test__update_and_report_device_info(
 ):
     with unittest.mock.patch("switchbot.SwitchbotCurtain.__init__", return_value=None):
         actor = _ButtonAutomator(mac_address="dummy", retry_count=21, password=None)
-    actor._get_device()._battery_percent = battery_percent
+    actor._get_device()._switchbot_device_data = {"data": {"battery": battery_percent}}
     mqtt_client_mock = unittest.mock.MagicMock()
     with unittest.mock.patch("switchbot.Switchbot.update") as update_mock:
         actor._update_and_report_device_info(mqtt_client=mqtt_client_mock)
@@ -170,21 +170,21 @@ def test_execute_command_bluetooth_error(caplog, mac_address, message_payload):
         ),
     ), caplog.at_level(logging.ERROR):
         _ButtonAutomator(
-            mac_address=mac_address, retry_count=3, password=None
+            mac_address=mac_address, retry_count=0, password=None
         ).execute_command(
             mqtt_client="dummy",
             mqtt_message_payload=message_payload,
             update_device_info=True,
         )
-    assert caplog.record_tuples == [
-        (
-            "switchbot",
-            logging.ERROR,
-            "Switchbot communication failed. Stopping trying.",
-        ),
-        (
-            "switchbot_mqtt._actors",
-            logging.ERROR,
-            f"failed to turn {message_payload.decode().lower()} switchbot {mac_address}",
-        ),
-    ]
+    assert len(caplog.records) == 2
+    assert caplog.records[0].name == "switchbot"
+    assert caplog.records[0].levelno == logging.ERROR
+    assert caplog.records[0].msg.startswith(
+        # pySwitchbot<0.11 had '.' suffix
+        "Switchbot communication failed. Stopping trying",
+    )
+    assert caplog.record_tuples[1] == (
+        "switchbot_mqtt._actors",
+        logging.ERROR,
+        f"failed to turn {message_payload.decode().lower()} switchbot {mac_address}",
+    )

+ 16 - 15
tests/test_switchbot_curtain_motor.py

@@ -121,8 +121,9 @@ def test__update_and_report_device_info(
 ):
     with unittest.mock.patch("switchbot.SwitchbotCurtain.__init__", return_value=None):
         actor = _CurtainMotor(mac_address="dummy", retry_count=21, password=None)
-    actor._get_device()._battery_percent = battery_percent
-    actor._get_device()._pos = position
+    actor._get_device()._switchbot_device_data = {
+        "data": {"battery": battery_percent, "position": position}
+    }
     mqtt_client_mock = unittest.mock.MagicMock()
     with unittest.mock.patch("switchbot.SwitchbotCurtain.update") as update_mock:
         actor._update_and_report_device_info(
@@ -299,21 +300,21 @@ def test_execute_command_bluetooth_error(caplog, mac_address, message_payload):
         ),
     ), caplog.at_level(logging.ERROR):
         _CurtainMotor(
-            mac_address=mac_address, retry_count=10, password="secret"
+            mac_address=mac_address, retry_count=0, password="secret"
         ).execute_command(
             mqtt_client="dummy",
             mqtt_message_payload=message_payload,
             update_device_info=True,
         )
-    assert caplog.record_tuples == [
-        (
-            "switchbot",
-            logging.ERROR,
-            "Switchbot communication failed. Stopping trying.",
-        ),
-        (
-            "switchbot_mqtt._actors",
-            logging.ERROR,
-            f"failed to {message_payload.decode().lower()} switchbot curtain {mac_address}",
-        ),
-    ]
+    assert len(caplog.records) == 2
+    assert caplog.records[0].name == "switchbot"
+    assert caplog.records[0].levelno == logging.ERROR
+    assert caplog.records[0].msg.startswith(
+        # pySwitchbot<0.11 had '.' suffix
+        "Switchbot communication failed. Stopping trying",
+    )
+    assert caplog.record_tuples[1] == (
+        "switchbot_mqtt._actors",
+        logging.ERROR,
+        f"failed to {message_payload.decode().lower()} switchbot curtain {mac_address}",
+    )