Per Camera Snooze - #1273
Conversation
- Add snoozed async property to BlinkCamera (checks all camera types) - Add async_snooze() method to BlinkCamera - Add request_camera_snooze() API function routing by product type - Tests
There was a problem hiding this comment.
Pull request overview
Adds per-camera snoozing support to BlinkPy by exposing a camera-level snooze API and a convenient camera property for reading snooze state, with product-type-specific endpoint routing.
Changes:
- Added
BlinkCamera.async_snooze()to set snooze duration and refresh homescreen for applicable product types. - Added
BlinkCamera.snoozedasync property to report current snooze state for both config-based and homescreen-based devices. - Added
api.request_camera_snooze()plus tests covering routing and camera behaviors.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| tests/test_cameras.py | Adds test coverage for per-camera snooze and snooze-state reading across product types and edge cases. |
| tests/test_api.py | Adds API-level test ensuring request_camera_snooze() routes per product type and returns expected responses. |
| blinkpy/camera.py | Implements snoozed async property and async_snooze() on BlinkCamera. |
| blinkpy/api.py | Extends request_get_config() for sedona and introduces request_camera_snooze() endpoint routing helper. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| for device in self.sync.blink.homescreen.get(collection_key, []): | ||
| if int(device.get("id")) == int(self.camera_id): | ||
| snooze_value = device.get("snooze") | ||
| return bool(snooze_value) | ||
| return False |
There was a problem hiding this comment.
Addressed in commit 70046de — replaced int() ID comparison in snoozed with str() to prevent TypeError from aborting the search loop on missing/non-numeric IDs, and extended request_update_config() to accept sedona alongside catalina to match request_get_config().
| elif product_type in ["catalina", "sedona"]: | ||
| url = f"{blink.urls.base_url}/network/{network}/camera/{camera_id}/config" |
There was a problem hiding this comment.
Addressed in commit 70046de — replaced int() ID comparison in snoozed with str() to prevent TypeError from aborting the search loop on missing/non-numeric IDs, and extended request_update_config() to accept sedona alongside catalina to match request_get_config().
|
I tested this branch against a live account (4 cameras: catalina, owl, chickadee, sonoran) while wiring the matching action up in Home Assistant core. Three findings, all measured rather than inferred. 1. The docstring says "Time in seconds to snooze camera. Default is 3600 (1 hour)". Sending So 300 was read as 300 minutes, and 2. Accepted range is 1..1439 minutes; Found by bisection between 300 and 1440. Two consequences:
3.
product_lookup = {
"catalina": "cameras",
"sedona": "cameras",
+ "sonoran": "cameras",
"owl": "owls",
"hawk": "owls",
+ "chickadee": "owls",
"doorbell": "doorbells",
"lotus": "doorbells",
}Caveat on 4. Snooze state is not exposed on the camera, and the two model families report it differently The async
Observed on a live account: Normalising both into def extract_snooze_info(self, config):
"""Normalize snooze status across camera models."""
self.snooze_till = config.get("snooze_till")
remaining = config.get("snooze_time_remaining")
snoozed = config.get("snooze")
if remaining is None and self.snooze_till:
try:
until = datetime.datetime.fromisoformat(self.snooze_till)
except (TypeError, ValueError):
_LOGGER.warning(
"Could not parse snooze_till %r for %s", self.snooze_till, self.name
)
else:
if until.tzinfo is None:
until = until.replace(tzinfo=datetime.timezone.utc)
seconds = (
until - datetime.datetime.now(datetime.timezone.utc)
).total_seconds()
remaining = max(0, math.ceil(seconds / 60))
self.snooze_time_remaining = remaining
self.snooze = bool(remaining) if snoozed is None else bool(snoozed)called from Happy to open a PR against your branch with the lookup entries, the docstring fix and this normalisation if that is easier than folding it in here. |
Description:
Adds
async_snooze()and asnoozedproperty toBlinkCameraso individual cameras can be snoozed. A newrequest_camera_snooze()API function handles routing to the right endpoint per product type (catalina/sedona→ cameras,owl/hawk→ owls,doorbell/lotus→ doorbells).Checklist:
toxrun successfully PR cannot be meged unless tests pass