|
| 1 | +from __future__ import annotations |
| 2 | + |
| 3 | +from datetime import datetime |
| 4 | +from struct import pack |
| 5 | +from uuid import UUID |
| 6 | +from contextlib import AsyncExitStack |
| 7 | + |
| 8 | +from bleak import BleakClient |
| 9 | +from bleak.exc import BleakError |
| 10 | +from bleak.backends.device import BLEDevice |
| 11 | + |
| 12 | +class ThermoProDevice: |
| 13 | + datetime_uuid = UUID("00010203-0405-0607-0809-0a0b0c0d2b11") |
| 14 | + |
| 15 | + |
| 16 | + def __init__(self, ble : BLEDevice): |
| 17 | + self.ble = ble |
| 18 | + self.stack = AsyncExitStack() |
| 19 | + self.client = None |
| 20 | + |
| 21 | + |
| 22 | + async def connect(self, timeout=30): |
| 23 | + if not self.client: |
| 24 | + self.client = await self.stack.enter_async_context(BleakClient(self.ble, timeout=timeout)) |
| 25 | + return self.client |
| 26 | + |
| 27 | + |
| 28 | + def pack_datetime(self, dt: datetime, ampm=False): |
| 29 | + # taken from https://github.com/koenvervloesem/bluetooth-clocks/blob/main/src/bluetooth_clocks/devices/thermopro.py |
| 30 | + return pack( |
| 31 | + "BBBBBBBBBB", |
| 32 | + 0xA5, |
| 33 | + dt.year % 2000, |
| 34 | + dt.month, |
| 35 | + dt.day, |
| 36 | + dt.hour, |
| 37 | + dt.minute, |
| 38 | + dt.second, |
| 39 | + dt.weekday() + 1, # Monday-Sunday -> 0-6 |
| 40 | + int(not ampm), # 1 means 24 hour format / 0 12 hour format |
| 41 | + 0x5A, |
| 42 | + ) |
| 43 | + |
| 44 | + |
| 45 | + async def set_datetime(self, dt: datetime): |
| 46 | + # taken from https://github.com/fuatakgun/generic_bt/blob/main/custom_components/generic_bt/binary_sensor.py |
| 47 | + # copy over https://github.com/fuatakgun/generic_bt/blob/2349b00f9202e891cd247f13b63954065f07a2d0/custom_components/generic_bt/generic_bt_api/device.py#L47 |
| 48 | + client = await self.connect() |
| 49 | + await client.write_gatt_char(ThermoProDevice.datetime_uuid, self.pack_datetime(dt), True) |
0 commit comments