90 lines
3.9 KiB
Diff
90 lines
3.9 KiB
Diff
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,
|
|
)
|