Prises en charge des devices avec l'application Smartlife/tuya

Voici la documentation pour avoir les infos pour utiliser Tuya.

  1. Créer un compte sur http://iot.tuya.com

  2. Créer un project cloud dans la section « Cloud » → « Development » → « Create Cloud Project »

  3. Choisissez un nom de projet, renseignez les différents champs :

    • Project Name : Le nom de votre project (ex: Gladys)
    • Industry : Smart Home ;
    • Development method : Smart Home ;
    • Data Center : Central Europe Data Center (même si vous vivez en Europe de l’Ouest, c’est mieux, sinon sélectionnez le datacenter le plus proche de chez vous).
      Cliquez sur « Create ».
  4. Autorisez les services API suivants :
    (Elles sont normalement sélectionnées par default)

  5. Copier les informations d’« Access key » et de « Secret Key » dans Gladys

  6. Allez sur l’onglet Devices puis Link Tuya App Account et cliquez sur le bouton Add App Account à droite.

  7. Scannez le QR Code avec votre application Smart Life en vous rendant dans Profil puis sur le scanner de codes situé en haut à droite.

  8. Sélectionnez Automatic Link puis Read, Write and Manage et validez avec OK .

  9. Copier l’information « App account UID » dans Gladys.

  10. Enregistrer la configuration sur Gladys, allez dans l’onglet « Découverte Tuya » et TADAM… vos appareils sont apparus

1 « J'aime »

@pierre-gilles : Et voila le résultat dans Gladys :

2 « J'aime »

Merci des changements, c’est beaucoup plus clair ! Tu as mis à jour l’image Docker ? :slight_smile:

Si oui, je partage avec la communauté !

Je viens de mettre a jour l’image docker :slight_smile:

1 « J'aime »

Merci @Lokkye :pray:

Je communique aujourd’hui sur le sujet, et je l’ajoute à la newsletter qui partira en fin de semaine !

2 « J'aime »

Hello,

Merci pour le développement de cette fonctionnalité. J’attends une prise connectée avec lecture des données de consommation (on/off, intensité, tension, énergie consommée…) d’ici la semaine prochaine.

Je pourrai tester à ce moment :slight_smile:

1 « J'aime »

Bonjour,

Je viens de recevoir ma prise (modèle PE-01E).

J’ai bien suivi le tuto pour la création du compte développeur ; tout est clair. Une remarque, « Smart Home Scene Linkage » est déprécié (c’est quand même bien présent avec je pense la nouvelle API « Smart Home Basic Service »).

Une fois tous les éléments renseignés dans Gladys dans la partie configuration, j’aurais apprécié un message qui confirme que tous les éléments renseignés permettent la connexion en vert quand ça fonctionne et en rouge dans le cas inverse (j’ai l’impression qu’on retrouve l’info lorsqu’on scanne ?). C’est un détail quand on voit le temps qu’on va passer sur cet écran mais ce serait un vrai plus pour lever tout doute de mauvaise configuration.

Je vais ensuite sur la partie « Découverte Tuya » ; une animation m’indique qu’un scan est en cours. Malheureusement, aucun device n’est trouvé (alors que bien présent sur l’application Tuya) ; est-ce que c’est parce qu’il n’est pas géré pour le moment ou il y a un délai entre la création et l’apparition dans le Cloud Tuya ?

Merci encore pour les dev en cours :slight_smile:

Edit : ma prise est bien affichée dans le cloud Tuya

1 « J'aime »

@PhilippeMA : Déjà merci d’avoir testé :slight_smile:
Est ce que tu pourrais me montrer ta configuration dans gladys ?
Est ce que tu pourrais m’envoyer les logs de gladys lorsque tu clic sur le bouton pour scanner les devices ?

1 « J'aime »

Bonjour @Lokkye,

Voici les logs :

