Tuya BLE integration, includes fingerbot

Hi all,

I’m working on Tuya BLE integration.

The starting point was this GitHub project: GitHub - redphx/python-tuya-ble: Python library to interact with Tuya BLE protocol

For now, I have almost working integration. The integration works locally, but connection to Tuya BLE device requires device ID and encryption key from Tuya IOT cloud. It could be obtained using the same credentials as in official Tuya integreation.

Supported devices are: three models of fingerbot and two different sensors. Here is a screenshot of interface:

I am interested in how many people have Tuya BLE devices and are interested in the integration.

18 Likes

Released integration GitHub - PlusPlus-ua/ha_tuya_ble: Home Assistant support for Tuya BLE devices

4 Likes

Hi, I’m Interested in this, I got a Tuya BLE Smart Lock, any chance to make it work locally? im happy to help with integration if there’s anything i can do.

1 Like

I have a Fingerbot Plus and would like to have it working with Home Assistant. It doesn’t work with Tuya integration.

Hi, thank you.

I think it’s possible if the lock is really BLE. I’ve bought a lock from Ali and it’s works via Bluetooth Mesh protocol. Unfortunately, BLE and Mesh are completely different. Have you tried to install the integration? Has it discovered your lock?

Have you installed the integration? Has it discovered your device?

Sorry for late reply, I was dealing with 500 internal server error issue. today after i updated the home assistant OS to 10.1 i could finally add the integration on second try :smiley: ,
so I have a Tuya Bluetooth gateway, before i unbind the device from Tuya gateway it actually discovered the lock in configuration section of integration, but the loading sign was keep spinning for a while and did’nt actually give me any error, so i had to cancel it,

after unbinding the lock from gateway, it just discovered the gateway and not the lock anymore (the mac address titled device in the photo), i also tried unplugging the gateway to see if it will discover the lock again but no luck…

here’s some details from my smart lock on Tuya IoT :

{
  "result": [
    {
      "id": "bffbdfsjhpau****",
      "mac": "DC234EF2F0F6",
      "uuid": "673da0b270675f97"
    }
  ],
  "success": true,
  "t": 1682336014650,
  "tid": "d8f18c18e29311ed8e7992e835dc8daa"
}


{
  "result": {
    "active_time": 1681978454,
    "category": "ms",
    "category_name": "Residential Lock",
    "create_time": 1681978454,
    "gateway_id": "",
    "icon": "smart/icon/ay15724370520156puq6/f08a38f98d274c577417a88e302d98d6.jpg",
    "id": "bffbdfsjhpaunwpk",
    "ip": "",
    "lat": "-33.7794",
    "local_key": "2124e21399c4****",
    "lon": "151.0960",
    "model": "PLD_190",
    "name": "Smart Lock",
    "online": false,
    "owner_id": "576800**",
    "product_id": "ludzroix",
    "product_name": "Smart Lock",
    "sub": false,
    "time_zone": "+10:00",
    "update_time": 1681978456,
    "uuid": "673da0b270675f97"
  },
  "success": true,
  "t": 1682336902199,
  "tid": "e9f021e9e29511ed8e7992e835dc8daa"
}

Device Debugging:

