Skip to content

Conversation

@hnw
Copy link
Contributor

@hnw hnw commented Jan 6, 2026

Description

This PR adds a callback parameter to the GetSwitchbotDevices class. This allows consumers of the library to process device advertisements in real-time as they are discovered.

Motivation / Real-world Use Case

I maintain an OSS project called switchbot-actions, which relies on pySwitchbot for device scanning. This tool triggers actions (webhooks, MQTT, shell commands) based on sensor updates. A common use case is turning on a light via webhook immediately when a motion sensor detects movement.

Currently, GetSwitchbotDevices.discover() waits for the full scan_timeout (default 5s) to complete before returning results. This introduces an average latency of half the scan duration, causing a noticeable delay in automation.

By adding a callback, applications can process the advertisement packet the moment it is received, enabling near real-time responsiveness without shortening the scan duration.

Changes

  • Updated GetSwitchbotDevices.__init__ to accept a callback.
  • Updated detection_callback to invoke the user-provided callback.
  • Added exception handling within the callback execution to prevent discovery interruptions due to user-land errors.

Technical Details

  • The callback must be a synchronous callable. Callers who need async behavior can manage their own tasks within the callback.
  • Adds exception handling within the callback execution to prevent discovery interruptions due to user-land errors.

Backward Compatibility

  • The callback parameter is optional. Existing implementations using discover() will function exactly as before without any changes.

Example Usage

from switchbot import GetSwitchbotDevices, SwitchBotAdvertisement

def on_device_discovered(device: SwitchBotAdvertisement) -> None:
    print(f"Discovered: {device.address} - {device.data}")

# Pass the callback during initialization
scanner = GetSwitchbotDevices(callback=on_device_discovered)
await scanner.discover()

Tests

  • Added tests/test_discovery_callback.py covering:
    • Synchronous callbacks.
    • Exception handling (ensuring discovery continues if the callback fails).

This introduces a `callback` parameter to the `GetSwitchbotDevices` constructor.
It allows users to handle device advertisements immediately upon detection.

Key changes:
- Support both synchronous and asynchronous callback functions.
- Add comprehensive tests for sync/async execution and error handling.
@codecov
Copy link

codecov bot commented Jan 6, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

Files with missing lines Coverage Δ
switchbot/discovery.py 56.09% <100.00%> (+21.43%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Member

@bdraco bdraco left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see comments above

Only support sync functions following the feedback. Callers can manage their own tasks for async execution.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a user-provided callback hook to device discovery so consumers can react to SwitchBot advertisements as they are received (instead of waiting for the full scan timeout).

Changes:

  • Extend GetSwitchbotDevices.__init__ with an optional callback parameter.
  • Invoke the callback from detection_callback and suppress/log callback exceptions.
  • Add pytest coverage for per-packet callback invocation and exception suppression.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.

File Description
switchbot/discovery.py Adds optional callback and calls it on each parsed advertisement.
tests/test_discovery_callback.py Introduces tests validating callback invocation and that callback exceptions don’t break discovery.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Member

@bdraco bdraco left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @hnw

@bdraco bdraco merged commit dbbe591 into sblibs:master Jan 25, 2026
5 checks passed
fankai777 pushed a commit to fankai777/pySwitchbot that referenced this pull request Jan 26, 2026
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants