codetheweb/tuyapi

"tuya-cli link" results in Device(s) failed to be registered! / Error: permission deny

christianhorn opened this issue · 11 comments

Describe the bug
Executing

tuya-cli link --api-key [..] --api-secret [..] --schema comfluxsmartapp --ssid 'fluxnet iot' --password [..] --region us

results in this:

✖ Device(s) failed to be registered!
Error: permission deny
    at TuyaLinkWizard.init (/usr/local/lib/node_modules/@tuyapi/cli/node_modules/@tuyapi/link/index.js:72:13)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async link (/usr/local/lib/node_modules/@tuyapi/cli/lib/link.js:45:3)

I modified api credentials intentionally and got other errors, so authentication by these should not be the problem. I executed the "tuya-cli link" command on 3 different systems (2x x86-64/Fedora36, 1x raspi4), all with this result. One of the systems was only to the WLAN connected which I use as parameters on the command line, that did not help either.

To Reproduce
Steps to reproduce the behaviour, at least for me with the Tuya-user created as per instructions:

  1. execution of above command
  2. See error

Expected behaviour
Device should be registered.

Debug Output
api-key, api-secret ans wlan-password in the following were changed into [..] .

[root@pi4 41°C ~]$ DEBUG=* tuya-cli link --api-key [..] --api-secret [..] --schema comfluxsmartapp --ssid 'fluxnet iot' --password [..] --region us
⠋ Registering devices(s)...  follow-redirects options {
  maxRedirects: 21,
  maxBodyLength: 10485760,
  protocol: 'https:',
  path: '/v1.0/token?grant_type=1',
  method: 'GET',
  headers: {
    Accept: 'application/json, text/plain, */*',
    t: '1660049114938',
    sign: '04CF7E06CCA6EBC1EDA9390C026B69FD805F4CB6792D216E2AF775DF094E5486',
    client_id: '[..]',
    sign_method: 'HMAC-SHA256',
    access_token: '',
    Dev_lang: 'Nodejs',
    Dev_channel: 'SaaSFramework',
    'Signature-Headers': '',
    'User-Agent': 'axios/0.21.4'
  },
  agent: undefined,
  agents: { http: undefined, https: undefined },
  auth: undefined,
  hostname: 'openapi.tuyaus.com',
  port: null,
  nativeProtocols: {
    'http:': {
      _connectionListener: [Function: connectionListener],
      METHODS: [Array],
      STATUS_CODES: [Object],
      Agent: [Function],
      ClientRequest: [Function: ClientRequest],
      IncomingMessage: [Function: IncomingMessage],
      OutgoingMessage: [Function: OutgoingMessage],
      Server: [Function: Server],
      ServerResponse: [Function: ServerResponse],
      createServer: [Function: createServer],
      validateHeaderName: [Function: __node_internal_],
      validateHeaderValue: [Function: __node_internal_],
      get: [Function: get],
      request: [Function: request],
      maxHeaderSize: [Getter],
      globalAgent: [Getter/Setter]
    },
    'https:': {
      Agent: [Function: Agent],
      globalAgent: [Agent],
      Server: [Function: Server],
      createServer: [Function: createServer],
      get: [Function: get],
      request: [Function: request]
    }
  }
} +0ms
⠹ Registering devices(s)...  follow-redirects options {
  maxRedirects: 21,
  maxBodyLength: 10485760,
  protocol: 'https:',
  path: '/v1.0/apps/comfluxsmartapp/user',
  method: 'POST',
  headers: {
    Accept: 'application/json, text/plain, */*',
    'Content-Type': 'application/json',
    t: '1660049116296',
    sign: '076F6865D304765916E4ED6B3003C1358547949E9E3B53A8AC257565FC502471',
    client_id: '[..]',
    sign_method: 'HMAC-SHA256',
    access_token: '622ca71a2406ae8faff8d134dd704252',
    Dev_lang: 'Nodejs',
    Dev_channel: 'SaaSFramework',
    'Signature-Headers': '',
    'User-Agent': 'axios/0.21.4',
    'Content-Length': 161
  },
  agent: undefined,
  agents: { http: undefined, https: undefined },
  auth: undefined,
  hostname: 'openapi.tuyaus.com',
  port: null,
  nativeProtocols: {
    'http:': {
      _connectionListener: [Function: connectionListener],
      METHODS: [Array],
      STATUS_CODES: [Object],
      Agent: [Function],
      ClientRequest: [Function: ClientRequest],
      IncomingMessage: [Function: IncomingMessage],
      OutgoingMessage: [Function: OutgoingMessage],
      Server: [Function: Server],
      ServerResponse: [Function: ServerResponse],
      createServer: [Function: createServer],
      validateHeaderName: [Function: __node_internal_],
      validateHeaderValue: [Function: __node_internal_],
      get: [Function: get],
      request: [Function: request],
      maxHeaderSize: [Getter],
      globalAgent: [Getter/Setter]
    },
    'https:': {
      Agent: [Function: Agent],
      globalAgent: [Agent],
      Server: [Function: Server],
      createServer: [Function: createServer],
      get: [Function: get],
      request: [Function: request]
    }
  }
} +1s
✖ Device(s) failed to be registered!
Error: permission deny
    at TuyaLinkWizard.init (/usr/local/lib/node_modules/@tuyapi/cli/node_modules/@tuyapi/link/index.js:72:13)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async link (/usr/local/lib/node_modules/@tuyapi/cli/lib/link.js:45:3)

