-
-
Notifications
You must be signed in to change notification settings - Fork 345
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Controlling Tuya devices with cloud API instead of controlling them locally #20
Comments
You have to apply to https://developer.tuya.com/user/cloud to get an accesskey. i will update this thread once i have more details. but if anyone has additional ideas, please let me know |
I believe the MD5 hash is the same as what's implemented in TuyAPI (see here), although I could be wrong. |
In the cloud API
There is a special case for the parameter
Just before you do the final MD5 of the whole string, it should look like this: [1] |
@bahorn thank you for the reply. i will try this as soon as i get the accesskey from tuya. |
Also one thing i was not aware of is that the postData is part of the MD5 hash to generate the sign. thank you |
@bahorn May I ask where did you get this information for the cloud API I just got my accessKey and keySecret from Tuya and I have tried both your method and the instructions on Tuya, that @michmike said. Using PostMan, I tried doing API requests and end up getting the following response after multiple tries:
|
@dominicklee I just recorded on my old phone (android old enough so i could have a root certificate for fiddler) so i got all the information about resquest&post-data + responses. I have recorded the following scenarios with the official SmartLife app:
I will need a little time to format everything (and scramble some personnal info before making it public) but i will make all the info available, maybe tonight (GMT -5) if I have time The only thing i'm not able to record is the action on the device. If I click to turn it on or off, nothings happens in fiddler, so no HTTP request seams to be made to the server, it must be something else. I checked for UDP on the network and it's not that either. So that's the part I did not figure out ! |
@dominicklee I stripped down my personal Python implementation that should clear up the issues. @Ericmas001 Devices are controlled by MQTT. Use Wireshark to log it, you can set a filter for just MQTT. Just to explain more of how this works, when you attempt to login you are given:
You construct the RSA key given and use it to encrypt the MD5(all 128 bits encoded as hex) of your password. This is then padded and then sent on to the server (along with the token). If the login details are correct, you get returned a session ID for use in other mobile requests. Worth noting is the "ecode" and the "p10001" thing that are returned along with the session ID, which you need to login to the MQTT server. After you login, you should make a call to "tuya.m.device.my.list" to get a list of devices, their uuids and local keys. With this, you can then connect to their MQTT server to issue commands. |
I would like to update that I have tried the methods as mentioned by @bahorn and sadly I have received "PERMISSION_DENIED" with the access keys that I have been given. I don't exactly understand why this does not work. Perhaps Tuya is limiting the cloud API access to the respective companies who ordered custom devices. If anyone got the Tuya cloud REST API working on a no-name (generic) Tuya device, please let me know. |
https://github.com/Ericmas001/Tuya-Api-Tools/wiki/Requests I scrambled some info and applied a little formatting to my fiddler outputs (I did not do it manually, of course a little script helped me 😃) There is more information than needed, but it's never too much when you try to understand something 😃 @bahorn The appKey and appSecret, can they be seen on those request or taken from existing app, or I really need to apply for one at the Tuya API Team ? |
@Ericmas001 wow, that looks like it was a lot of work - thank you. The API keys I thought were sent in HTTP/HTTPS requests to Tuya's servers, but from your requests it looks like that isn't the case. |
@Ericmas001 the clientId is actually the accessKey which Tuya app uses. But you will not be able use any Tuya Cloud API without knowing the keySecret, which is technically in the md5 hashed sign. Unless you can decode the sign, which is virtually impossible, you won't be able to get the keySecret. And as said, I rightfully requested for a set of API credentials from Tuya and tried them. They apparently do not give me permission to do anything on any generic devices. |
Also, one more things you guys should understand is that Tuya devices can be controlled via both MQTT and HTTPS API. However, their app chose to use MQTT for some reason, which explains why actions could not be recorded in an HTTP sniffer. |
I've done a bit of wiresharking between my phone, device and tuya cloud using the eFamilyCloud app and I can successfully decode all of the MQTT messages from the device using my device key. The MD5 example on the Tuya site is not 100% accurate and needs some modification to get the MD5 hash that the site shows out the other end. I think their formatting in the code boxes is a bit messed up. I can login to the cloud and subscribe to MQTT queues using the mqttfx app and if I send a control action from my phone, I can see it appear in the subscription queue and then decode the message using a PowerShell script I wrote. Wireshark shows your username and password in the MQTT connect message in plain text. I've tried reversing this and constructing a message to send to the MQTT queue using the same method but unfortunately it just gets dropped by the server. I'm pretty sure that I'm signing the message in the same way that the eFamilyCloud app does so I had got to the point where I thought there must be some set up done over HTTPS before the MQTT conversation starts. My decode script decodes both genuine MQTT data and my own constructed data in the same way. I've gone as far as exporting a conversation between my phone and the cloud (which successfully controls the device) and then another conversation between mqttfx and the cloud with my encoded data (which doesn't work) and the MQTT conversation looks identical (bar the data and IPs etc.) It's possible that I'm not encoding the 'data' json part of the message correctly. When I get a few minutes, I'll tidy up the encode/decode PowerShell scripts and publish them. Turns out I had a few minutes, here's where I got with the encode/decode |
@bobalob I'm a MQTT total noob, so maybe this makes no sence, but does MQTT have some kind of headers, like HttpHeaders, that could be different, something like a userAgent that would be blocked or i don't know ... |
@Ericmas001 You can extract them from the many apps, which was discussed early on in #5. In the app I looked at I found the signing process was dumped in the android logs, which includes the AppSecret and AppKey. (Look for "SignRequest" or something on that line.) I was able to send messages directly to their MQTT server using the paho-mqtt Python library. I just logged in using details I took from packet captures (I only later figured out how usernames/passwords were generated). The app actually supports MQTT over TLS but never uses it for some reason. Worth noting that you can actually replay messages sent over MQTT as the time is actually ignored (or at least by the devices I used). @bobalob Are you sending it to the topic "smart/mb/out/"? You code for producing messages seems correct but I don't have a Windows box on me right to verify. The first commented out template is what I've used to control devices. @dominicklee I actually didn't know the Cloud/App API supported that. I thought it would fall back to it when I forced everything though a HTTP proxy but it never did so I assumed they didn't support it. I tested the Just wondering, did you modify my code to use any of the cloud actions listed on https://docs.tuya.com/en/cloudapi/cloudAPI/index.html |
@bahorn I'm impressed that you were able to use |
@bahorn You have successfully got the app access working it seems. However, the cloud access for API is not exactly the same, and that is what I am trying to figure out. |
@dominicklee Just got a call to both Code: |
@bahorn Yes, I was publishing on the "smart/mb/out/devId" while subscribed to smart/mb/in and another topic pXXXXXX/mb/euXXXXXXXX. I wasn't aware you could replay a message from the phone. I did try that but that also got dropped. Perhaps the application I'm using is doing something weird or I'm missing something. |
@Ericmas001 there are headers in the packet for various MQTT controls like message type, flags, QoS, retain etc. I'm setting those all the same as the app does. |
@bahorn and @Ericmas001 Thank you guys for your helpful inputs! I have been able to to get Tuya mobile API working using your code examples and hints. Although I still haven't been able to control devices with the Tuya Cloud API, I feel the mobile API would do just as well in terms of controlling devices. To confirm and clear up any confusion, the mobile API is signed as: For mobile, you will need to be logged in (with an SID provided) to perform actions. While the Tuya Cloud API is signed as: Both API credentials are different. However, even if you request the cloud API credentials for Tuya, they will only allow you to access only the devices you manufacture with them. If you are able to get the API keys for another working app, that may work but it goes beyond the scope of this issue. |
@bahorn have you been able to use the mobile or cloud API to control the devices as well? I have yet to try what @dominicklee mentioned where you can use the API versus MQTT to control the power plug |
@dominicklee I'd love to see your progress. Any chance you have a fork hosted somewhere with these changes? |
I like the idea of this library using LOCAL control over Cloud control. Of course, having both options would be ideal, giving the user choice, and providing failover if one isn't available. Another nice aspect of getting at least SOME of the Cloud API worked out... the Cloud API returns deviceID and localKey for all devices. Having this piece in place would keep people from having to wireshark their keys and would act as a "discovery" mode of sorts. |
@dlashua right, it would be ideal if a user could just sign in with the same username & password and be able to control all their devices. I'm planning to add cloud control of devices as optional functionality if this ever works. (Meaning, TuyAPI will default to controlling stuff locally unless told otherwise by the user.) |
That's perfect! I applied for the Cloud API Key 3 days ago so that I could help get this underway, but I've yet to get info from them and my application still shows as "under review". It's a shame they didn't make this a little bit easier. Tuya products are EVERYWHERE, they work quite well (as long as you use their permissions laiden apps), and are fairly inexpensive. And all that's "missing" is some documentation, and a way to easily access localKey. There are several big downsides to the cloud approach as Tuya presents it. As best as I can tell, you'll need to perform a "tuya.cloud.user.sync" for each user that wishes to use the cloud through your key. Additionally, at that point, that cloud account will have access (without a password, from that point on) to that user's devices. So, this means 1) you can't put the Cloud API creds directly in the library or else everyone will have access to everyone else's devices, 2) because of this, a intermediate API will need to be developed for the library to hit, 3) this API will have to be hosted somewhere ($$$) and publically available, 4) users will have to trust this cloud service with their credentials. Another option will be to require that every user seek their own Cloud API credentials, but, as you can see from my experience, this doesn't cater to the "I want it now" mentality, as I've been waiting three days with no response. |
I haven't tested it, but it looks like Tuya released their docs for their API at some point. Tuya Docs: https://docs.tuya.com/docDetail?code=K8v0h3gsie1b9 |
They've had those up for a while. :) Although some endpoints do seem more thoroughly documented now. |
You wouldn't happen to know if it costs money to use the API @codetheweb? I am having a tough time figuring that out by looking at their website. I want to implement a library in C++ for the api, but I don't plan on selling it as a product, so I am only going to do it if it is free. |
The API was free to use, then they added a $2000 paywall, and now it appears it might be free to use again. It's not clear because it says to contact support to get the the API secret. If you want to try, create an account on iot.tuya.com and make a new app under App Service. |
This could be of interest: https://github.com/unparagoned/cloudtuya |
You can request an API user + secret for free. I contacted support for help but I really don't understand what to do. I'm leaving the entire conversarion here. If anyone have a clue about what do to, please answer me, because I'm in the dark. Support conversation:
|
Just to chip in the discussion. You must have OEM a Tuya app (your own
rebranded app) to be able to use the API. The user and devices must be
registered under your own rebranded app in order for the API to work.
Otherwise you only get permission denied.
The clientId and secret is tied to the name space of your own rebranded app
…On Sat, Nov 16, 2019, 12:36 PM mateusscheper ***@***.***> wrote:
You can request an API user + secret for free.
I got mine and tried to make requests using Postman, but I always get *permission
denied*.
I contacted support for help but I really don't understand what to do.
I'm leaving the entire conversarion here. If anyone have a clue about what
do to, please answer me, because I'm in the dark.
Support conversation:
*Me* 2019-11-12 02:02:02
Hi!
I'm trying to use the open API but I'm getting permission denied on some
requests. I've been reading in the docs and I have to set "schema", but I'm
using Smart Life App in my phone and Postman in my PC. How can I do this?
Thank you!
*Tuya* 2019-11-12 11:17:14
hi dear.When you call a device’s related interface and are prompted
“Permission denied”, check the two dimensions of permissions following and
ensure you are conforming to them.
App dimension: Users linked with devices are the developer’s users on the
Tuya Cloud app; developers have indirect permissions to operate the devices
of their app users.
Product dimension: the devices used by the products belong to the
developer on Tuya Cloud product devices; developers have operation
permissions on these devices.
*Me* 2019-11-12 12:50:36
Hi! Thank you for your reply.
I still don't quite understand.
I'm following this tutorial:
https://docs.tuya.com/en/iot/open-api/quick-start/quick-start
Yet I can't make requests. What am I missing?
Thank you.
*Tuya* 2019-11-12 13:06:23
In brief, the product and app you develop must be under your account, and
you can check it from the two dimensions I sent above.Smart Life App is
tuya's app. You can't develop it~best wishes
*Me* 2019-11-13 22:55:19
Hi!
I'm not developing an app. I'm just using the open API to make requests.
Tuya 2019-11-14 10:26:07
hi dear The device API you call must be a product you created on the IOT
platform, or it will be prompted “Permission denied”
*Me* 2019-11-15 13:07:48
Ah, you are saying I need to create an OEM app! I see now!
Well, I did, but it asks to reset my smart plug, but I cannot do this
because it is already connected to Smart Life App.
Can I use Smart Life App's schema inside API? I don't want to use my own
app for this.
*Tuya* 2019-11-15 13:18:23
Hello,smart life belongs to tuya, which cannot make API calls from the
application dimension. You need to create OEM app or app SDK. best wishes~
*Me* 31 minutes ago
Hi!
Ok, I created an app. The app's package name is "com.mateus.smartplug", so
I set schema in Postman as "mateussmartplug", but I'm still getting
permission denied. What am I doing wrong?
*Tuya* 23 minutes ago
hi dear pls refer to this link:
https://docs.tuya.com/en/iot/open-api/tuya-open-platform-access-guide/simple-grant
best wishes~
This is what I'm getting:
[image: postman-tuya-open-api]
<https://user-images.githubusercontent.com/43916794/68988119-5a429280-0811-11ea-822f-f85f9b415264.jpg>
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#20?email_source=notifications&email_token=AHWN76NCTWGVWEPZEIJW6RDQT52DXA5CNFSM4ENSFISKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEEHJJCA#issuecomment-554603656>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AHWN76IW45TMHE4RXN4BYU3QT52DXANCNFSM4ENSFISA>
.
|
So if I want to use the Cloud API I can't use Google Assistant with the same device, since the device can't be in two apps at the same time, and a rebranded app will not appear in Google Assistant list. Correct? |
Yes, AFAIK. |
Is the development of the HA integration still active? |
When i tried to Login and get a key from Tuya Developer Console, it says the following. Looks like they going to replace with a different platform. "
|
For people trying to get the Tuya Cloud API working, the advice here 100% works - https://developer.tuya.com/en/docs/iot/open-api/quick-start/quick-start1?id=K95ztz9u9t89n You have to make 2 calls -
Plus one optional call to find out the control API your device supports. Hope this helps. |
I read a very interesting sentence here : "Tuya devices can be controlled via both MQTT and HTTPS API" |
If the MQTT API is used, where can I find the names of the topics ? |
I can confirm you can control your Tuya devices using HTTP GET/POST with Cloud API [HTTPS].
A few things to keep in mind... HMAC can be generated using ClientID, current Unix time [in ms] and your Secret as the HMAC Key/Secret. The script below is to control an RGB Bulb but should be nearly identical for other Tuya products. GET /v1.0/devices/DEVICEID HTTP/1.1 Here's an example of my project:
The above script is for a program called OpenBullet: https://github.com/openbullet/openbullet Incase you use uBot, I also made this in uBot. This was written in a hurry, but feel free to ask any questions! :) |
Thanks to you all; I am able to login and get the device list and successfully connect to mqtt server as well, using information from this thread. |
@newdevsa I don't think anyone else has successfully gotten cameras to work. |
Here is a php client with an example to open a stream for your tuya smart camera from these docs https://github.com/ifsale/tuyapiphp use ffplay -i rtsps://xxxxxxxxx to stream the link |
Hello everyone! But it seems that different apps use different signing and encryption method so I share my findings:
I fund large log file from some device using this mechanism here: http://jira.skyoss.com/secure/attachment/400894/2021-09-16_16-27-45_logcat.log hope it'll help someone! |
Fantastic work!!!!!,would you please tell me how you have generated sign and access token? |
#FUNCTION_Sign FUNCTION HMAC SHA256 "YOURSECRETCODEFROMAPP" "YOURCLIENTID" -> VAR "sign" #Get_token REQUEST GET "https://openapi.tuyaeu.com/v1.0/token?grant_type=1" HEADER "Host: openapi.tuyaeu.com" PARSE " |
Here a nodejs snippet which helps to connect to tuya cloud and control the device https://gist.github.com/nk-gears/a185c83d3e521c47d64d252197e87c88 @SakshiRathi77 , it contains the code to generate HMAC signature |
Here is the full script in python I'm using: To use it you have to put values into global variables at the beginning. I use this script as a part of Home Assistant automation.
|
hi there,
First thank you for your valuable contributions to the tuya library. I realize this is a long shot, but i am wondering if anyone had success in calling the tuya cloud API? i used fiddler and i was able to decipher a lot of the information on the calls, but there is one thing missing.
How is tuya calculating the MD5 hash? I was not able to replicate their "sign" parameter to the URL and the details on this as slim. Most of the info is located at https://docs.tuya.com/en/cloudapi/cloud_access.html#access-mode (search for accesskey) but i could not get it to work following the example. (I had to order my parameters, i used localKey as the accessKey, and then i did a utf-8 encoded MD5 hash). For the time, i got it in seconds using Unix epoch time.
Once i complete my work, i will share the PowerShell script that can be replicated into standard http/json requests.
The text was updated successfully, but these errors were encountered: