Skip to content

Commit ae0e26f

Browse files
authored
Merge pull request #912 from fronzbot/dev
0.22.7
2 parents f68e20b + 234e418 commit ae0e26f

22 files changed

+86
-56
lines changed

.github/workflows/coverage.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
steps:
2020
- uses: actions/checkout@v4
2121
- name: Set up Python ${{ matrix.python-version }}
22-
uses: actions/setup-python@v4
22+
uses: actions/setup-python@v5
2323
with:
2424
python-version: ${{ matrix.python-version }}
2525
- name: Install dependencies
@@ -33,9 +33,10 @@ jobs:
3333
run: |
3434
tox -r -e cov
3535
- name: Codecov
36-
uses: codecov/codecov-action@v3
36+
uses: codecov/codecov-action@v4
37+
env:
38+
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
3739
with:
38-
token: ${{ secrets.CODECOV_TOKEN }}
3940
flags: unittests
4041
file: ./coverage.xml
4142
name: blinkpy

CHANGES.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ Changelog
44

55
A list of changes between each release
66

7+
0.22.7 (2024-04-15)
8+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9+
10+
See release notes: (`0.22.7 <https://github.com/fronzbot/blinkpy/releases/tag/v0.22.7>`__)
11+
712

813
0.22.6 (2024-01-24)
914
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

CONTRIBUTING.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ You can then run all of the tests with the following command:
8585
8686
**Tips**
8787

88-
If you only want to see if you can pass the local tests, you can run ``tox -e py37`` (or whatever python version you have installed. Only ``py36``, ``py37``, and ``py38`` will be accepted). If you just want to check for style violations, you can run ``tox -e lint``. Regardless, when you submit a pull request, your code MUST pass both the unit tests, and the linters.
88+
If you only want to see if you can pass the local tests, you can run ``tox -e py39`` (or whatever python version you have installed. Only ``py39`` through ``py312`` will be accepted). If you just want to check for style violations, you can run ``tox -e lint``. Regardless, when you submit a pull request, your code MUST pass both the unit tests, and the linters.
8989

9090
If you need to change anything in ``requirements.txt`` for any reason, you'll want to regenerate the virtual envrionments used by ``tox`` by running with the ``-r`` flag: ``tox -r``
9191

@@ -104,7 +104,7 @@ If your code is taking a while to develop, you may be behind the ``dev`` branch,
104104
105105
If rebase detects conflicts, repeat the following process until all changes have been resolved:
106106

107-
1. ``git status`` shows you the filw with a conflict. You will need to edit that file and resolve the lines between ``<<<< | >>>>``.
107+
1. ``git status`` shows you the file with a conflict. You will need to edit that file and resolve the lines between ``<<<< | >>>>``.
108108
2. Add the modified file: ``git add <file>`` or ``git add .``.
109109
3. Continue rebase: ``git rebase --continue``.
110110
4. Repeat until all conflicts resolved.

