jasonacox / tinytuya

Python API for Tuya WiFi smart devices using a direct local area network (LAN) connection or the cloud (TuyaCloud API).
MIT License
933 stars 167 forks source link

Any way to add device locally w/o IoT Cloud subscription? #249

Open anar4732 opened 1 year ago

anar4732 commented 1 year ago

So the IoT Platform seems like having no free plan for individual developers like us. (only 1-month trial) https://www.tuya.com/vas/commodity/IOT_CORE_V2

I will control devices locally. but unable to add my new devices since my trial was expired. Is there any way to add devices locally?

jasonacox commented 1 year ago

Hi @anar4732 - Unfortunately, the cloud is the easiest way to get the Tuya device local key.

I'm curious, during the setup do you recall if you selected an account type?

image

Also, are you able to sign up for a new account?

anar4732 commented 1 year ago

Hi @anar4732 - Unfortunately, the cloud is the easiest way to get the Tuya device local key.

I'm curious, during the setup do you recall if you selected an account type?

image

Also, are you able to sign up for a new account?

do I need to skip selecting the account type?

jasonacox commented 1 year ago

Yes, in my testing, I "skip this step" and my accounts did not expire. I have that instruction in the PDF but should add that detail to the main readme if it works for you too.

tjbcatch22 commented 1 year ago

I used cloud-cutter (https://github.com/tuya-cloudcutter/tuya-cloudcutter) on my bulb and am able to run my bulb without a cloud subscription, however, I have reduced functionality on the bulb (detailed below).

For the details, in case this might work for you: I've only used the Smart Home app to initially connect the bulb to get the module version (1.2.16 in my case, for example). I wonder using the app is even necessary for subsequent bulbs of the same manufacture date code or lot

My bulb seems to be a generic of some kind: Schwaiger A19 60W Equivalent Color Selectable Dimmable LED Light Bulb, (see here for more info: https://www.menards.com/main/p-1642874274122411.htm). I run cloud-cutter, get the Device_id and a Local_key, inpute those into Bulb.py and useing Tinytuya bulb.py I can get the light to turn off, on, some dimming, and some limited modes. ( mode-scene has a softer light, mode-colour and music will turn the bulb red)

The bulb does not do any colors, except for when its in music or color mod as mentioned above. I have not yet found a way to make the buld anything other than red. And - the Smart Life app does not connect to it ( hence the cloud-cutter).

jasonacox commented 1 year ago

Thanks @tjbcatch22 ! The vulnerability and exploit is fascinating. @uzlonewolf have you seen this? The timeline indicates that Tuya began patching so I wonder how long this path will remain open for people to avoid the cloud to get their keys.

@tjbcatch22 It does seem odd that this would disable color from your bulb. Were you able to set color before tuya-cloudcutter?

When you say bulb.py are you using the example here? I would recommend turning on debug by adding the line:

# debug mode
tinytuya.set_debug(True)

It may give some clues as to what is happening during the d.set_colour(r, g, b) calls.

tjbcatch22 commented 1 year ago

I'll check out the debug. Thank you for mentioning that. Stay tuned. (perhaps I should create a new issue with the results so as not to bury the findings in this post)

Yes - The exploit if fascinating. I'm wondering if that is why the bulb are on sale for 50% off.

uzlonewolf commented 1 year ago

@jasonacox Yes I'm familiar with it, I just didn't think there would be much overlap with TinyTuya users as it completely eliminates Tuya's cloud and app. If someone was going to do that I figured they'd just install Tasmota or OpenBK7231N/OpenBeken (https://github.com/openshwprojects/OpenBK7231T_App) and be done with it.

jasonacox commented 1 year ago

Good point. Having said that, the pure OTA possibility with tuya-cloudcutter could be attractive to some not wanting to break open their devices. I confess, I'm behind on catching up on what is possible with Tasmota these days so that could be a path there too. But your point is still valid. I'm sure there is a large portion of our community that, like me, have cloud integrations they are not keen to break. And, as I mentioned above, I suspect there is likely a limited exploit window on this OTA hack. New firmware updates and devices will be coming from Tuya.

In the context of this issue, I do wish we could convince Tuya to provide an easier path for our home IoT maker community to get local keys without using their elaborate commercial Tuya IoT Developer process.

tjbcatch22 commented 1 year ago

I would be in the camp of struggling with Tasmota or OpenBK7231N/OpenBeken. I'm not a programmer - just an enthusiastic hobbyist - who is not compiling code very often. Seems like OpenBK7231N would have a binary that I can use cloudcutter to upload, but im stuck on either finding the binary or building it. Tinytuna, for me, is ready to go. Easy python scripts.

uzlonewolf commented 1 year ago

Prebuild binaries are available on the 'releases' page https://github.com/openshwprojects/OpenBK7231T_App/releases . I can understand not wanting to mess with it though.

tjbcatch22 commented 1 year ago

Thank you! Those binaries are great. Looks like I was not able to find those on my own.

uzlonewolf commented 1 year ago

If you don't mind using npm/node.js instead of Python then it looks like you can also get local keys via the "pretend to be the Android app" method. A slight tweak to https://github.com/rospogrigio/localtuya/issues/1188 gets you everything with just your app username and password, no developer account required. Simply add console.log(device); right after the console.log('group: "%s"\tdevice: ... line and run it.

jasonacox commented 1 year ago

Whoa! Nice! Should we implement this for the wizard?

Example cloud.js that can be used to create a devices.json for tinytuya:

/* Add your Android App Credentials */
const email = "XXXXX";
const password = "XXXXX";
const region = "AZ";        /* AZ=Americas, AY=Asia, EU=Europe, IN=India */

/* Select your App */

/* Smart Life App - Certificate */
const apiKeys = {
  "key": "ekmnwp9f5pnh3trdtpgy",
  "secret": "r3me7ghmxjevrvnpemwmhw3fxtacphyg",
  "secret2": "jfg5rs5kkmrj5mxahugvucrsvw43t48x",
  "certSign": "0F:C3:61:99:9C:C0:C3:5B:A8:AC:A5:7D:AA:55:93:A2:0C:F5:57:27:70:2E:A8:5A:D7:B3:22:89:49:F8:88:FE" 
};

/* Tuya App - Certificate */
/*
const apiKeys = {
  "key": "3fjrekuxank9eaej3gcx",
  "secret": "aq7xvqcyqcnegvew793pqjmhv77rneqc",
  "secret2": "vay9g59g9g99qf3rtqptmc3emhkanwkx",
  "certSign": "93:21:9F:C2:73:E2:20:0F:4A:DE:E5:F7:19:1D:C6:56:BA:2A:2D:7B:2F:F5:D2:4C:D5:5C:4B:61:55:00:1E:40" 
};
*/

/* Fetch Devices */
const Cloud = require('@tuyapi/cloud');
const is = require('is');
const api = new Cloud({key: apiKeys.key, secret: apiKeys.secret,secret2: apiKeys.secret2, certSign: apiKeys.certSign, apiEtVersion: '0.0.1', region: region});
api.loginEx({email: email, password: password}).then(async sid => {
  api.request({action: 'tuya.m.location.list'}).then(async groups => {
    for (const group of groups) {
      api.request({action: 'tuya.m.my.group.device.list', gid: group.groupId}).then(async devicesArr => {
        var output = [];
        for (const device of devicesArr) {
          // console.log(device); // full raw device detail
          var item = {
            "mac": device.mac, "name": device.name, "key": device.localKey, "id": device.devId
          };
          output.push(item);
        }
        console.log(JSON.stringify(output, null, 3));
      });
    }
  });
});
npm i @tuyapi/cloud
node cloud.js > devices.json

Which produces a list of all my devices including the local key.

Also, note, it will also push an alert to your phone:

IMG_1156

uzlonewolf commented 1 year ago

I'm not thrilled with the idea of distributing the key/secret from a hacked Android app with tinytuya, but having the framework there so someone can just paste it in on their own would be good.

jasonacox commented 1 year ago

Excellent point. That appears to be the approach tuyapi/cloud took as well.

Are these API keys likely only associated with one device and/or app install?

uzlonewolf commented 1 year ago

No, they're tied to the app version, they'll only change if a new version of the app is released.

uzlonewolf commented 1 year ago

Aaaand I found a Python version: https://gist.github.com/avataar/2a6ee4f58aaedfcc062a838380f3cffb which is a standalone version of https://github.com/rospogrigio/localtuya/pull/1131 . The secret that one expects is '_'.join( (certSign, secret2, secret) )

I also found a few more app keys: For Ledvance:

{
  "key": "fx3fvkvusmw45d7jn8xh",
  "secret": "cgqx3ku34mh5qdesd7fcaru3gx7tyurr",
  "secret2": "armptsqyfpxa4ftvtc739ardncett3uy",
  "certSign": "A" 
}

For Sylvania Smart WiFi

{
  "key": "creq75hn4vdg5qvrgryp",
  "secret": "wparh3scdv8dc7rrnuegaf9mqmn4snpk",
  "secret2": "ag4xcmp9rjttkj9yf9e8c3wfxry7yr44",
  "certSign": "A" 
}
blakadder commented 1 year ago

How about this blakadder/tuya-uncover?

uzlonewolf commented 1 year ago

Very nice @blakadder !

anar4732 commented 1 year ago

Very nice @blakadder !

can it potentially implement on tinyTuya?

uzlonewolf commented 1 year ago

can it potentially implement on tinyTuya?

Like I mentioned above, I'm not thrilled with the idea of distributing the key/secret from a hacked Android app with TinyTuya, so you're going to need to convince @jasonacox if you want it. Alternately, I wouldn't mind submitting a PR to blakadder/tuya-uncover to add an option to make it spit out a TinyTuya-compatible devices.json file.

jasonacox commented 1 year ago

Thanks @anar4732 for the suggestion. However, I agree completely with @uzlonewolf. We are not going to bundle the extracted Android app secrets into the PyPI module. Those may work today but could be disabled in the future. And more importantly, storing potentially confidential keys could violate PyPI's Terms of Use.

I'm not opposed to having @blakadder 's script produce a compatible devices.json and referencing that link in the project as a helpful option.

uzlonewolf commented 11 months ago

I now have a PR in with @blakadder to add support for tinytuya-compatible device.json files.