2023-06-26T12:25:35+0200 <error> tuya.discoverDevices.js:38 (TuyaHandler.discoverDevices) Unable to load Tuya devices Error: getaddrinfo EAI_AGAIN openapi-weaz.tuyaeu.com
    at GetAddrInfoReqWrap.onlookup [as oncomplete] (node:dns:107:26) {
  errno: -3001,
  code: 'EAI_AGAIN',
  syscall: 'getaddrinfo',
  hostname: 'openapi-weaz.tuyaeu.com',
  config: {
    url: 'https://openapi-weaz.tuyaeu.com/v1.0/token?grant_type=1',
    method: 'get',
    headers: {
      Accept: 'application/json, text/plain, */*',
      t: '1687775130691',
      sign: 'MONSIGN',
      client_id: 'MONCLIENTID',
      sign_method: 'HMAC-SHA256',
      access_token: '',
      Dev_lang: 'Nodejs',
      Dev_channel: 'SaaSFramework',
      'Signature-Headers': '',
      'User-Agent': 'axios/0.21.4'
    },
    transformRequest: [ [Function: transformRequest] ],
    transformResponse: [ [Function: transformResponse] ],
    timeout: 0,
    adapter: [Function: httpAdapter],
    xsrfCookieName: 'XSRF-TOKEN',
    xsrfHeaderName: 'X-XSRF-TOKEN',
    maxContentLength: -1,
    maxBodyLength: -1,
    validateStatus: [Function: validateStatus],
    transitional: {
      silentJSONParsing: true,
      forcedJSONParsing: true,
      clarifyTimeoutError: false
    },
    data: undefined
  },
  request: <ref *1> Writable {
    _writableState: WritableState {
      objectMode: false,
      highWaterMark: 16384,
      finalCalled: false,
      needDrain: false,
      ending: false,
      ended: false,
      finished: false,
      destroyed: false,
      decodeStrings: true,
      defaultEncoding: 'utf8',
      length: 0,
      writing: false,
      corked: 0,
      sync: true,
      bufferProcessing: false,
      onwrite: [Function: bound onwrite],
      writecb: null,
      writelen: 0,
      afterWriteTickInfo: null,
      buffered: [],
      bufferedIndex: 0,
      allBuffers: true,
      allNoop: true,
      pendingcb: 0,
      constructed: true,
      prefinished: false,
      errorEmitted: false,
      emitClose: true,
      autoDestroy: true,
      errored: null,
      closed: false,
      closeEmitted: false,
      [Symbol(kOnFinished)]: []
    },
    _events: [Object: null prototype] {
      response: [Function: handleResponse],
      error: [Function: handleRequestError]
    },
    _eventsCount: 2,
    _maxListeners: undefined,
    _options: {
      maxRedirects: 21,
      maxBodyLength: 10485760,
      protocol: 'https:',
      path: '/v1.0/token?grant_type=1',
      method: 'GET',
      headers: [Object],
      agent: undefined,
      agents: [Object],
      auth: undefined,
      hostname: 'openapi-weaz.tuyaeu.com',
      port: null,
      nativeProtocols: [Object],
      pathname: '/v1.0/token',
      search: '?grant_type=1'
    },
    _ended: true,
    _ending: true,
    _redirectCount: 0,
    _redirects: [],
    _requestBodyLength: 0,
    _requestBodyBuffers: [],
    _onNativeResponse: [Function (anonymous)],
    _currentRequest: ClientRequest {
      _events: [Object: null prototype],
      _eventsCount: 7,
      _maxListeners: undefined,
      outputData: [],
      outputSize: 0,
      writable: true,
      destroyed: false,
      _last: true,
      chunkedEncoding: false,
      shouldKeepAlive: false,
      maxRequestsOnConnectionReached: false,
      _defaultKeepAlive: true,
      useChunkedEncodingByDefault: false,
      sendDate: false,
      _removedConnection: false,
      _removedContLen: false,
      _removedTE: false,
      strictContentLength: false,
      _contentLength: 0,
      _hasBody: true,
      _trailer: '',
      finished: true,
      _headerSent: true,
      _closed: false,
      socket: [TLSSocket],
      _header: 'GET /v1.0/token?grant_type=1 HTTP/1.1\r\n' +
        'Accept: application/json, text/plain, */*\r\n' +
        't: 1687775130691\r\n' +
        'sign: MONSIGN\r\n' +
        'client_id: MONCLIENTID\r\n' +
        'sign_method: HMAC-SHA256\r\n' +
        'access_token: \r\n' +
        'Dev_lang: Nodejs\r\n' +
        'Dev_channel: SaaSFramework\r\n' +
        'Signature-Headers: \r\n' +
        'User-Agent: axios/0.21.4\r\n' +
        'Host: openapi-weaz.tuyaeu.com\r\n' +
        'Connection: close\r\n' +
        '\r\n',
      _keepAliveTimeout: 0,
      _onPendingData: [Function: nop],
      agent: [Agent],
      socketPath: undefined,
      method: 'GET',
      maxHeaderSize: undefined,
      insecureHTTPParser: undefined,
      joinDuplicateHeaders: undefined,
      path: '/v1.0/token?grant_type=1',
      _ended: false,
      res: null,
      aborted: false,
      timeoutCb: null,
      upgradeOrConnect: false,
      parser: null,
      maxHeadersCount: null,
      reusedSocket: false,
      host: 'openapi-weaz.tuyaeu.com',
      protocol: 'https:',
      _redirectable: [Circular *1],
      [Symbol(kCapture)]: false,
      [Symbol(kBytesWritten)]: 0,
      [Symbol(kNeedDrain)]: false,
      [Symbol(corked)]: 0,
      [Symbol(kOutHeaders)]: [Object: null prototype],
      [Symbol(errored)]: null,
      [Symbol(kUniqueHeaders)]: null
    },
    _currentUrl: 'https://openapi-weaz.tuyaeu.com/v1.0/token?grant_type=1',
    [Symbol(kCapture)]: false
  },
  response: undefined,
  isAxiosError: true,
  toJSON: [Function: toJSON]
}