Desktop (please complete the following information):

  • OS: Fedora
  • OS Version 36
  • Node Version v16.14.0 (I did also try latest node version, not packaged in Fedora but having npm update itself into /usr/local)

I'm getting the exact same error when I try to add a new device.

Having this same exact issue.

Scratch that...I think I figured it out. When you login to the iot.tuya.com interface, click on "Cloud" and then the project you created. You should have created a Cloud Authorization, but you also need to create an App Authorization by clicking on that tab and adding an authorization for the custom App you created earlier. (I'm making a lot of assumptions here :) )

The issue is that your Cloud Project doesn't know anything about the App you created. They're completely separate..you have to let your Cloud project know about your App by authorizing it.

@waverly360 Thank you for the hint, tried a bit around, but not really advancing.
When calling 'tuya-cli link', the --schema is also hinting on the app which was created.

Did you manage to add a link between app and project, and then get further?
This seems like quite an important step, it it's required.. I wonder how the howto was written and used apparently in the past without that.

When I go to cloud->development->my project->authorization->App Authorization->Add Authorization, then 3 authorization types are possible (ios, android, other), I did not get further with adding authorizations for all 3. Most logic choice seems 'Android'. Selecting that one, a sha1 hash is requested, that can apparently be anything, in a format like this: "ec:59:b4:32[..]". Application ID should apparently be same as 'schema', for me "comfluxsmartapp". Values "Authorization Name" and "Description" are apparently just for personal reference.
From the other side I looked at the website at app->sdk development->myapp. There is a tab "get key", but the pieces I can get from there do not seem to match what "Add Authorization" from the project above is asking for.

As the docs on https://github.com/codetheweb/tuyapi say, some names in the menus are no longer matching. So for people like me who have not yet used this successfully, it makes things much harder as we have not even played this through in the past.
Could someone comment whether the procedure was recently used successfully? Sending a pull request then to fix the names to match the current website would be nice - I volunteer to do that if I get my device hooked up.. but without that I can't be sure about the correct procedure.

@christianhorn You're not wrong about the documentation. My issue (and possibly a lot of folk's issues) is that there are a few different ways to go about this, and I just happened to end up down this path. Heck, I initially started with trying to replace the firmware on all of my Tuya controlled DayBetter bulbs so I could use local control..and ended up down the path of using Local Tuya with the original firmware....I digress :).

So, first of all, I ended up using the "Cloud API Explorer" to test things out, specifically the "Get App Details" option. It was a bit easier to do than going back to the CLI everytime. (Tuya IOT Platform->Cloud->API Explorer->Smart Home Device System->Application Management->Get App Details). You can put your schema name in the text box and see if things are linked properly.

If it's not, you'll get this:
{ "code": 1106, "msg": "permission deny", "success": false, "t": 1668353754867, "tid": "c4d263b3636811edb7719e1973e28e3f" }

While a successful call looks like this:
{ "result": { "app_icon": "https://images.tuyaus.com/smart_res/static/logo.png", "app_name": "Tuya Smart" }, "success": true, "t": 16698723489872, "tid": "b78152e363691aedb520b22a353fa8b8" }

