Giter VIP home page Giter VIP logo

tinytuya's Introduction

Welcome! โšก Key Projects

  • Build-OpenSSL-cURL - Build OpenSSL, nghttp2 and curl for MacOS (Intel & Apple Silicon), iOS and tvOS.
  • TinyTuya - Python PyPI module to interface with Tuya WiFi smart devices.
  • Powerwall-Dashboard - Dashboard for local monitoring of Tesla Powerwall using Grafana.
  • pyPowerwall - Python PyPI module to interface with Tesla Energy Powerwall Gateways.
  • TM1637TinyDisplay - Arduino library to display numbers and text on 4 and 6 digit 7-segment TM1637 display modules.
  • TinyStepper - Arduino library to drive stepper motors. Simple, small and easy to use.
  • Ender3-Filament-Digital-Scale - Digital filament scale for Creality Ender-3 3D Printer.
  • TinySplunk - Tools and instructions to build and use a free version of Splunk for home.
  • ATtiny85-Weather-Station - ATtiny85 based digital weather station for temp, humidity and pressure.
  • OpenGL-LIDAR-Display - Display realtime LIDAR point cloud data from Slamtec RPLIDAR via OpenGL.
  • GridBug - Simple visualization to show network connectivity between multiple nodes.
  • TinyLLM - Setup and run a local LLM and Chatbot using consumer grade hardware.

๐Ÿ’ฌ @jasonacox | ๐ŸŒŽ jasonacox.com | ๐Ÿ”— LinkedIn

tinytuya's People

Contributors

bikerglen avatar clusterm avatar cowboy3d avatar cy1110 avatar dormant-user avatar elfman03 avatar elockman avatar eykamp avatar fajarmnrozaki avatar felix-pi avatar fr3dz10 avatar gstein avatar jasonacox avatar knrdl avatar leodenham avatar mafrosis avatar mschlenstedt avatar nyok92 avatar osomdev avatar pawel-szopinski avatar pkasprzyk avatar poil avatar syrooo avatar teejo75 avatar theonlywayup avatar unit-404 avatar uzlonewolf avatar valentindusollier avatar whytey avatar xgustavoh 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

tinytuya's Issues

Missing New Authorization instruction for the project in Setup Wizard step

Hello,

I was getting KeyError: 'result' errors when running the wizard after following the instruction to subscribe in API Products:

IMPORTANT Under "Cloud" -> select your project -> "API Management" -> "API Products" that the following API groups have status "Subscribed": Smart Home Devices Management, Authorization and Smart Home Family Management (see screenshot here)

After authorizing each API Product above to my project as described in https://github.com/codetheweb/tuyapi/blob/master/docs/SETUP.md#linking-a-tuya-device-with-smart-link like below

Click into the Product and click Subscribe
Select the free tier and Buy Now
Click back to the API Products page and select the API again
Click to the Projects tab
Click **New Authorization
Select your Project from the dropdown and click OK

I am able to complete the wizard successfully (note: I did not have to subscribe to Smart Home Data Service
Smart Home Scene Linkage as mentioned in the tuyapi documentation).

Can't get .status() from switch

Hi,

i can get the status from my 10 lamps, but when I try to get a status from a switch, i get the following error. This is my code:

a = tinytuya.OutletDevice('here_is_my_key', '192.168.178.46', 'secret_key_here')
a.set_version(3.3)
data =  a.status()
print(data)

And this error occurs:

Traceback (most recent call last):
  File "tuya.py", line 89, in <module>
    data =  a.status()
  File "/home/pi/tinytuya/tinytuya/__init__.py", line 405, in status
    result = json.loads(result)
  File "/usr/lib/python3.7/json/__init__.py", line 348, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python3.7/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python3.7/json/decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

Event listener

Hi all,

I was Tuya dimming units that can also can be switched by a physical switch. I would like to receive an update through the socket connected to the device to know when that happens, so i can sync my Dashboard (Openhab). Anyone any success in getting this to
work?
I think i could add a listener to the socket on the device object directly, but it seems like a hack to me: what happens when the the socket closes and a new one is made? I assume the socket listener is gone then as well. Also, i may read data which is the response to a command instead of a physical switch...

Any thoughts?

thanks! Michiel

Sensor devices

How can I connect a TEmp/Hum sensor fron tuya ?. It works in my app but cant fint it in tinytuya.
Is there a class for Sensor Devices such as Temp/Hum sensors?

I found the block descriptor Version 3.3 - Sensor Type.

Fast color changing

Hi, I came across a certain problem.

I am trying to make my BulbDevice change color every 0.2 second. The desired effect is blinking light.
Unfortunately, while program is running, bulb starts blinking in a desired way, but after a few blinkings it starts pulsating and then stars blinking again. I change color from (255, 0, 255) to (0, 0, 0) and by "pulsating" I mean that bulb only darkens a little and comes back to (255, 0, 255). I am wondering now, if it results from bulb limitations or it is something wrong with my code.

My code:

import tinytuya
import time
import random