La configuration dans Glayds :

@PhilippeMA: Le compte Tuya est configuré sur Central Europe (ce qui est très bien) mais sur gladys c’est configuré en Western Europe, est ce que tu pourrais changer en Central Europe et me dire si cela a réglé le problème ?

Le message d’erreur est le même.

J’ai ce message depuis l’écran de configuration et depuis l’écran de scan.

Qu’est-ce que je peux faire pour t’aider ?

Pour info, cette erreur est un timeout lors de la résolution DNS.

Le domaine est pourtant bien valide:

@PhilippeMA tu n’as pas une configuration réseau/un bloqueur DNS configuré sur ta machine/ton réseau (type PiHole) ?

Non, aucun bloqueur à ma connaissance. J’ai un moyen de vérifier en utilisant une app ou commande ?

Tu peux faire un simple curl :

curl -I https://openapi-weaz.tuyaeu.com/

Tu devrais voir:

HTTP/2 200 
content-type: application/json;charset=UTF-8
date: Tue, 27 Jun 2023 15:43:03 GMT

Le commande me retourne :

HTTP/2 200 
content-type: application/json;charset=UTF-8
date: Thu, 29 Jun 2023 07:26:31 GMT
access-control-allow-credentials: true
access-control-allow-headers: 
access-control-allow-headers: access_token,Content-Type
access-control-allow-methods: POST
access-control-allow-methods: OPTIONS
access-control-allow-methods: GET
access-control-allow-methods: DELETE
access-control-allow-methods: PUT
access-control-allow-origin: https://iot.tuya.com
gateway-info: highway
strict-transport-security: max-age=31536000;includeSubDomains;preload 

Ok, tout semble bon donc… On est d’accord tu as testé sur la même machine que celle qui fait tourner Gladys ?

Tu as toujours la même erreur dans les logs ?

Non, sur mon pc portable.

Peut-être est-ce lié à l’installation ?

Voici ce que j’ai fait (repris dans la documentation):

docker run -d \
--log-driver json-file \
--log-opt max-size=10m \
--cgroupns=host \
--restart=always \
--privileged \
--network=host \
--name gladys \
-e NODE_ENV=production \
-e SERVER_PORT=80 \
-e TZ=Europe/Paris \
-e SQLITE_FILE_PATH=/var/lib/gladysassistant/gladys-production.db \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /var/lib/gladysassistant:/var/lib/gladysassistant \
-v /dev:/dev \
-v /run/udev:/run/udev:ro \
delogzway/gladys:tuya

Tu peux tester sur ta machine qui fait tourner Gladys?

Je ne pense pas que ça ait de lien, ça me parait très bien :slight_smile:

@Lokkye Tu confirmes que chez toi, tu as testé avec chaque serveur et ça fonctionnait bien ?

Oui il fonctionne tous sauf pour le china qui n’est compatible qu’avec des IP chinoises

1 « J'aime »

@Lokkye je t’ai rajouté une petite remarque sur la PR, ce serait bien de préfixer les variables avec TUYA_ pour que ce soit plus clair dans la DB