So first, once you've created your "App", you shouldn't need to do anything else from that section. All of the linking and authorizing should happen from within the "Cloud" section. (You might need to go back to the "App" section to get your id/password info...I'm in the interface now and struggling to recall)

Now go into your Cloud project that you created (Tuya IOT Platform->Cloud->Development->Your Custom Project). Here is where I found things to get tricky. Within your project you have several tabs: Overview, Authorization, Service API, Assets, Users, Devices. ***One of the things that messed me up early on is the fact that some of these tabs would cause my browser to refresh, and prevent me from actually going into those sections. Specifically, the Assets/Users/Devices pages seemed to do this, and I would have to re-login and even close my browser at times. All of the following steps should be done within your custom project (some may or may not be needed and the order maybe slightly different...it's hard to remember 😆 ):

Authorization->Cloud Authorization - Click "Add Authorization" and follow any additional instructions

Authorization->App Authorization - Click "Add Authorization" and pick either the "Tuya IoT App SDK" for iOS or Android (I found the iOS ones easier because you don't have to come up with a SHA Hash. It doesn't matter which you pick I don't think...the bundle identifier/auth name/description can all be anything, but you may need them in a later step.

Service API - These were already populated for me, but for the record I have IoT Core, Authorization Token Management, Smart Home Scene Linkage, and Data Dashboard Service.

Devices->Link Tuya App Account->Add App Account - This is the part I missed for so long. This will throw a QR code that you will need to scan into the Tuya Smart app on your phone. Open up the Tuya Smart app, click on the profile icon in the bottom right, and then click on the [-] icon in the top right to do this.

Devices->Link My App->Add Apps->Link the fake app you created earlier. (I used "Automatic Link" and gave it "Read, write, and Manage" but you might not need to give it full permissions?

I think at this point, if you try the test above, you will no longer get a permission denied message.

As a subsequent note, I think this is what led me down the right path to get this working, even though I hadn't intended to use the project itself:

https://pypi.org/project/tinytuya/

There maybe instructions there I neglected to add here.

@waverly360 Wooho, thanks a bunch for putting this together!
Thanks to your way to see "Get App Details", I was able to verify that both of the projects I had created had the apps properly connected.
The other settings also look good for me. Linking up the device then was for me the first part where I had to use the mobile, scan the QR-code and then find my smartplug - I had not seen any step like this in the official docs. From further testing here I conclude that actually my device is not Tuya compatible, it's not getting picked up with the Android mobile via the "Smart Life App", but only with the "+style app". The device is a ゴウサンド/Gosund WP6-1, I had assumed it's the Japanese variant of a supported plug, but that's apparently not the case.

I can only encourage others who hit the issue reported to go through the steps from @waverly360 , and if succeeding to send a pull request to update the instructions. While these are not updated, consuming the official steps and the pieces from @waverly360 here seem like the way to go.

Hey, just to add to this issue for others that are finding this thread:

  • Make sure you are connecting to the correct datacenter! https://developer.tuya.com/en/docs/iot/Data_Center_Introduction?id=Kav2hlac2ppnw <= look up your country and it's corresponding datacenter (mine wasn't that obvious being in Europe)
  • Make sure to use the 'TUYA Smart' app itself (although they look exactly the same) don't use a localized version, because the scanning of the QR-code will not work.

I hope this will be helpful for someone down the line.

@s0x00c Great hints! I think I got messages whenever using the wrong data center, so that was easy to debug. I was also using a different app - but also "TUYA Smart' app does not find my device.

Hey, just to add to this issue for others that are finding this thread:

  • Make sure you are connecting to the correct datacenter! https://developer.tuya.com/en/docs/iot/Data_Center_Introduction?id=Kav2hlac2ppnw <= look up your country and it's corresponding datacenter (mine wasn't that obvious being in Europe)
  • Make sure to use the 'TUYA Smart' app itself (although they look exactly the same) don't use a localized version, because the scanning of the QR-code will not work.

I hope this will be helpful for someone down the line.

Adding to this: I never figured out the linking command in my case, but I am able to communicate with the plug via CLI because the QR code scanning linked the plug for me.
From there I am able to send commands:

  • tuya-cli set --id id --key key --dps 1 --set true <= enable the smartplug
  • tuya-cli set --id id --key key --dps 1 --set false <= disable the smartplug

I had a similar issue with permission deny on this step, and I realized I'm chosen wrong data center. So you can find a match here
https://developer.tuya.com/en/docs/iot/oem-app-data-center-distributed?id=Kafi0ku9l07qb

Please note, after changing the datacenter, in Cloud Project you need re-link again under the Devices tab