d = tinytuya.BulbDevice('x', 'x', 'x, 'device22')
d.set_dpsUsed({"1": None})
d.set_version(3.3) 
d.set_socketPersistent(True)
d.set_socketNODELAY(False)

for i in range(100):
    d.set_colour(255, 0, 255)
    time.sleep(0.2)
    d.set_colour(0, 0, 0)
    time.sleep(0.2)

Error when using 'wizzard'

After typing the: api key, secret, deviceId and region.
tiny python gives some python error:
Traceback (most recent call last): File "/usr/local/Cellar/[email protected]/3.9.1_6/Frameworks/Python.framework/Versions/3.9/lib/python3.9/runpy.py", line 197, in _run_module_as_main return _run_code(code, main_globals, None, File "/usr/local/Cellar/[email protected]/3.9.1_6/Frameworks/Python.framework/Versions/3.9/lib/python3.9/runpy.py", line 87, in _run_code exec(code, run_globals) File "/usr/local/lib/python3.9/site-packages/tinytuya/__main__.py", line 48, in <module> tinytuya.wizard(color) File "/usr/local/lib/python3.9/site-packages/tinytuya/__init__.py", line 1548, in wizard uid = response_dict['result']['uid'] KeyError: 'result'

scan not showing device ID

py -m tinytuya scan -nocolor

TinyTuya (Tuya device scanner) [1.1.3]

Scanning on UDP ports 6666 and 6667 for devices (15 retries)...

  • Unexpected payload=%r
    b"\xd0\x97fgo3i\xeb\x10\xb5\xe9\xf12\xfd\x80*\xc1w\xcf=\x9e\xc5\xe6\x8dD\xed'\xad\xe5\xe7U0\xde\x19\xf6\x08\xc0\xf6\x16&\xb1\xf8w\x87'\x97\xc
    ao\x1a{\xcbu\xef[\xb8\xeb3\n\xd3D\xdd\x0b\x10h\xdb\x19\xaf\x80#H\xb8\x03B\x1e@\xba\n{|x\xfa@g\xfbZs\x89\xaf\xbe\xaf\x88\n\x12\xd3\xbbl\x9f9`\x
    8aV\xbc\x82\x10\x8d\xd9\x84\xa5\xbf\xdc\x87\xe3ZtL95'>\xa5*ez\xcc\xeeOT\xa4\xa1,\xcaMo\xba\xcc\x17l\xe6\xa4\x01T\xedr2b\x7f,=\x9cGDX^G\x1bj/\x
    c4y\xca"
    Device Found [Unknown payload]: 192.168.1.3
    ID = , Product ID = , Version =
    No Stats - Device Key required to poll for status
  • Unexpected payload=%r
    b"\xd0\x97fgo3i\xeb\x10\xb5\xe9\xf12\xfd\x80*\xc1w\xcf=\x9e\xc5\xe6\x8dD\xed'\xad\xe5\xe7U0\xde\x19\xf6\x08\xc0\xf6\x16&\xb1\xf8w\x87'\x97\xc
    ao\x1a{\xcbu\xef[\xb8\xeb3\n\xd3D\xdd\x0b\x10h\xdb\x19\xaf\x80#H\xb8\x03B\x1e@\xba\n{|x\xfa@g\xfbZs\x89\xaf\xbe\xaf\x88\n\x12\xd3\xbbl\x9f9`\x
    8aV\xbc\x82\x10\x8d\xd9\x84\xa5\xbf\xdc\x87\xe3ZtL95'>\xa5*ez\xcc\xeeOT\xa4\xa1,\xcaMo\xba\xcc\x17l\xe6\xa4\x01T\xedr2b\x7f,=\x9cGDX^G\x1bj/\x
    c4y\xca"
  • Unexpected payload=%r
    b"\xd0\x97fgo3i\xeb\x10\xb5\xe9\xf12\xfd\x80*\xc1w\xcf=\x9e\xc5\xe6\x8dD\xed'\xad\xe5\xe7U0\xde\x19\xf6\x08\xc0\xf6\x16&\xb1\xf8w\x87'\x97\xc
    ao\x1a{\xcbu\xef[\xb8\xeb3\n\xd3D\xdd\x0b\x10h\xdb\x19\xaf\x80#H\xb8\x03B\x1e@\xba\n{|x\xfa@g\xfbZs\x89\xaf\xbe\xaf\x88\n\x12\xd3\xbbl\x9f9`\x
    8aV\xbc\x82\x10\x8d\xd9\x84\xa5\xbf\xdc\x87\xe3ZtL95'>\xa5*ez\xcc\xeeOT\xa4\xa1,\xcaMo\xba\xcc\x17l\xe6\xa4\x01T\xedr2b\x7f,=\x9cGDX^G\x1bj/\x
    c4y\xca"
  • Unexpected payload=%r
    b"\xd0\x97fgo3i\xeb\x10\xb5\xe9\xf12\xfd\x80*\xc1w\xcf=\x9e\xc5\xe6\x8dD\xed'\xad\xe5\xe7U0\xde\x19\xf6\x08\xc0\xf6\x16&\xb1\xf8w\x87'\x97\xc
    ao\x1a{\xcbu\xef[\xb8\xeb3\n\xd3D\xdd\x0b\x10h\xdb\x19\xaf\x80#H\xb8\x03B\x1e@\xba\n{|x\xfa@g\xfbZs\x89\xaf\xbe\xaf\x88\n\x12\xd3\xbbl\x9f9`\x
    8aV\xbc\x82\x10\x8d\xd9\x84\xa5\xbf\xdc\x87\xe3ZtL95'>\xa5*ez\xcc\xeeOT\xa4\xa1,\xcaMo\xba\xcc\x17l\xe6\xa4\x01T\xedr2b\x7f,=\x9cGDX^G\x1bj/\x
    c4y\xca"

Scan Complete! Found 1 devices.

On scanning i am not getting device details like version, device id
These are beca thermostat sensor it was working fine before, Now it is not showing anything
Please help

Multiple DPS

Hi,

I was wondering how to set multiple DPS in one request? F.e. i want to turn on a dimmer and set the dimming value in the same request. The devices support the following format i got from Googling around:

{multiple: true,data: {'1': true,'2': 50}}

Any thoughts?

Thanks!!

Different / Varied Failure Cases

Hi,

Really liking tinytuya - appreciate it! But I admit, seeing some odd results here. I think that's my specialty though ... ๐Ÿคฃ.

I am polling my devices on a regular basis, using them for power monitoring (of some switches providing energy monitoring capability). But ... relatively often (i.e. 10+ times a day), they cause my code to "yell", for a few different reasons. So attaching my code below, as well as some of the error messages. And a few thoughts,

  1. I was going to add code to check for the recently added Error status ... but nothing is there in the case of passing results? Thinking there should always be a return status? Just to avoid try ... catch loops (they just seem nasty, LOL!)
  2. I seem to be seeing different outcomes and failures, some of them not caught (reported) by the Error status. Or am I missing it?

My code, called inside the loop, with except to let me know what kinds of failure I am seeing,

        try:
            device = tinytuya.OutletDevice(currdevice['id'], currdevice['hostname'], currdevice['key'])
            device.set_version(currdevice['ver'])
            device.set_socketPersistent(True)
            device.updatedps()
            currData = device.status()
            if currdevice['ver'] == 3.1:
                time.sleep(0.5)
            dps = currData["dps"]
            # Check for power data - DP 19 on some 3.1/3.3 devices
            W = A = V = 0
            if "19" in dps.keys():
                W = float(dps['19']) / 10.0
                A = float(dps['18']) / 1000.0
                V = float(dps['20']) / 10.0
            # Check for power data - DP 5 for some 3.1 devices
            elif "5" in dps.keys():
                W = float(dps["5"]) / 10.0
                A = float(dps["4"]) / 1000.0
                V = float(dps["6"]) / 10.0
            # Return power measurement results
            return {'Current': A, 'Power': W, 'Voltage': V}
        except OSError:
            print("[OSError] Error reading Tuya power meter, ", currdevice['hostname'])
            return None
        except ValueError:
            print("[ValueError] Error reading Tuya power meter, ", currdevice['hostname'])
            return None
        except KeyError:
            print("[KeyError] Error reading Tuya power meter, ", currdevice['hostname'])
            print("[KeyError] Data, ", currData)
            return None
        except TypeError:
            print("[TypeError] Error reading Tuya power meter, ", currdevice['hostname'])
            print("[TypeError] Data, ", currData)
            return None

And, some of the exceptions (some normal / caught, others not,

[KeyError] Error reading Tuya power meter,  emFrontSwitch [KeyError] Data,  {'Error': 'Network Error: Unable to Connect', 'Err': '901', 'Payload': None}
[TypeError] Error reading Tuya power meter,  emRussell [TypeError] Data,  None
[KeyError] Error reading Tuya power meter,  emWinServer [KeyError] Data,  {'dps': {'18': 530, '19': 642}, 't': 1617010003}
[KeyError] Error reading Tuya power meter,  emRussell [KeyError] Data,  {'Error': 'Network Error: Device Unreachable', 'Err': '905', 'Payload': None}

And this one, when using the data (somehow wrong data type?),

influxdb.exceptions.InfluxDBClientError: 400: {"error":"partial write: field type conflict: input field \"value\" on measurement \"Current\" is type integer, already exists as type float dropped=3"}

Thanks!

Empty Payload Response

Hi,
I'm using an Energizer bulb I realized was talking to the Tuya servers. It works from the Tuya app, but Tuya demands that I use their beta IoT solutions app, and when I try to control it locally I get the following error.

DEBUG:raw unpacked message = TuyaMessage(seqno=1, cmd=10, retcode=1, payload=b"\x96\xa2\x8d\x9dB\xf1\xcc\xae\xe6{K\xc9'\xe8\x19\x11\xab\xbf\x8dL\x91v\x13\xa9!\xd2\xdck\x89\xc1\x96n", crc=2352078917) DEBUG:decode payload=b"\x96\xa2\x8d\x9dB\xf1\xcc\xae\xe6{K\xc9'\xe8\x19\x11\xab\xbf\x8dL\x91v\x13\xa9!\xd2\xdck\x89\xc1\x96n" DEBUG:decrypting=b"\x96\xa2\x8d\x9dB\xf1\xcc\xae\xe6{K\xc9'\xe8\x19\x11\xab\xbf\x8dL\x91v\x13\xa9!\xd2\xdck\x89\xc1\x96n" DEBUG:decrypted 3.3 payload='' DEBUG:decoded results='' DEBUG:ERROR Invalid JSON Response from Device - 900 - payload: "" DEBUG:status() received data={'Error': 'Invalid JSON Response from Device', 'Err': '900', 'Payload': ''}

This is after requesting a status. It is worth noting I cannot poll locally.

[WinError 10054]

Sometimes this error appears, probably because a connection hasnt been closed before connecting to it again. How would I make sure that a connection to a device is closed?

Exception when status() receives 28byte payload

I got a local key via the wizard, construct an OutletDevice, and invoke status(). Sometimes it works but often it crashes with an exception (below).

I believe there's a bug in the following line. The device is sending me a 28 byte response. This line should test "len(data) <= 28" to catch the 28-byte case, and try again. But it's not catching the 28 byte response, and so isn't retrying. Once I changed this line in the tinytuya library to be "<= 28" rather than "< 28", then my invocations of status() all started working reliably.

                # Some devices fail to send full payload in first response
                # Note - some devices respond with len = 28 for error response
                if self.retry and len(data) < 28:  
                    time.sleep(0.1)
                    data = self.socket.recv(1024)  # try again

Here is the debug trace from when I invoked status(). (the line numbers are marginally off because I deleted a few python2-compatible lines from my copy of tinytuya.py so it would pass clean in MyPy).

DEBUG:tinytuya:status() entry (dev_type is default)
DEBUG:tinytuya:json_payload=b'{"gwId":"10871285d8bfc016260e","devId":"10871285d8bfc016260e","uid":"10871285d8bfc016260e","t":"1610307603"}'
DEBUG:tinytuya:status received data=b'\x00\x00U\xaa\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x0c\x00\x00\x00\x00x\x93p\x91\x00\x00\xaaU'
DEBUG:tinytuya:result=b''
[2021-01-10 11:40:03.156686] Table lamps: exception - TypeError('ord() expected a character, but string of length 0 found')
Traceback (most recent call last):
  File "./lights.py", line 92, in set_dimmer_loop
    status = device.status()
  File "/Users/ljw/code/bell/tinytuya.py", line 484, in status
    result = cipher.decrypt(result, False)
  File "/Users/ljw/code/bell/tinytuya.py", line 162, in decrypt
    return self._unpad(raw).decode('utf-8')
  File "/Users/ljw/code/bell/tinytuya.py", line 177, in _unpad
    return s[:-ord(s[len(s)-1:])]
TypeError: ord() expected a character, but string of length 0 found

Timeout errors while toggling device state

I'm sure there's something I'm doing wrong here, but every time I try to set the state of my OutletDevice I get timeout errors. I checked this with the example test.py too. I followed all the instructions for getting the device key and checked through them multiple times, and watched the linked video as well. I can get the device state fine, I just can't set it, which is what leads me to believe it's something to do with the device key. Any help or explanation as to what is happening here would be much appreciated.

Thank you

status() Shutting Off Power on v3.1 Device

OK, I thought I was crazy before (in fairness, I likely was ๐Ÿ˜†), but now seeing it a second time. Let me explain ...

  1. Had an earlier Tuya switch, it was v3.1 - and it seemed like when I did a status() query, it was (sometimes?) shutting the switch off. Wasn't 100% sure, but got Tuya to push a firmware upgrade ... it went to v3.3, and the issue went away. Case closed ... I thought, but then ...
  2. Bought another switch, it's on v3.1 - and Tuya says there is no firmware update for this one. It does the same ... shuts off (often / always - to be confirmed yet) when I run a status() command.

So, time to figure out why? Is there a defined format for messages in and out? I can try to capture the traffic, and we can decipher then (i.e. tcpdump and/or Wireshark).

Thanks!

JSONDecodeError

Good evening Mr. Cox,

I came across this issue when testing devices on v3.3:
image

I am testing on a Windows10 x64-19041; Python 3.8; PyCharm.

Any insight would be greatly appreciated.
I am new to the developing scene. Please, pardon my ignorance.

Unable to pull dps

Hi, I'm new to IoT programming so please forgive me for stupid mistakes.
I've bought a no-brand smart bulb (this) and I'm trying to use it with this library but I get the error " Unexpected error for 192.168.1.193: Unable to poll " whenever I use the tinytuya scanner and even the example script provided crash as soon as it neet to set the version with error: " if 'dps' in status:
TypeError: argument of type 'NoneType' is not iterable ".
does anyone have an idea on how to fix this?
Thanks!

Cause of unreachable devices while scanning

I have about 20 dimmable tuya lights on a 2.4 Ghz network. I am attempting to control these using the localtuya project and Home Assistant, but I wanted to start here as I think I can determine my problem within tinytuya alone.

A couple observations:

  • All 20 of my lights are controllable using the Tuya app via Tuya cloud as the manufacturer intended
  • Immediately after configuring my lights in the Tuya app, they all appeared successfully when running python3 -m tinytuya scan
  • When I configure and begin communicating with the lights using localtuya and hass.io, most of the lights respond. These lights no longer appear when running python3 -m tinytuya scan
  • A handful of lights never respond via localtuya running on a hass.io machine, and these lights do respond when running python3 -m tinytuya scan

So there seems to be something mutually exclusive where lights controlled by localtuya can't be reached by tinytuya, and lights that can be reached by tintuya cannot be controlled by localtuya. All devices can be controlled from tuya cloud.

Note that I am putting all my devices on a common 2.4ghz network that I am connected to from my macbook, etc. when running scans. I can see all the devices assigned to respective static IPs on the network.

Any ideas?

How to get power status of light bulb, Py noob

Hello I would like to know how make a script that checks status of lights before switching strate.
Looking at how the code is made it should be possible but i cannot figure it out as i'm still learning python
DPS_2_STATE = does not end at 24 in this file

my output from print('\nCurrent Status of Bulb: %r' % data) is Current Status of Bulb: {'dps': {'20': True, '21': 'white', '22': 1000, '23': 1000, '24': '000003e803e8', '25': '000e0d0000000000000000c80000', '26': 0}}
Is that why I cant see the power state ?

Python ERROR when trying to run 'wizzard'

When I type the command: 'python3 -m tinytua wizard' I can enter the: 'api Key, apiSecret, apiRegion, apiDeviceID'. But then running the command an error shows up after like 2sec:

Traceback (most recent call last):
File "/usr/lib/python3.8/runpy.py", line 194, in _run_module_as_main
return _run_code(code, main_globals, None,
File "/usr/lib/python3.8/runpy.py", line 87, in _run_code
exec(code, run_globals)
File "/usr/local/lib/python3.8/dist-packages/tinytuya/main.py", line 48, in
tinytuya.wizard(color)
File "/usr/local/lib/python3.8/dist-packages/tinytuya/init.py", line 1548, in wizard
uid = response_dict['result']['uid']
KeyError: 'result'

Tested platforms: mac osx high Sierra 10.13.6 and linux(pop os! 2020)
Also I have 3 tuya devices(Breaker) and they are connected using the Tuya Smart app.

Can't control/get state of single socket WiFi power plugs

Controlling a 4-socket WiFi power strip works fine...

Though when using those Marmitek Power SE single socket WiFi Plugs, no state can be read nor can the switch be set to on or off....tested with version 3.1 and 3.3 protocol....

The devices.json file was created correctly with the keys for the WiFi plugs as the keys can be used in Home Assistants LocalTuya add on without any problems...

In Home Assistant I can control single socket and 4 socket power plugs...here I can only control the 4 socket power stips...

With the dps example I don't get any output...so no error message...

With the test script:

TinyTuya (Tuya Interface) [1.2.3]

TESTING: Device 8626xxxxxxxxxxxxx at 10.0.100.49 with key xxxxxxxxxxxxxxxx version 3.3

READING TEST: Response {'Error': 'Network Error: Unable to Connect', 'Err': '901', 'Payload': None}

READING TEST: Response {'Error': 'Network Error: Unable to Connect', 'Err': '901', 'Payload': None}

READING TEST: Response {'Error': 'Network Error: Unable to Connect', 'Err': '901', 'Payload': None}
TIMEOUT: No response from plug 8626xxxxxxxxxxxxx [10.0.100.49] after 2 attempts.

And yes..the device is there (o;

Starting Nmap 7.70 ( https://nmap.org ) at 2021-03-06 10:26 CET
Nmap scan report for 10.0.100.49
Host is up (0.0032s latency).
Not shown: 999 closed ports
PORT STATE SERVICE
6668/tcp open irc

Nmap done: 1 IP address (1 host up) scanned in 7.37 seconds

Registering a Cloud Project on iot.tuya.com is not free anymore

Hi, I was following the instructions to Get the Tuya Device LOCAL_KEY found on https://pypi.org/project/tinytuya/, but it seems that it is not longer supported as a free service.
From the developer framework https://iot.tuya.com/cloud/, if I click on Cloud => Projects => Try It Free, I get the message that I need a personal authentication or enterprise authentication. It is not clear what is a personal authentication, whereas an enterprise authentication seems reserverd to big companies. And after all, the Free Trial is just for three months.
I asked for support in chat, the answer was that API usage is not for device users, but only for companies.
Does it means that the use of TinyTuya is precluded to single developers?

Set Scene Not Doing Anything

I have been trying to get my bulb to use one of the scenes but nothing appears to happen on my bulb when I run the code. Are my bulbs just not compatible?

import tinytuya

d = tinytuya.BulbDevice('XXXX', 'XXXX', 'XXXX')
d.set_version(3.3)
data = d.status()

d.set_mode('scene')
d.set_scene(3)

default22 device

Well one of my device is in

Problem :

I am tryinig get_status and its always return None.


DEBUG:building payload=b'{"gwId":"bf89e15533aa8988cd4avu","devId":"bf89e15533aa8988cd4avu","uid":"bf89e15533aa8988cd4avu","t":"1623820243"}'
DEBUG:payload generated=b"\x00\x00U\xaa\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x88j\xff\xbf\xbd\xcb1y\x00\x1d=\x0f\x92\x02\x8d>\x142\x10\x8b\xffW\xa4\xfa\x13'\x04\xeb\xf2\x1a 1\x1f\x18\x93\xdah\x89\xf4\xa2\x13\xb5ku\xd3{\x19-\x91\xd5o\xdd\xb2\xcbl\xf4\xea\xc7\x98\x11\x9eFa\xe2\xec\xff\xbc]\xdc\xca\x05C\x90\xb7\x87\t\xa0e\xa2\xed\x802\x10\x8b\xffW\xa4\xfa\x13'\x04\xeb\xf2\x1a 1\x1f@AI\x9a;\x88n\xe9 \x92D\x84\xf8\xec\xd8\xc5\x9a/\x8c\nI\x9a@\xa6\xf0C\xaf\xac\xd2\xd3\xa5\x8f\xf9\x91\xe3\x08\x00\x00\xaaU"
DEBUG:received data=b'\x00\x00U\xaa\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00,\x00\x00\x00\x01\x02:jyw\ta\xb85\xe7\xd3\x82\x1d\x9b\xb1\xd2\xc1==\xc9\xa4\xf2\xfb\xcb\xbf\xf8\x88OyC\x97\xe7$\xb3g\xd5\x00\x00\xaaU'
DEBUG:raw unpacked message = TuyaMessage(seqno=0, cmd=10, retcode=1, payload=b'\x02:jyw\ta\xb85\xe7\xd3\x82\x1d\x9b\xb1\xd2\xc1==\xc9\xa4\xf2\xfb\xcb\xbf\xf8\x88OyC\x97\xe7', crc=615737301)
DEBUG:decode payload=b'\x02:jyw\ta\xb85\xe7\xd3\x82\x1d\x9b\xb1\xd2\xc1==\xc9\xa4\xf2\xfb\xcb\xbf\xf8\x88OyC\x97\xe7'
DEBUG:decrypting=b'\x02:jyw\ta\xb85\xe7\xd3\x82\x1d\x9b\xb1\xd2\xc1==\xc9\xa4\xf2\xfb\xcb\xbf\xf8\x88OyC\x97\xe7'
DEBUG:decrypted 3.3 payload='json obj data unvalid'
DEBUG:'data unvalid' error detected: switching to dev_type 'device22'
DEBUG:Re-send b"\x00\x00U\xaa\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x88j\xff\xbf\xbd\xcb1y\x00\x1d=\x0f\x92\x02\x8d>\x142\x10\x8b\xffW\xa4\xfa\x13'\x04\xeb\xf2\x1a 1\x1f\x18\x93\xdah\x89\xf4\xa2\x13\xb5ku\xd3{\x19-\x91\xd5o\xdd\xb2\xcbl\xf4\xea\xc7\x98\x11\x9eFa\xe2\xec\xff\xbc]\xdc\xca\x05C\x90\xb7\x87\t\xa0e\xa2\xed\x802\x10\x8b\xffW\xa4\xfa\x13'\x04\xeb\xf2\x1a 1\x1f@AI\x9a;\x88n\xe9 \x92D\x84\xf8\xec\xd8\xc5\x9a/\x8c\nI\x9a@\xa6\xf0C\xaf\xac\xd2\xd3\xa5\x8f\xf9\x91\xe3\x08\x00\x00\xaaU" due to device type change (default -> device22)
DEBUG:received data=b'\x00\x00U\xaa\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00,\x00\x00\x00\x01\x02:jyw\ta\xb85\xe7\xd3\x82\x1d\x9b\xb1\xd2\xc1==\xc9\xa4\xf2\xfb\xcb\xbf\xf8\x88OyC\x97\xe7$\xb3g\xd5\x00\x00\xaaU'
DEBUG:raw unpacked message = TuyaMessage(seqno=0, cmd=10, retcode=1, payload=b'\x02:jyw\ta\xb85\xe7\xd3\x82\x1d\x9b\xb1\xd2\xc1==\xc9\xa4\xf2\xfb\xcb\xbf\xf8\x88OyC\x97\xe7', crc=615737301)
DEBUG:decode payload=b'\x02:jyw\ta\xb85\xe7\xd3\x82\x1d\x9b\xb1\xd2\xc1==\xc9\xa4\xf2\xfb\xcb\xbf\xf8\x88OyC\x97\xe7'
DEBUG:removing 3.3=b'\xd2\xc1==\xc9\xa4\xf2\xfb\xcb\xbf\xf8\x88OyC\x97\xe7'
DEBUG:decrypting=b'\xd2\xc1==\xc9\xa4\xf2\xfb\xcb\xbf\xf8\x88OyC\x97\xe7'
DEBUG:incomplete payload=b'\xd2\xc1==\xc9\xa4\xf2\xfb\xcb\xbf\xf8\x88OyC\x97\xe7'
DEBUG:status received data=None

But if we call get status again - its normal return data. So re-send data is not working.
I think need some timeout ?

DEBUG:status() entry (dev_type is device22)
DEBUG:building payload=b'{"devId":"bf89e15533aa8988cd4avu","uid":"bf89e15533aa8988cd4avu","t":"1623820269","dps":{"1":null}}'
DEBUG:payload generated=b"\x00\x00U\xaa\x00\x00\x00\x02\x00\x00\x00\r\x00\x00\x00\x873.3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x001G\x967\x8eS\x89\xba\xab\x96\x97\x10.\xe1\x94\xbc\xd5o\xdd\xb2\xcbl\xf4\xea\xc7\x98\x11\x9eFa\xe2\xec\xff\xbc]\xdc\xca\x05C\x90\xb7\x87\t\xa0e\xa2\xed\x802\x10\x8b\xffW\xa4\xfa\x13'\x04\xeb\xf2\x1a 1\x1f\xde\xb7\x99W\xf18\xa2\xaf1V\x87\xf1\xa1\xcb\xc4}\xa2\x85dS\xea\xa03\tr\xff\xfc-T\xc7\x97(\xe7\x8e\xee\x95\xf08\xc1\x13i\x9af\x87l#\x0e\xe5G@NC\x00\x00\xaaU"
DEBUG:received data=b'\x00\x00U\xaa\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00K\x00\x00\x00\x003.3\x00\x00\x00\x00\x00\x00\x00N\x00\x00\x00\x01\x91e4K\x02\x17o\x1c\x81N\xac\xa0\x91\x98\xd4\xed\x95\xd2;\xa2\xfe\xffP\xd4X\xa9k@b\xb1\xf3r\xef\xc7\xf2O3\x18e\xb4\xf6\xe7\x03f\x90}\xb1nrIQV\x00\x00\xaaU'
DEBUG:raw unpacked message = TuyaMessage(seqno=0, cmd=8, retcode=0, payload=b'3.3\x00\x00\x00\x00\x00\x00\x00N\x00\x00\x00\x01\x91e4K\x02\x17o\x1c\x81N\xac\xa0\x91\x98\xd4\xed\x95\xd2;\xa2\xfe\xffP\xd4X\xa9k@b\xb1\xf3r\xef\xc7\xf2O3\x18e\xb4\xf6\xe7\x03f\x90}\xb1n', crc=1917407574)
DEBUG:decode payload=b'3.3\x00\x00\x00\x00\x00\x00\x00N\x00\x00\x00\x01\x91e4K\x02\x17o\x1c\x81N\xac\xa0\x91\x98\xd4\xed\x95\xd2;\xa2\xfe\xffP\xd4X\xa9k@b\xb1\xf3r\xef\xc7\xf2O3\x18e\xb4\xf6\xe7\x03f\x90}\xb1n'
DEBUG:removing 3.3=b'\x91e4K\x02\x17o\x1c\x81N\xac\xa0\x91\x98\xd4\xed\x95\xd2;\xa2\xfe\xffP\xd4X\xa9k@b\xb1\xf3r\xef\xc7\xf2O3\x18e\xb4\xf6\xe7\x03f\x90}\xb1n'
DEBUG:decrypting=b'\x91e4K\x02\x17o\x1c\x81N\xac\xa0\x91\x98\xd4\xed\x95\xd2;\xa2\xfe\xffP\xd4X\xa9k@b\xb1\xf3r\xef\xc7\xf2O3\x18e\xb4\xf6\xe7\x03f\x90}\xb1n'
DEBUG:decrypted 3.3 payload='{"dps":{"1":true},"t":1623820269}'
DEBUG:decoded results='{"dps":{"1":true},"t":1623820269}'
DEBUG:status received data={'dps': {'1': True}, 't': 1623820269}

Do you have an example with set_colour(r,g,b) ?

THanks for a very useful package !

I'm able to turn on/off on my Tuya enabled lights and able to set their brightness, but I'm not able to get the set_colour(r,g,b) to work properly. set_colour(r,g,b) seems to hang no matter what values I put in for r,g,b. I can't find an example of being usedโ€ฆ So perhaps I'm doing it wrong. It looks OK from the source codeโ€ฆ Any suggestions?

John Cohn
[email protected]

thanks again !

here's my code

import tinytuya
import random

candles = {}
candles[0] = tinytuya.BulbDevice('868515018caab5ef1554', '192.168.1.26', '03ca98398a11c78a')
candles[1] = tinytuya.BulbDevice('86851501e09806ac519d', '192.168.1.27', '970cdd010944cf8b')
candles[2] = tinytuya.BulbDevice('868515018caab5e57b07', '192.168.1.28', '5aa724e67b0b4bd9')
candles[3] = tinytuya.BulbDevice('868515018caab5ef1d2b', '192.168.1.29', '129668119d3e840c')
candles[4] = tinytuya.BulbDevice('868515018caab5e48e96', '192.168.1.30', '431b646c91ffca5c')
candles[5] = tinytuya.BulbDevice('868515018caab5ef529e', '192.168.1.31', 'daf67a675bf9287d')
candles[6] = tinytuya.BulbDevice('eb14adb45f8dfeb872fk5x', '192.168.1.25', '2f239ce262516e4b')
candles[7] = tinytuya.BulbDevice('ebe1eb6797591db8eslal', '192.168.1.24', 'eefb1deb6155f9f6')
candles[8] = tinytuya.BulbDevice('eb044207ff02162f1f248g', '192.168.1.4', '44b9d8edcf92ca3e')
for i in range (9):
    candles[i].set_version(3.3)

for i in range (9):
    candles[i].set_value('20',True) # turn on each light                                                                                                                             
    z = random.randint(10, 1000) # choose a random brightness                                                                                                                        
    candles[i].set_value('22',z) # set brighntess (this works)                                                                                                                       
## if uncommented, the next line hangss                                                                                                                                              
#    candles[i].set_colour(100,100,100) # attempt to set a colour .. (this does NOT work.. iit hangs  forever))                                                                      
    data = candles[i].status()  # NOTE this does NOT require a valid key vor version 3.1                                                                                             
    print(data)




Strange data on dp 18 for wattmeter

Hello, I'm completely new in smart home devices but i'm running very fast and set multiple devices that runs ok.
Maybe i've lost something during this fast way but i cannot read data from my new wattmeter . I can read from other plugs but i would like to use a din mount device.
this is what comes out from the status:
{'dps': {'1': 1277, '10': 0, '16': True, '18': '111111111111'}}
1277 is the total power consumption (12.77Kwh)
16: true is the switch on or off
the main info that i needed was the current, active power, and voltage (that are readable on smartlife app) but does not appear here. there is only that 18: 1111111111
Have you got any suggestion.
the device is https://www.amazon.it/gp/product/B07TJS27D6/ref=ppx_yo_dt_b_asin_title_o02_s00?ie=UTF8&psc=1
All the other i can see on italian amazon seem to be the same product with different label.... have you got any way to make it work or a suggestion on an alternative device working with tinytuya?
Thank you

Network Error: Device Unreachable

I get device unreachable error when I have two interface connected, eth0 and wlan0 with ip address of 192.168.1.108 and 192.168.1.10 respectively. Any reason causing this happening?

Another JSONDecodeError

Hi
I have similar problem with a bulb. tinytuya on RPi Zero. Python 3.7.3
3 equal bulbs. 2 of them I can read just fine.

TinyTuya (Tuya device scanner) [1.1.3]

Scanning on UDP ports 6666 and 6667 for devices (15 retries)...

3.1 Device Found [Valid payload]: 192.168.0.115
    ID = 37800275840d8e54d1d2, Product ID = keyneruwsdethu7u, Version = 3.1
    Status: {'1': False, '9': 0, '18': 0, '19': 0, '20': 2344, '21': 1, '22': 748, '23': 32838, '24': 22222, '25': 935}
3.3 Device Found [Valid payload]: 192.168.0.109
    ID = 8052770184f3ebeec5b1, Product ID = keyj979nf3q3theh, Version = 3.3
    No Stats - Device Key required to poll for status
3.3 Device Found [Valid payload]: 192.168.0.189
    ID = 01147546600194dd1765, Product ID = keyjcr45yfptp7h7, Version = 3.3
    No Stats - Device Key required to poll for status
3.3 Device Found [Valid payload]: 192.168.0.161
    ID = 80527701ecfabc47dfac, Product ID = keyj979nf3q3theh, Version = 3.3
    No Stats - Device Key required to poll for status
3.3 Device Found [Valid payload]: 192.168.0.138
    ID = 8052770184f3ebf633b5, Product ID = keyj979nf3q3theh, Version = 3.3
    No Stats - Device Key required to poll for status
                    
Scan Complete!  Found 5 devices.
Traceback (most recent call last):
  File "main.py", line 255, in <module>
    get_tuya_data_test('80527701ecfabc47dfac', '192.168.0.161', '6af642384da9f2d1')
  File "/root/tee/tee/data.py", line 262, in get_tuya_data_test
    d.set_version(3.3)
  File "/usr/local/lib/python3.7/dist-packages/tinytuya/__init__.py", line 891, in set_version
    status = self.status()
  File "/usr/local/lib/python3.7/dist-packages/tinytuya/__init__.py", line 589, in status
    result = json.loads(result)
  File "/usr/lib/python3.7/json/__init__.py", line 348, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python3.7/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python3.7/json/decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
def get_tuya_data_test(tuya_id, ip_addr, tuya_key):
    
        d = tinytuya.BulbDevice(tuya_id, ip_addr, tuya_key)
        d.set_version(3.3)
        data = d.status()
        print(data)

Originally posted by @burgas1 in #4 (comment)

New To Python, Tuya & TinyTuya, tips to start & operate Garage Door control

I hate to ask as a real newbie to this but not sure where to start. I can program VBA so not a complete idiot.
Have Garage door set up fine on Tuya, works fine, Alexa etc.
Would like a script to operate from PC. Windows 10.
Have installed Python, py V 3.93, has the built in PIP installer.
TinyTuya seemed to installed OK
python -m tinytuya - runs OK but says 0 devices found
I have no idea what to do with sudo apt-get install python-crypto python-pip # for RPi, Linux
from py command prompt, above gives syntax error, with or without the # bit
Could you just point me in the right direction.
Many thanks I/A

Smart Energy meter

Hello,
I have 2 smart energy meter, the first one has a firmware version 1.0.2 and the second is in 1.1.17.
The first one is working fine and I can get the current and power with tinytuya.

The second one return with tinytuya
import tinytuya

PLUGID = 'nzexeqam9qulajbf'
PLUGIP = '192.168.0.94'
PLUGKEY = 'XXXXXXX'
PLUGVERS = '3.3'

d = tinytuya.OutletDevice(PLUGID, PLUGIP, PLUGKEY)
d.set_version(3.3)
data = d.status()
print('set_status() result %r' % data)

set_status() result {'dps': {'1': 133, '10': 0, '16': True, '18': '111111111111'}}

Field '1' correspond to the total energy consumption but I can not see the real time power or the current consumption.

It seems to be linked to a newer firmware. Do you plan a new upgrade to this firmware?

This happened while trying to scan my network from Raspbian on a Pi 4

Scanning local network for Tuya devices...
Traceback (most recent call last):
File "/usr/lib/python3.7/runpy.py", line 193, in _run_module_as_main
"main", mod_spec)
File "/usr/lib/python3.7/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "/home/shane/.local/lib/python3.7/site-packages/tinytuya/main.py", line 48, in
tinytuya.wizard(color)
File "/home/shane/.local/lib/python3.7/site-packages/tinytuya/init.py", line 1479, in wizard
devices = deviceScan(False, 20)
File "/home/shane/.local/lib/python3.7/site-packages/tinytuya/init.py", line 1139, in deviceScan
client.bind(("", UDPPORT))
OSError: [Errno 98] Address already in use

Yeeuu K1 Smart Lock Box

Hi,
I'm trying to use tinytuya to check status and open a Smart Lock Box (https://www.yeeuu.com/products/yeeuu-k1-smart-lock-box ) connected to Wifi via a Bluetooth Bridge (https://www.yeeuu.com/products/yeeuu-h1-gateway ). I have imported both of them via tuya.com and see both in devices.json
{ "name": "YEEUU K1 Smart Lock Box", "id": "id-made-of-22-chars", "key": "mykey" }, { "name": "YEEUU H1 WiFi Bridge", "id": "id-made-of-22-chars", "key": "same key as above" },

so I have tried using the suggestion to handle 22-chars-id's:
`import tinytuya

DEVICEID = "the id of the K1"
DEVICEIP = "the IP"
DEVICEKEY = "mykey"
DEVICEVERS = "3.3"

a = tinytuya.CoverDevice(DEVICEID, DEVICEIP, DEVICEKEY, 'device22')
a.set_version(3.3)
a.set_dpsUsed({"1": None}) # This needs to be a datapoint available on the device
data = a.status()
print(data)`

but when I run this I get a timeout

python3 k1test.py Exceeded tinytuya retry limit (5) Traceback (most recent call last): File "/usr/local/lib/python3.7/dist-packages/tinytuya/__init__.py", line 353, in _send_receive data = self.socket.recv(1024) # try again socket.timeout: timed out Traceback (most recent call last): File "k1test.py", line 11, in <module> data = a.status() File "/usr/local/lib/python3.7/dist-packages/tinytuya/__init__.py", line 556, in status data = self._send_receive(payload) File "/usr/local/lib/python3.7/dist-packages/tinytuya/__init__.py", line 353, in _send_receive data = self.socket.recv(1024) # try again socket.timeout: timed out

Any clue of what I am doing wrong? I also haven't tried "open_cover(switch=1):" yet because I am physically far away in VPN...

Thanks!
R

Energy Monitor, Measurement Refresh

Hi,

Looping through, getting energy monitor readings from a switch (outlet). => it can take a minute (or more) for the reading to update ... but if I "trigger" it from SmartLife, it updates immediately. Does some sort of refresh / trigger need to be sent, to get the reading to update (or is it cached somehow?)?

Thanks!

tinytuya requests time out

When running tinytuya the smartbulb is found and its status is displayed. But when running the wizard or trying to change the status of the light, there is no response. The light works fine with the tuya app and with Alexa.

Help would be much appreciated as I am running out of ideas myself :)

colourtemp_percentage works the same way as white_percentage

The command set_colourtemp_percentage works the exact same way as set_white_percentage.
It seems to revert to the white color instead of adjusting the temp of the current color.
Is this intended?

I noticed this while i did some testing with my program "tuyactl" that is based on your library

TreatLife Product

Hello Jason!
I am working on TreatLife switches and LED lights and have some details, along with some code I have been fiddling with for a couple of weeks to familiarize my just over a year old Python with your Module.

Now in your examples you have bulb.py and this is using ""class BulbDevice(Device):"" I see you have two types A and B for different DPS.
Now both the switch and lights work on the ""class OutletDevice(Device):"" for TreatLife and I can cycle both using the modified send_raw_dps_''_.py below.
##bulb.py does print its tasks with no actions when I pounded out line 34 else: and 35 d.set_version(3.1) to get it to run as BulbDevice. Now when I use OutletDevice it fails when calling d.set_white() with an attributeError as this type probably needs to be added as type C?

Next is my snapshot.json and the switches have a "devId" and the name for my one and only switch that is "name": "Office Outside Lights". This should make it easier to get them separated as I am writing separate control polyglot Node Servers one for lighting and the other switches/dimmers.
The lights do not have "devId" in their json listing between the "dps".

Now I am trying to build a modified wizard to bring in the DEVICEID, IP, KEY and the snapshot.py is a fantastic start I see you just added!
So I will create the json, parse the data for the control of each switch and of course the token with requests.

Have one running as a Universal Devices Node Server and it is cycling a switch with manual inputs for its DEVICE key id & ip upon a token refresh every 20 minutes, but it is not working at all for actual control, lol.

I hope you do not mind my long winded message and hope to ask you some more questions along my weary path. I am 60 so it is kind of old dog with new tricks to keep my brain young. Sometime I get stuck on the simplest fundamentals mostly string formatting, lol! So for me to Len or separate out all of the switches from a json, then grab the data for DEVICE, then create another class to push that to for control, takes some brain twisting!
What's that advertisement for jellyfish brain enhancers, Previgen? lol!

Highest Regards and Thank You for Your TIME!

Code Examples,

send_raw_dps_light_treatlife.py
Light Bulb

import tinytuya
import time
import os
import random

DEVICEID = "BLAAAA"  
DEVICEIP = "BLAAAA" 
DEVICEKEY = "BLAAAA"   
DEVICEVERS = "us" ##This works? instead of 3.3 which they all are

# Check for environmental variables and always use those if available
DEVICEID = os.getenv("DEVICEID", DEVICEID)
DEVICEIP = os.getenv("DEVICEIP", DEVICEIP)
DEVICEKEY = os.getenv("DEVICEKEY", DEVICEKEY)
DEVICEVERS = os.getenv("DEVICEVERS", DEVICEVERS)

print("TinyTuya - Smart Bulb RGB Test [%s]\n" % tinytuya.__version__)
print('TESTING: Device %s at %s with key %s version %s' %
      (DEVICEID, DEVICEIP, DEVICEKEY, DEVICEVERS))


# Connect to the device - replace with real values
d=tinytuya.OutletDevice(DEVICEID, DEVICEIP, DEVICEKEY)
d.set_version(3.3)
# Show status of device
data = d.status()


# Generate the payload to send - add all the DPS values you want to change here
payload1=d.generate_payload(tinytuya.CONTROL, {'20': False, '22': 100, '23': 10,})
#time.sleep(1)
print('\nCurrent Status of Bulb: %r' % data)
time.sleep(2)
payload2=d.generate_payload(tinytuya.CONTROL, {'20': True, '22': 100, '23': 10,})
#time.sleep(1)
print('\nCurrent Status of Bulb: %r' % data)
#time.sleep(2)
payload3=d.generate_payload(tinytuya.CONTROL, {'20': True, '22': 1000, '23': 236,})
#time.sleep(1)
print('\nCurrent Status of Bulb: %r' % data)
# Send the payload to the device

d._send_receive(payload1)
time.sleep(2)
d._send_receive(payload2)
time.sleep(2)
d._send_receive(payload3)
#print('\nCurrent Status of Bulb: %r' % data)`

send_raw_dps_switch_treatlife.py
Switch

import tinytuya
import time
import os
import random

DEVICEID = "BLAAAA"
DEVICEIP = "192.168.1.137"
DEVICEKEY = "BLAAAA"
DEVICEVERS = "us" ##This works? instead of 3.3 which they all are

# Check for environmental variables and always use those if available
DEVICEID = os.getenv("DEVICEID", DEVICEID)
DEVICEIP = os.getenv("DEVICEIP", DEVICEIP)
DEVICEKEY = os.getenv("DEVICEKEY", DEVICEKEY)
DEVICEVERS = os.getenv("DEVICEVERS", DEVICEVERS)

print("TinyTuya - Smart Bulb RGB Test [%s]\n" % tinytuya.__version__)
print('TESTING: Device %s at %s with key %s version %s' %
      (DEVICEID, DEVICEIP, DEVICEKEY, DEVICEVERS))


# Connect to the device - replace with real values
d=tinytuya.OutletDevice(DEVICEID, DEVICEIP, DEVICEKEY)
d.set_version(3.3)

# Generate the payload to send - add all the DPS values you want to change here
#if data != [0]
#payload=d.generate_payload(tinytuya.CONTROL, {'1': False, '2': 50})
#time.sleep(2)
#payload=d.generate_payload(tinytuya.CONTROL, {'1': True, '2': 50})
#time.sleep(2)

payload1=d.generate_payload(tinytuya.CONTROL, {'1': False, '2': 50})
payload2=d.generate_payload(tinytuya.CONTROL, {'1': True, '2': 50})

# Send the payload to the device

d._send_receive(payload1)
time.sleep(2)
d._send_receive(payload2)

# Get the status of the device
#response = requests.request("GET", url, headers=headers, data=payload)

#print(str(d._send_receive(payload)))

#Command for 
# Show status of device
data = d.status()
print('\nCurrent Status of Bulb: %r' % data)

Here is my snapshot.json

{
    "timestamp": 1613548219.2819111,
    "devices": [
        {
            "name": "Under Cabinets",
            "ip": "192.168.1.158",
            "ver": "3.3",
            "id": "BLAAAAAAAAAAAAA",
            "key": "BLAAAAAAAAAAA",
            "dps": {
                "dps": {
                    "20": false,
                    "21": "scene",
                    "24": "007d007903e8",
                    "25": "05464601000003e803e800000000464601007803e803e80000000046460100f003e803e800000000464601003d03e803e80000000046460100ae03e803e800000000464601011303e803e800000000",
                    "26": 0
                }
            }
        },
        {
            "name": "Office Outside Lights",
            "ip": "192.168.1.137",
            "ver": "3.3",
            "id": "BLAAAAAAAAAA",
            "key": "BLAAAAAAAA",
            "dps": {
                "devId": "BLAAAAAAAAAA",
                "dps": {
                    "1": true,
                    "9": 0
                }
            }
        },
        {
            "name": "Garage",
            "ip": "192.168.1.138",
            "ver": "3.3",
            "id": "BLAAAAAAAAAA",
            "key": "BLAAAAAAAAAA",
            "dps": {
                "dps": {
                    "20": true,
                    "21": "colour",
                    "22": 1000,
                    "23": 767,
                    "24": "00ac02c501f0",
                    "25": "000e0d0000000000000000c803e8",
                    "26": 0
                }
            }
        },
        {
            "name": "Office Light",
            "ip": "192.168.1.139",
            "ver": "3.3",
            "id": "BLAAAAAAAAAA",
            "key": "BLAAAAAAAAAA",
            "dps": {
                "dps": {
                    "20": true,
                    "21": "white",
                    "22": 1000,
                    "23": 236,
                    "24": "00d60000026c",
                    "25": "000e0d0000000000000000c803e8",
                    "26": 0
                }
            }
        }
    ]
}

Lastly Postman Function list for the lights.

{
    "result": {
        "category": "dj",
        "functions": [
            {
                "code": "switch_led",
                "desc": "switch led",
                "name": "switch led",
                "type": "Boolean",
                "values": "{}"
            },
            {
                "code": "work_mode",
                "desc": "work mode",
                "name": "work mode",
                "type": "Enum",
                "values": "{\"range\":[\"white\",\"colour\",\"scene\",\"music\",\"scene_1\",\"scene_2\",\"scene_3\",\"scene_4\"]}"
            },
            {
                "code": "bright_value_v2",
                "desc": "bright value v2",
                "name": "bright value v2",
                "type": "Integer",
                "values": "{\"min\":10,\"scale\":0,\"unit\":\"\",\"max\":1000,\"step\":1}"
            },
            {
                "code": "temp_value_v2",
                "desc": "temp value v2",
                "name": "temp value v2",
                "type": "Integer",
                "values": "{\"min\":0,\"scale\":0,\"unit\":\"\",\"max\":1000,\"step\":1}"
            },
            {
                "code": "colour_data_v2",
                "desc": "colour data v2",
                "name": "colour data v2",
                "type": "Json",
                "values": "{}"
            },
            {
                "code": "scene_data_v2",
                "desc": "scene data v2",
                "name": "scene data v2",
                "type": "Json",
                "values": "{}"
            },
            {
                "code": "music_data",
                "desc": "music data",
                "name": "music data",
                "type": "Json",
                "values": "{}"
            },
            {
                "code": "control_data",
                "desc": "control data",
                "name": "control data",
                "type": "Json",
                "values": "{}"
            },
            {
                "code": "countdown_1",
                "desc": "countdown 1",
                "name": "countdown 1",
                "type": "Integer",
                "values": "{\"unit\":\"\",\"min\":0,\"max\":86400,\"scale\":0,\"step\":1}"
            },
            {
                "code": "bright_value",
                "desc": "bright value",
                "name": "bright value",
                "type": "Integer",
                "values": "{\"min\":25,\"scale\":0,\"unit\":\"\",\"max\":255,\"step\":1}"
            },
            {
                "code": "temp_value",
                "desc": "temp value",
                "name": "temp value",
                "type": "Integer",
                "values": "{\"min\":0,\"scale\":0,\"unit\":\"\",\"max\":255,\"step\":1}"
            },
            {
                "code": "flash_scene_1",
                "desc": "flash scene 1",
                "name": "flash scene 1",
                "type": "Json",
                "values": "{\"h\":{\"min\":1,\"scale\":0,\"unit\":\"\",\"max\":360,\"step\":1},\"s\":{\"min\":1,\"scale\":0,\"unit\":\"\",\"max\":255,\"step\":1},\"v\":{\"min\":1,\"scale\":0,\"unit\":\"\",\"max\":255,\"step\":1}}"
            },
            {
                "code": "flash_scene_2",
                "desc": "flash scene 2",
                "name": "flash scene 2",
                "type": "Json",
                "values": "{\"h\":{\"min\":1,\"scale\":0,\"unit\":\"\",\"max\":360,\"step\":1},\"s\":{\"min\":1,\"scale\":0,\"unit\":\"\",\"max\":255,\"step\":1},\"v\":{\"min\":1,\"scale\":0,\"unit\":\"\",\"max\":255,\"step\":1}}"
            },
            {
                "code": "flash_scene_3",
                "desc": "flash scene 3",
                "name": "flash scene 3",
                "type": "Json",
                "values": "{\"h\":{\"min\":1,\"scale\":0,\"unit\":\"\",\"max\":360,\"step\":1},\"s\":{\"min\":1,\"scale\":0,\"unit\":\"\",\"max\":255,\"step\":1},\"v\":{\"min\":1,\"scale\":0,\"unit\":\"\",\"max\":255,\"step\":1}}"
            },
            {
                "code": "flash_scene_4",
                "desc": "flash scene 4",
                "name": "flash scene 4",
                "type": "Json",
                "values": "{\"h\":{\"min\":1,\"scale\":0,\"unit\":\"\",\"max\":360,\"step\":1},\"s\":{\"min\":1,\"scale\":0,\"unit\":\"\",\"max\":255,\"step\":1},\"v\":{\"min\":1,\"scale\":0,\"unit\":\"\",\"max\":255,\"step\":1}}"
            },
            {
                "code": "scene_select",
                "desc": "scene select",
                "name": "scene select",
                "type": "Enum",
                "values": "{\"range\":[\"1\",\"2\",\"3\",\"4\",\"5\"]}"
            },
            {
                "code": "read_time",
                "desc": "read time",
                "name": "read time",
                "type": "Integer",
                "values": "{\"unit\":\"minute\",\"min\":1,\"max\":60,\"scale\":0,\"step\":1}"
            },
            {
                "code": "rest_time",
                "desc": "rest time",
                "name": "rest time",
                "type": "Integer",
                "values": "{\"unit\":\"minute\",\"min\":1,\"max\":60,\"scale\":0,\"step\":1}"
            },
            {
                "code": "switch_health_read",
                "desc": "switch health read",
                "name": "switch health read",
                "type": "Boolean",
                "values": "{}"
            },
            {
                "code": "colour_data",
                "desc": "colour data",
                "name": "colour data",
                "type": "Json",
                "values": "{}"
            },
            {
                "code": "scene_data",
                "desc": "scene data",
                "name": "scene data",
                "type": "Json",
                "values": "{}"
            },
            {
                "code": "rhythm_mode",
                "desc": "rhythm mode",
                "name": "rhythm mode",
                "type": "Raw",
                "values": "{\"maxlen\":255}"
            },
            {
                "code": "wakeup_mode",
                "desc": "wakeup mode",
                "name": "wakeup mode",
                "type": "Raw",
                "values": "{\"maxlen\":255}"
            },
            {
                "code": "power_memory",
                "desc": "power memory",
                "name": "power memory",
                "type": "Raw",
                "values": "{\"maxlen\":255}"
            },
            {
                "code": "debug_data",
                "desc": "debug data",
                "name": "debug data",
                "type": "String",
                "values": "{\"maxlen\":255}"
            },
            {
                "code": "sleep_mode",
                "desc": "sleep mode",
                "name": "sleep mode",
                "type": "Raw",
                "values": "{\"maxlen\":255}"
            }
        ]
    },
    "success": true,
    "t": 1613549900843
}

Sombody Help me with my code

I have managed to make two simple scripts to turn a light on and off.
I would like to know, how i can make the script a bit more interactive & check status of power before flipping it to the other state. I cannot seem to make it show power status bol of 1 or 0 but using the smart life app it displays the status just fine so my bulbs are capable of providing that data.

So to clarify I have got two 432mhz switches that my rpi is listening to. i would like to assign them to the power flip flop i was asking about.

At the moment it works using a bash script. It monitors the exec binary that prints a "signal received" msg. and that in turn triggers my two independent simple py scripts

So how do i add it all into one python script that can also control a group of lights.

I hope this is possible to someone with greater knowledge than me.
Thank you in advance if you decide to help.

Scan failed when color=False

TinyTuya (Tuya device scanner) [1.2.7]

Scanning on UDP ports 6666 and 6667 for devices (10 retries)...

Traceback (most recent call last):
File "run.py", line 45, in
tinytuya.scan(max_retries, color)
File "d:\Downloads\TinyTuya\libs\tinytuya_init_.py", line 1629, in scan
d = deviceScan(True, maxretry, color)
File "d:\Downloads\TinyTuya\libs\tinytuya_init_.py", line 1792, in deviceScan
normal, version, dim, productKey, note, subbold, ip, cyan, gwId, red, dkey, yellow, version))
UnboundLocalError: local variable 'cyan' referenced before assignment

Nedis Zigbee Gateway can't connect using tinytuya

Hello, I'm working on a project where I would like to read temperature/humidity from a sensor connected through a Nedis Zigbee Gateway. I am not able to connect the gateway. I this possible with tinytuya?

I would be very thankful if someone could take a look or at least tell me if it's supported.

Simply running it on my PC using Python 3.8.5

python -m tinytuya

TinyTuya (Tuya device scanner) [1.1.4]

Scanning on UDP ports 6666 and 6667 for devices (15 retries)...

3.3 Device Found [Valid payload]: 192.168.8.XXX
    ID = XXXXXX, Product ID = XXXXX, Version = 3.3
    No Stats - Device Key required to poll for status

Scan Complete!  Found 1 devices.

Here is a snapshot created by the wizard

Poll local devices? (Y/n): Y

Scanning local network for Tuya devices...
    1 local devices discovered

Polling local devices...
    [Temperature and humidity sensor] - 0 - Error: No IP found
    [Zigbee Smart Gateway] - 192.168.8.XXX - No Response

>> Saving device snapshot data to snapshot.json

Done.
{
    "timestamp": 1612792884.4107103,
    "devices": [
        {
            "name": "Temperature and humidity sensor",
            "ip": 0,
            "ver": 0,
            "id": "XXXX",
            "key": "XXXX"
        },
        {
            "name": "Zigbee Smart Gateway",
            "ip": "192.168.8.XXX",
            "ver": "3.3",
            "id": "XXXX",
            "key": "XXXX"
        }
    ]
}

Checking the SmartLife app I was able to find another IP-adress for the Gateway (5.240.XXX.XX) which I am able to ping at least.
Pinging 192.168.8.XXX does not work.

Tested the following code on the two different IP-addresses

import tinytuya

if __name__ == "__main__":
    d = tinytuya.OutletDevice('DEVICE_ID', 'IP_ADRESS', 'DEVICE_SECRET')
    d.set_version(3.3)
    data = d.status()  
    print(data)

192.168.8.XXX

Traceback (most recent call last):
  File ".\main.py", line 6, in <module>
    data = d.status()
  File "C:\Users\Krille\git\temper\venv\lib\site-packages\tinytuya\__init__.py", line 580, in status
    data = self._send_receive(payload)
  File "C:\Users\Krille\git\temper\venv\lib\site-packages\tinytuya\__init__.py", line 364, in _send_receive
    self._get_socket(False)
  File "C:\Users\Krille\git\temper\venv\lib\site-packages\tinytuya\__init__.py", line 350, in _get_socket
    self.socket.connect((self.address, self.port))
socket.timeout: timed out
(venv) PS C:\Users\Krille\git\temper> 

5.240.XXX.XX

Traceback (most recent call last):
  File ".\main.py", line 6, in <module>
    data = d.status()
  File "C:\Users\Krille\git\temper\venv\lib\site-packages\tinytuya\__init__.py", line 613, in status
    result = json.loads(result)
  File "c:\users\krille\appdata\local\programs\python\python38-32\lib\json\__init__.py", line 357, in loads
    return _default_decoder.decode(s)
  File "c:\users\krille\appdata\local\programs\python\python38-32\lib\json\decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "c:\users\krille\appdata\local\programs\python\python38-32\lib\json\decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

Tried the following as well:

import tinytuya

if __name__ == "__main__":
    d = tinytuya.OutletDevice('DEVICE_ID', 'IP_ADRESS', 'DEVICE_SECRET', 'device22')
    d.set_version(3.3)
    d.set_dpsUsed({"1": None})
    data = d.status()  
    print(data)
Traceback (most recent call last):
  File ".\main.py", line 7, in <module>
    data = d.status()
  File "C:\Users\Krille\git\temper\venv\lib\site-packages\tinytuya\__init__.py", line 580, in status
    data = self._send_receive(payload)
  File "C:\Users\Krille\git\temper\venv\lib\site-packages\tinytuya\__init__.py", line 374, in _send_receive
    data = self.socket.recv(1024)  # try again
socket.timeout: timed out
```

Wrong path in setup.py

1.0.0 points to the wrong location of README.md.

+ /usr/bin/python3 setup.py build '--executable=/usr/bin/python3 -s'
Traceback (most recent call last):
  File "setup.py", line 5, in <module>
    with open("tinytuya/README.md", "r") as fh:
FileNotFoundError: [Errno 2] No such file or directory: 'tinytuya/README.md'

This was fixed with 24fcf56

Error 901 , very new to python.

Ok so when I tried the test file for an RGB bulb it would only change the color right after i turned the light off and then on again.After that it would not work until i turned it off and then on again.I am using a rasberry pi 4.

Cover Control time

Hi, After log time I finaly found this great py....

I have bought the Loratap blinds cover

https://nl.aliexpress.com/item/33052311020.html?spm=a2g0o.productlist.0.0.1fce6edfWhEofY&algo_pvid=4a8c0398-bc03-4c6a-8910-49a94bf9925e&algo_expid=4a8c0398-bc03-4c6a-8910-49a94bf9925e-0&btsid=0b0a050116172030867828749e1023&ws_ab_test=searchweb0_0,searchweb201602_,searchweb201603_

And when i pull the status I get

Dictionary {u'dps': {u'1': u'stop', u'3': 15, u'2': u'forward'}}

I made 3 scripts... open/stop/close
e.g.
import tinytuya

d = tinytuya.CoverDevice('#####', '######', '#######')
d.set_version(3.3)
data = d.status()
#print(data)

d.open_cover(switch=1)

Show status of first controlled switch on device

#print('Dictionary %r' % data)
print('State %r' % data['dps']['1'])
print('State %r' % data['dps']['2'])
print('State %r' % data['dps']['3'])

Now comes the parts I want to controll the u3: 15
This the time that the cover(shutter) rolls....
I did allot of commands but i don't get the right one..

let's say I want to get to 21 value.....
please help..
thanks

Remco aka mupsje

No data after Wizard

Hello all,
I get this error after wizard. I'm on Debian 10 in VM. Can you help me please ?

root@debian:/home/franck# python3 -m tinytuya wizard TinyTuya Setup Wizard [1.2.1]

Existing settings:
API Key=xxx
Secret=xxx
DeviceID=xxx
Region=eu

Use existing credentials (Y/n): Y
Traceback (most recent call last):
File "/usr/lib/python3.7/runpy.py", line 193, in _run_module_as_main
"main", mod_spec)
File "/usr/lib/python3.7/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "/usr/local/lib/python3.7/dist-packages/tinytuya/main.py", line 48, in
tinytuya.wizard(color)
File "/usr/local/lib/python3.7/dist-packages/tinytuya/init.py", line 1789, in wizard
uid = response_dict['result']['uid']
KeyError: 'result'
root@debian:/home/franck#

d.status() not working

The outlet is correctly turning on and off, but d.status() is raising a JSONDecodeError

Traceback (most recent call last): File "C:/Users/theco/Desktop/AA.py", line 11, in <module> data= d.status() File "C:\Users\theco\AppData\Local\Programs\Python\Python39\lib\site-packages\tinytuya\__init__.py", line 502, in status result = json.loads(result) File "C:\Users\theco\AppData\Local\Programs\Python\Python39\lib\json\__init__.py", line 346, in loads return _default_decoder.decode(s) File "C:\Users\theco\AppData\Local\Programs\Python\Python39\lib\json\decoder.py", line 337, in decode obj, end = self.raw_decode(s, idx=_w(s, 0).end()) File "C:\Users\theco\AppData\Local\Programs\Python\Python39\lib\json\decoder.py", line 355, in raw_decode raise JSONDecodeError("Expecting value", s, err.value) from None json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

Any help on this?

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.