Giter Club home page Giter Club logo

tuya-iot-python-sdk's Introduction

Tuya IoT Python SDK

PyPI

PyPI - Downloads

PyPI - Python Version

A Python sdk for Tuya Open API, which provides basic IoT capabilities like device management, asset management and industry capabilities, helping you create IoT solutions. With diversified devices and industries, Tuya IoT Development Platform opens basic IoT capabilities like device management, AI scenarios, and data analytics services, as well as industry capabilities, helping you create IoT solutions.

Features

Base APIs

  • TuyaOpenAPI

    • connect
    • is_connect
    • get
    • post
    • put
    • delete
  • TuyaOpenMQ

    • start
    • stop
    • add_message_listener
    • remove_message_listener

APIs

  • TuyaDeviceListener
    • update_device
    • add_device
    • remove_device

Device control

  • TuyaDeviceManager
    • update_device_list_in_smart_home
    • update_device_caches
    • update_device_function_cache
    • add_device_listener
    • remove_device_listener
    • get_device_info
    • get_device_list_info
    • remove_device
    • remove_device_list
    • get_factory_info
    • factory_reset
    • get_device_status
    • get_device_list_status
    • get_device_functions
    • get_category_functions
    • get_device_specification
    • send_commands

Home

  • TuyaHomeManager
    • update_device_cache
    • query_scenes
    • trigger_scene
    • query_infrared_devices
    • trigger_infrared_commands

Assets

  • TuyaAssetManager
    • get_device_list
    • get_asset_info
    • get_asset_list

Possible scenarios

Prerequisite

Registration

Please check Tuya IoT Platform Configuration Guide to register an account on the Tuya IoT Platform, and get the required information. You need to create a Cloud project and complete the configuration of asset, user, and application. Then, you will get the username, password, Access ID, and Access Secret.

Usage

Installation

pip3 install tuya-iot-py-sdk

Sample code

OpenAPI Sample

Open IoT Hub Sample

Tuya Open API reference

Tuya opens up a variety of APIs covering business scenarios such as device pairing, smart home management, device control, and scene automation. You can call APIs according to API integration documents to implement applications.

For more information, see the documentation.

Issue feedback

You can provide feedback on your issue via Github Issue or Technical Ticket.

License

tuya-iot-py-sdk is available under the MIT license. Please see the LICENSE file for more info.

tuya-iot-python-sdk's People

Contributors

0x5e avatar 3v1n0 avatar dengweijun avatar fhempy avatar frenck avatar jhonattan-souza avatar jinjuan-li avatar onkelbeh avatar tsutsuku avatar yuvalabou avatar zephirenz avatar zlinoliver avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tuya-iot-python-sdk's Issues

tuya_iot getting error "Failed to establish a new connection"

I am getting a error where the API intermittently will fail to connect.

From what I can tell, the error causes the Tuya integration in Home Assistant to stop tracking device state. I have two devices, a light and a heat pump, and both are "frozen" in time after the error occurs. A reboot will usually fix the issue (presumably at the time of the reboot, the API is responsive again).

I can see multiple issues on Home Assistant Core which seem could be related:
home-assistant/core#63957
home-assistant/core#64077
home-assistant/core#65099
home-assistant/core#65524
home-assistant/core#65634
home-assistant/core#65758

I think one solution would be to use exponential backoff to retry the API. Based on the log below, it's looks to be trying a few times and then stops tracking state entirely.

Here's the most recent log from today, that shows the issue. Home Assistant shows no state change from 16:06 onwards.

