Skip to content

Golang API for tuya devices using protocol v3.3

License

Notifications You must be signed in to change notification settings

vshmoylov/golang-tuya-api

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

32 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

tuya

Golang API for tuya devices (or the like)

Experimental code subject to major changes

Limits

Support limited to protocol version 3.1

Tested only with Neo power plugs

Standalone application

Primary as an example and for my one use I have released a small web application that uses this API.

The application can be installed on a Raspberry PI (for example).

You will find it there : https://github.com/py60800/tinytuya

Acknowledgements

@codetheweb for reverse engineering the protocol

Prerequisites

Collect the keys and the id of tuya devices according to @Codetheweb method

Reliability

The Neo devices I use (Tuya clone) behave as expected most of the time but I have experienced some random crash during development.

Usage

Get the API go get "github.com/py60800/tuya"

Import 'github.com/py60800/tuya`

Create json configuration, thanks to keys and id collected previously (Use backquotes for multiline conf data or get it from a file)

conf := `[{"gwId":"1582850884f3eb30128e", "key":"XXXXXXX", "type":"Switch", "name":"s1"}]`
//multiline data
conf := `[
 {"gwId":"1582850884f3eb30128e", 
  "key":"XXXXXXXXXXX",
  "type":"Switch",
  "name":"sw1" },
 {"gwId":"86273325cc50e3c8fe2d",
  "key":"XXXXXXXXXXX",
  "type":"Switch",
  "name":"sw2" }
  ]`

Create a device manager: dm := tuya.NewDeviceManager(conf)

Get configured devices by their name b1,ok := dm.GetDevice("sw1")

Check type and cast to get active interface sw1 := b1.(tuya.Switch)

Play with the device :

sw1.Set(true) // doesn't wait for the result of the command

sw1.SetW(5*time.Second) // ensure the command is properly done

st,_ := sw1.Status()

fmt.Println("sw1 status:", st)

Design considerations

IP addresses are collected automatically from UDP messages broadcast on port 6666

API is supposed to be thread safe (I hope). A device can be used by concurrent go coroutines however communication with each device are serialized (no more than one TCP connection)

Communication with Tuya device is asynchronous. This means that tuya device can notify a change if someone plays with the hardware switch. Naive implement may encounters issues while a expecting one request for each response.

Extension

Looking at switch.go source code, it should be easy to create new devices using the same protocol.

Just define appropriate interface, code what is specific in a dedicated file and update the factory to make it usable.

Notes

I have found many oddities in tuya protocol:

  • Actual 64 bits encryption instead of 128 bits encryption (incorrect string to byte conversion)

  • ECB encryption is weak

  • Half of MD5 signing is used

  • Useless prefixes and suffixes

  • Worthless base64 encoding

  • Protocol not properly layered (command outside payload)

By many aspects, it seems that the protocol was designed for serial line communication.

Need help ?

Open an issue!

About

Golang API for tuya devices using protocol v3.3

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Go 53.7%
  • CSS 45.2%
  • JavaScript 1.1%