blinkapp/blinkapp.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Script to run blinkpy as an blinkapp."""
2+
23
from os import environ
34
import asyncio
45
from datetime import datetime, timedelta

blinkpy/api.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -514,8 +514,9 @@ async def wait_for_command(blink, json_data: dict) -> bool:
514514
_LOGGER.debug("Making GET request waiting for command")
515515
status = await request_command_status(blink, network_id, command_id)
516516
_LOGGER.debug("command status %s", status)
517-
if status.get("status_code", 0) != 908:
518-
return False
519-
if status.get("complete"):
520-
return True
517+
if status:
518+
if status.get("status_code", 0) != 908:
519+
return False
520+
if status.get("complete"):
521+
return True
521522
await sleep(COMMAND_POLL_TIME)

blinkpy/auth.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Login handler for blink."""
2+
23
import logging
34
from aiohttp import (
45
ClientSession,

blinkpy/blinkpy.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717
import logging
1818
import datetime
1919
import aiofiles
20-
from aiofiles import ospath
21-
2220
from requests.structures import CaseInsensitiveDict
2321
from dateutil.parser import parse
2422
from slugify import slugify
@@ -414,7 +412,7 @@ async def _parse_downloaded_items(self, result, camera, path, delay, debug):
414412
filename = os.path.join(path, filename)
415413

416414
if not debug:
417-
if await ospath.isfile(filename):
415+
if await aiofiles.ospath.isfile(filename):
418416
_LOGGER.info("%s already exists, skipping...", filename)
419417
continue
420418

blinkpy/camera.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Defines Blink cameras."""
2+
23
import copy
34
import string
45
import os
@@ -30,6 +31,7 @@ def __init__(self, sync):
3031
self._version = None
3132
self.motion_enabled = None
3233
self.battery_level = None
34+
self._battery_voltage = None
3335
self.clip = None
3436
# A clip remains in the recent clips list until is has
3537
# been downloaded or has been expired.
@@ -59,6 +61,7 @@ def attributes(self):
5961
"temperature_calibrated": self.temperature_calibrated,
6062
"battery": self.battery,
6163
"battery_level": self.battery_level,
64+
"battery_voltage": self._battery_voltage,
6265
"thumbnail": self.thumbnail,
6366
"video": self.clip,
6467
"recent_clips": self.recent_clips,
@@ -78,6 +81,11 @@ def battery(self):
7881
"""Return battery as string."""
7982
return self.battery_state
8083

84+
@property
85+
def battery_voltage(self):
86+
"""Return battery voltage as a number in 100ths of volts, so 165 = 1.65v."""
87+
return self._battery_voltage
88+
8189
@property
8290
def temperature_c(self):
8391
"""Return temperature in celsius."""
@@ -246,14 +254,14 @@ def extract_config_info(self, config):
246254
self.serial = config.get("serial")
247255
self._version = config.get("fw_version")
248256
self.motion_enabled = config.get("enabled", "unknown")
257+
self._battery_voltage = config.get("battery_voltage", None)
249258
self.battery_state = config.get("battery_state") or config.get("battery")
259+
self.wifi_strength = config.get("wifi_strength")
250260
if signals := config.get("signals"):
251-
self.wifi_strength = signals.get("wifi")
252261
self.battery_level = signals.get("battery")
253262
self.sync_signal_strength = signals.get("lfr")
254263
self.temperature = signals.get("temp")
255264
else:
256-
self.wifi_strength = config.get("wifi_strength")
257265
self.temperature = config.get("temperature")
258266
self.product_type = config.get("type")
259267

blinkpy/helpers/util.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66
import time
77
import secrets
88
import re
9-
import aiofiles
109
from asyncio import sleep
1110
from calendar import timegm
1211
from functools import wraps
1312
from getpass import getpass
13+
import aiofiles
1414
import dateutil.parser
1515
from blinkpy.helpers import constants as const
1616

blinkpy/sync_module.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Defines a sync module for Blink."""
2+
23
import logging
34
import string
45
import datetime
@@ -49,10 +50,11 @@ def __init__(self, blink, network_name, network_id, camera_list):
4950
self.last_records = {}
5051
self.camera_list = camera_list
5152
self.available = False
53+
# type_key_map is only for the mini's and the doorbells.
54+
# Outdoor cameras have their own URL API which must be queried.
5255
self.type_key_map = {
5356
"mini": "owls",
5457
"doorbell": "doorbells",
55-
"outdoor": "cameras",
5658
}
5759
self._names_table = {}
5860
self._local_storage = {

codecov.yml

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
codecov:
22
branch: dev
3+
bot: codecov-io
4+
max_report_age: 24
5+
disable_default_path_fixes: no
6+
require_ci_to_pass: yes
7+
notify:
8+
wait_for_ci: yes
39
coverage:
10+
precision: 1
11+
round: down
12+
range: 85..100
413
status:
514
project:
615
default:
7-
target: 80%
8-
threshold: 2%
9-
patch:
10-
default:
11-
target: 60%
16+
target: auto
1217
threshold: 5%
13-
14-
comment: true
15-
require_ci_to_pass: yes
18+

pyproject.toml

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "blinkpy"
7-
version = "0.22.6"
7+
version = "0.22.7"
88
license = {text = "MIT"}
99
description = "A Blink camera Python Library."
1010
readme = "README.rst"
@@ -39,7 +39,7 @@ include-package-data = true
3939
include = ["blinkpy*"]
4040

4141
[tool.ruff]
42-
select = [
42+
lint.select = [
4343
"C", # complexity
4444
"D", # docstrings
4545
"E", # pydocstyle
@@ -54,11 +54,11 @@ select = [
5454
"Q000", # Double quotes found but single quotes preferred
5555
"SIM118", # Use {key} in {dict} instead of {key} in {dict}.keys()
5656
"TRY004", # Prefer TypeError exception for invalid type
57-
"TRY200", # Use raise from to specify exception cause
57+
"B904", # Use raise from to specify exception cause
5858
"UP", # pyupgrade
5959
"W", # pycodestyle
6060
]
61-
ignore = [
61+
lint.ignore = [
6262
"D202", # No blank lines allowed after function docstring
6363
"D203", # 1 blank line required before class docstring
6464
"D212", # Multi-line docstring summary should start at the first line
@@ -86,10 +86,9 @@ ignore = [
8686

8787
line-length = 88
8888

89-
target-version = "py311"
89+
target-version = "py312"
9090

91-
[tool.ruff.per-file-ignores]
91+
[tool.ruff.lint.per-file-ignores]
9292

93-
94-
[tool.ruff.mccabe]
95-
max-complexity = 25
93+
[tool.ruff.lint.mccabe]
94+
max-complexity = 25

requirements_test.txt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
ruff==0.1.14
2-
black==23.12.1
3-
build==1.0.3
4-
coverage==7.4.0
5-
pytest==7.4.4
6-
pytest-cov==4.1.0
7-
pytest-sugar==0.9.7
8-
pytest-timeout==2.2.0
1+
ruff==0.3.7
2+
black==24.3.0
3+
build==1.2.1
4+
coverage==7.4.4
5+
pytest==8.1.1
6+
pytest-cov==5.0.0
7+
pytest-sugar==1.0.0
8+
pytest-timeout==2.3.1
99
restructuredtext-lint==1.4.0
1010
pygments==2.17.2
1111
testtools>=2.4.0

tests/mock_responses.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Simple mock responses definitions."""
2+
23
from unittest import mock
34

45

tests/test_api.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -176,9 +176,9 @@ async def test_wait_for_command(self, mock_resp):
176176
response = await api.wait_for_command(self.blink, COMMAND_RESPONSE)
177177
assert response
178178

179-
mock_resp.side_effect = (COMMAND_NOT_COMPLETE, {})
180-
response = await api.wait_for_command(self.blink, COMMAND_RESPONSE)
181-
self.assertFalse(response)
179+
# mock_resp.side_effect = (COMMAND_NOT_COMPLETE, COMMAND_NOT_COMPLETE, None)
180+
# response = await api.wait_for_command(self.blink, COMMAND_RESPONSE)
181+
# self.assertFalse(response)
182182

183183
mock_resp.side_effect = (COMMAND_COMPLETE_BAD, {})
184184
response = await api.wait_for_command(self.blink, COMMAND_RESPONSE)

tests/test_blink_functions.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Tests camera and system functions."""
2+
23
from unittest import mock, IsolatedAsyncioTestCase
34
import time
45
import random

tests/test_blinkpy.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,12 @@ async def test_throttle(self, mock_time):
6969
self.assertEqual(self.blink.last_refresh, None)
7070
self.assertEqual(self.blink.check_if_ok_to_update(), True)
7171
self.assertEqual(self.blink.last_refresh, None)
72-
with mock.patch(
73-
"blinkpy.sync_module.BlinkSyncModule.refresh", return_value=True
74-
), mock.patch("blinkpy.blinkpy.Blink.get_homescreen", return_value=True):
72+
with (
73+
mock.patch(
74+
"blinkpy.sync_module.BlinkSyncModule.refresh", return_value=True
75+
),
76+
mock.patch("blinkpy.blinkpy.Blink.get_homescreen", return_value=True),
77+
):
7578
await self.blink.refresh(force=True)
7679

7780
self.assertEqual(self.blink.last_refresh, now)
@@ -81,12 +84,12 @@ async def test_throttle(self, mock_time):
8184
async def test_not_available_refresh(self):
8285
"""Check that setup_post_verify executes on refresh when not avialable."""
8386
self.blink.available = False
84-
with mock.patch(
85-
"blinkpy.sync_module.BlinkSyncModule.refresh", return_value=True
86-
), mock.patch(
87-
"blinkpy.blinkpy.Blink.get_homescreen", return_value=True
88-
), mock.patch(
89-
"blinkpy.blinkpy.Blink.setup_post_verify", return_value=True
87+
with (
88+
mock.patch(
89+
"blinkpy.sync_module.BlinkSyncModule.refresh", return_value=True
90+
),
91+
mock.patch("blinkpy.blinkpy.Blink.get_homescreen", return_value=True),
92+
mock.patch("blinkpy.blinkpy.Blink.setup_post_verify", return_value=True),
9093
):
9194
self.assertTrue(await self.blink.refresh(force=True))
9295
with mock.patch("time.time", return_value=time.time() + 4):

tests/test_camera_functions.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
"serial": "12345678",
2323
"enabled": False,
2424
"battery_state": "ok",
25+
"battery_voltage": 163,
26+
"wifi_strength": -38,
2527
"signals": {"lfr": 5, "wifi": 4, "battery": 3, "temp": 68},
2628
"thumbnail": "/thumb",
2729
}
@@ -68,7 +70,8 @@ async def test_camera_update(self, mock_resp):
6870
self.assertEqual(self.camera.temperature, 68)
6971
self.assertEqual(self.camera.temperature_c, 20)
7072
self.assertEqual(self.camera.temperature_calibrated, 71)
71-
self.assertEqual(self.camera.wifi_strength, 4)
73+
self.assertEqual(self.camera.battery_voltage, 163)
74+
self.assertEqual(self.camera.wifi_strength, -38)
7275
self.assertEqual(
7376
self.camera.thumbnail, "https://rest-test.immedia-semi.com/thumb.jpg"
7477
)
@@ -378,5 +381,4 @@ async def test_missing_keys(self, mock_resp):
378381
mresp.MockResponse({"foobar": 200}, 200, raw_data="foobar"),
379382
]
380383
await self.camera.update(config, expire_clips=False, force=True)
381-
self.assertEqual(self.camera.wifi_strength, None)
382384
self.assertEqual(self.camera.battery_level, None)

tests/test_doorbell_as_sync.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Tests camera and system functions."""
2+
23
from unittest import mock
34
from unittest import IsolatedAsyncioTestCase
45
import pytest

tests/test_errors.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Test blink Utils errors."""
2+
23
import unittest
34
from blinkpy.helpers.errors import (
45
USERNAME,

tests/test_mini_as_sync.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Tests camera and system functions."""
2+
23
from unittest import mock
34
from unittest import IsolatedAsyncioTestCase
45
import pytest

tests/test_sync_module.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Tests camera and system functions."""
2+
23
import datetime
34
import logging
45
from unittest import IsolatedAsyncioTestCase
@@ -31,7 +32,7 @@ def setUp(self):
3132
self.blink: Blink = Blink(motion_interval=0, session=mock.AsyncMock())
3233
self.blink.last_refresh = 0
3334
self.blink.urls = BlinkURLHandler("test")
34-
self.blink.sync["test"]: (BlinkSyncModule) = BlinkSyncModule(
35+
self.blink.sync["test"]: BlinkSyncModule = BlinkSyncModule(
3536
self.blink, "test", "1234", []
3637
)
3738
self.blink.sync["test"].network_info = {"network": {"armed": True}}

0 commit comments

Comments
 (0)