2022-02-06 16:04:55 DEBUG (Thread-33) [tuya_iot] _on_log: Received PUBLISH (d0, q0, r0, m0), 'cloud/token/in/d249680c232bf1a26ec786b86fecbf0f', ...  (348 bytes)
2022-02-06 16:04:55 DEBUG (Thread-33) [tuya_iot] payload-> b'{"data":"dRgRVE73G2xRptoTBwYRK0o5qn+tmZWI+0Sadjg7p+jmFAPNqPDoQMSoWxiI7X62X0mAVEdXxSIK1ooNccSsMob3dCy5cx7t4SBdBSBhhpF+R/sAVw93LMPxvio06DqsgHu7nYUK4jOJ6ACEvb3roOoUgyKzMTLn80277aitytz2h0zqqUpBtojYaS1HUOApEfMiOiqJadn4K+tC3U4OboBuuSa2u1ZhLDtrFocRlGtjAWlupFrG58u/tvjGzn5z","protocol":4,"pv":"2.0","sign":"3d4f08833ce8be059c2a88b564dcb365","t":1644116694}'
2022-02-06 16:04:55 DEBUG (Thread-33) [tuya_iot] on_message: {'data': {'dataId': '3eeb7ae6-930c-4e3d-ac1c-399df3f0ba23', 'devId': '078443178caab57ec4c8', 'productKey': 'gylvqvz3p94i3zdn', 'status': [{'3': 24, 'code': 'temp_current', 't': '1644116694', 'value': 24}]}, 'protocol': 4, 'pv': '2.0', 'sign': '3d4f08833ce8be059c2a88b564dcb365', 't': 1644116694}
2022-02-06 16:04:55 DEBUG (Thread-33) [tuya_iot] mq receive-> {'data': {'dataId': '3eeb7ae6-930c-4e3d-ac1c-399df3f0ba23', 'devId': '078443178caab57ec4c8', 'productKey': 'gylvqvz3p94i3zdn', 'status': [{'3': 24, 'code': 'temp_current', 't': '1644116694', 'value': 24}]}, 'protocol': 4, 'pv': '2.0', 'sign': '3d4f08833ce8be059c2a88b564dcb365', 't': 1644116694}
2022-02-06 16:04:55 DEBUG (Thread-33) [tuya_iot] mq _on_device_report-> [{'3': 24, 'code': 'temp_current', 't': '1644116694', 'value': 24}]
2022-02-06 16:04:55 DEBUG (Thread-33) [homeassistant.components.tuya] Received update for device 078443178caab57ec4c8: {'switch': True, 'temp_set': 24, 'temp_current': 24, 'mode': 'cold', 'anion': False, 'temp_set_f': 61, 'temp_current_f': 32}
2022-02-06 16:05:18 DEBUG (Thread-33) [tuya_iot] _on_log: Sending PINGREQ
2022-02-06 16:05:18 DEBUG (Thread-33) [tuya_iot] _on_log: Received PINGRESP
2022-02-06 16:05:44 DEBUG (Thread-33) [tuya_iot] _on_log: Received PUBLISH (d0, q0, r0, m0), 'cloud/token/in/d249680c232bf1a26ec786b86fecbf0f', ...  (348 bytes)
2022-02-06 16:05:45 DEBUG (Thread-33) [tuya_iot] payload-> b'{"data":"iHsj7kaTxdR5zYikRVh0oQoBrIUDK6SZ59En0NdecuUV0bpkMJU/e8e97NrJZwaKX0mAVEdXxSIK1ooNccSsMob3dCy5cx7t4SBdBSBhhpF+R/sAVw93LMPxvio06DqsgHu7nYUK4jOJ6ACEvb3roOoUgyKzMTLn80277aitytyHLFff/vzp/sSHFYMNyxN/EfMiOiqJadn4K+tC3U4Obp+vMnCJhNITPzBgDfMAFmWXG93EDTzim9Aa7i73r2/y","protocol":4,"pv":"2.0","sign":"a414390bb2befd85584774524097bf2e","t":1644116743}'
2022-02-06 16:05:45 DEBUG (Thread-33) [tuya_iot] on_message: {'data': {'dataId': '218f257e-4c72-4f29-9410-387f5a60522d', 'devId': '078443178caab57ec4c8', 'productKey': 'gylvqvz3p94i3zdn', 'status': [{'3': 23, 'code': 'temp_current', 't': '1644116743', 'value': 23}]}, 'protocol': 4, 'pv': '2.0', 'sign': 'a414390bb2befd85584774524097bf2e', 't': 1644116743}
2022-02-06 16:05:45 DEBUG (Thread-33) [tuya_iot] mq receive-> {'data': {'dataId': '218f257e-4c72-4f29-9410-387f5a60522d', 'devId': '078443178caab57ec4c8', 'productKey': 'gylvqvz3p94i3zdn', 'status': [{'3': 23, 'code': 'temp_current', 't': '1644116743', 'value': 23}]}, 'protocol': 4, 'pv': '2.0', 'sign': 'a414390bb2befd85584774524097bf2e', 't': 1644116743}
2022-02-06 16:05:45 DEBUG (Thread-33) [tuya_iot] mq _on_device_report-> [{'3': 23, 'code': 'temp_current', 't': '1644116743', 'value': 23}]
2022-02-06 16:05:45 DEBUG (Thread-33) [homeassistant.components.tuya] Received update for device 078443178caab57ec4c8: {'switch': True, 'temp_set': 24, 'temp_current': 23, 'mode': 'cold', 'anion': False, 'temp_set_f': 61, 'temp_current_f': 32}
2022-02-06 16:05:46 DEBUG (Thread-33) [tuya_iot] _on_log: Received PUBLISH (d0, q0, r0, m0), 'cloud/token/in/d249680c232bf1a26ec786b86fecbf0f', ...  (348 bytes)
2022-02-06 16:05:46 DEBUG (Thread-33) [tuya_iot] payload-> b'{"data":"o0YNq9wgHukb77DoDinU4AuUfzTPUFHg+IryeGIOWKzNIAVp5B5j/Wgkgx/szz6WX0mAVEdXxSIK1ooNccSsMob3dCy5cx7t4SBdBSBhhpF+R/sAVw93LMPxvio06DqsgHu7nYUK4jOJ6ACEvb3roOoUgyKzMTLn80277aitytz2h0zqqUpBtojYaS1HUOApEfMiOiqJadn4K+tC3U4ObhBhjV4btFSnXJlvbvKV+bZjAWlupFrG58u/tvjGzn5z","protocol":4,"pv":"2.0","sign":"d93f9d396e76ae4d939f60f0a14e30f6","t":1644116745}'
2022-02-06 16:05:46 DEBUG (Thread-33) [tuya_iot] on_message: {'data': {'dataId': 'f0aba7ce-3878-4dca-80f2-20b6303ed5bf', 'devId': '078443178caab57ec4c8', 'productKey': 'gylvqvz3p94i3zdn', 'status': [{'3': 24, 'code': 'temp_current', 't': '1644116745', 'value': 24}]}, 'protocol': 4, 'pv': '2.0', 'sign': 'd93f9d396e76ae4d939f60f0a14e30f6', 't': 1644116745}
2022-02-06 16:05:46 DEBUG (Thread-33) [tuya_iot] mq receive-> {'data': {'dataId': 'f0aba7ce-3878-4dca-80f2-20b6303ed5bf', 'devId': '078443178caab57ec4c8', 'productKey': 'gylvqvz3p94i3zdn', 'status': [{'3': 24, 'code': 'temp_current', 't': '1644116745', 'value': 24}]}, 'protocol': 4, 'pv': '2.0', 'sign': 'd93f9d396e76ae4d939f60f0a14e30f6', 't': 1644116745}
2022-02-06 16:05:46 DEBUG (Thread-33) [tuya_iot] mq _on_device_report-> [{'3': 24, 'code': 'temp_current', 't': '1644116745', 'value': 24}]
2022-02-06 16:05:46 DEBUG (Thread-33) [homeassistant.components.tuya] Received update for device 078443178caab57ec4c8: {'switch': True, 'temp_set': 24, 'temp_current': 24, 'mode': 'cold', 'anion': False, 'temp_set_f': 61, 'temp_current_f': 32}
2022-02-06 16:06:18 DEBUG (Thread-33) [tuya_iot] _on_log: Sending PINGREQ
2022-02-06 16:06:18 DEBUG (Thread-33) [tuya_iot] _on_log: Received PINGRESP
2022-02-06 16:06:20 DEBUG (Thread-33) [tuya_iot] _on_log: Received PUBLISH (d0, q0, r0, m0), 'cloud/token/in/d249680c232bf1a26ec786b86fecbf0f', ...  (348 bytes)
2022-02-06 16:06:20 DEBUG (Thread-33) [tuya_iot] payload-> b'{"data":"gNFDOxLjZG3IJDxyG7mnzvfXpvkcj4kgIu1URZfC1e7Kt0mYlvr9LJd2Hc4Iab5nX0mAVEdXxSIK1ooNccSsMob3dCy5cx7t4SBdBSBhhpF+R/sAVw93LMPxvio06DqsgHu7nYUK4jOJ6ACEvb3roOoUgyKzMTLn80277aitytwwWOckLP1BaMf9gswE6vdBEfMiOiqJadn4K+tC3U4ObnNMQ2jHyxHDRK/NKMWvv4PlWZzn4sTjqROwVZy3mgVT","protocol":4,"pv":"2.0","sign":"c454868db621f241b62807100c47deb7","t":1644116779}'
2022-02-06 16:06:20 DEBUG (Thread-33) [tuya_iot] on_message: {'data': {'dataId': '1d448d81-3136-400b-8b8d-5bc35ebcf9ae', 'devId': '078443178caab57ec4c8', 'productKey': 'gylvqvz3p94i3zdn', 'status': [{'3': 25, 'code': 'temp_current', 't': '1644116779', 'value': 25}]}, 'protocol': 4, 'pv': '2.0', 'sign': 'c454868db621f241b62807100c47deb7', 't': 1644116779}
2022-02-06 16:06:20 DEBUG (Thread-33) [tuya_iot] mq receive-> {'data': {'dataId': '1d448d81-3136-400b-8b8d-5bc35ebcf9ae', 'devId': '078443178caab57ec4c8', 'productKey': 'gylvqvz3p94i3zdn', 'status': [{'3': 25, 'code': 'temp_current', 't': '1644116779', 'value': 25}]}, 'protocol': 4, 'pv': '2.0', 'sign': 'c454868db621f241b62807100c47deb7', 't': 1644116779}
2022-02-06 16:06:20 DEBUG (Thread-33) [tuya_iot] mq _on_device_report-> [{'3': 25, 'code': 'temp_current', 't': '1644116779', 'value': 25}]
2022-02-06 16:06:20 DEBUG (Thread-33) [homeassistant.components.tuya] Received update for device 078443178caab57ec4c8: {'switch': True, 'temp_set': 24, 'temp_current': 25, 'mode': 'cold', 'anion': False, 'temp_set_f': 61, 'temp_current_f': 32}
2022-02-06 16:06:25 DEBUG (Thread-18) [tuya_iot] Request: method = GET,                 url = https://openapi.tuyaus.com/v1.0/token/506c665c72bdc06091c264dac8ec4100,                params = None,                body = None,                t = 1644116785539
2022-02-06 16:06:30 ERROR (Thread-18) [root] Uncaught thread exception
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/urllib3/connection.py", line 174, in _new_conn
    conn = connection.create_connection(
  File "/usr/local/lib/python3.9/site-packages/urllib3/util/connection.py", line 72, in create_connection
    for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM):
  File "/usr/local/lib/python3.9/socket.py", line 954, in getaddrinfo
    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno -3] Try again

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/urllib3/connectionpool.py", line 703, in urlopen
    httplib_response = self._make_request(
  File "/usr/local/lib/python3.9/site-packages/urllib3/connectionpool.py", line 386, in _make_request
    self._validate_conn(conn)
  File "/usr/local/lib/python3.9/site-packages/urllib3/connectionpool.py", line 1040, in _validate_conn
    conn.connect()
  File "/usr/local/lib/python3.9/site-packages/urllib3/connection.py", line 358, in connect
    conn = self._new_conn()
  File "/usr/local/lib/python3.9/site-packages/urllib3/connection.py", line 186, in _new_conn
    raise NewConnectionError(
urllib3.exceptions.NewConnectionError: <urllib3.connection.HTTPSConnection object at 0x7f0c25d07460>: Failed to establish a new connection: [Errno -3] Try again

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/requests/adapters.py", line 440, in send
    resp = conn.urlopen(
  File "/usr/local/lib/python3.9/site-packages/urllib3/connectionpool.py", line 785, in urlopen
    retries = retries.increment(
  File "/usr/local/lib/python3.9/site-packages/urllib3/util/retry.py", line 592, in increment
    raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='openapi.tuyaus.com', port=443): Max retries exceeded with url: /v1.0/token/506c665c72bdc06091c264dac8ec4100 (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x7f0c25d07460>: Failed to establish a new connection: [Errno -3] Try again'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.9/threading.py", line 973, in _bootstrap_inner
    self.run()
  File "/usr/local/lib/python3.9/site-packages/tuya_iot/openmq.py", line 158, in run
    self.__run_mqtt()
  File "/usr/local/lib/python3.9/site-packages/tuya_iot/openmq.py", line 164, in __run_mqtt
    mq_config = self._get_mqtt_config()
  File "/usr/local/lib/python3.9/site-packages/tuya_iot/openmq.py", line 62, in _get_mqtt_config
    response = self.api.post(
  File "/usr/local/lib/python3.9/site-packages/tuya_iot/openapi.py", line 316, in post
    return self.__request("POST", path, None, body)
  File "/usr/local/lib/python3.9/site-packages/tuya_iot/openapi.py", line 238, in __request
    self.__refresh_access_token_if_need(path)
  File "/usr/local/lib/python3.9/site-packages/tuya_iot/openapi.py", line 164, in __refresh_access_token_if_need
    response = self.get(
  File "/usr/local/lib/python3.9/site-packages/tuya_iot/openapi.py", line 302, in get
    return self.__request("GET", path, params, None)
  File "/usr/local/lib/python3.9/site-packages/tuya_iot/openapi.py", line 266, in __request
    response = self.session.request(
  File "/usr/local/lib/python3.9/site-packages/requests/sessions.py", line 529, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/local/lib/python3.9/site-packages/requests/sessions.py", line 645, in send
    r = adapter.send(request, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/requests/adapters.py", line 519, in send
    raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: HTTPSConnectionPool(host='openapi.tuyaus.com', port=443): Max retries exceeded with url: /v1.0/token/506c665c72bdc06091c264dac8ec4100 (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x7f0c25d07460>: Failed to establish a new connection: [Errno -3] Try again'))
2022-02-06 16:07:19 DEBUG (Thread-33) [tuya_iot] _on_log: Sending PINGREQ
2022-02-06 16:07:19 DEBUG (Thread-33) [tuya_iot] _on_log: Received PINGRESP
2022-02-06 16:08:19 DEBUG (Thread-33) [tuya_iot] _on_log: Sending PINGREQ
2022-02-06 16:08:19 DEBUG (Thread-33) [tuya_iot] _on_log: Received PINGRESP
2022-02-06 16:09:19 DEBUG (Thread-33) [tuya_iot] _on_log: Sending PINGREQ
2022-02-06 16:09:19 DEBUG (Thread-33) [tuya_iot] _on_log: Received PINGRESP
2022-02-06 16:10:19 DEBUG (Thread-33) [tuya_iot] _on_log: Sending PINGREQ
2022-02-06 16:10:19 DEBUG (Thread-33) [tuya_iot] _on_log: Received PINGRESP
2022-02-06 16:11:19 DEBUG (Thread-33) [tuya_iot] _on_log: Sending PINGREQ
2022-02-06 16:11:20 DEBUG (Thread-33) [tuya_iot] _on_log: Received PINGRESP
2022-02-06 16:12:20 DEBUG (Thread-33) [tuya_iot] _on_log: Sending PINGREQ
2022-02-06 16:12:20 DEBUG (Thread-33) [tuya_iot] _on_log: Received PINGRESP
2022-02-06 16:13:20 DEBUG (Thread-33) [tuya_iot] _on_log: Sending PINGREQ
2022-02-06 16:13:20 DEBUG (Thread-33) [tuya_iot] _on_log: Received PINGRESP
2022-02-06 16:14:20 DEBUG (Thread-33) [tuya_iot] _on_log: Sending PINGREQ
2022-02-06 16:14:20 DEBUG (Thread-33) [tuya_iot] _on_log: Received PINGRESP
2022-02-06 16:15:20 DEBUG (Thread-33) [tuya_iot] _on_log: Sending PINGREQ
2022-02-06 16:15:21 DEBUG (Thread-33) [tuya_iot] _on_log: Received PINGRESP
2022-02-06 16:16:21 DEBUG (Thread-33) [tuya_iot] _on_log: Sending PINGREQ
2022-02-06 16:16:21 DEBUG (Thread-33) [tuya_iot] _on_log: Received PINGRESP
2022-02-06 16:17:21 DEBUG (Thread-33) [tuya_iot] _on_log: Sending PINGREQ
2022-02-06 16:17:21 DEBUG (Thread-33) [tuya_iot] _on_log: Received PINGRESP
2022-02-06 16:18:21 DEBUG (Thread-33) [tuya_iot] _on_log: Sending PINGREQ
2022-02-06 16:18:21 DEBUG (Thread-33) [tuya_iot] _on_log: Received PINGRESP
2022-02-06 16:19:21 DEBUG (Thread-33) [tuya_iot] _on_log: Sending PINGREQ
2022-02-06 16:19:21 DEBUG (Thread-33) [tuya_iot] _on_log: Received PINGRESP
2022-02-06 16:20:21 DEBUG (Thread-33) [tuya_iot] _on_log: Sending PINGREQ
2022-02-06 16:20:22 DEBUG (Thread-33) [tuya_iot] _on_log: Received PINGRESP
2022-02-06 16:21:22 DEBUG (Thread-33) [tuya_iot] _on_log: Sending PINGREQ
2022-02-06 16:21:22 DEBUG (Thread-33) [tuya_iot] _on_log: Received PINGRESP
2022-02-06 16:22:22 DEBUG (Thread-33) [tuya_iot] _on_log: Sending PINGREQ
2022-02-06 16:22:22 DEBUG (Thread-33) [tuya_iot] _on_log: Received PINGRESP

Stream only on the SUB(SD) profile and not on the MAIN(HD).

When comparing the stream from my local cameras with those in the cloud (Tuya), I could see that the default in the HA stream is in SD.

Is there any possibility to select (SUB/MAIN) or define MAIN as default?

For those who use NVR Frigate, the quality exported from the official Tuya integration - HA, impairs the detection of motion, objects, etc.

flood detector is not supported

Hi,

I have a flood detector in my tuya account. The api manages to see it, but the get_device_specification returns an error:

{'code': 2009, 'msg': 'not support this device', 'success': False, 't': 1634819747170}

The device details (redacted):

TuyaDevice(active_time=1634819598, biz_type=18, category='qt', create_time=1634810143, icon='smart/icon/ay1571196781060cNsAn/3fafd1da9189d454def861b3beafbf7f.png', id='81742188483fda843f70', ip='-----', lat='----', local_key='-----', lon='-----', model='Hey403', name='Flood Detector', online=True, owner_id='-----', product_id='tinzuhnp2osaxtd5', product_name='Hey! Flood Detector', status={}, sub=False, time_zone='----', uid='-----', update_time=1634819715, uuid='-----')

Who can I address to help get it supported?

Thanks

BHT-002 thermostats reports wrong temperature

BHT-002 thermostat (sometimes called Moes) temperature conversion is wrong.

The temperature to / from the thermostat through the Tuya Open API is reported as an "Integer data type".

According to:
https://developer.tuya.com/en/docs/iot/datatypedescription?id=K9i5ql2jo7j1k
-> The Integer value shall be divided by 10^(scale value) to get the temperature value in Celcius.

However, BHT-002 expects the integer value to be divided by 2^(scale value).

Is this an issue in the Tuya IoT Python SDK or in the firmware of the thermostat?

Note that the temperature is reported correctly in the Smart Life App, but it is reported incorrectly in the Tuya IoT Development Platform (https://auth.tuya.com/).

get energy stats?

Hi,
is there a way to get the energy statistics of the device via this API or via general cloud API calls? That would be really great, as that is an important feature for most of the users.

Thx!

ImportError: cannot import name 'Literal' from 'typing' using python 3.7.9

trying to run api.py from example, it shows the following errors:

File "api.py", line 2, in
from tuya_iot import TuyaOpenAPI, tuya_logger
File "C:\Users\yolo\AppData\Local\Programs\Python\Python37\lib\site-packages\tuya_iot_init_.py", line 2, in
from .device import TuyaDevice, TuyaDeviceListener, TuyaDeviceManager
File "C:\Users\yolo\AppData\Local\Programs\Python\Python37\lib\site-packages\tuya_iot\device.py", line 7, in
from typing import Any, Literal, Optional
ImportError: cannot import name 'Literal' from 'typing'

changing the import routes in device.py to from typing_extensions import Literal as suggested in stackoverflow gives the following error:

File "api.py", line 2, in
from tuya_iot import TuyaOpenAPI, tuya_logger
ImportError: cannot import name 'tuya_logger' from 'tuya_iot'

Intermittent failures in Home Assistant - "error while get mqtt config"

I am seeing intermittent issues in Home Assistant that started 2-3 days ago.
The logs show the following errors:

2021-12-15` 07:39:57 ERROR (Thread-5411) [tuya_iot] Unexpected disconnection.7
2021-12-15 07:40:01 ERROR (Thread-5411) [tuya_iot] Unexpected disconnection.5
2021-12-15 07:49:04 ERROR (Thread-5411) [tuya_iot] Unexpected disconnection.7
2021-12-15 11:37:53 ERROR (Thread-34) [tuya_iot] error while get mqtt config

Once this occurs, devices no longer reflect their current state in Home Assistant and changing the state (turning on\off\etc) does not work either.
Reloading the integration in Home Assistant works fine for a few hours which implies that the issue is intermittent but seems to put tuya_iot in a bad state until reloaded.

I've already checked the project on Tuya IoT to ensure all needed APIs are enabled as per instructions (also it was working fine for many weeks until the issues started a couple of days ago).

Given that the integration reload in Home Assistant fixes the issue, it seems that tuya_iot should be able to handle this as well by retrying\reconnecting\etc.

Connection pool is full, discarding connection

Hi,

I get a lot of those messages in my log

2021-09-19 09:28:23,914 - WARNING  - urllib3.connectionpool: Connection pool is full, discarding connection: openapi.tuyaeu.com
2021-09-19 09:28:23,923 - WARNING  - urllib3.connectionpool: Connection pool is full, discarding connection: openapi.tuyaeu.com
2021-09-19 09:28:23,998 - WARNING  - urllib3.connectionpool: Connection pool is full, discarding connection: openapi.tuyaeu.com
2021-09-19 09:28:24,002 - WARNING  - urllib3.connectionpool: Connection pool is full, discarding connection: openapi.tuyaeu.com
2021-09-19 09:28:24,012 - WARNING  - urllib3.connectionpool: Connection pool is full, discarding connection: openapi.tuyaeu.com

Based on this
home-assistant/core#38903 (comment)
the code needs to be adapted here
https://github.com/tuya/tuya-iot-python-sdk/blob/master/tuya_iot/openapi.py#L69

Can you help me on this one? Thanks!

Tag the source

It would be very helpful if you could tag releases as well. This would enable distributions to fetch the package from GitHub instead of Pypi, where the not all files are present, e.g., the license file.

Thanks

Unexpected disconnection.1 - tuya_iot/openmq.py line 121

Since running the Tuya V2 Home Assistant integration I got a massive amount of errors in the log:

`Logger: tuya iot
Source: /usr/local/lib/python3.9/site-packages/tuya_iot/openmq.py:121
First occurred: 2:13:32 AM (31669 occurrences)
Last logged: 2:22:26 PM

Unexpected disconnection.1`

More than 30000 in 12 hours time. After a while Home assistant goes into safe mode.

I have 3 tuya devices in my local network, 2 of them connected to home assistant (Bulb, shutter). A IR device isn´t available in home assistant, but in the SmartLife App.
In the App the devices works just fine.

Any suggestions?

Wrong endpoint url used in get_device_status implementation

Currently to get the device status according to Tuya developer API documentation (1) , it need the suffix '/status'
Without that suffix it uses another endpoint for device details, which won't return the status for some type of devices (could be also an issue at Tuya itself with 'sub devices').

https://github.com/tuya/tuya-iot-python-sdk/blob/main/tuya_iot/device.py#L592
Fix could be following

    def get_device_status(self, device_id: str) -> dict[str, Any]:
        return self.api.get(f"/v1.0/devices/{device_id}/status")

(1) https://eu.iot.tuya.com/cloud/explorer?id=p1672264192429jq7u3m&groupId=group-home&interfaceId=470224763027537

Robot Mower Support

I have a Tuya robot Mower, device code 'gcj', that I can control via the Tuya app on an Android phone but not via this Python SDK. It would seem there are no functions that are listed beyond the battery status.

Could you help identify what I'm doing wrong? I was hoping to try and add support to Home Assistant.

Thanks

openmq.py: mq_config not defined

I get the following exception:

Traceback (most recent call last):
File "/usr/lib/python3.8/threading.py", line 932, in _bootstrap_inner
self.run()
File "/home/nuc/.homeassistant/deps/lib/python3.8/site-packages/tuya_iot/openmq.py", line 174, in run
time.sleep(self.mq_config.expire_time - 60)
AttributeError: 'NoneType' object has no attribute 'expire_time'

Tuya Smart Door lock

Doodle smart door lock using Doodle API how to control? Anybody know that? thank you

Again issues with updates

It seems that there is again a bug in the tuya cloud. Notifications aren't sent correctly and therefore it happens that after some time (hours or days) no notifications are received.

We had that issue already some time ago and it was fixed in the tuya cloud. Please check again and fix it or at least provide local usage when the cloud remains that unstable. Thx!

Error when I try to retrive data

Hello,

I use that guide to retrieve data from my Fingerbot: https://www.home-assistant.io/integrations/tuya/

I also use that repo to extract the data:
https://github.com/redphx/tuya-local-key-extractor

When I use the extract.py file I get that error:

Exception in thread Thread-1: Traceback (most recent call last): openapi <tuya_iot.openapi.TuyaOpenAPI object at 0x7f7c4ccb24c0> openmq <TuyaOpenMQ(Thread-1, started 140171782297344)> File "/usr/lib/python3.8/threading.py", line 932, in _bootstrap_inner self.run() File "/home/xavier/.local/lib/python3.8/site-packages/tuya_iot/openmq.py", line 158, in run self.__run_mqtt() File "/home/xavier/.local/lib/python3.8/site-packages/tuya_iot/openmq.py", line 164, in __run_mqtt mq_config = self._get_mqtt_config() File "/home/xavier/.local/lib/python3.8/site-packages/tuya_iot/openmq.py", line 67, in _get_mqtt_config "uid": self.api.token_info.uid, AttributeError: 'NoneType' object has no attribute 'uid' Traceback (most recent call last): File "./extract.py", line 31, in <module> device_manager.update_device_list_in_smart_home() File "/home/xavier/.local/lib/python3.8/site-packages/tuya_iot/device.py", line 239, in update_device_list_in_smart_home response = self.api.get(f"/v1.0/users/{self.api.token_info.uid}/devices") AttributeError: 'NoneType' object has no attribute 'uid'

Here is the code I use:

import json
import logging
import os

from config import (
    ENDPOINT,
    APP,
    EMAIL,
    PASSWORD,
    ACCESS_ID,
    ACCESS_KEY,
)

from tuya_iot import (
    TuyaOpenAPI,
    AuthType,
    TuyaOpenMQ,
    TuyaDeviceManager,
)


openapi = TuyaOpenAPI(ENDPOINT, ACCESS_ID, ACCESS_KEY, AuthType.SMART_HOME)
openapi.connect(EMAIL, PASSWORD, country_code=84, schema=APP.value)

openmq = TuyaOpenMQ(openapi)
openmq.start()

print('openapi {}'.format(openapi))
print('openmq {}'.format(openmq))
device_manager = TuyaDeviceManager(openapi, openmq)
device_manager.update_device_list_in_smart_home()

devices = []
for tuya_device in device_manager.device_map.values():
    device = {
        'device_id': tuya_device.id,
        'device_name': tuya_device.name,
        'product_id': tuya_device.product_id,
        'product_name': tuya_device.product_name,
        'category': tuya_device.category,
        'uuid': tuya_device.uuid,
        'local_key': tuya_device.local_key,
    }

    try:
        resp = openapi.get('/v1.0/iot-03/devices/factory-infos?device_ids={}'.format(tuya_device.id))
        factory_info = resp['result'][0]
        if 'mac' in factory_info:
            mac = ':'.join(factory_info['mac'][i:i + 2] for i in range(0, 12, 2))
            device['mac_address'] = mac
    except Exception as e:
        print(e)

    devices.append(device)

print(json.dumps(devices, indent=2))
os._exit(0)

I am on Ubuntu 20.04 and I install the python sdk with tha t command:
pip3 install tuya-iot-py-sdk

Error code "1010" causing a "token invalid"

Hi, I am getting an error {'code': 1010, 'msg': 'token invalid', 'success': False, 't': 1682574088236, 'tid': '27e13586e4be11eda0c0360158882c1b'}.

Here is my code

from tuya_iot import TuyaOpenAPI
import json

secrets = json.load(open('secret.json', 'r'))

ACCESS_ID = secrets['access_id']
ACCESS_KEY = secrets['access_key']

ENDPOINT = secrets['endpoint']

USERNAME = secrets['username']
PASSWORD = secrets['password']

LIGHTBULB_DEVICE_ID = secrets['lightbulb_device_id']

openapi = TuyaOpenAPI(ENDPOINT, ACCESS_ID, ACCESS_KEY)
openapi.connect(USERNAME, PASSWORD)

commands = {
    'commands': [
        {
            'code': 'switch_led',
            'value': True
        }
    ]
}

result = openapi.post(
    f'/v1.0/iot-03/devices/{LIGHTBULB_DEVICE_ID}/commands', commands)
print(result)

Thank You,

work_mode change can be lost if sent with brightness

As documented in home-assistant/core#58569, if an RGBCCT bulb is in work_mode colour, then sending a command that has switch_led, work_mode, and temp_value_v2 will correctly transition the bulb to color temperature mode at the requested brightness. I.e.:

{
  'switch_led': True,
  'work_mode': 'white',
  'temp_value_v2': 0,
  'bright_value_v2': 1000
}

will produce a response like:

{
  'switch_led': True,
  'work_mode': 'white',
  'bright_value_v2': 1000,
  'temp_value_v2': 0,
  'colour_data_v2': '{"h":30,"s":1000,"v":39}',
  'scene_data_v2': '{"scene_num":1,"scene_units"[{"bright":200,"h":0,"s":0,"temperature":0,"unit_change_mode":"static","unit_gradient_duration":13,"unit_switch_duration":14,"v":0}]}',
  'countdown_1': 0,
  'control_data': ''
}

However, a subsequent command that tries to change it back to colour with a different brightness:

{
  'switch_led': True,
  'work_mode': 'colour',
  'bright_value_v2': 49,
  'colour_data_v2': {"h": 20, "s": 1000, "v": 39},
}

will update the brightness and the colour_data, but not change work_mode, as demonstrated in the response:

{
  'switch_led': True,
  'work_mode': 'white',    <-- should have been updated to 'colour'
  'bright_value_v2': 49,
  'temp_value_v2': 0,
  'colour_data_v2': '{"h":20,"s":1000,"v":39}',
  'scene_data_v2': '{"scene_num":1,"scene_units":[{"bright":200,"h":0,"s":0,"temperature":0,"unit_change_mode":"static","unit_gradient_duration":13,"unit_switch_duration":14,"v":0}]}',
  'countdown_1': 0,
  'control_data': ''
}

The desired final state can only be achieved by sending two commands, one for the color setting, and one for brightness.

Reproduced in Home Assistant 2021.11.0b0 which is using tuya-iot-py-sdk 0.6.3.

Token is never refreshed

if self.is_connect() is False:

But is_connect() never check if the token is expired.

Besides, this bug needs more than a one-line fix. You have another hidden problem in your code:

__request() => __refresh_access_token_if_need() => post() => __request() => __refresh_access_token_if_need()

Currently the loop breaks because of is_connect() == True. However, you should be aware that once you fix the bug mentioned above, you must also check whether path.startswith(TO_C_REFRESH_TOKEN_API).

Returns the modified DPcode

def __update_device(self, device: TuyaDevice, DPcode: str, value):
    # await hass.bus.async_fire(event_name, event_data)
    for listener in self.device_listeners:
        listener.update_device(device)     #Returns the modified DPcode

def _on_device_report(self, device_id: str, status: list):
    device = self.device_map.get(device_id, None)
    if not device:
        return
    logger.debug(f"mq _on_device_report-> {status}")
    for item in status:
        if "code" in item and "value" in item:
            code = item["code"]
            value = item["value"]
            device.status[code] = value

    self.__update_device(device)

code: 1004 sign invalid

I get an error with the following code.
Is there a workaround?

from tuya_iot import TuyaOpenAPI, AuthType

api = TuyaOpenAPI("https://openapi.tuyaus.com", "<id>", "<secret>", AuthType.SMART_HOME)
res = api.connect("<user>", "<pass>", "<country>", "smartlife")
{"code": 1004, "msg": "sign invalid", "success": false, "t": ***}

tuya-iot-py-sdk version is 0.5.0

MAC check fails on device rename

Raising a value error in TuyaOpenMQ when I update a device's name through the tuya smart mobile app. After this error, I no longer receive any data in the message listener.

Error

Exception in thread Thread-2 (_thread_main):
Traceback (most recent call last):
  File "C:\Users\sarah\AppData\Local\Programs\Python\Python310\lib\threading.py", line 1009, in _bootstrap_inner
    self.run()
  File "C:\Users\sarah\AppData\Local\Programs\Python\Python310\lib\threading.py", line 946, in run
    self._target(*self._args, **self._kwargs)
  File "D:\Programming\PycharmProjects\test-tuya\venv\lib\site-packages\paho\mqtt\client.py", line 3591, in _thread_main
    self.loop_forever(retry_first_connection=True)
  File "D:\Programming\PycharmProjects\test-tuya\venv\lib\site-packages\paho\mqtt\client.py", line 1756, in loop_forever
    rc = self._loop(timeout)
  File "D:\Programming\PycharmProjects\test-tuya\venv\lib\site-packages\paho\mqtt\client.py", line 1164, in _loop
    rc = self.loop_read()
  File "D:\Programming\PycharmProjects\test-tuya\venv\lib\site-packages\paho\mqtt\client.py", line 1556, in loop_read
    rc = self._packet_read()
  File "D:\Programming\PycharmProjects\test-tuya\venv\lib\site-packages\paho\mqtt\client.py", line 2439, in _packet_read
    rc = self._packet_handle()
  File "D:\Programming\PycharmProjects\test-tuya\venv\lib\site-packages\paho\mqtt\client.py", line 3033, in _packet_handle
    return self._handle_publish()
  File "D:\Programming\PycharmProjects\test-tuya\venv\lib\site-packages\paho\mqtt\client.py", line 3327, in _handle_publish
    self._handle_on_message(message)
  File "D:\Programming\PycharmProjects\test-tuya\venv\lib\site-packages\paho\mqtt\client.py", line 3570, in _handle_on_message
    on_message(self, self._userdata, message)
  File "D:\Programming\PycharmProjects\test-tuya\venv\lib\site-packages\tuya_iot\openmq.py", line 137, in _on_message
    decrypted_data = self._decode_mq_message(
  File "D:\Programming\PycharmProjects\test-tuya\venv\lib\site-packages\tuya_iot\openmq.py", line 110, in _decode_mq_message
    plaintext = cipher.decrypt_and_verify(data_buffer, tag_buffer).decode(
  File "D:\Programming\PycharmProjects\test-tuya\venv\lib\site-packages\Crypto\Cipher\_mode_gcm.py", line 567, in decrypt_and_verify
    self.verify(received_mac_tag)
  File "D:\Programming\PycharmProjects\test-tuya\venv\lib\site-packages\Crypto\Cipher\_mode_gcm.py", line 508, in verify
    raise ValueError("MAC check failed")
ValueError: MAC check failed

Minimal Reproducible Code

from tuya_iot import TuyaOpenAPI, AuthType, TuyaAssetManager, TuyaOpenMQ
BASE = "https://openapi.tuyaeu.com"
client_api = TuyaOpenAPI(
   BASE, access_id, secret, auth_type=AuthType.CUSTOM
)
asset_client = TuyaAssetManager(client_api)
iot_hub = TuyaOpenMQ(client_api)
client_api.connect(username, password)
def event(d):
   print(d) # No longer prints after the error was raised.

iot_hub.add_message_listener(event)
iot_hub.start()

After running you would just have to change the name of any device.

If you need more code, the full code is on my repository: https://github.com/InterStella0/discord-iot-bot

Problem in connection. 'skill id invalid' Error.

I'm trying to connect Tuya Cloud by the following line:

openapi.connect(USERNAME, PASSWORD, country_code, schema)

This gives me the following response:

{'code': 2406,
 'msg': 'skill id invalid',
 'success': False,
 't': 1678601679934,
 'tid': '2c049292c09d11edbcdaea52450d735d'}

I guess skill id invalid is country_code related problem. Here it is 49 since my data center is Central Europe Data Center, and location of this data center is in Germany. I found this from this doc:
https://developer.tuya.com/en/docs/iot/Data_Center_Introduction?id=Kav2hlac2ppnw

I tried it with other country code under Central Europe Data Center.
https://developer.tuya.com/en/docs/iot/oem-app-data-center-distributed?id=Kafi0ku9l07qb
Still no luck!

ImportError: cannot import name 'Literal' from 'typing' (/usr/lib64/python3.7/typing.py)

line 1, in <module>
    from tuya_iot import TuyaOpenAPI
  File "/usr/local/lib/python3.7/site-packages/tuya_iot/__init__.py", line 2, in <module>
    from .device import TuyaDevice, TuyaDeviceListener, TuyaDeviceManager
  File "/usr/local/lib/python3.7/site-packages/tuya_iot/device.py", line 7, in <module>
    from typing import Any, Literal, Optional
ImportError: cannot import name 'Literal' from 'typing' (/usr/lib64/python3.7/typing.py)

python/typing#707 explains that is how it's staying in 3.7 stdlib & suggests using typing_extensions

OpenMQ conflict if used in two different HomeAssistant integrations

Hi, I am facing an issue using OpenMQ. I am trying to use it in a custom integration I am developing, and I am using the official Tuya Integration at the same time.
What I am experiencing is that I have set a message listener with the openmq.add_message_listener command, but at that point, I see that some status messages are received by the official Tuya Integration's listener, and some by my integration's one: they keep stealing the messages to each other, leading to having non-consistent status for the devices in both integrations.
Note that, if I launch the same code in a script (outside HomeAssistant) at the same time, it works perfectly and receives all the messages (that are divided between the two Integrations in HomeAssistant).
So, questions:

  • is this an expected behavior or is it a bug?
  • in any case, how can I overcome it and have both Integrations receive all the messages?

Thank you

`sign invalid` problem for device logs query.

The following api request works fine:

res = openapi.get('/v1.0/iot-03/devices/{}/status'.format(DEVICE_ID))

However, when I request for device logs it returns sign invalid.

res = openapi.get("/v1.0/iot-03/devices/{}/logs?end_time=9999999999999&start_time=0&event_types=1".format(DEVICE_ID))

This is confusing. How to fix this problem?

Feature request: add battery_low information

Hi @tsutsuku. Thank for the effort of maintaining this repo.

From what it states in the doc of Tuya open API, the returned message seems to contain a field called battery_low indicating if the battery is low(obviously). But this field is missing in the device information. Is the return message just for demo purpose? If not, it shouldn't be hard to add the missing part, right?

Thx.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.