FD50 GATT fallback patch (vs ShonP40/Tuya-BLE master dabbf9e)
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
diff --git a/custom_components/tuya_local_ble/tuya_ble/const.py b/custom_components/tuya_local_ble/tuya_ble/const.py
|
||||
index b1514a9..c73f268 100644
|
||||
--- a/custom_components/tuya_local_ble/tuya_ble/const.py
|
||||
+++ b/custom_components/tuya_local_ble/tuya_ble/const.py
|
||||
@@ -9,6 +9,12 @@ DEFAULT_ATTEMPTS = 0xFFFF
|
||||
CHARACTERISTIC_NOTIFY = "00002b10-0000-1000-8000-00805f9b34fb"
|
||||
CHARACTERISTIC_WRITE = "00002b11-0000-1000-8000-00805f9b34fb"
|
||||
|
||||
+# Newer TuyaOS firmware (e.g. jtmspro hc7n0urm fw 6.0) drops the legacy
|
||||
+# 0xA201 service and exposes the data channel via these characteristics
|
||||
+# of the 0xFD50 service instead.
|
||||
+CHARACTERISTIC_NOTIFY_FD50 = "00000002-0000-1001-8001-00805f9b07d0"
|
||||
+CHARACTERISTIC_WRITE_FD50 = "00000001-0000-1001-8001-00805f9b07d0"
|
||||
+
|
||||
SERVICE_UUID = "0000a201-0000-1000-8000-00805f9b34fb"
|
||||
|
||||
MANUFACTURER_DATA_ID = 0x07D0
|
||||
diff --git a/custom_components/tuya_local_ble/tuya_ble/tuya_ble.py b/custom_components/tuya_local_ble/tuya_ble/tuya_ble.py
|
||||
index 274cbf6..73049eb 100644
|
||||
--- a/custom_components/tuya_local_ble/tuya_ble/tuya_ble.py
|
||||
+++ b/custom_components/tuya_local_ble/tuya_ble/tuya_ble.py
|
||||
@@ -24,7 +24,9 @@ from Crypto.Cipher import AES
|
||||
|
||||
from .const import (
|
||||
CHARACTERISTIC_NOTIFY,
|
||||
+ CHARACTERISTIC_NOTIFY_FD50,
|
||||
CHARACTERISTIC_WRITE,
|
||||
+ CHARACTERISTIC_WRITE_FD50,
|
||||
GATT_MTU,
|
||||
MANUFACTURER_DATA_ID,
|
||||
RESPONSE_WAIT_TIMEOUT,
|
||||
@@ -231,6 +233,9 @@ class TuyaBLEDevice:
|
||||
self._current_seq_num = 1
|
||||
self._seq_num_lock = asyncio.Lock()
|
||||
|
||||
+ self._characteristic_notify = CHARACTERISTIC_NOTIFY
|
||||
+ self._characteristic_write = CHARACTERISTIC_WRITE
|
||||
+
|
||||
self._is_bound = False
|
||||
self._flags = 0
|
||||
self._protocol_version = 2
|
||||
@@ -540,11 +545,25 @@ class TuyaBLEDevice:
|
||||
self._expected_disconnect = True
|
||||
self._client = None
|
||||
if client and client.is_connected:
|
||||
- await client.stop_notify(CHARACTERISTIC_NOTIFY)
|
||||
+ await client.stop_notify(self._characteristic_notify)
|
||||
await client.disconnect()
|
||||
async with self._seq_num_lock:
|
||||
self._current_seq_num = 1
|
||||
|
||||
+ def _select_characteristics(self, client: BleakClientWithServiceCache) -> None:
|
||||
+ """Select the GATT channel actually exposed by the device."""
|
||||
+ if client.services.get_characteristic(CHARACTERISTIC_NOTIFY):
|
||||
+ self._characteristic_notify = CHARACTERISTIC_NOTIFY
|
||||
+ self._characteristic_write = CHARACTERISTIC_WRITE
|
||||
+ elif client.services.get_characteristic(CHARACTERISTIC_NOTIFY_FD50):
|
||||
+ _LOGGER.debug(
|
||||
+ "%s: legacy characteristics not present,"
|
||||
+ " using FD50 GATT channel",
|
||||
+ self.address,
|
||||
+ )
|
||||
+ self._characteristic_notify = CHARACTERISTIC_NOTIFY_FD50
|
||||
+ self._characteristic_write = CHARACTERISTIC_WRITE_FD50
|
||||
+
|
||||
async def _ensure_connected(self) -> None:
|
||||
"""Ensure connection to device is established."""
|
||||
global global_connect_lock
|
||||
@@ -609,9 +628,10 @@ class TuyaBLEDevice:
|
||||
_LOGGER.debug("%s: Connected; RSSI: %s",
|
||||
self.address, self.rssi)
|
||||
self._client = client
|
||||
+ self._select_characteristics(client)
|
||||
try:
|
||||
await self._client.start_notify(
|
||||
- CHARACTERISTIC_NOTIFY,
|
||||
+ self._characteristic_notify,
|
||||
self._notification_handler,
|
||||
bluez={"use_start_notify": True},
|
||||
)
|
||||
@@ -968,7 +988,7 @@ class TuyaBLEDevice:
|
||||
try:
|
||||
# _LOGGER.debug("%s: Sending packet: %s", self.address, packet.hex())
|
||||
await self._client.write_gatt_char(
|
||||
- CHARACTERISTIC_WRITE,
|
||||
+ self._characteristic_write,
|
||||
packet,
|
||||
False,
|
||||
)
|
||||
Reference in New Issue
Block a user