unlock_method_create	Raw	
{}
unlock_method_delete	Raw	
{}
unlock_method_modify	Raw	
{}
residual_electricity	Integer	
{
  "min": -1,
  "max": 100,
  "scale": 0,
  "step": 1
}
unlock_fingerprint	Integer	
{
  "min": 0,
  "max": 999,
  "scale": 0,
  "step": 1
}
unlock_password	Integer	
{
  "min": 0,
  "max": 999,
  "scale": 0,
  "step": 1
}
unlock_dynamic	Integer	
{
  "min": 0,
  "max": 999,
  "scale": 0,
  "step": 1
}
unlock_ble	Integer	
{
  "min": 0,
  "max": 999,
  "scale": 0,
  "step": 1
}
alarm_lock	Enum	
{
  "range": [
    "wrong_finger",
    "wrong_password",
    "low_battery"
  ]
}
beep_volume	Enum	
{
  "range": [
    "mute",
    "low",
    "normal",
    "high"
  ]
}
lock_motor_state	Boolean	
"{true,false}"
temporary_password_creat	Raw	
{}
temporary_password_delete	Raw	
{}
temporary_password_modify	Raw	
{}
synch_method	Raw	
{}
unlock_temporary	Integer	
{
  "min": 0,
  "max": 999,
  "scale": 0,
  "step": 1
}
remote_no_pd_setkey	Raw	
{}
remote_no_dp_key	Raw	
{}
unlock_phone_remote	Integer	
{
  "min": 0,
  "max": 999,
  "scale": 0,
  "step": 1
}
password_offline_time	String	
{}
unlock_offline_clear_single	Raw	
{}
unlock_offline_clear	Raw	
{}
unlock_offline_pd	Raw	
{}

ive checked out the DP id’s for example ble_unlock dp id is 6,

it would be awsome if you can include the lock in this integration, i’ve been searching for the past month to find a way to get it to work with home assistant i’ve seen hundreds of posts about it :smiley:

Thanks!

UPDATE1:
so after removing the lock of my Smart Life app, and re-adding it, still didn’t work, but when i turned off my phone bluetooth, so it was added to my account but surely wasn’t connected to my phone via bluetooth, surprisingly it just poped up on my devices and integrations page :flushed:
but it is still stuck on configure screen (Loading forever) :

UPDATE2:
Finally!! added the config after 30mins (technically it didn’t) , now i can see the device and it says Fail to Setup,
Log:

Logger: homeassistant.config_entries
Source: custom_components/tuya_ble/tuya_ble/tuya_ble.py:623
Integration: Tuya BLE
First occurred: 7:08:02 PM (1 occurrences)
Last logged: 7:08:02 PM

