From 5e58c1a14f7a8b2919c173358496d25242ad86de Mon Sep 17 00:00:00 2001 From: Kevin Fronczak Date: Mon, 18 Dec 2023 12:11:28 -0500 Subject: [PATCH 01/50] Update pyproject.toml --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c88b1abf..8800fbe5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "blinkpy" -version = "0.22.4" +version = "0.23.0b3" license = {text = "MIT"} description = "A Blink camera Python Library." readme = "README.rst" From 58049888f87f96b2f84229e671e724f7659e66ce Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Dec 2023 18:37:21 +0000 Subject: [PATCH 02/50] Bump ruff from 0.1.8 to 0.1.9 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.1.8 to 0.1.9. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/v0.1.8...v0.1.9) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_test.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_test.txt b/requirements_test.txt index 2eb03f58..9aa2343f 100644 --- a/requirements_test.txt +++ b/requirements_test.txt @@ -1,4 +1,4 @@ -ruff==0.1.8 +ruff==0.1.9 black==23.12.0 build==1.0.3 coverage==7.3.2 From e6fdb83b18fcfa80c6adbacec6a670353e47c61d Mon Sep 17 00:00:00 2001 From: mkmer Date: Sat, 30 Dec 2023 16:46:06 +0000 Subject: [PATCH 03/50] Add new keys --- blinkpy/camera.py | 23 +++++++++++++++-------- tests/test_camera_functions.py | 2 +- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/blinkpy/camera.py b/blinkpy/camera.py index bc5c6d80..b7ca575d 100644 --- a/blinkpy/camera.py +++ b/blinkpy/camera.py @@ -43,6 +43,7 @@ def __init__(self, sync): self._cached_video = None self.camera_type = "" self.product_type = None + self.sync_signal = None @property def attributes(self): @@ -64,6 +65,7 @@ def attributes(self): "wifi_strength": self.wifi_strength, "network_id": self.sync.network_id, "sync_module": self.sync.name, + "sync_signal": self.sync_signal, "last_record": self.last_record, "type": self.product_type, } @@ -229,15 +231,20 @@ def extract_config_info(self, config): self.name = config.get("name", "unknown") self.camera_id = str(config.get("id", "unknown")) self.network_id = str(config.get("network_id", "unknown")) - self.serial = config.get("serial", None) + self.serial = config.get("serial") self.motion_enabled = config.get("enabled", "unknown") - self.battery_voltage = config.get("battery_voltage", None) - self.battery_state = config.get("battery_state", None) or config.get( - "battery", None - ) - self.temperature = config.get("temperature", None) - self.wifi_strength = config.get("wifi_strength", None) - self.product_type = config.get("type", None) + self.battery_voltage = config.get("battery_voltage") + self.battery_state = config.get("battery_state") or config.get("battery") + self.temperature = config.get("temperature") + if signals := config.get("signals"): + self.wifi_strength = signals.get("wifi") + self.battery_voltage = signals.get("battery") + self.sync_signal = signals.get("lfr") + else: + self.wifi_strength = config.get("wifi_strength") + self.battery_voltage = config.get("battery_voltage") + + self.product_type = config.get("type") async def get_sensor_info(self): """Retrieve calibrated temperature from special endpoint.""" diff --git a/tests/test_camera_functions.py b/tests/test_camera_functions.py index c1b7df49..b881a6b1 100644 --- a/tests/test_camera_functions.py +++ b/tests/test_camera_functions.py @@ -56,7 +56,7 @@ async def test_camera_update(self, mock_resp): "battery_voltage": 90, "battery_state": "ok", "temperature": 68, - "wifi_strength": 4, + "signals": {"lfr":5,"wifi":4,"battery":3}, "thumbnail": "/thumb", } self.camera.last_record = ["1"] From 852dd6a33ba9cb4a5205576bd17124b8a33088b1 Mon Sep 17 00:00:00 2001 From: mkmer Date: Sat, 30 Dec 2023 17:09:33 +0000 Subject: [PATCH 04/50] Lint again --- tests/test_camera_functions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_camera_functions.py b/tests/test_camera_functions.py index b881a6b1..3e1f1d85 100644 --- a/tests/test_camera_functions.py +++ b/tests/test_camera_functions.py @@ -56,7 +56,7 @@ async def test_camera_update(self, mock_resp): "battery_voltage": 90, "battery_state": "ok", "temperature": 68, - "signals": {"lfr":5,"wifi":4,"battery":3}, + "signals": {"lfr": 5, "wifi": 4, "battery": 3}, "thumbnail": "/thumb", } self.camera.last_record = ["1"] From 61d1fbb077c017b33743e63797b212b1a721895a Mon Sep 17 00:00:00 2001 From: mkmer Date: Sat, 30 Dec 2023 19:10:49 +0000 Subject: [PATCH 05/50] return percentage --- blinkpy/camera.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/blinkpy/camera.py b/blinkpy/camera.py index b7ca575d..a0db0511 100644 --- a/blinkpy/camera.py +++ b/blinkpy/camera.py @@ -237,9 +237,18 @@ def extract_config_info(self, config): self.battery_state = config.get("battery_state") or config.get("battery") self.temperature = config.get("temperature") if signals := config.get("signals"): - self.wifi_strength = signals.get("wifi") - self.battery_voltage = signals.get("battery") - self.sync_signal = signals.get("lfr") + try: # x / 5 * 100 = x * 20 for percentage + self.wifi_strength = signals.get("wifi") * 20 + except TypeError: + self.wifi_strength = None + try: + self.battery_voltage = signals.get("battery") * 20 + except TypeError: + self.battery_voltage = None + try: + self.sync_signal = signals.get("lfr") * 20 + except TypeError: + self.sync_signal = None else: self.wifi_strength = config.get("wifi_strength") self.battery_voltage = config.get("battery_voltage") From 4302eb6a095e3e01f245f53fd2e7aea666164fd4 Mon Sep 17 00:00:00 2001 From: mkmer Date: Sat, 30 Dec 2023 19:19:29 +0000 Subject: [PATCH 06/50] Fix test to percentage --- tests/test_camera_functions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_camera_functions.py b/tests/test_camera_functions.py index 3e1f1d85..6332d824 100644 --- a/tests/test_camera_functions.py +++ b/tests/test_camera_functions.py @@ -80,7 +80,7 @@ async def test_camera_update(self, mock_resp): self.assertEqual(self.camera.temperature, 68) self.assertEqual(self.camera.temperature_c, 20) self.assertEqual(self.camera.temperature_calibrated, 71) - self.assertEqual(self.camera.wifi_strength, 4) + self.assertEqual(self.camera.wifi_strength, 80) self.assertEqual( self.camera.thumbnail, "https://rest-test.immedia-semi.com/thumb.jpg" ) From 3e02763ca1da0242fbd5fe28c71b5519a9dcd818 Mon Sep 17 00:00:00 2001 From: mkmer Date: Sat, 30 Dec 2023 19:58:07 +0000 Subject: [PATCH 07/50] Add tests for missing keys --- tests/test_camera_functions.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/test_camera_functions.py b/tests/test_camera_functions.py index 6332d824..ecade4ab 100644 --- a/tests/test_camera_functions.py +++ b/tests/test_camera_functions.py @@ -408,3 +408,26 @@ async def test_save_recent_clips_exception(self, mock_clip, mock_open, mock_resp in "\t".join(dl_log.output) ) assert mock_open.call_count == 1 + + async def test_missing_keys(self, mock_resp): + """Tests missing signal keys.""" + config = { + "name": "new", + "id": 1234, + "network_id": 5678, + "serial": "12345678", + "enabled": False, + "battery_state": "ok", + "temperature": 68, + "signals": {"junk": 1}, + "thumbnail": "", + } + self.camera.sync.homescreen = {"devices": []} + mock_resp.side_effect = [ + {"temp": 71}, + mresp.MockResponse({"test": 200}, 200, raw_data="test"), + mresp.MockResponse({"foobar": 200}, 200, raw_data="foobar"), + ] + await self.camera.update(config, expire_clips=False, force=True) + self.assertEqual(self.camera.wifi_strength, None) + self.assertEqual(self.camera.battery_voltage, None) From c5a606c23b103e49c18555da1470c1b077e8181d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jan 2024 16:44:00 +0000 Subject: [PATCH 08/50] Bump black from 23.12.0 to 23.12.1 Bumps [black](https://github.com/psf/black) from 23.12.0 to 23.12.1. - [Release notes](https://github.com/psf/black/releases) - [Changelog](https://github.com/psf/black/blob/main/CHANGES.md) - [Commits](https://github.com/psf/black/compare/23.12.0...23.12.1) --- updated-dependencies: - dependency-name: black dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_test.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_test.txt b/requirements_test.txt index 9aa2343f..dcd399a6 100644 --- a/requirements_test.txt +++ b/requirements_test.txt @@ -1,5 +1,5 @@ ruff==0.1.9 -black==23.12.0 +black==23.12.1 build==1.0.3 coverage==7.3.2 pytest==7.4.3 From 5ef42bb0719cc379e97ea82a1bccf0dc94fcf83a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jan 2024 16:44:03 +0000 Subject: [PATCH 09/50] Bump coverage from 7.3.2 to 7.4.0 Bumps [coverage](https://github.com/nedbat/coveragepy) from 7.3.2 to 7.4.0. - [Release notes](https://github.com/nedbat/coveragepy/releases) - [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst) - [Commits](https://github.com/nedbat/coveragepy/compare/7.3.2...7.4.0) --- updated-dependencies: - dependency-name: coverage dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements_test.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_test.txt b/requirements_test.txt index 9aa2343f..c7e9720a 100644 --- a/requirements_test.txt +++ b/requirements_test.txt @@ -1,7 +1,7 @@ ruff==0.1.9 black==23.12.0 build==1.0.3 -coverage==7.3.2 +coverage==7.4.0 pytest==7.4.3 pytest-cov==4.1.0 pytest-sugar==0.9.7 From a49a54354abd0866f3a103393c3037badfa38ced Mon Sep 17 00:00:00 2001 From: mkmer Date: Mon, 1 Jan 2024 20:14:21 +0000 Subject: [PATCH 10/50] back to raw values remove extra battery_voltage assignment --- blinkpy/camera.py | 16 +++------------- tests/test_camera_functions.py | 2 +- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/blinkpy/camera.py b/blinkpy/camera.py index a0db0511..2e08957c 100644 --- a/blinkpy/camera.py +++ b/blinkpy/camera.py @@ -233,22 +233,12 @@ def extract_config_info(self, config): self.network_id = str(config.get("network_id", "unknown")) self.serial = config.get("serial") self.motion_enabled = config.get("enabled", "unknown") - self.battery_voltage = config.get("battery_voltage") self.battery_state = config.get("battery_state") or config.get("battery") self.temperature = config.get("temperature") if signals := config.get("signals"): - try: # x / 5 * 100 = x * 20 for percentage - self.wifi_strength = signals.get("wifi") * 20 - except TypeError: - self.wifi_strength = None - try: - self.battery_voltage = signals.get("battery") * 20 - except TypeError: - self.battery_voltage = None - try: - self.sync_signal = signals.get("lfr") * 20 - except TypeError: - self.sync_signal = None + self.wifi_strength = signals.get("wifi") + self.battery_voltage = signals.get("battery") + self.sync_signal = signals.get("lfr") else: self.wifi_strength = config.get("wifi_strength") self.battery_voltage = config.get("battery_voltage") diff --git a/tests/test_camera_functions.py b/tests/test_camera_functions.py index ecade4ab..c7283d35 100644 --- a/tests/test_camera_functions.py +++ b/tests/test_camera_functions.py @@ -80,7 +80,7 @@ async def test_camera_update(self, mock_resp): self.assertEqual(self.camera.temperature, 68) self.assertEqual(self.camera.temperature_c, 20) self.assertEqual(self.camera.temperature_calibrated, 71) - self.assertEqual(self.camera.wifi_strength, 80) + self.assertEqual(self.camera.wifi_strength, 4) self.assertEqual( self.camera.thumbnail, "https://rest-test.immedia-semi.com/thumb.jpg" ) From 6e1aa6bf9d52d0e253bc065bdff674934e3fa5ec Mon Sep 17 00:00:00 2001 From: mkmer Date: Tue, 2 Jan 2024 12:16:59 +0000 Subject: [PATCH 11/50] better name for sync signal --- blinkpy/camera.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/blinkpy/camera.py b/blinkpy/camera.py index 2e08957c..512a951d 100644 --- a/blinkpy/camera.py +++ b/blinkpy/camera.py @@ -65,7 +65,7 @@ def attributes(self): "wifi_strength": self.wifi_strength, "network_id": self.sync.network_id, "sync_module": self.sync.name, - "sync_signal": self.sync_signal, + "sync_signal_strength": self.sync_signal_strength, "last_record": self.last_record, "type": self.product_type, } @@ -238,7 +238,7 @@ def extract_config_info(self, config): if signals := config.get("signals"): self.wifi_strength = signals.get("wifi") self.battery_voltage = signals.get("battery") - self.sync_signal = signals.get("lfr") + self.sync_signal_strength = signals.get("lfr") else: self.wifi_strength = config.get("wifi_strength") self.battery_voltage = config.get("battery_voltage") From ba99ae7d013041ad8d47b98e569eaae3611514bc Mon Sep 17 00:00:00 2001 From: mkmer Date: Tue, 2 Jan 2024 12:19:58 +0000 Subject: [PATCH 12/50] Missed var --- blinkpy/camera.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/blinkpy/camera.py b/blinkpy/camera.py index 512a951d..a535a7c0 100644 --- a/blinkpy/camera.py +++ b/blinkpy/camera.py @@ -43,7 +43,7 @@ def __init__(self, sync): self._cached_video = None self.camera_type = "" self.product_type = None - self.sync_signal = None + self.sync_signal_strength = None @property def attributes(self): @@ -56,7 +56,7 @@ def attributes(self): "temperature_c": self.temperature_c, "temperature_calibrated": self.temperature_calibrated, "battery": self.battery, - "battery_voltage": self.battery_voltage, + "battery_level": self.battery_level, "thumbnail": self.thumbnail, "video": self.clip, "recent_clips": self.recent_clips, From 85fe440a6172bdaf03326cbf6d60aed8fba81d17 Mon Sep 17 00:00:00 2001 From: mkmer Date: Tue, 2 Jan 2024 12:25:04 +0000 Subject: [PATCH 13/50] in advertant variable name change --- blinkpy/camera.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blinkpy/camera.py b/blinkpy/camera.py index a535a7c0..dc37d216 100644 --- a/blinkpy/camera.py +++ b/blinkpy/camera.py @@ -56,7 +56,7 @@ def attributes(self): "temperature_c": self.temperature_c, "temperature_calibrated": self.temperature_calibrated, "battery": self.battery, - "battery_level": self.battery_level, + "battery_level": self.battery_voltage, "thumbnail": self.thumbnail, "video": self.clip, "recent_clips": self.recent_clips, From 6703cb8e593d5df07aad0f5ca96d50e0c5591b13 Mon Sep 17 00:00:00 2001 From: mkmer Date: Tue, 2 Jan 2024 12:27:19 +0000 Subject: [PATCH 14/50] voltage not level --- blinkpy/camera.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blinkpy/camera.py b/blinkpy/camera.py index dc37d216..fb54fbc1 100644 --- a/blinkpy/camera.py +++ b/blinkpy/camera.py @@ -56,7 +56,7 @@ def attributes(self): "temperature_c": self.temperature_c, "temperature_calibrated": self.temperature_calibrated, "battery": self.battery, - "battery_level": self.battery_voltage, + "battery_voltage": self.battery_voltage, "thumbnail": self.thumbnail, "video": self.clip, "recent_clips": self.recent_clips, From 72ca60bccfc351dbc4c419d7052b96c39e844926 Mon Sep 17 00:00:00 2001 From: mkmer Date: Tue, 2 Jan 2024 19:54:50 +0000 Subject: [PATCH 15/50] Address not awaited warning --- tests/test_camera_functions.py | 2 +- tests/test_cameras.py | 2 +- tests/test_sync_module.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_camera_functions.py b/tests/test_camera_functions.py index c1b7df49..800424c5 100644 --- a/tests/test_camera_functions.py +++ b/tests/test_camera_functions.py @@ -27,7 +27,7 @@ } -@mock.patch("blinkpy.auth.Auth.query") +@mock.patch("blinkpy.auth.Auth.query", return_value={}) class TestBlinkCameraSetup(IsolatedAsyncioTestCase): """Test the Blink class in blinkpy.""" diff --git a/tests/test_cameras.py b/tests/test_cameras.py index 8689237f..84477a0a 100644 --- a/tests/test_cameras.py +++ b/tests/test_cameras.py @@ -26,7 +26,7 @@ } -@mock.patch("blinkpy.auth.Auth.query") +@mock.patch("blinkpy.auth.Auth.query", return_value={}) class TestBlinkCameraSetup(IsolatedAsyncioTestCase): """Test the Blink class in blinkpy.""" diff --git a/tests/test_sync_module.py b/tests/test_sync_module.py index 9b4c5a5d..b0fd81cb 100644 --- a/tests/test_sync_module.py +++ b/tests/test_sync_module.py @@ -22,7 +22,7 @@ _LOGGER.setLevel(logging.DEBUG) -@mock.patch("blinkpy.auth.Auth.query") +@mock.patch("blinkpy.auth.Auth.query", return_value={"status": 200}) class TestBlinkSyncModule(IsolatedAsyncioTestCase): """Test BlinkSyncModule functions in blinkpy.""" From e16d488e1526a4608f085e8f17a6614efdef9ec6 Mon Sep 17 00:00:00 2001 From: mkmer Date: Tue, 2 Jan 2024 12:36:20 +0000 Subject: [PATCH 16/50] Add battery level remove battery voltage --- blinkpy/camera.py | 8 +++----- tests/test_camera_functions.py | 14 +++++++------- tests/test_cameras.py | 8 ++++---- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/blinkpy/camera.py b/blinkpy/camera.py index fb54fbc1..72ddd11e 100644 --- a/blinkpy/camera.py +++ b/blinkpy/camera.py @@ -28,7 +28,7 @@ def __init__(self, sync): self.thumbnail = None self.serial = None self.motion_enabled = None - self.battery_voltage = None + self.battery_level = None self.clip = None # A clip remains in the recent clips list until is has # been downloaded or has been expired. @@ -56,7 +56,7 @@ def attributes(self): "temperature_c": self.temperature_c, "temperature_calibrated": self.temperature_calibrated, "battery": self.battery, - "battery_voltage": self.battery_voltage, + "battery_level": self.battery_level, "thumbnail": self.thumbnail, "video": self.clip, "recent_clips": self.recent_clips, @@ -237,12 +237,10 @@ def extract_config_info(self, config): self.temperature = config.get("temperature") if signals := config.get("signals"): self.wifi_strength = signals.get("wifi") - self.battery_voltage = signals.get("battery") + self.battery_level = signals.get("battery") self.sync_signal_strength = signals.get("lfr") else: self.wifi_strength = config.get("wifi_strength") - self.battery_voltage = config.get("battery_voltage") - self.product_type = config.get("type") async def get_sensor_info(self): diff --git a/tests/test_camera_functions.py b/tests/test_camera_functions.py index c7283d35..b6d2a568 100644 --- a/tests/test_camera_functions.py +++ b/tests/test_camera_functions.py @@ -18,7 +18,7 @@ CAMERA_CFG = { "camera": [ { - "battery_voltage": 90, + "battery_level": 5, "motion_alert": True, "wifi_strength": -30, "temperature": 68, @@ -53,7 +53,7 @@ async def test_camera_update(self, mock_resp): "network_id": 5678, "serial": "12345678", "enabled": False, - "battery_voltage": 90, + "battery_level": 5, "battery_state": "ok", "temperature": 68, "signals": {"lfr": 5, "wifi": 4, "battery": 3}, @@ -112,7 +112,7 @@ async def test_no_thumbnails(self, mock_resp): "network_id": 5678, "serial": "12345678", "enabled": False, - "battery_voltage": 90, + "battery_level": 90, "battery_state": "ok", "temperature": 68, "wifi_strength": 4, @@ -149,7 +149,7 @@ async def test_no_video_clips(self, mock_resp): "network_id": 5678, "serial": "12345678", "enabled": False, - "battery_voltage": 90, + "battery_level": 90, "battery_state": "ok", "temperature": 68, "wifi_strength": 4, @@ -173,7 +173,7 @@ async def test_recent_video_clips(self, mock_resp): "network_id": 5678, "serial": "12345678", "enabled": False, - "battery_voltage": 90, + "battery_level": 5, "battery_state": "ok", "temperature": 68, "wifi_strength": 4, @@ -199,7 +199,7 @@ async def test_recent_video_clips_missing_key(self, mock_resp): "network_id": 5678, "serial": "12345678", "enabled": False, - "battery_voltage": 90, + "battery_level": 5, "battery_state": "ok", "temperature": 68, "wifi_strength": 4, @@ -430,4 +430,4 @@ async def test_missing_keys(self, mock_resp): ] await self.camera.update(config, expire_clips=False, force=True) self.assertEqual(self.camera.wifi_strength, None) - self.assertEqual(self.camera.battery_voltage, None) + self.assertEqual(self.camera.battery_level, None) diff --git a/tests/test_cameras.py b/tests/test_cameras.py index 8689237f..410569ea 100644 --- a/tests/test_cameras.py +++ b/tests/test_cameras.py @@ -17,7 +17,7 @@ CAMERA_CFG = { "camera": [ { - "battery_voltage": 90, + "battery_level": 5, "motion_alert": True, "wifi_strength": -30, "temperature": 68, @@ -134,7 +134,7 @@ async def test_different_thumb_api(self, mock_resp): "network_id": 5678, "serial": "12345678", "enabled": False, - "battery_voltage": 90, + "battery_level": 5, "battery_state": "ok", "temperature": 68, "wifi_strength": 4, @@ -157,7 +157,7 @@ async def test_thumb_return_none(self, mock_resp): "network_id": 5678, "serial": "12345678", "enabled": False, - "battery_voltage": 90, + "battery_level": 5, "battery_state": "ok", "temperature": 68, "wifi_strength": 4, @@ -183,7 +183,7 @@ async def test_new_thumb_url_returned(self, mock_resp): "network_id": 5678, "serial": "12345678", "enabled": False, - "battery_voltage": 90, + "battery_level": 5, "battery_state": "ok", "temperature": 68, "wifi_strength": 4, From cdf0e2c00d220607435222749046c169279c9b8a Mon Sep 17 00:00:00 2001 From: mkmer Date: Tue, 2 Jan 2024 14:19:07 +0000 Subject: [PATCH 17/50] Optimize camera function tests --- tests/test_camera_functions.py | 104 +++++++++------------------------ 1 file changed, 26 insertions(+), 78 deletions(-) diff --git a/tests/test_camera_functions.py b/tests/test_camera_functions.py index b6d2a568..4fdd985f 100644 --- a/tests/test_camera_functions.py +++ b/tests/test_camera_functions.py @@ -15,18 +15,19 @@ from blinkpy.camera import BlinkCamera, BlinkCameraMini, BlinkDoorbell import tests.mock_responses as mresp -CAMERA_CFG = { - "camera": [ - { - "battery_level": 5, - "motion_alert": True, - "wifi_strength": -30, - "temperature": 68, - } - ] +CONFIG = { + "name": "new", + "id": 1234, + "network_id": 5678, + "serial": "12345678", + "enabled": False, + "battery_level": 5, + "battery_state": "ok", + "temperature": 68, + "signals": {"lfr": 5, "wifi": 4, "battery": 3}, + "thumbnail": "/thumb", } - @mock.patch("blinkpy.auth.Auth.query") class TestBlinkCameraSetup(IsolatedAsyncioTestCase): """Test the Blink class in blinkpy.""" @@ -47,18 +48,6 @@ def tearDown(self): async def test_camera_update(self, mock_resp): """Test that we can properly update camera properties.""" - config = { - "name": "new", - "id": 1234, - "network_id": 5678, - "serial": "12345678", - "enabled": False, - "battery_level": 5, - "battery_state": "ok", - "temperature": 68, - "signals": {"lfr": 5, "wifi": 4, "battery": 3}, - "thumbnail": "/thumb", - } self.camera.last_record = ["1"] self.camera.sync.last_records = { "new": [{"clip": "/test.mp4", "time": "1970-01-01T00:00:00"}] @@ -70,7 +59,7 @@ async def test_camera_update(self, mock_resp): ] self.assertIsNone(self.camera.image_from_cache) - await self.camera.update(config, expire_clips=False) + await self.camera.update(CONFIG, expire_clips=False) self.assertEqual(self.camera.name, "new") self.assertEqual(self.camera.camera_id, "1234") self.assertEqual(self.camera.network_id, "5678") @@ -106,18 +95,11 @@ async def test_no_thumbnails(self, mock_resp): """Tests that thumbnail is 'None' if none found.""" mock_resp.return_value = "foobar" self.camera.last_record = ["1"] - config = { - "name": "new", - "id": 1234, - "network_id": 5678, - "serial": "12345678", - "enabled": False, - "battery_level": 90, - "battery_state": "ok", - "temperature": 68, - "wifi_strength": 4, + config = CONFIG + config.update({ "thumbnail": "", - } + }) + self.camera.sync.homescreen = {"devices": []} self.assertEqual(self.camera.temperature_calibrated, None) with self.assertLogs() as logrecord: @@ -143,18 +125,10 @@ async def test_no_thumbnails(self, mock_resp): async def test_no_video_clips(self, mock_resp): """Tests that we still proceed with camera setup with no videos.""" mock_resp.return_value = "foobar" - config = { - "name": "new", - "id": 1234, - "network_id": 5678, - "serial": "12345678", - "enabled": False, - "battery_level": 90, - "battery_state": "ok", - "temperature": 68, - "wifi_strength": 4, + config = CONFIG + config.update({ "thumbnail": "/foobar", - } + }) mock_resp.return_value = mresp.MockResponse({"test": 200}, 200, raw_data="") self.camera.sync.homescreen = {"devices": []} await self.camera.update(config, force_cache=True, expire_clips=False) @@ -167,18 +141,10 @@ async def test_recent_video_clips(self, mock_resp): Tests that the last records in the sync module are added to the camera recent clips list. """ - config = { - "name": "new", - "id": 1234, - "network_id": 5678, - "serial": "12345678", - "enabled": False, - "battery_level": 5, - "battery_state": "ok", - "temperature": 68, - "wifi_strength": 4, + config = CONFIG + config.update({ "thumbnail": "/thumb", - } + }) self.camera.sync.last_records["foobar"] = [] record2 = {"clip": "/clip2", "time": "2022-12-01 00:00:10+00:00"} self.camera.sync.last_records["foobar"].append(record2) @@ -193,25 +159,13 @@ async def test_recent_video_clips(self, mock_resp): async def test_recent_video_clips_missing_key(self, mock_resp): """Tests that the missing key failst.""" - config = { - "name": "new", - "id": 1234, - "network_id": 5678, - "serial": "12345678", - "enabled": False, - "battery_level": 5, - "battery_state": "ok", - "temperature": 68, - "wifi_strength": 4, - "thumbnail": "/thumb", - } self.camera.sync.last_records["foobar"] = [] record2 = {"clip": "/clip2"} self.camera.sync.last_records["foobar"].append(record2) self.camera.sync.motion["foobar"] = True with self.assertLogs(level="ERROR") as dl_log: - await self.camera.update_images(config, expire_clips=False) + await self.camera.update_images(CONFIG, expire_clips=False) self.assertIsNotNone(dl_log.output) @@ -411,17 +365,11 @@ async def test_save_recent_clips_exception(self, mock_clip, mock_open, mock_resp async def test_missing_keys(self, mock_resp): """Tests missing signal keys.""" - config = { - "name": "new", - "id": 1234, - "network_id": 5678, - "serial": "12345678", - "enabled": False, - "battery_state": "ok", - "temperature": 68, + config = CONFIG + config.update({ "signals": {"junk": 1}, "thumbnail": "", - } + }) self.camera.sync.homescreen = {"devices": []} mock_resp.side_effect = [ {"temp": 71}, From 295ab397bbb090f649e9853e08d9c5eb166d62c7 Mon Sep 17 00:00:00 2001 From: mkmer Date: Tue, 2 Jan 2024 14:29:10 +0000 Subject: [PATCH 18/50] Optimize config dict --- tests/test_camera_functions.py | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/tests/test_camera_functions.py b/tests/test_camera_functions.py index 4fdd985f..ac2e5f8f 100644 --- a/tests/test_camera_functions.py +++ b/tests/test_camera_functions.py @@ -95,10 +95,9 @@ async def test_no_thumbnails(self, mock_resp): """Tests that thumbnail is 'None' if none found.""" mock_resp.return_value = "foobar" self.camera.last_record = ["1"] - config = CONFIG - config.update({ + config = CONFIG | { "thumbnail": "", - }) + } self.camera.sync.homescreen = {"devices": []} self.assertEqual(self.camera.temperature_calibrated, None) @@ -125,10 +124,9 @@ async def test_no_thumbnails(self, mock_resp): async def test_no_video_clips(self, mock_resp): """Tests that we still proceed with camera setup with no videos.""" mock_resp.return_value = "foobar" - config = CONFIG - config.update({ + config = CONFIG | { "thumbnail": "/foobar", - }) + } mock_resp.return_value = mresp.MockResponse({"test": 200}, 200, raw_data="") self.camera.sync.homescreen = {"devices": []} await self.camera.update(config, force_cache=True, expire_clips=False) @@ -141,17 +139,13 @@ async def test_recent_video_clips(self, mock_resp): Tests that the last records in the sync module are added to the camera recent clips list. """ - config = CONFIG - config.update({ - "thumbnail": "/thumb", - }) self.camera.sync.last_records["foobar"] = [] record2 = {"clip": "/clip2", "time": "2022-12-01 00:00:10+00:00"} self.camera.sync.last_records["foobar"].append(record2) record1 = {"clip": "/clip1", "time": "2022-12-01 00:00:00+00:00"} self.camera.sync.last_records["foobar"].append(record1) self.camera.sync.motion["foobar"] = True - await self.camera.update_images(config, expire_clips=False) + await self.camera.update_images(CONFIG, expire_clips=False) record1["clip"] = self.blink.urls.base_url + "/clip1" record2["clip"] = self.blink.urls.base_url + "/clip2" self.assertEqual(self.camera.recent_clips[0], record1) @@ -365,11 +359,10 @@ async def test_save_recent_clips_exception(self, mock_clip, mock_open, mock_resp async def test_missing_keys(self, mock_resp): """Tests missing signal keys.""" - config = CONFIG - config.update({ + config = CONFIG | { "signals": {"junk": 1}, "thumbnail": "", - }) + } self.camera.sync.homescreen = {"devices": []} mock_resp.side_effect = [ {"temp": 71}, From e8bdae6bc9796a697d2513a596509f188c5e61a3 Mon Sep 17 00:00:00 2001 From: mkmer Date: Tue, 2 Jan 2024 14:54:38 +0000 Subject: [PATCH 19/50] More clean up on common config --- tests/test_camera_functions.py | 2 +- tests/test_cameras.py | 61 +++++++++------------------------- 2 files changed, 16 insertions(+), 47 deletions(-) diff --git a/tests/test_camera_functions.py b/tests/test_camera_functions.py index ac2e5f8f..2d815d41 100644 --- a/tests/test_camera_functions.py +++ b/tests/test_camera_functions.py @@ -21,13 +21,13 @@ "network_id": 5678, "serial": "12345678", "enabled": False, - "battery_level": 5, "battery_state": "ok", "temperature": 68, "signals": {"lfr": 5, "wifi": 4, "battery": 3}, "thumbnail": "/thumb", } + @mock.patch("blinkpy.auth.Auth.query") class TestBlinkCameraSetup(IsolatedAsyncioTestCase): """Test the Blink class in blinkpy.""" diff --git a/tests/test_cameras.py b/tests/test_cameras.py index 410569ea..a405d6fd 100644 --- a/tests/test_cameras.py +++ b/tests/test_cameras.py @@ -14,15 +14,17 @@ from blinkpy.camera import BlinkCamera, BlinkCameraMini, BlinkDoorbell import tests.mock_responses as mresp -CAMERA_CFG = { - "camera": [ - { - "battery_level": 5, - "motion_alert": True, - "wifi_strength": -30, - "temperature": 68, - } - ] +CONFIG = { + "name": "new", + "id": 1234, + "network_id": 5678, + "serial": "12345678", + "enabled": False, + "battery_state": "ok", + "temperature": 68, + "thumbnail": 1357924680, + "signals": {"lfr": 5, "wifi": 4, "battery": 3}, + "type": "test", } @@ -128,41 +130,18 @@ async def test_camera_stream(self, mock_resp): async def test_different_thumb_api(self, mock_resp): """Test that the correct url is created with new api.""" thumb_endpoint = "https://rest-test.immedia-semi.com/api/v3/media/accounts/9999/networks/5678/test/1234/thumbnail/thumbnail.jpg?ts=1357924680&ext=" - config = { - "name": "new", - "id": 1234, - "network_id": 5678, - "serial": "12345678", - "enabled": False, - "battery_level": 5, - "battery_state": "ok", - "temperature": 68, - "wifi_strength": 4, - "thumbnail": 1357924680, - "type": "test", - } mock_resp.side_effect = [ {"temp": 71}, mresp.MockResponse({"test": 200}, 200, raw_data="test"), ] self.camera.sync.blink.account_id = 9999 - await self.camera.update(config, expire_clips=False) + await self.camera.update(CONFIG, expire_clips=False) self.assertEqual(self.camera.thumbnail, thumb_endpoint) async def test_thumb_return_none(self, mock_resp): """Test that a 'None" thumbnail is doesn't break system.""" - config = { - "name": "new", - "id": 1234, - "network_id": 5678, - "serial": "12345678", - "enabled": False, - "battery_level": 5, - "battery_state": "ok", - "temperature": 68, - "wifi_strength": 4, - "thumbnail": None, - "type": "test", + config = CONFIG | { + "thumbnail": None, } mock_resp.side_effect = [ {"temp": 71}, @@ -177,18 +156,8 @@ async def test_new_thumb_url_returned(self, mock_resp): "/api/v3/media/accounts/9999/networks/5678/" "test/1234/thumbnail/thumbnail.jpg?ts=1357924680&ext=" ) - config = { - "name": "new", - "id": 1234, - "network_id": 5678, - "serial": "12345678", - "enabled": False, - "battery_level": 5, - "battery_state": "ok", - "temperature": 68, - "wifi_strength": 4, + config = CONFIG | { "thumbnail": thumb_return, - "type": "test", } mock_resp.side_effect = [ {"temp": 71}, From 3edbb4e05bd06801a202787ea5dce89a87ce4001 Mon Sep 17 00:00:00 2001 From: mkmer Date: Tue, 2 Jan 2024 16:35:27 +0000 Subject: [PATCH 20/50] Lint :( --- tests/test_cameras.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_cameras.py b/tests/test_cameras.py index a405d6fd..0709f61f 100644 --- a/tests/test_cameras.py +++ b/tests/test_cameras.py @@ -141,7 +141,7 @@ async def test_different_thumb_api(self, mock_resp): async def test_thumb_return_none(self, mock_resp): """Test that a 'None" thumbnail is doesn't break system.""" config = CONFIG | { - "thumbnail": None, + "thumbnail": None, } mock_resp.side_effect = [ {"temp": 71}, From d48b50728792f043a08d56d90b5cd79341197c56 Mon Sep 17 00:00:00 2001 From: mkmer Date: Tue, 2 Jan 2024 18:08:59 +0000 Subject: [PATCH 21/50] Py3.8 compatibility --- tests/test_camera_functions.py | 23 ++++++++++++++++------- tests/test_cameras.py | 14 ++++++++++---- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/tests/test_camera_functions.py b/tests/test_camera_functions.py index 2d815d41..96e4f69f 100644 --- a/tests/test_camera_functions.py +++ b/tests/test_camera_functions.py @@ -95,8 +95,11 @@ async def test_no_thumbnails(self, mock_resp): """Tests that thumbnail is 'None' if none found.""" mock_resp.return_value = "foobar" self.camera.last_record = ["1"] - config = CONFIG | { - "thumbnail": "", + config = { + **CONFIG, + **{ + "thumbnail": "", + }, } self.camera.sync.homescreen = {"devices": []} @@ -124,8 +127,11 @@ async def test_no_thumbnails(self, mock_resp): async def test_no_video_clips(self, mock_resp): """Tests that we still proceed with camera setup with no videos.""" mock_resp.return_value = "foobar" - config = CONFIG | { - "thumbnail": "/foobar", + config = { + **CONFIG, + **{ + "thumbnail": "/foobar", + }, } mock_resp.return_value = mresp.MockResponse({"test": 200}, 200, raw_data="") self.camera.sync.homescreen = {"devices": []} @@ -359,9 +365,12 @@ async def test_save_recent_clips_exception(self, mock_clip, mock_open, mock_resp async def test_missing_keys(self, mock_resp): """Tests missing signal keys.""" - config = CONFIG | { - "signals": {"junk": 1}, - "thumbnail": "", + config = { + **CONFIG, + **{ + "signals": {"junk": 1}, + "thumbnail": "", + }, } self.camera.sync.homescreen = {"devices": []} mock_resp.side_effect = [ diff --git a/tests/test_cameras.py b/tests/test_cameras.py index 0709f61f..e104d7cd 100644 --- a/tests/test_cameras.py +++ b/tests/test_cameras.py @@ -140,8 +140,11 @@ async def test_different_thumb_api(self, mock_resp): async def test_thumb_return_none(self, mock_resp): """Test that a 'None" thumbnail is doesn't break system.""" - config = CONFIG | { - "thumbnail": None, + config = { + **CONFIG, + **{ + "thumbnail": None, + }, } mock_resp.side_effect = [ {"temp": 71}, @@ -156,8 +159,11 @@ async def test_new_thumb_url_returned(self, mock_resp): "/api/v3/media/accounts/9999/networks/5678/" "test/1234/thumbnail/thumbnail.jpg?ts=1357924680&ext=" ) - config = CONFIG | { - "thumbnail": thumb_return, + config = { + **CONFIG, + **{ + "thumbnail": thumb_return, + }, } mock_resp.side_effect = [ {"temp": 71}, From 209f347c3ed141ad057e9f3a52f72fb750740889 Mon Sep 17 00:00:00 2001 From: Kevin Fronczak Date: Tue, 2 Jan 2024 15:01:48 -0500 Subject: [PATCH 22/50] Remove 3.8, Add 3.12 --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 4b8812e3..d424c132 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -14,7 +14,7 @@ jobs: matrix: platform: - ubuntu-latest - python-version: ['3.8', '3.9', '3.10', '3.11'] + python-version: ['3.9', '3.10', '3.11', '3.12'] steps: - uses: actions/checkout@v3 From 982c1f55eb8717182d603859c35004a4d6dc5c40 Mon Sep 17 00:00:00 2001 From: Kevin Fronczak Date: Tue, 2 Jan 2024 15:02:55 -0500 Subject: [PATCH 23/50] Change to 3.11 --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 517d64fa..3c35998c 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -17,7 +17,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v4 with: - python-version: '3.9' + python-version: '3.11' - name: Install dependencies run: | python -m pip install --upgrade pip From 46eaad923c2d93f8282b97af6ae70579d508e002 Mon Sep 17 00:00:00 2001 From: Kevin Fronczak Date: Tue, 2 Jan 2024 15:03:11 -0500 Subject: [PATCH 24/50] Change to 3.11 --- .github/workflows/lint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 58510477..7a40cc7e 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [3.9] + python-version: [3.11] steps: - uses: actions/checkout@v2 From 6de795d4cb157727b2a1007612a82e241c6e703b Mon Sep 17 00:00:00 2001 From: Kevin Fronczak Date: Tue, 2 Jan 2024 15:03:56 -0500 Subject: [PATCH 25/50] Update to 3.11 --- .github/workflows/coverage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 5b036714..659b56fb 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -14,7 +14,7 @@ jobs: matrix: platform: - ubuntu-latest - python-version: ['3.9'] + python-version: ['3.11'] steps: - uses: actions/checkout@v3 From 285d00dfd392553d1f548a8ba03d68f467ee5549 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 20:16:33 +0000 Subject: [PATCH 26/50] Bump pytest from 7.4.3 to 7.4.4 Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.4.3 to 7.4.4. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/7.4.3...7.4.4) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_test.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_test.txt b/requirements_test.txt index b2fac096..fa528dc7 100644 --- a/requirements_test.txt +++ b/requirements_test.txt @@ -2,7 +2,7 @@ ruff==0.1.9 black==23.12.1 build==1.0.3 coverage==7.4.0 -pytest==7.4.3 +pytest==7.4.4 pytest-cov==4.1.0 pytest-sugar==0.9.7 pytest-timeout==2.2.0 From d53580a7aaebe2a7254c7217495eabfe229f3408 Mon Sep 17 00:00:00 2001 From: Kevin Fronczak Date: Tue, 2 Jan 2024 15:17:07 -0500 Subject: [PATCH 27/50] Deprecate py38 --- pyproject.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 8800fbe5..e1266b2e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,13 +15,13 @@ classifiers = [ "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Topic :: Home Automation", ] -requires-python = ">=3.8.0" +requires-python = ">=3.9.0" dynamic = ["dependencies"] [tool.setuptools.dynamic] @@ -85,7 +85,7 @@ ignore = [ line-length = 88 -target-version = "py39" +target-version = "py311" [tool.ruff.per-file-ignores] From 4cc7f748109031c269b822634f34e50a9bb8817c Mon Sep 17 00:00:00 2001 From: Kevin Fronczak Date: Tue, 2 Jan 2024 16:53:02 -0500 Subject: [PATCH 28/50] Lint fixes --- blinkpy/camera.py | 4 +--- blinkpy/sync_module.py | 2 +- tox.ini | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/blinkpy/camera.py b/blinkpy/camera.py index 72ddd11e..d8bf1d3a 100644 --- a/blinkpy/camera.py +++ b/blinkpy/camera.py @@ -431,9 +431,7 @@ async def save_recent_clips( num_saved = 0 for clip in recent: clip_time = datetime.datetime.fromisoformat(clip["time"]) - clip_time_local = clip_time.replace( - tzinfo=datetime.timezone.utc - ).astimezone(tz=None) + clip_time_local = clip_time.replace(tzinfo=datetime.UTC).astimezone(tz=None) created_at = clip_time_local.strftime("%Y%m%d_%H%M%S") clip_addr = clip["clip"] diff --git a/blinkpy/sync_module.py b/blinkpy/sync_module.py index 01af15c8..10970efa 100644 --- a/blinkpy/sync_module.py +++ b/blinkpy/sync_module.py @@ -351,7 +351,7 @@ async def check_new_videos(self): last_manifest_read = self._local_storage["last_manifest_read"] last_read_local = ( datetime.datetime.fromisoformat(last_manifest_read) - .replace(tzinfo=datetime.timezone.utc) + .replace(tzinfo=datetime.UTC) .astimezone(tz=None) ) last_clip_time = None diff --git a/tox.ini b/tox.ini index 0adeb49b..6dcfbb95 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = build, py38, py39, py310, py311, lint +envlist = build, py39, py310, py311, py312, lint skip_missing_interpreters = True skipsdist = True From afdd1a8cea5b0046ebb2fc021dec13685009f1b0 Mon Sep 17 00:00:00 2001 From: Kevin Fronczak Date: Tue, 2 Jan 2024 17:08:09 -0500 Subject: [PATCH 29/50] Remove UP017 from check. --- blinkpy/camera.py | 4 +++- blinkpy/sync_module.py | 2 +- pyproject.toml | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/blinkpy/camera.py b/blinkpy/camera.py index d8bf1d3a..72ddd11e 100644 --- a/blinkpy/camera.py +++ b/blinkpy/camera.py @@ -431,7 +431,9 @@ async def save_recent_clips( num_saved = 0 for clip in recent: clip_time = datetime.datetime.fromisoformat(clip["time"]) - clip_time_local = clip_time.replace(tzinfo=datetime.UTC).astimezone(tz=None) + clip_time_local = clip_time.replace( + tzinfo=datetime.timezone.utc + ).astimezone(tz=None) created_at = clip_time_local.strftime("%Y%m%d_%H%M%S") clip_addr = clip["clip"] diff --git a/blinkpy/sync_module.py b/blinkpy/sync_module.py index 10970efa..01af15c8 100644 --- a/blinkpy/sync_module.py +++ b/blinkpy/sync_module.py @@ -351,7 +351,7 @@ async def check_new_videos(self): last_manifest_read = self._local_storage["last_manifest_read"] last_read_local = ( datetime.datetime.fromisoformat(last_manifest_read) - .replace(tzinfo=datetime.UTC) + .replace(tzinfo=datetime.timezone.utc) .astimezone(tz=None) ) last_clip_time = None diff --git a/pyproject.toml b/pyproject.toml index e1266b2e..03fae4a1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -79,6 +79,7 @@ ignore = [ "UP006", # keep type annotation style as is "UP007", # keep type annotation style as is "UP015", # Unnecessary open mode parameters + "UP017", # UTC stuff # Ignored due to performance: https://github.com/charliermarsh/ruff/issues/2923 "UP038", # Use `X | Y` in `isinstance` call instead of `(X, Y)` ] From 0f551419089aa86d24b4fb2611b1962a4c5bef9c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Jan 2024 18:55:50 +0000 Subject: [PATCH 30/50] Bump ruff from 0.1.9 to 0.1.11 Bumps [ruff](https://github.com/astral-sh/ruff) from 0.1.9 to 0.1.11. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/v0.1.9...v0.1.11) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements_test.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_test.txt b/requirements_test.txt index fa528dc7..3ec2cc31 100644 --- a/requirements_test.txt +++ b/requirements_test.txt @@ -1,4 +1,4 @@ -ruff==0.1.9 +ruff==0.1.11 black==23.12.1 build==1.0.3 coverage==7.4.0 From 049d151a91079e7fc38cb62b06668f153033ebed Mon Sep 17 00:00:00 2001 From: mkmer Date: Thu, 4 Jan 2024 19:44:31 +0000 Subject: [PATCH 31/50] Add firmware version --- blinkpy/camera.py | 3 +++ blinkpy/sync_module.py | 3 +++ 2 files changed, 6 insertions(+) diff --git a/blinkpy/camera.py b/blinkpy/camera.py index 72ddd11e..ba0a37b1 100644 --- a/blinkpy/camera.py +++ b/blinkpy/camera.py @@ -27,6 +27,7 @@ def __init__(self, sync): self.network_id = None self.thumbnail = None self.serial = None + self.version = None self.motion_enabled = None self.battery_level = None self.clip = None @@ -52,6 +53,7 @@ def attributes(self): "name": self.name, "camera_id": self.camera_id, "serial": self.serial, + "version": self.version, "temperature": self.temperature, "temperature_c": self.temperature_c, "temperature_calibrated": self.temperature_calibrated, @@ -232,6 +234,7 @@ def extract_config_info(self, config): self.camera_id = str(config.get("id", "unknown")) self.network_id = str(config.get("network_id", "unknown")) self.serial = config.get("serial") + self.version = config.get("fw_version") self.motion_enabled = config.get("enabled", "unknown") self.battery_state = config.get("battery_state") or config.get("battery") self.temperature = config.get("temperature") diff --git a/blinkpy/sync_module.py b/blinkpy/sync_module.py index 01af15c8..44f96a60 100644 --- a/blinkpy/sync_module.py +++ b/blinkpy/sync_module.py @@ -34,6 +34,7 @@ def __init__(self, blink, network_name, network_id, camera_list): self.region_id = blink.auth.region_id self.name = network_name self.serial = None + self.version = None self.status = "offline" self.sync_id = None self.host = None @@ -72,6 +73,7 @@ def attributes(self): "id": self.sync_id, "network_id": self.network_id, "serial": self.serial, + "version": self.version, "status": self.status, "region_id": self.region_id, "local_storage": self.local_storage, @@ -153,6 +155,7 @@ async def sync_initialize(self): "Could not retrieve sync module information with response: %s", response ) return False + self.version = self.summary.get("fw_version") return response async def _init_local_storage(self, sync_id): From 64af647d5a5f41bc2aa685ef071c1fa9332e2e26 Mon Sep 17 00:00:00 2001 From: mkmer Date: Thu, 4 Jan 2024 20:08:51 +0000 Subject: [PATCH 32/50] Catch content type error in 2FA --- blinkpy/auth.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/blinkpy/auth.py b/blinkpy/auth.py index 09eab0a0..c5cfdd71 100644 --- a/blinkpy/auth.py +++ b/blinkpy/auth.py @@ -1,6 +1,6 @@ """Login handler for blink.""" import logging -from aiohttp import ClientSession, ClientConnectionError +from aiohttp import ClientSession, ClientConnectionError, ContentTypeError from blinkpy import api from blinkpy.helpers import util from blinkpy.helpers.constants import ( @@ -220,7 +220,7 @@ async def send_auth_key(self, blink, key): if not blink.available: _LOGGER.error("%s", json_resp["message"]) return False - except (KeyError, TypeError): + except (KeyError, TypeError, ContentTypeError): _LOGGER.error("Did not receive valid response from server.") return False return True From a4c57f5e423a16975c20e50343e0ff3d71b225a7 Mon Sep 17 00:00:00 2001 From: mkmer Date: Fri, 5 Jan 2024 15:36:59 +0000 Subject: [PATCH 33/50] Additional logging Add file update --- blinkpy/auth.py | 12 ++++++++---- blinksync/blinksync.py | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/blinkpy/auth.py b/blinkpy/auth.py index c5cfdd71..7c18d62f 100644 --- a/blinkpy/auth.py +++ b/blinkpy/auth.py @@ -172,10 +172,11 @@ async def query( url=url, data=data, headers=headers, timeout=timeout ) return await self.validate_response(response, json_resp) - except (ClientConnectionError, TimeoutError): + except (ClientConnectionError, TimeoutError) as er: _LOGGER.error( - "Connection error. Endpoint %s possibly down or throttled.", + "Connection error. Endpoint %s possibly down or throttled. Error: %s", url, + er, ) except BlinkBadResponse: code = None @@ -220,8 +221,11 @@ async def send_auth_key(self, blink, key): if not blink.available: _LOGGER.error("%s", json_resp["message"]) return False - except (KeyError, TypeError, ContentTypeError): - _LOGGER.error("Did not receive valid response from server.") + except (KeyError, TypeError, ContentTypeError) as er: + _LOGGER.error( + "Did not receive valid response from server. Error: %s", + er, + ) return False return True diff --git a/blinksync/blinksync.py b/blinksync/blinksync.py index 346c649f..8f21e236 100644 --- a/blinksync/blinksync.py +++ b/blinksync/blinksync.py @@ -100,6 +100,7 @@ async def main(): working = None frame = None await session.close() + await blink.save(f"{path}/blink.json") # Run the program From 3bde710fc3556a41572dec1989c91f02c632b95a Mon Sep 17 00:00:00 2001 From: Kevin Fronczak Date: Fri, 5 Jan 2024 12:06:21 -0500 Subject: [PATCH 34/50] Update README.rst --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index a2767e39..b3058a90 100644 --- a/README.rst +++ b/README.rst @@ -1,6 +1,6 @@ blinkpy |Build Status| |Coverage Status| |PyPi Version| |Codestyle| ============================================================================================= -A Python library for the Blink Camera system (Python 3.8+) +A Python library for the Blink Camera system (Python 3.9+) Like the library? Consider buying me a cup of coffee! From 0309e7b2ea58a0ae56520df00d6edff8ea3314b5 Mon Sep 17 00:00:00 2001 From: mkmer Date: Fri, 5 Jan 2024 18:44:10 +0000 Subject: [PATCH 35/50] Log text response --- blinkpy/auth.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/blinkpy/auth.py b/blinkpy/auth.py index 7c18d62f..bb559907 100644 --- a/blinkpy/auth.py +++ b/blinkpy/auth.py @@ -1,6 +1,11 @@ """Login handler for blink.""" import logging -from aiohttp import ClientSession, ClientConnectionError, ContentTypeError +from aiohttp import ( + ClientSession, + ClientConnectionError, + ContentTypeError, + ClientResponse, +) from blinkpy import api from blinkpy.helpers import util from blinkpy.helpers.constants import ( @@ -123,7 +128,7 @@ async def startup(self): if None in self.login_attributes.values(): await self.refresh_token() - async def validate_response(self, response, json_resp): + async def validate_response(self, response: ClientResponse, json_resp): """Check for valid response.""" if not json_resp: self.is_errored = False @@ -137,6 +142,9 @@ async def validate_response(self, response, json_resp): json_data = await response.json() except (AttributeError, ValueError) as error: raise BlinkBadResponse from error + except ContentTypeError as error: + _LOGGER.warning("Got text for JSON response: %s", await response.text()) + raise BlinkBadResponse from error self.is_errored = False return json_data From f532663c03f257abc61e5dc44252e6dccd60e81b Mon Sep 17 00:00:00 2001 From: mkmer Date: Fri, 5 Jan 2024 20:00:03 +0000 Subject: [PATCH 36/50] Add tests --- tests/mock_responses.py | 13 ++++++++++++- tests/test_auth.py | 6 +++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/tests/mock_responses.py b/tests/mock_responses.py index 2e249d21..43a6d608 100644 --- a/tests/mock_responses.py +++ b/tests/mock_responses.py @@ -5,7 +5,14 @@ class MockResponse: """Class for mock request response.""" - def __init__(self, json_data, status_code, headers={}, raw_data=None): + def __init__( + self, + json_data, + status_code, + headers={}, + raw_data=None, + raise_error=None, + ): """Initialize mock get response.""" self.json_data = json_data self.status = status_code @@ -13,9 +20,13 @@ def __init__(self, json_data, status_code, headers={}, raw_data=None): self.reason = "foobar" self.headers = headers self.read = mock.AsyncMock(return_value=self.raw_data) + self.raise_error = raise_error + self.text = mock.AsyncMock(return_vlaue="some text") async def json(self): """Return json data from get_request.""" + if self.raise_error: + raise self.raise_error("I'm broken", "") return self.json_data def get(self, name): diff --git a/tests/test_auth.py b/tests/test_auth.py index c881fa8e..31a9bda5 100644 --- a/tests/test_auth.py +++ b/tests/test_auth.py @@ -2,7 +2,7 @@ from unittest import mock from unittest import IsolatedAsyncioTestCase -from aiohttp import ClientConnectionError +from aiohttp import ClientConnectionError, ContentTypeError from blinkpy.auth import ( Auth, TokenRefreshFailed, @@ -100,6 +100,10 @@ async def test_bad_response_code(self): with self.assertRaises(UnauthorizedError): await self.auth.validate_response(fake_resp, True) self.assertTrue(self.auth.is_errored) + fake_resp = mresp.MockResponse({"code": 101}, 406, raise_error=ContentTypeError) + with self.assertRaises(BlinkBadResponse): + await self.auth.validate_response(fake_resp, True) + self.assertTrue(self.auth.is_errored) async def test_good_response_code(self): """Check good response code from server.""" From da1d876d0d47a0dccb91b4271932f161a46203bc Mon Sep 17 00:00:00 2001 From: mkmer Date: Fri, 5 Jan 2024 20:24:31 +0000 Subject: [PATCH 37/50] Fix log issue --- tests/test_blink_functions.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_blink_functions.py b/tests/test_blink_functions.py index bb3326ab..f4e58138 100644 --- a/tests/test_blink_functions.py +++ b/tests/test_blink_functions.py @@ -220,6 +220,8 @@ async def test_download_videos_file_exists(self, mock_isfile, mock_req): ] with self.assertLogs(level="DEBUG") as dl_log: await self.blink.download_videos("/tmp", camera="foo", stop=2, delay=0) + if len(dl_log.output) > 3: + dl_log.output.pop([0]) self.assertListEqual(dl_log.output, expected_log) @mock.patch("blinkpy.blinkpy.api.request_videos") From cbefce7b95765cb66778bd6cdc98a1b38b2a2865 Mon Sep 17 00:00:00 2001 From: mkmer Date: Fri, 5 Jan 2024 21:02:20 +0000 Subject: [PATCH 38/50] fix pop --- tests/test_blink_functions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_blink_functions.py b/tests/test_blink_functions.py index f4e58138..f9cef91b 100644 --- a/tests/test_blink_functions.py +++ b/tests/test_blink_functions.py @@ -221,7 +221,7 @@ async def test_download_videos_file_exists(self, mock_isfile, mock_req): with self.assertLogs(level="DEBUG") as dl_log: await self.blink.download_videos("/tmp", camera="foo", stop=2, delay=0) if len(dl_log.output) > 3: - dl_log.output.pop([0]) + dl_log.output.pop(0) self.assertListEqual(dl_log.output, expected_log) @mock.patch("blinkpy.blinkpy.api.request_videos") From cb7dbde5b0abbd9fd1e3c1951e37a670b33d507e Mon Sep 17 00:00:00 2001 From: mkmer Date: Fri, 5 Jan 2024 21:23:17 +0000 Subject: [PATCH 39/50] reformat log test --- tests/test_blink_functions.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/test_blink_functions.py b/tests/test_blink_functions.py index f9cef91b..7e0c2b17 100644 --- a/tests/test_blink_functions.py +++ b/tests/test_blink_functions.py @@ -220,9 +220,7 @@ async def test_download_videos_file_exists(self, mock_isfile, mock_req): ] with self.assertLogs(level="DEBUG") as dl_log: await self.blink.download_videos("/tmp", camera="foo", stop=2, delay=0) - if len(dl_log.output) > 3: - dl_log.output.pop(0) - self.assertListEqual(dl_log.output, expected_log) + self.assertListEqual(dl_log.output, expected_log) @mock.patch("blinkpy.blinkpy.api.request_videos") async def test_parse_camera_not_in_list(self, mock_req): From bd0d5120317d9856000f72f24acf25a6332b8329 Mon Sep 17 00:00:00 2001 From: mkmer Date: Fri, 5 Jan 2024 21:35:49 +0000 Subject: [PATCH 40/50] Refactor test again --- tests/test_blink_functions.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/test_blink_functions.py b/tests/test_blink_functions.py index 7e0c2b17..95ee5ffa 100644 --- a/tests/test_blink_functions.py +++ b/tests/test_blink_functions.py @@ -220,7 +220,9 @@ async def test_download_videos_file_exists(self, mock_isfile, mock_req): ] with self.assertLogs(level="DEBUG") as dl_log: await self.blink.download_videos("/tmp", camera="foo", stop=2, delay=0) - self.assertListEqual(dl_log.output, expected_log) + assert expected_log[0]in dl_log.output + assert expected_log[1]in dl_log.output + assert expected_log[2]in dl_log.output @mock.patch("blinkpy.blinkpy.api.request_videos") async def test_parse_camera_not_in_list(self, mock_req): From f3a59fceba8908779178e9e9d260e8826e8f5ea2 Mon Sep 17 00:00:00 2001 From: mkmer Date: Fri, 5 Jan 2024 21:36:18 +0000 Subject: [PATCH 41/50] lint --- tests/test_blink_functions.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_blink_functions.py b/tests/test_blink_functions.py index 95ee5ffa..afd62a2f 100644 --- a/tests/test_blink_functions.py +++ b/tests/test_blink_functions.py @@ -220,9 +220,9 @@ async def test_download_videos_file_exists(self, mock_isfile, mock_req): ] with self.assertLogs(level="DEBUG") as dl_log: await self.blink.download_videos("/tmp", camera="foo", stop=2, delay=0) - assert expected_log[0]in dl_log.output - assert expected_log[1]in dl_log.output - assert expected_log[2]in dl_log.output + assert expected_log[0] in dl_log.output + assert expected_log[1] in dl_log.output + assert expected_log[2] in dl_log.output @mock.patch("blinkpy.blinkpy.api.request_videos") async def test_parse_camera_not_in_list(self, mock_req): From 3f0659e016e1bd42d1f86ff7fa62f6d58f2966e4 Mon Sep 17 00:00:00 2001 From: mkmer Date: Sat, 6 Jan 2024 17:46:27 +0000 Subject: [PATCH 42/50] Handle Emtpy put response --- blinkpy/api.py | 7 +++++-- tests/test_api.py | 3 +++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/blinkpy/api.py b/blinkpy/api.py index a10c4497..82485dad 100644 --- a/blinkpy/api.py +++ b/blinkpy/api.py @@ -503,8 +503,11 @@ async def http_post(blink, url, is_retry=False, data=None, json=True, timeout=TI async def wait_for_command(blink, json_data: dict) -> bool: """Wait for command to complete.""" _LOGGER.debug("Command Wait %s", json_data) - network_id = json_data.get("network_id") - command_id = json_data.get("id") + try: + network_id = json_data.get("network_id") + command_id = json_data.get("id") + except AttributeError: + return False if command_id and network_id: for _ in range(0, MAX_RETRY): _LOGGER.debug("Making GET request waiting for command") diff --git a/tests/test_api.py b/tests/test_api.py index 1c6e02d7..f5159d68 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -183,3 +183,6 @@ async def test_wait_for_command(self, mock_resp): mock_resp.side_effect = (COMMAND_COMPLETE_BAD, {}) response = await api.wait_for_command(self.blink, COMMAND_RESPONSE) self.assertFalse(response) + + response = await api.wait_for_command(self.blink, {}) + self.assertFalse(response) From c78f42b201c23a1b1e2bcdfdb293d0e756ceb1ac Mon Sep 17 00:00:00 2001 From: mkmer Date: Sat, 6 Jan 2024 18:01:03 +0000 Subject: [PATCH 43/50] Fix test --- tests/test_api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_api.py b/tests/test_api.py index f5159d68..86edb1fd 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -184,5 +184,5 @@ async def test_wait_for_command(self, mock_resp): response = await api.wait_for_command(self.blink, COMMAND_RESPONSE) self.assertFalse(response) - response = await api.wait_for_command(self.blink, {}) + response = await api.wait_for_command(self.blink, None) self.assertFalse(response) From 8a3133b852de2df3be1ae285ef73332ba24ba4be Mon Sep 17 00:00:00 2001 From: mkmer Date: Sat, 6 Jan 2024 21:59:30 +0000 Subject: [PATCH 44/50] Move to android as user agent? --- blinkpy/helpers/constants.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/blinkpy/helpers/constants.py b/blinkpy/helpers/constants.py index b208f56c..3207ec16 100644 --- a/blinkpy/helpers/constants.py +++ b/blinkpy/helpers/constants.py @@ -20,11 +20,7 @@ """ OTHER """ -DEFAULT_USER_AGENT = ( - "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) " - "AppleWebKit/537.36 (KHTML, like Gecko) " - "Chrome/71.0.3578.98 Safari/537.36" -) +DEFAULT_USER_AGENT = ("27.0ANDROID_28373244") DEVICE_ID = "Blinkpy" TIMESTAMP_FORMAT = "%Y-%m-%dT%H:%M:%S%z" DEFAULT_MOTION_INTERVAL = 1 From b79f8ca4833011658ad58eada38e54a189dd4af1 Mon Sep 17 00:00:00 2001 From: mkmer Date: Sat, 6 Jan 2024 22:16:09 +0000 Subject: [PATCH 45/50] lint fix --- blinkpy/helpers/constants.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blinkpy/helpers/constants.py b/blinkpy/helpers/constants.py index 3207ec16..ccf2ea81 100644 --- a/blinkpy/helpers/constants.py +++ b/blinkpy/helpers/constants.py @@ -20,7 +20,7 @@ """ OTHER """ -DEFAULT_USER_AGENT = ("27.0ANDROID_28373244") +DEFAULT_USER_AGENT = "27.0ANDROID_28373244" DEVICE_ID = "Blinkpy" TIMESTAMP_FORMAT = "%Y-%m-%dT%H:%M:%S%z" DEFAULT_MOTION_INTERVAL = 1 From 453ba62bcb545ac5cf5a7bd895d31ad96c44e89c Mon Sep 17 00:00:00 2001 From: Gingermonkey Date: Sun, 7 Jan 2024 12:45:57 +0100 Subject: [PATCH 46/50] fix/ha integration status becomes unvailable when requesting api --- blinkpy/helpers/constants.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/blinkpy/helpers/constants.py b/blinkpy/helpers/constants.py index b208f56c..ee8568ba 100644 --- a/blinkpy/helpers/constants.py +++ b/blinkpy/helpers/constants.py @@ -21,9 +21,9 @@ OTHER """ DEFAULT_USER_AGENT = ( - "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) " + "Mozilla/5.0 (Linux; Android 14) " "AppleWebKit/537.36 (KHTML, like Gecko) " - "Chrome/71.0.3578.98 Safari/537.36" + "Chrome/120.0.6099.193 Mobile Safari/537.36" ) DEVICE_ID = "Blinkpy" TIMESTAMP_FORMAT = "%Y-%m-%dT%H:%M:%S%z" From e1f2f9988160045a77b24d9522a1aba3e5871fba Mon Sep 17 00:00:00 2001 From: Kevin Fronczak Date: Sun, 7 Jan 2024 11:28:27 -0500 Subject: [PATCH 47/50] Update dev install instructions --- README.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.rst b/README.rst index b3058a90..269ee368 100644 --- a/README.rst +++ b/README.rst @@ -32,9 +32,7 @@ To install the current development version, perform the following steps. Note t $ cd ~ $ git clone https://github.com/fronzbot/blinkpy.git $ cd blinkpy - $ rm -rf build dist - $ python3 setup.py bdist_wheel - $ pip3 install --upgrade dist/*.whl + $ pip install . If you'd like to contribute to this library, please read the `contributing instructions `__. From 5d379bfb1516e65c66ccb3e82729fa51c9bba262 Mon Sep 17 00:00:00 2001 From: Kevin Fronczak Date: Sun, 7 Jan 2024 11:36:37 -0500 Subject: [PATCH 48/50] Update CHANGES.rst --- CHANGES.rst | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 403d98bf..cf43887d 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,13 +4,42 @@ Changelog A list of changes between each release +0.22.5 (2024-01-07) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Warning: This release removes support for Python 3.8 and adds Python 3.12 support. + +**Bugfixes** + +- Add new keys for wifi, lfr, and battery (`mkmer #835 `__) +- Battery level (`mkmer #837 `__) +- Address not awaited warning (`mkmer #838 `__) +- Catch ContentTypeError in 2FA (`mkmer #843 `__) +- Handle empty put response in wait_command (`mkmer #847 `__) +- Change default user agent to fix API calls (`gingerm0nkey #848 `__) +- Android for new user agent (`mkmer #850 `__) + +**Other changes** + +- Remove Py3.8, add 3.12 (`fronzbot #839 `__) +- Deprecate py38 (`fronzbot #840 `__) +- Add/extract firmware version (`mkmer #842 `__) +- Additional logging, fix blinksync json (`mkmer #844 `__) +- Log text response (`mkmer #845 `__) +- Add tests for logging (`mkmer #846 `__) +- Bump ruff to 0.1.11 +- Bump black to 23.12.1 +- Bump coverage to 7.4.0 +- Bump pytest to 7.4.4 + + 0.22.4 (2023-12-18) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ **Bugfixes** -- Allow kwargs to throttled functions, await sleep in throttle (`mkmer #823 `__) -- add missing entry in type_key_map (`@Rosi2143 `__) +- Allow kwargs to throttled functions, await sleep in throttle (`mkmer #823 `__) +- add missing entry in type_key_map (`@Rosi2143 #813 `__) ** Other Changes ** From 3b7b48f10353d98b89188f2934c9bf202fda7dac Mon Sep 17 00:00:00 2001 From: Kevin Fronczak Date: Sun, 7 Jan 2024 11:37:06 -0500 Subject: [PATCH 49/50] version bump 0.22.5 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 03fae4a1..0c703e76 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "blinkpy" -version = "0.23.0b3" +version = "0.22.5" license = {text = "MIT"} description = "A Blink camera Python Library." readme = "README.rst" From 30addb630f07cd9802bb2434ff80553e37bef926 Mon Sep 17 00:00:00 2001 From: mkmer Date: Sun, 7 Jan 2024 18:21:57 +0000 Subject: [PATCH 50/50] Bump actions to new versions --- .github/workflows/coverage.yml | 4 ++-- .github/workflows/lint.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 659b56fb..b1887704 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -17,7 +17,7 @@ jobs: python-version: ['3.11'] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v4 with: @@ -33,7 +33,7 @@ jobs: run: | tox -r -e cov - name: Codecov - uses: codecov/codecov-action@v1 + uses: codecov/codecov-action@v3 with: token: ${{ secrets.CODECOV_TOKEN }} flags: unittests diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 7a40cc7e..da2d3818 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -17,7 +17,7 @@ jobs: python-version: [3.11] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v4 with: