Package: tinytuya
TinyTuyaPython module to interface with Tuya WiFi smart devicesDescriptionThis python module controls and reads state ofTuyacompatible WiFi Smart Devices (Plugs, Switches, Lights, Window Covers, etc.) using the local area network (LAN) or the cloud (TuyaCloud API).  This is a compatible replacement for thepytuyaPyPI module and currently supports Tuya Protocols 3.1, 3.2, 3.3, 3.4 and 3.5.Tuyadevices are designed to communicate with the TuyaCloud but most also expose a local area network API.  This allows us to directly control the devices without using the cloud. This python module provides a way to poll status and issue commands to these devices.TinyTuya can also connect to the Tuya Cloud to poll status and issue commands to Tuya devices.# Example Usage of TinyTuyaimporttinytuyad=tinytuya.OutletDevice('DEVICE_ID_HERE','IP_ADDRESS_HERE','LOCAL_KEY_HERE')d.set_version(3.3)data=d.status()print('Device status:%r'%data)NOTE: Devices need to beactivatedby Smart Life App.TinyTuya Installation# Install TinyTuyapython-mpipinstalltinytuyaPip will attempt to installcryptography,requestsandcoloramaif not already installed.Tuya Device PreparationControlling and monitoring Tuya devices on your network requires the following:Address- Network address (IPv4) of the device e.g. 10.0.1.100Device ID- Unique identifier for the Tuya deviceVersion- Tuya protocol version used (3.1, 3.2, 3.3, 3.4 or 3.5)Local_Key- Security key needed to access the Tuya device. SeeSetup Wizardto get these keys.Network ScannerTinyTuya has a built in network scanner that can be used to find Tuya Devices on your local network. It will showAddress,Device IDandVersionfor each device. Your LAN and firewall will need to allow UDP (6666, 6667 and 7000) and TCP (6668) traffic.python-mtinytuyascanSetup Wizard - Getting Local KeysTinyTuya has a built-in setup Wizard that uses the Tuya IoT Cloud Platform to generate a JSON list (devices.json) of all your registered devices, including secretLocal_KeyandNameof your devices. Follow the steps below:PAIR - Download theSmart Life ApporTuya Smart App, available foriPhoneorAndroid. Set up your SmartLife account and pair all of your Tuya devices (this is important as you cannot access a device that has not been paired).SCAN (Optional) - Run the TinyTuya scan to get a list of Tuya devices on your network. It will show deviceAddress,Device IDandVersionnumber (3.x):python-mtinytuyascanNOTE: You will need to use one of the displayedDevice IDsfor step 4.TUYA ACCOUNT - Set up a Tuya Account (seePDF Instructions):NOTE: Tuya often changes their portal and services. Please open anissuewith screenshots if we need to update these instructions.Create a Tuya Developer account oniot.tuya.com. When it asks for the "Account Type", select "Skip this step..." (seescreenshot).Click on "Cloud" icon -> "Create Cloud Project"Pick the correct Data Center "Region" for your location (checkHEREto find your Region).  This will be used by TinyTuya Wizard (screenshot).Skip the configuration wizard but remember the Authorization Key:API IDandSecretfor below (screenshot).Click on "Cloud" icon -> Select your project ->Devices->Link Tuya App Account(see screenshot)ClickAdd App Account(screenshot) and it will pop-up a "Link Tuya App Account" dialog, chose "Automatic" and "Read Only Status" (it will still alow commands). Click OK and it will display a QR code. Scan the QR code with theSmart Life appon your Phone (see step 1 above) by going to the "Me" tab in theSmart Life appand clicking on the QR code button[..]in the upper right hand corner of the app. When you scan the QR code, it will link all of the devices registered in yourSmart Life appinto your Tuya IoT project. If the QR code will not scan then make sure to disable any browser theming plug-ins (such as Dark Reader) and try again.NO DEVICES?If no devices show up after scanning the QR code, you will need to select a different data center and edit your project (or create a new one) until you see your paired devices from theSmart Life Appshow up. (screenshot). The data center may not be the most logical. As an example, some in the UK have reported needing to select "Central Europe" instead of "Western Europe".SERVICE API:Under "Service API" ensure these APIs are listed:IoT CoreandAuthorization. To be sure, click subscribe again on every service.  Very important:disable popup blockersotherwise subscribing won't work without providing any indication of a failure. Make sure you authorize your Project to use those APIs:Click "Service API" tabClick "Go to Authorize" buttonSelect the API Groups from the dropdown and clickSubscribe(screenshot)WIZARD - Run Setup Wizard:From your Linux/Mac/Win PC run the TinyTuya SetupWizardto fetch theLocal_Keysfor all of your registered devices:python-mtinytuyawizard# use -nocolor for non-ANSI-color terminalsTheWizardwill prompt you for theAPI IDkey, APISecret, APIRegion(cn, us, us-e, eu, eu-w, or in) from your Tuya IoT project as set in Step 3 above.To find those again, go toiot.tuya.com, choose your project and clickOverviewAPI Key: Access ID/Client IDAPI Secret: Access Secret/Client SecretIt will also ask for a sampleDevice ID.  You can have the wizard scan for one (enterscan), use one from step 2 above or in the Device List on your Tuya IoT project.TheWizardwill poll the Tuya IoT Cloud Platform and print a JSON list of all your registered devices with the "name", "id" and "key" of your registered device(s). The "key"s in this list are the Devices'Local_Keyyou will use to access your device.In addition to displaying the list of devices,Wizardwill create a local filedevices.jsonthat TinyTuya will use to provide additional details for scan results fromtinytuya.deviceScan()or when runningpython -m tinytuya scan. The wizard also creates a local filetuya-raw.jsonthat contains the entire payload from Tuya Cloud.TheWizardwill ask if you want to poll all the devices. If you do, it will display the status of all devices on record and create asnapshot.jsonfile with these results. Make sure your LAN and firewall permit UDP (6666, 6667 and 7000) and TCP (6668) traffic.Notes:If you ever reset or re-pair your smart devices, theLocal_Keywill be reset and you will need to repeat the steps above.The TinyTuyaWizardwas inspired by the TuyAPI CLI which is an alternative way to fetch theLocal_Keys:npm i @tuyapi/cli -gand runtuya-cli wizardProgramming with TinyTuyaAfter importing tinytuya, you create a device handle for the device you want to read or control.  Here is an example for a Tuya smart switch or plug:importtinytuya# Connect to Deviced=tinytuya.OutletDevice(dev_id='DEVICE_ID_HERE',address='IP_ADDRESS_HERE',# Or set to 'Auto' to auto-discover IP addresslocal_key='LOCAL_KEY_HERE',version=3.3)# Get Statusdata=d.status()print('set_status() result%r'%data)# Turn Ond.turn_on()# Turn Offd.turn_off()TinyTuya Module Classes and FunctionsGlobal Functions
    devices = deviceScan()             # Returns dictionary of devices found on local network
    scan()                             # Interactive scan of local network
    wizard()                           # Interactive setup wizard
    set_debug(toggle, color)           # Activate verbose debugging output

Classes
    OutletDevice(args...)
    CoverDevice(args...)
    BulbDevice(args...)
      Where args:
        dev_id (str): Device ID e.g. 01234567891234567890
        address (str): Device Network IP Address e.g. 10.0.1.99 or "Auto" to auto-find
        local_key (str): The encryption key
        dev_type (str): Device type for payload options (see below)
        connection_timeout = 5 (int): Timeout in seconds
        version = 3.1 (float): Tuya Protocol (e.g. 3.1, 3.2, 3.3, 3.4, 3.5)
        persist = False (bool): Keep TCP link open
        cid = None (str): Optional sub device id
        node_id = None (str): Alias for cid
        parent = None (object): Gateway device object this is a child of
        connection_retry_limit = 5 (int)
        connection_retry_delay = 5 (int)

    Cloud(apiRegion, apiKey, apiSecret, apiDeviceID, new_sign_algorithm)


Functions:

  Configuration Settings: 

    set_version(version)               # Set device version 3.1 [default] or 3.3 (all new devices)
    set_socketPersistent(False/True)   # Keep connect open with device: False [default] or True
    set_socketNODELAY(False/True)      # Add cooldown period for slow Tuya devices: False or True [default]
    set_socketRetryLimit(integer)      # Set retry count limit [default 5]
    set_socketTimeout(s)               # Set connection timeout in seconds [default 5]
    set_dpsUsed(dpsUsed)               # Set data points (DPs) to expect (rarely needed)
    set_retry(retry=True)              # Force retry if response payload is truncated
    set_sendWait(num_secs)             # Seconds to wait after sending for a response
    set_bulb_type(type):               # For BulbDevice, set type to A, B or C

  Device Commands:

    status()                           # Fetch status of device (json payload)
    subdev_query(nowait)               # query sub-device list and online status (only for gateway devices)
    detect_available_dps()             # Return list of DPS available from device
    set_status(on, switch=1, nowait)   # Control status of the device to 'on' or 'off' (bool)
                                       # nowait (default False) True to send without waiting for response
    set_value(index, value, nowait)    # Send and set value of any DPS/index on device.
    set_multiple_values(index_value_dict, nowait)
                                       # Set multiple values with a single request
				       # Note: Some devices do not like this!
    heartbeat(nowait)                  # Send heartbeat to device
    updatedps(index=[1], nowait)       # Send updatedps command to device to refresh DPS values
    turn_on(switch=1, nowait)          # Turn on device / switch #
    turn_off(switch=1, nowait)         # Turn off device
    set_timer(num_secs, nowait)        # Set timer for num_secs on devices (if supported)
    generate_payload(command, data)    # Generate TuyaMessage payload for command with data
    send(payload)                      # Send payload to device (do not wait for response)
    receive()                          # Receive payload from device

    OutletDevice:
        set_dimmer(percentage):
        
    CoverDevice:
        open_cover(switch=1):  
        close_cover(switch=1):
        stop_cover(switch=1):

    BulbDevice
        set_colour(r, g, b, nowait):
        set_hsv(h, s, v, nowait):
        set_white(brightness, colourtemp, nowait):
        set_white_percentage(brightness=100, colourtemp=0, nowait):
        set_brightness(brightness, nowait):
        set_brightness_percentage(brightness=100, nowait):
        set_colourtemp(colourtemp, nowait):
        set_colourtemp_percentage(colourtemp=100, nowait):
        set_scene(scene, nowait):             # 1=nature, 3=rave, 4=rainbow
        set_mode(mode='white', nowait):       # white, colour, scene, music
        result = brightness():
        result = colourtemp():
        (r, g, b) = colour_rgb():
        (h,s,v) = colour_hsv():
        result = state():
    
    Cloud
        setregion(apiRegion)
	cloudrequest(url, action=[POST if post else GET], post={}, query={})
        getdevices(verbose=False)
        getstatus(deviceid)
        getfunctions(deviceid)
        getproperties(deviceid)
        getdps(deviceid)
        sendcommand(deviceid, commands [, uri])
	getconnectstatus(deviceid)
	getdevicelog(deviceid, start=[now - 1 day], end=[now], evtype="1,2,3,4,5,6,7,8,9,10", size=0, max_fetches=50, start_row_key=None, params={})TinyTuya Error CodesStarting with v1.2.0 TinyTuya functions will return error details in the JSON data responses instead of raising exceptions.  The format for this response:{"Error":"Invalid JSON Payload","Err":"900","Payload":"{Tuya Message}"}The "Err" number will be one of these:900 (ERR_JSON) - Invalid JSON Response from Device901 (ERR_CONNECT) - Network Error: Unable to Connect902 (ERR_TIMEOUT) - Timeout Waiting for Device903 (ERR_RANGE) - Specified Value Out of Range904 (ERR_PAYLOAD) - Unexpected Payload from Device905 (ERR_OFFLINE) - Network Error: Device Unreachable906 (ERR_STATE) - Device in Unknown State907 (ERR_FUNCTION) - Function Not Supported by Device908 (ERR_DEVTYPE) - Device22 Detected: Retry Command909 (ERR_CLOUDKEY) - Missing Tuya Cloud Key and Secret910 (ERR_CLOUDRESP) - Invalid JSON Response from Cloud911 (ERR_CLOUDTOKEN) - Unable to Get Cloud Token912 (ERR_PARAMS) - Missing Function Parameters913 (ERR_CLOUD) - Error Response from Tuya Cloud914 (ERR_KEY_OR_VER) - Check device key or versionExample UsageSee the sample python scripttest.pyfor an OutletDevice example or look in theexamplesdirectory for other scripts.importtinytuya"""OUTLET Device"""d=tinytuya.OutletDevice('DEVICE_ID_HERE','IP_ADDRESS_HERE','LOCAL_KEY_HERE')d.set_version(3.3)data=d.status()# Show status and state of first controlled switch on deviceprint('Dictionary%r'%data)print('State (bool, true is ON)%r'%data['dps']['1'])# Toggle switch stateswitch_state=data['dps']['1']data=d.set_status(notswitch_state)# This requires a valid keyifdata:print('set_status() result%r'%data)# On a switch that has 4 controllable ports, turn the fourth OFF (1 is the first)data=d.set_status(False,4)ifdata:print('set_status() result%r'%data)print('set_status() extra%r'%data[20:-8])"""RGB Bulb Device"""importtimed=tinytuya.BulbDevice('DEVICE_ID_HERE','IP_ADDRESS_HERE','LOCAL_KEY_HERE')d.set_version(3.3)# IMPORTANT to set this regardless of versiond.set_socketPersistent(True)# Optional: Keep socket open for multiple commandsdata=d.status()# Show status of first controlled switch on deviceprint('Dictionary%r'%data)# Set to RED Color - set_colour(r, g, b):d.set_colour(255,0,0)# Cycle through the Rainbowrainbow={"red":[255,0,0],"orange":[255,127,0],"yellow":[255,200,0],"green":[0,255,0],"blue":[0,0,255],"indigo":[46,43,95],"violet":[139,0,255]}forcolorinrainbow:[r,g,b]=rainbow[color]d.set_colour(r,g,b,nowait=True)# nowait = Go fast don't wait for responsetime.sleep(0.25)# Brightness: Type A devices range = 25-255 and Type B = 10-1000d.set_brightness(1000)# Set to White - set_white(brightness, colourtemp):#    colourtemp: Type A devices range = 0-255 and Type B = 0-1000d.set_white(1000,10)# Set Bulb to Scene Moded.set_mode('scene')# Scene Example: Set Color Rotation Scened.set_value(25,'07464602000003e803e800000000464602007803e803e80000000046460200f003e803e800000000464602003d03e803e80000000046460200ae03e803e800000000464602011303e803e800000000')Example Device MonitorYou can set up a persistent connection to a device and then monitor the state changes with a continual loop. This is helpful for troubleshooting and discovering DPS values.importtinytuyad=tinytuya.OutletDevice('DEVICEID','DEVICEIP','DEVICEKEY')d.set_version(3.3)d.set_socketPersistent(True)print(" > Send Request for Status < ")payload=d.generate_payload(tinytuya.DP_QUERY)d.send(payload)print(" > Begin Monitor Loop <")while(True):# See if any data is availabledata=d.receive()print('Received Payload:%r'%data)# Send keyalive heartbeatprint(" > Send Heartbeat Ping < ")payload=d.generate_payload(tinytuya.HEART_BEAT)d.send(payload)# NOTE If you are not seeing updates, you can force them - uncomment:# print(" > Send Request for Status < ")# payload = d.generate_payload(tinytuya.DP_QUERY)# d.send(payload)# NOTE Some smart plugs require an UPDATEDPS command to update power data# print(" > Send DPS Update Request < ")# payload = d.generate_payload(tinytuya.UPDATEDPS)# d.send(payload)Tuya Cloud AccessYou can poll and manage Tuya devices using theCloudclass and functions.CAUTION: The free Tuya IoT Developer (Trial) account allows a very limited number of Cloud API calls. Be aware of the restrictions before enabling any automation that makes frequent calls.importtinytuya# Connect to Tuya Cloud# c = tinytuya.Cloud()  # uses tinytuya.jsonc=tinytuya.Cloud(apiRegion="us",apiKey="xxxxxxxxxxxxxxxxxxxx",apiSecret="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",apiDeviceID="xxxxxxxxxxxxxxxxxxID")# Display list of devicesdevices=c.getdevices()print("Device List:%r"%devices)# Select a Device ID to Testid="xxxxxxxxxxxxxxxxxxID"# Display Properties of Deviceresult=c.getproperties(id)print("Properties of device:\n",result)# Display Status of Deviceresult=c.getstatus(id)print("Status of device:\n",result)# Send Command - Turn on switchcommands={"commands":[{"code":"switch_1","value":True},{"code":"countdown_1","value":0},]}print("Sending command...")result=c.sendcommand(id,commands)print("Results\n:",result)Up to one week of device logs can also be pulled from the Cloud.  By default getdevicelog() will pull 1 day of logs or 5000 log entries, whichever comes first.  The returned timestamps are unixtime*1000, and event_id 7 (data report) will probably be the most useful.importtinytuyaimportjsonc=tinytuya.Cloud()#r = c.getdevicelog( '00112233445566778899', start=-1, end=0, size=0, max_fetches=50 )#r = c.getdevicelog( '00112233445566778899', start=1669990000, end=1669990300, size=20 )r=c.getdevicelog('00112233445566778899')print(json.dumps(r,indent=2))Encryption NotesTuya devices use AES encryption which is not available in the Python standard library.PyCA/cryptographyis recommended and installed by default. Other options includePyCryptodome,PyCryptoandpyaes.Deprecation notice for pyaes: The pyaes library works for Tuya Protocol <= 3.4 but will not work for 3.5 devices. This is because pyaes does not support GCM which is required for v3.5 devices.Command Linepython -m tinytuya <command> [<max_time>] [-debug] [-nocolor] [-force [192.168.0.0/24 192.168.1.0/24 ...]] [-h]

  wizard         Launch Setup Wizard to get Tuya Local KEYs.
  scan           Scan local network for Tuya devices.
  devices        Scan all devices listed in devices.json file.
  snapshot       Scan devices listed in snapshot.json file.
  json           Scan devices listed in snapshot.json file [JSON].
  <max_time>     Maximum time to find Tuya devices [Default=18]
  -nocolor       Disable color text output.
  -force         Force network scan of device IP addresses based on format:
                 [net1/mask1 net2/mask2 ...] Auto-detects if none provided.
  -no-broadcasts Ignore broadcast packets when force scanning.
  -debug         Activate debug mode.
  -h             Show usage.Scan ToolThe functiontinytuya.scan()will listen to your local network (UDP 6666 and 6667) and identify Tuya devices broadcasting their Address, Device ID, Product ID and Version and will print that and their stats to stdout.  This can help you get a list of compatible devices on your network. Thetinytuya.deviceScan()function returns all found devices and their stats (via dictionary result).You can run the scanner from the command line using these interactive commands:# Listen for Tuya Devices and match to devices.json if availablepython-mtinytuyascan# The above creates a snapshot.json file with IP addresses for devices# You can use this command to get a rapid poll of status of all devicespython-mtinytuyasnapshot# The sames thing as above but with a non-interactive JSON responsepython-mtinytuyajson# List all register devices discovered from Wizard and poll thempython-mtinytuyadevicesBy default, the scan functions will retry 15 times to find new devices. If you are not seeing all your devices, you can increase max_retries by passing an optional arguments (eg. 50 retries):# command linepython-mtinytuyascan50# invoke verbose interactive scantinytuya.scan(50)# return payload of devicesdevices=tinytuya.deviceScan(false,50)TroubleshootingTuya devices only allow one TCP connection at a time.  Make sure you close the TuyaSmart or SmartLife app before usingTinyTuyato connect.Some devices ship with older firmware that may not work withTinyTuya. If you're experiencing issues, please try updating the device's firmware in the official app.The LOCAL KEY for Tuya devices will change every time a device is removed and re-added to the TuyaSmart app. If you're getting decrypt errors, try getting the key again as it might have changed.Devices running protocol version 3.1 (e.g. below Firmware 1.0.5) do not require a deviceLocal_Keyto read the status. All devices will require a deviceLocal_Keyto control the device.Some devices with 22 character IDs will require additional setting to poll correctly. TinyTuya will attempt to detect and accomodate for this, but it can be specified directly:a=tinytuya.OutletDevice('here_is_my_key','192.168.x.x','secret_key_here','device22')a.set_version(3.3)a.set_dpsUsed({"1":None})# This needs to be a datapoint available on the devicedata=a.status()print(data)Windows 10 Users - TinyTuyawizardandscaninteractive tools use ANSI color. This will work correctly in PowerShell but will show cryptic escape codes when run in WindowsCMD.  You can fix this by using the-nocoloroption on tinytuya, or by changing the WindowsCMDconsole registry to process ANSI escape codes by doing something like this:reg add HKEY_CURRENT_USER\Console /v VirtualTerminalLevel /t REG_DWORD /d 0x00000001 /fUser Contributed Device ModulesIn addition to the built-inOutletDevice,BulbDeviceandCoverDevicedevice support, the community is encourage to submit additional device modules which are available here:Contrib Library:# Example usage of community contributed device modulesfromtinytuyaimportContribthermo=Contrib.ThermostatDevice('abcdefghijklmnop123456','172.28.321.475','1234567890123abc')Tuya Data Points - DPS TableThe Tuya devices send back data points (DPS) also called device function points, in a json string.  The DPS attributes define the state of the device.  Each key in the DPS dictionary refers to key value pair, the key is the DP ID and its value is the dpValue. You can refer to theTuya developer platformfor definition of function points for the products.The following table represents several of the standard Tuya DPS values and their properties. It represents data compiled from Tuya documentation and self-discovery. Devices may vary. Feedback or additional data would would be appreciated.  Please submit a Issue or Pull Request if you have additional data that would be helpful for others.To find Tuya DPS for devices not listed below, you can discover the DPS values using the Tuya IoT platform. See this help here:Find your Data Point.DPS Read and Set Example:# Read Value of DPS 25data=d.status()print("Value of DPS 25 is ",data['dps']['25'])# Set Value of DPS 25d.set_value(25,'010e0d0000000000000003e803e8')Version 3.1 DevicesVersion 3.1 (and some 3.3) - Plug or Switch TypeDP IDFunction PointTypeRangeUnits1SwitchboolTrue/False2Countdown?integer0-86400s4Currentinteger0-30000mA5Powerinteger0-50000W6Voltageinteger0-5000VVersion 3.1 - Light Type (RGB)DP IDFunction PointTypeRangeUnits1SwitchboolTrue/False2Modeenumwhite,colour,scene,music3Brightinteger10-1000*4Color Tempinteger0-1000*5Colorhexstringr:0-255,g:0-255,b:0-255,h:0-360,s:0-255,v:0-255rgb+hsvVersion 3.3 DevicesVersion 3.3 - Plug, Switch, Power Strip TypeDP IDFunction PointTypeRangeUnits1Switch 1boolTrue/False2Switch 2boolTrue/False3Switch 3boolTrue/False4Switch 4boolTrue/False5Switch 5boolTrue/False6Switch 6boolTrue/False7Switch 7/usbboolTrue/False9Countdown 1integer0-86400s10Countdown 2integer0-86400s11Countdown 3integer0-86400s12Countdown 4integer0-86400s13Countdown 5integer0-86400s14Countdown 6integer0-86400s15Countdown 7integer0-86400s17Add Electricityinteger0-50000kwh18Currentinteger0-30000mA19Powerinteger0-50000W20Voltageinteger0-5000V21Test Bitinteger0-5n/a22Voltage coeff.integer0-100000023Current coeff.integer0-100000024Power coeff.integer0-100000025Electricity coeff.integer0-100000026Faultfaultov_cr38Power-on state settingenumoff, on, memory39Overcharge SwitchboolTrue/False40Indicator status settingenumnone, on, relay, pos41Child LockboolTrue/False42UNKNOWN43UNKNOWN44UNKNOWNNote: Some 3.3 energy management plugs use the DPS values of the 3.1 plug above.Version 3.3 - Dimmer SwitchDP IDFunction PointTypeRangeUnits1SwitchboolTrue/False2Brightnessinteger10-1000*3Minimum of Brightnessinteger10-1000*4Type of light source1enumLED,incandescent,halogen5ModeenumwhiteVersion 3.3 - Light Type (RGB)DP IDFunction PointTypeRangeUnits20SwitchboolTrue/False21Modeenumwhite,colour,scene,music22Brightinteger10-1000*23Color Tempinteger0-100024Colorhexstringh:0-360,s:0-1000,v:0-1000hsv25Scenestringn/a26Left timeinteger0-86400s27Musicstringn/a28Debuggerstringn/a29Debugstringn/a30Rhythmsn/an/a31Go To Sleepn/an/a32Wake Upn/an/a33Power Off Memoryn/an/a34Do not Disturbn/an/a41Remote Control Switchn/an/a209Cycle Timingn/an/a210Vaction Timingn/an/aVersion 3.3 - Automated Curtain TypeDP IDFunction PointTypeRangeUnits1Curtain Switch 1enumopen, stop, close, continue2Percent control 1integer0-100%3Accurate Calibration 1enumstart, end4Curtain Switch 2enumopen, stop, close, continue5Percent control 2integer0-1006Accurate Calibration 2enumstart, end8Motor Steer 1enumforward, back9Motor steer 2enumforward, back10Quick Calibration 1integer1-180s11Quick Calibration 2integer1-180s12Motor Mode 1enumstrong_power, dry_contact13Motor Mode 2enumstrong_power, dry_contact14Light modeenumrelay, pos, noneVersion 3.3 - Fan Switch TypeDP IDFunction PointTypeRangeUnits1Fan switchboolTrue/Falsen/a2Fan countdowninteger0-86400s3Fan speedenumlevel_1, level_2, level_3, level_4, level_54Fan speedinteger1-100%5Fan light switchboolTrue/False6Brightness integerinteger10-10007Fan light countdowninteger0-864008Minimum brightnessinteger10-10009Maximum brightnessinteger10-100010Modeenumwhite11Power-on state settingenumoff, on, memory12Indicator status settingenumnone, relay, pos13Backlight switchboolTrue/FalseVersion 3.3 - Universal IR Controller with optional Temp/HumidityDP IDFunction PointTypeRangeUnits101Current Temperatureinteger0-60010x Celsius102Current Humidityinteger0-100%201IR Commands (set only)JSON*n/an/a# The IR Commands JSON has the following format:command={"control":"send_ir","head":"","key1":"[[TO_BE_REPLACED]]","type":0,"delay":300,}# Sending the IR command:payload=d.generate_payload(tinytuya.CONTROL,{"201":json.dumps(command)})d.send(payload)Thekey1attribute is a base64 string that contains the IR signal. You can extract it using this procedure:Register a new IR device on Tuya Smart / Smart Life app (if not registered already) and map, setup or import your buttons.Tap multiple times on the button you wish to control.Go toTuya IoT Platformand select your app under Cloud > Development section.Go to to the Device tab and select "Debug Device" on the parent device. Browse Device Logs section and retrieve thekey1attribute that matches your tapping timestamp from step 2 above. Use thatkey1attribute in the payload example above.You need to repeat these steps for each button (cloud logging is not always sequential).Version 3.3 - Sensor TypeImportant Note:Battery-powered Tuya sensors are usually designed to stay in sleep mode until a state change (eg.open or close alert). This means you will not be able to poll these devices except in the brief moment they awake, connect to the WiFi and send their state update payload the the Tuya Cloud. Keep in mind that if you manage to poll the device enough to keep it awake, you will likely quickly drain the battery.DP IDFunction PointTypeRangeUnits1Door SensorboolTrue/False2Battery level stateenumlow, middle, high3Battery levelinteger0-100%4Temper alarmboolTrue/False5Flooding Detection Stateenumalarm, normal6Luminance detection stateenumlow, middle, high, strong7Current Luminanceinteger0-100%8Current Temperatureinteger400-20009Current Humidityinteger0-100%10Shake Stateenumnormal, vibration, drop, tilt11Pressure Stateenumalarm, normal12PIR stateenumpir, none13Smoke Detection Stateenumalarm, normal14Smoke valueinteger0-100015Alarm Volumeenumlow, middle, high, mute16Alarm Ringtoneenum1, 2, 3, 4, 517Alarm Timeinteger0-60s18Auto-DetectboolTrue/False19Auto-Detect Resultenumchecking, check_success, check_failure, others20PreheatboolTrue/False21Fault Alarmfaultfault, serious_fault, sensor_fault, probe_fault, power_faultBarrier22LifecycleboolTrue/False23Alarm SwitchboolTrue/False24SilenceboolTrue/False25Gas Detection Stateenumalarm, normal26Detected Gasinteger0-100027CH4 Detection Stateenumalarm, normal28CH4 valueinteger0-100029Alarm stateenumalarm_sound, alarm_light, alarm_sound_light, normal30VOC Detection Stateenumalarm, normal31VOC valueinteger0-99932PM2.5 stateenumalarm, normal33PM2.5 valueinteger0-99934CO stateenumalarm, normal35CO valueinteger0-100036CO2 Detection Stateenumalarm, normal37CO2 valueinteger0-100038Formaldehyde Detection Stateenumalarm, normal39CH2O valueinteger0-100040Master modeenumdisarmed, arm, home, sos41Air quality indexenumlevel_1, level_2, level_3, level_4, level_5, level_6NOTE (*) - The range can vary depending on the device. As an example, for dimmers, it may be 10-1000 or 25-255.Version 3.3 - WiFi Air Quality Detector PM2.5/Formaldehyde/VOC/CO2/Temperature/HumidityDP IDFunction PointTypeRangeUnits2PM2.5 valueinteger0 - 999ug/m318Current Temperatureinteger0 - 850˚C (multiplied by 10)19Current Humidityinteger0 - 1000% (multiplied by 10)20CH2O (Formaldehyde) valueinteger0 - 1000ppm21VOC (Volatile organic compound) valueinteger0 - 2000ppm22CO2 valueinteger350 - 2000ppmExample device:https://www.aliexpress.com/item/1005005034880204.htmlVersion 3.3 - Robot Mower TypeDP IDFunction PointTypeRangeUnits6Batteryinteger0-100%101Machine StatusenumSTANDBY MOWINGCHARGINGEMERGENCYLOCKEDPAUSEDPARKCHARGING_WITH_TASK_SUSPENDFIXED_MOWING102Machine errorinteger0, ?103Machine warningenumMOWER_LEANMOWER_EMERGENCYMOWER_UI_LOCKED104Rain modebooleanTrue/False105Work timeinterger1-99hours106Machine passwordbyte str?107Clear machine appointmentbooleanTrue/False108Query machine reservationbooleanTrue/False109Query partition parametersbooleanTrue/False110Report machine reservationbyte str111Error logbyte str112Work logbyte str113Partition parametersbyte str114Work modeenumAutoMode/??Referencepymoebotfor further definition.Version 3.3 - 24v Thermostat (i.e. PCT513-TY)DP IDFunction PointTypeRangeUnits2System Modeenum[ 'auto' 'cool' 'heat' 'off' others? ]16Center of Setpoint, High-Resolution °Cinteger500-3200°C x 100 in steps of 5017Center of Setpoint, °Finteger20-102°F18*Cooling Setpoint, Low-Resolution °Finteger20-102°F19*Cooling Setpoint, Low-Resolution °Cinteger500-3200°C20*Heating Setpoint, Low-Resolution °Finteger20-102°F23Display Unitsenum[ 'f' 'c' ]24Current Temperature, High-Resolution °Cinteger500-3200°C x 100 in steps of 5026*Heating Setpoint, Low-Resolution °Cinteger5-32°C27*Temperature Correctioninteger-10 - +1029Current Temperature, °Finteger20-102°F34Current Humidityinteger0-100%45Fault Flagsbitmask[ e1 e2 e3 ]107System Typeinteger-as-string??108*Cooling Setpoint, High-Resolution °Cinteger500-3200°C x 100 in steps of 50109*Heating Setpoint, High-Resolution °Cinteger500-3200°C x 100 in steps of 50110*Cooling Setpoint, °Finteger20-102°F111*Heating Setpoint, °Finteger20-102°F115Fan Modeenum[ 'auto' 'cycle' 'on' ]116"at home/away from home"integer-as-string??118Schedule Database64binary blob119Schedule EnabledboolTrue/False120Hold/Scheduleenum[ 'permhold' 'temphold' 'followschedule' ]121Vacation Database64binary blob122Sensor Data, list 1base64binary blob123Minimum Fan Run Timeinteger0-55minutes per hour125Sensor Data, list 2base64binary blob126Sensor Data, list 3base64binary blob127Sensor Data, list 4base64binary blob128Sensor Data, list 5base64binary blob129System Stateenum[ 'fanon' 'coolfanon' 'alloff' others? ]130Weather Forcast???NOTE (*) - Depending on the firmware, either 18/19/20/26/27 or 108/109/110/111/x are used, not bothA user contributed module is available for this device in theContrib library:fromtinytuyaimportContribthermo=Contrib.ThermostatDevice('abcdefghijklmnop123456','172.28.321.475','1234567890123abc')For info on the Sensor Data lists, seehttps://github.com/jasonacox/tinytuya/discussions/139Tuya ReferencesTuya Hardware Development - Protocol:https://developer.tuya.com/en/docs/iot/device-development/embedded-software-development/mcu-development-access/wifi-mcu-sdk-solution/tuya-cloud-universal-serial-port-access-protocol?id=K9hhi0xxtn9cbTuyaMCU listing of Tuya DP IDs:https://tasmota.github.io/docs/TuyaMCU/#switches-or-plugspower-stripsCreditsTuyAPIhttps://github.com/codetheweb/tuyapiby codetheweb and blackrozes.
Protocol reverse engineering from jepsonrob and clach04.PyTuyahttps://github.com/clach04/python-tuyaby clach04.
The origin of this python module (now abandoned). Thanks to nijave for pycryptodome support and testing, Exilit for unittests and docstrings, mike-gracia for improved Python version support, samuscherer for RGB Bulb support, magneticflux for improved Python version support, sean6541 for initial PyPi package and Home Assistant supporthttps://github.com/sean6541/tuya-homeassistant, ziirish - for resolving a dependency problem related to version numbers at install timehttps://github.com/rospogrigio/localtuya-homeassistantby rospogrigio.
Updated pytuya to support devices with Device IDs of 22 charactersThanks to@uzlonewolf, our top contributor and resident wizard, for expanding the Outlet/Cover/Bulb/Cloud modules into separate files, introducing Contrib structure for user generated device modules, making enhancements to TuyaMessage logic for multi-payload messages, rewriting the scanner and addingTuya Protocol 3.2, 3.4 & 3.5support to TinyTuya!Finally, thanks to the entire TinyTuya community for the great engagement, contributions and encouragement! SeeRELEASE notesfor the ever growing journal of improvements and the incredible list of talent making this project possible.Related Projectshttps://github.com/sean6541/tuyaapiPython API to the web apihttps://github.com/codetheweb/tuyapinode.jshttps://github.com/Marcus-L/m4rcus.TuyaCore- .NEThttps://github.com/SDNick484/rectec_status/- RecTec pellet smokers control (with Alexa skill)https://github.com/TradeFace/tuyaface- Python Async Tuya APITinyTuya Powered ProjectsPlease feel free to submit a PR or open an issue to add your project.https://github.com/mafrosis/tinytuya2mqtt- A bridge between TinyTuya and Home Assistant via MQTThttps://github.com/Whytey/pymoebot- A Python library intended to monitor and control the MoeBot robotic lawn mowers.https://github.com/make-all/tuya-local- Local support for Tuya devices in Home Assistanthttps://github.com/teejo75/mtghs- Provides an HTTP service for Moonraker to control Tuya outlets.https://github.com/Xenomes/Domoticz-TinyTUYA-Plugin- Plugin for Domoticz Home Automation