Error setting up entry Smart Lock F2F0F6 for tuya_ble
Traceback (most recent call last):
  File "/config/custom_components/tuya_ble/tuya_ble/tuya_ble.py", line 620, in _ensure_connected
    await self._client.start_notify(
  File "/usr/local/lib/python3.10/site-packages/bleak/__init__.py", line 717, in start_notify
    await self._backend.start_notify(characteristic, wrapped_callback, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/bleak/backends/bluezdbus/client.py", line 943, in start_notify
    assert_reply(reply)
  File "/usr/local/lib/python3.10/site-packages/bleak/backends/bluezdbus/utils.py", line 22, in assert_reply
    raise BleakDBusError(reply.error_name, reply.body)
bleak.exc.BleakDBusError: [org.bluez.Error.Failed] Operation failed with ATT error: 0x0e (Unlikely Error)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/config_entries.py", line 383, in async_setup
    result = await component.async_setup_entry(hass, self)
  File "/config/custom_components/tuya_ble/__init__.py", line 44, in async_setup_entry
    await device.initialize()
  File "/config/custom_components/tuya_ble/tuya_ble/tuya_ble.py", line 272, in initialize
    await self.update()
  File "/config/custom_components/tuya_ble/tuya_ble/tuya_ble.py", line 312, in update
    await self._send_packet(TuyaBLECode.FUN_SENDER_DEVICE_STATUS, bytes())
  File "/config/custom_components/tuya_ble/tuya_ble/tuya_ble.py", line 869, in _send_packet
    await self._ensure_connected()
  File "/config/custom_components/tuya_ble/tuya_ble/tuya_ble.py", line 623, in _ensure_connected
    except [BLEAK_EXCEPTIONS, BleakNotFoundError]:
TypeError: catching classes that do not inherit from BaseException is not allowed```

Thank you for comprehensive information and logs.

To add device to the integration, id’s of all DP are needed.

At this point, I have no idea how to deal with these RAW datapoints.

It’s only one file of documentation about Tuya BLE API which is available for now (I’ve read it using Google Translate). There is mentioned that unlocking of the lock requires additional request to Tuya IOT Cloud for each opening. However, I have no idea how to use “instruction” received from cloud.

2 Likes

It is also important to ensure that the lock doesn’t use Tuya BLE protocol version 4. I’ve implemented only protocol version 3, because I have no devices with protocol version 4 to debug. It’s not so big deal, but I don’t like to write code which I can’t check.

1 Like

Thanks for Looking into it,
looks like that those RAW datapoints are for Creating Password or unlocking via password, which i dont think needs to be integrated home assistant anyway (or it would be hard to do so, like you said need to be send to cloud and go back to lock again and that would not make sense because all this effort is to try to control the lock locally!)
i think having these entities integrated would be more than enough:
(Control, Alarm, Battery Monitor and maybe Beep Volume)

[wrap=“columns”]

Code Type Values
alarm_lock Enum {
range: [
wrong_finger,
wrong_password,
low_battery
]
}
lock_motor_state Boolean {true,false}
residual_electricity Integer {
min: -1,
max: 100,
scale: 0,
step: 1
}
beep_volume Enum {
range: [
mute,
low,
normal,
high
]
}

[/wrap=“columns”]

DP Id’s:
Lock Alarm : 21
Lock Motor State : 47
Remaining Battery (residual_electricity) : 8
Lock Navigation Volume: 31

And about the Bluetooth version im not sure, i tried searching in the smart life app and Tuya IoT platform device section and API Explorer, unfortunetly i didnt have any luck finding the hardware’s bluetooth version, is there a way to check bluetooth version when my android phone is connected to the lock via bluetooth??

also im gonna dump some logs here hope you don’t mind, it might help developing a solution: :smiley:

This error originated from a custom integration.

Logger: aiohttp.server
Source: custom_components/tuya_ble/config_flow.py:175
Integration: Tuya BLE
First occurred: April 28, 2023 at 6:19:04 PM (10 occurrences)
Last logged: April 28, 2023 at 7:11:52 PM

Error handling request
Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/aiohttp/web_protocol.py", line 433, in _handle_request
    resp = await request_handler(request)
  File "/usr/local/lib/python3.10/site-packages/aiohttp/web_app.py", line 504, in _handle
    resp = await handler(request)
  File "/usr/local/lib/python3.10/site-packages/aiohttp/web_middlewares.py", line 117, in impl
    return await handler(request)
  File "/usr/src/homeassistant/homeassistant/components/http/security_filter.py", line 85, in security_filter_middleware
    return await handler(request)
  File "/usr/src/homeassistant/homeassistant/components/http/forwarded.py", line 100, in forwarded_middleware
    return await handler(request)
  File "/usr/src/homeassistant/homeassistant/components/http/request_context.py", line 28, in request_context_middleware
    return await handler(request)
  File "/usr/src/homeassistant/homeassistant/components/http/ban.py", line 80, in ban_middleware
    return await handler(request)
  File "/usr/src/homeassistant/homeassistant/components/http/auth.py", line 235, in auth_middleware
    return await handler(request)
  File "/usr/src/homeassistant/homeassistant/components/http/view.py", line 146, in handle
    result = await result
  File "/usr/src/homeassistant/homeassistant/components/config/config_entries.py", line 241, in post
    return await super().post(request, flow_id)
  File "/usr/src/homeassistant/homeassistant/components/http/data_validator.py", line 72, in wrapper
    result = await method(view, request, data, *args, **kwargs)
  File "/usr/src/homeassistant/homeassistant/helpers/data_entry_flow.py", line 110, in post
    result = await self._flow_mgr.async_configure(flow_id, data)
  File "/usr/src/homeassistant/homeassistant/data_entry_flow.py", line 271, in async_configure
    result = await self._async_handle_step(
  File "/usr/src/homeassistant/homeassistant/data_entry_flow.py", line 367, in _async_handle_step
    result: FlowResult = await getattr(flow, method)(user_input)
  File "/config/custom_components/tuya_ble/config_flow.py", line 175, in async_step_login
    entry: TuyaBLEData = self.hass.data[DOMAIN][
KeyError: 'tuya_ble'












This error originated from a custom integration.

Logger: homeassistant.config_entries
Source: custom_components/tuya_ble/tuya_ble/tuya_ble.py:591
Integration: Tuya BLE
First occurred: April 28, 2023 at 7:40:52 PM (1 occurrences)
Last logged: April 28, 2023 at 7:40:52 PM

Error setting up entry Smart Lock F2F0F6 for tuya_ble
Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/bleak_retry_connector/__init__.py", line 344, in establish_connection
    await client.connect(
  File "/usr/src/homeassistant/homeassistant/components/bluetooth/wrappers.py", line 253, in connect
    wrapped_backend = self._async_get_best_available_backend_and_device(manager)
  File "/usr/src/homeassistant/homeassistant/components/bluetooth/wrappers.py", line 352, in _async_get_best_available_backend_and_device
    raise BleakError(
bleak.exc.BleakError: No backend with an available connection slot that can reach address DC:23:4E:F2:F0:F6 was found

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/config_entries.py", line 383, in async_setup
    result = await component.async_setup_entry(hass, self)
  File "/config/custom_components/tuya_ble/__init__.py", line 44, in async_setup_entry
    await device.initialize()
  File "/config/custom_components/tuya_ble/tuya_ble/tuya_ble.py", line 272, in initialize
    await self.update()
  File "/config/custom_components/tuya_ble/tuya_ble/tuya_ble.py", line 312, in update
    await self._send_packet(TuyaBLECode.FUN_SENDER_DEVICE_STATUS, bytes())
  File "/config/custom_components/tuya_ble/tuya_ble/tuya_ble.py", line 869, in _send_packet
    await self._ensure_connected()
  File "/config/custom_components/tuya_ble/tuya_ble/tuya_ble.py", line 591, in _ensure_connected
    client = await establish_connection(
  File "/usr/local/lib/python3.10/site-packages/bleak_retry_connector/__init__.py", line 420, in establish_connection
    await wait_for_disconnect(device, backoff_time)
  File "/usr/local/lib/python3.10/site-packages/bleak_retry_connector/bluez.py", line 286, in wait_for_disconnect
    await asyncio.sleep(min_wait_time)
  File "/usr/local/lib/python3.10/asyncio/tasks.py", line 605, in sleep
    return await future
asyncio.exceptions.CancelledError












This error originated from a custom integration.

Logger: custom_components.tuya_ble.tuya_ble.tuya_ble
Source: custom_components/tuya_ble/tuya_ble/tuya_ble.py:272
Integration: Tuya BLE
First occurred: April 28, 2023 at 7:45:20 PM (2 occurrences)
Last logged: April 28, 2023 at 7:45:20 PM

DC:23:4E:F2:F0:F6: timeout receiving response, RSSI: None
DC:23:4E:F2:F0:F6: Sending device info request failed









This error originated from a custom integration.

Logger: custom_components.tuya_ble.tuya_ble.tuya_ble
Source: custom_components/tuya_ble/tuya_ble/tuya_ble.py:591
Integration: Tuya BLE
First occurred: April 28, 2023 at 6:47:30 PM (30 occurrences)
Last logged: April 28, 2023 at 7:49:43 PM

DC:23:4E:F2:F0:F6: device not found, not in range, or poor RSSI: None
Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/bleak/backends/bluezdbus/client.py", line 204, in connect
    reply = await self._bus.call(
  File "/usr/local/lib/python3.10/site-packages/dbus_fast/aio/message_bus.py", line 371, in call
    await future
asyncio.exceptions.CancelledError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/bleak_retry_connector/__init__.py", line 344, in establish_connection
    await client.connect(
  File "/usr/src/homeassistant/homeassistant/components/bluetooth/wrappers.py", line 269, in connect
    connected = await super().connect(**kwargs)
  File "/usr/local/lib/python3.10/site-packages/bleak/__init__.py", line 531, in connect
    return await self._backend.connect(**kwargs)
  File "/usr/local/lib/python3.10/site-packages/bleak/backends/bluezdbus/client.py", line 141, in connect
    async with async_timeout(timeout):
  File "/usr/local/lib/python3.10/site-packages/async_timeout/__init__.py", line 129, in __aexit__
    self._do_exit(exc_type)
  File "/usr/local/lib/python3.10/site-packages/async_timeout/__init__.py", line 212, in _do_exit
    raise asyncio.TimeoutError
asyncio.exceptions.TimeoutError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/config/custom_components/tuya_ble/tuya_ble/tuya_ble.py", line 591, in _ensure_connected
    client = await establish_connection(
  File "/usr/local/lib/python3.10/site-packages/bleak_retry_connector/__init__.py", line 361, in establish_connection
    _raise_if_needed(name, device.address, exc)
  File "/usr/local/lib/python3.10/site-packages/bleak_retry_connector/__init__.py", line 310, in _raise_if_needed
    raise BleakNotFoundError(msg) from exc
bleak_retry_connector.BleakNotFoundError: DC:23:4E:F2:F0:F6 - DC:23:4E:F2:F0:F6: Failed to connect: 







This error originated from a custom integration.

Logger: custom_components.tuya_ble.tuya_ble.tuya_ble
Source: custom_components/tuya_ble/tuya_ble/tuya_ble.py:525
Integration: Tuya BLE
First occurred: April 28, 2023 at 6:59:58 PM (8 occurrences)
Last logged: April 28, 2023 at 7:50:23 PM

DC:23:4E:F2:F0:F6: Device unexpectedly disconnected; RSSI: None








This error originated from a custom integration.

Logger: homeassistant.config_entries
Source: custom_components/tuya_ble/tuya_ble/tuya_ble.py:623
Integration: Tuya BLE
First occurred: April 28, 2023 at 7:08:02 PM (3 occurrences)
Last logged: April 28, 2023 at 7:50:23 PM

Error setting up entry Smart Lock F2F0F6 for tuya_ble
Traceback (most recent call last):
  File "/config/custom_components/tuya_ble/tuya_ble/tuya_ble.py", line 620, in _ensure_connected
    await self._client.start_notify(
  File "/usr/local/lib/python3.10/site-packages/bleak/__init__.py", line 717, in start_notify
    await self._backend.start_notify(characteristic, wrapped_callback, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/bleak/backends/bluezdbus/client.py", line 943, in start_notify
    assert_reply(reply)
  File "/usr/local/lib/python3.10/site-packages/bleak/backends/bluezdbus/utils.py", line 22, in assert_reply
    raise BleakDBusError(reply.error_name, reply.body)
bleak.exc.BleakDBusError: [org.bluez.Error.Failed] Operation failed with ATT error: 0x0e (Unlikely Error)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/config_entries.py", line 383, in async_setup
    result = await component.async_setup_entry(hass, self)
  File "/config/custom_components/tuya_ble/__init__.py", line 44, in async_setup_entry
    await device.initialize()
  File "/config/custom_components/tuya_ble/tuya_ble/tuya_ble.py", line 272, in initialize
    await self.update()
  File "/config/custom_components/tuya_ble/tuya_ble/tuya_ble.py", line 312, in update
    await self._send_packet(TuyaBLECode.FUN_SENDER_DEVICE_STATUS, bytes())
  File "/config/custom_components/tuya_ble/tuya_ble/tuya_ble.py", line 869, in _send_packet
    await self._ensure_connected()
  File "/config/custom_components/tuya_ble/tuya_ble/tuya_ble.py", line 623, in _ensure_connected
    except [BLEAK_EXCEPTIONS, BleakNotFoundError]:
TypeError: catching classes that do not inherit from BaseException is not allowed

these are the some errors and warning logged to HA since last night that i tried to add the lock,
at the moment i can see the lock in devices section but it says" Failed to set up
[Check the logs]"

Thanks Heaps!

Hi Alex
Thank you for doing this integration.
I got it working on my test HA setup. I then removed it from there, and added it to my main HA box (HAOS).
I get this error:
image
I set up a new Tuya project (client ID / secret) and the same issue…
Any ideas? I don’t see anything in the HA log… is there anything I can do to help trouble shoot this?
Thanks
Andrew

Thanks,

It looks like your BT adapter doesn’t see your device. Try to move your device closer to check it.

Hi Alex
Thank you! You were of course correct :slight_smile:

So with that solved, can we use a ESP32 as a ‘BT range extender’ with this? Will bluetooth proxy by ESPHome work?

bluetooth_proxy:
  active: true

Yes, I’ve tested one of my devices (Soil moisture sensor) with ESP32 based proxy.

I’ve used the site ESPHome Bluetooth Proxy to flash my ESP. If you like to flash it manually, parameter ‘active’ must be true.

1 Like

Thanks very much! ESPHome BT proxy working with ESP32 and an Adaprox fingerbot :slight_smile:

I’m going to first attempt to add your device to the integration. I think it’s better to open an issue in the GitHub repository and continue our conversation there.

1 Like

Will Do, Thank You! :slightly_smiling_face:

I am definitely interested, I have several LED recessed lights that use the Tuya BLE and my Home assistant Tuya integration broke when my free account expired. Such a pain. I would love to get local control of these.
I have a Bluetooth hub that came with the lights.
Let me know what I can do to help.
Thanks!

1 Like

Hi,

I just got one of those deveices but i’m having trouble adding in to HA. I’m constantly getting error that the device is not linked to the cloud, when i can clearly see it in the tuya developer acount. Any ideas what I’m doin wrong?

Also if i try several times I can get trough but then the integration cannto launch and i have the following error message in the log

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/config_entries.py", line 383, in async_setup
    result = await component.async_setup_entry(hass, self)
  File "/config/custom_components/tuya_ble/__init__.py", line 44, in async_setup_entry
    await device.initialize()
  File "/config/custom_components/tuya_ble/tuya_ble/tuya_ble.py", line 272, in initialize
    await self.update()
  File "/config/custom_components/tuya_ble/tuya_ble/tuya_ble.py", line 312, in update
    await self._send_packet(TuyaBLECode.FUN_SENDER_DEVICE_STATUS, bytes())
  File "/config/custom_components/tuya_ble/tuya_ble/tuya_ble.py", line 843, in _send_packet
    await self._ensure_connected()
  File "/config/custom_components/tuya_ble/tuya_ble/tuya_ble.py", line 593, in _ensure_connected
    client = await establish_connection(
  File "/usr/local/lib/python3.10/site-packages/bleak_retry_connector/__init__.py", line 344, in establish_connection
    await client.connect(
  File "/usr/src/homeassistant/homeassistant/components/bluetooth/wrappers.py", line 269, in connect
    connected = await super().connect(**kwargs)
  File "/usr/local/lib/python3.10/site-packages/bleak/__init__.py", line 531, in connect
    return await self._backend.connect(**kwargs)
  File "/usr/local/lib/python3.10/site-packages/bleak/backends/bluezdbus/client.py", line 204, in connect
    reply = await self._bus.call(
  File "/usr/local/lib/python3.10/site-packages/dbus_fast/aio/message_bus.py", line 371, in call
    await future
asyncio.exceptions.CancelledError