Skip to content

Instantly share code, notes, and snippets.

@mogenson
Created October 7, 2025 13:59
Show Gist options
  • Select an option

  • Save mogenson/077376e43957a23b0588a3b5b10e536c to your computer and use it in GitHub Desktop.

Select an option

Save mogenson/077376e43957a23b0588a3b5b10e536c to your computer and use it in GitHub Desktop.
#!/usr/bin/env -S uv run --script
# /// script
# dependencies = [
# "bleak",
# ]
# ///
import asyncio
from bleak import BleakClient, BleakScanner
CMD_CHAR = "cba20002-224d-11e6-9fb8-0002a5d5c51b"
RSP_CHAR = "cba20003-224d-11e6-9fb8-0002a5d5c51b"
SERVICE_UUID = "0000fd3d-0000-1000-8000-00805f9b34fb"
SERVICE_DATA = bytes.fromhex("4800E400")
PRESS_CMD = bytes.fromhex("570100")
PRESS_RSP = bytes.fromhex("01FF00")
async def main():
scan_result = asyncio.get_running_loop().create_future()
def scan_result_callback(device, advertising_data):
if advertising_data.rssi > -70:
return
if advertising_data.service_data.get(SERVICE_UUID) == SERVICE_DATA:
print(f"found switchbot: {device.address}")
if not scan_result.done():
scan_result.set_result(device)
async with BleakScanner(scan_result_callback):
device = await scan_result
response = asyncio.get_running_loop().create_future()
async with BleakClient(device) as client:
print("connected")
await client.start_notify(
RSP_CHAR, lambda char, data: response.set_result(data)
)
print("subscribed")
await client.write_gatt_char(CMD_CHAR, PRESS_CMD, response=True)
print("pressed")
print("success") if await response == PRESS_RSP else print("failure")
asyncio.run(main())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment