Bonjour à tous,
Après avoir passé de longues heures sur le sujet et vous avoir pas mal sollicité, je peux vous livrer le fruit de ce travail.
Mon objectif était de pouvoir interroger les APIs tuya sans pour autan dupliquer les nœuds de la palette: « node-red-contrib-tuya-smart-device ». En effet c’est dernier ne permettait pas de passer les informations d’entité par le biais d’un message.
En m’inspirant du travail de notenoughtech, j’ai créé un subflow appelable facilement.
Avant de vous vous parler du subflow en particulier, je vais vous fournir une liste d’action possible.
1. Les prérequis
Pour y arriver, j’ai dû utilisé la palette suivante pour gérer le chiffrement:
node-red-contrib-crypto-js-dynamic
2. Le flow
[{"id":"4bf109a5.a97ad8","type":"tab","label":"Tuya Cloud API","disabled":false,"info":"\r\n# Tuya Cloud API for beginners\r\n\r\nThis project explains how to work with Tuya Cloud API and how to use Postman to develop REST request for NodeRED \r\nThanks to James Wilson for udating the flow to match latest authtentication requirement\r\n\r\n\r\n![Logo](https://notenoughtech.com/wp-content/uploads/2021/07/2021-07-12-23_35_30-Brand-Logo-Guidelines-Video-v2.0.0_0817.pdf-Personal-Microsoft%E2%80%8B-Edge.jpg)\r\n\r\n \r\n## Features\r\n\r\n- Authentication\r\n- Get device list\r\n- Get status and data points\r\n- Issue commands\r\n\r\n \r\n## Documentation\r\n\r\n[Documentation](https://linktodocumentation)\r\n\r\n \r\n## More on\r\n\r\nVisit my page and the [article](https://notenoughtech.com/home-automation/tuya-cloud-api/) covering this topic.\r\n\r\n \r\n## Appendix\r\n\r\nPostman, Tuya Cloud API\r\n \r\n## 🔗 Follow my work\r\n[![Twitter Follow](https://img.shields.io/twitter/follow/notenoughtech?label=%40notenoughtech&logo=twitter&style=for-the-badge)](https://twitter.com/NotEnoughTECH)\r\n[![YouTube Channel Subscribers](https://img.shields.io/youtube/channel/subscribers/UC7V__uBIaZotHn_smHJShGQ?label=NotEnoughTech&logo=YouTube&logoColor=red&style=for-the-badge)](https://www.youtube.com/channel/UC7V__uBIaZotHn_smHJShGQ)\r\n[![Subreddit subscribers](https://img.shields.io/reddit/subreddit-subscribers/not_enough_tech?logo=reddit&logoColor=white&style=for-the-badge)](https://www.reddit.com/r/Not_Enough_Tech/)","env":[]},{"id":"5313998d.974bb8","type":"function","z":"4bf109a5.a97ad8","name":"","func":"var device_id = flow.get(\"device_id\");\nvar url = \"https://openapi.tuyaeu.com/v1.0/devices/\" + device_id +\"/status\";\nvar t = msg.time;\nvar method = \"GET\";\nvar client_id = flow.get(\"tuya_client_id\");\nvar creds = flow.get(\"tuya\");\nvar token = creds.access_token;\nvar sign = msg.payload;\nmsg.headers ={\n \"sign_method\": \"HMAC-SHA256\",\n \"client_id\" : client_id,\n \"t\": t.toString(),\n \"mode\" : \"cors\",\n \"Content-Type\": \"application/json\",\n \"sign\": sign.toUpperCase(),\n \"access_token\" : token\n },\n msg.payload = '';\n msg.url = url;\n msg.method = \"GET\";\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":720,"y":440,"wires":[["3ac1a645.0bb26a"]]},{"id":"3ac1a645.0bb26a","type":"http request","z":"4bf109a5.a97ad8","name":"","method":"use","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","x":890,"y":440,"wires":[["c5c9b72789116e0f"]]},{"id":"a87ea183.b0d6b","type":"inject","z":"4bf109a5.a97ad8","name":"","props":[{"p":"time","v":"","vt":"date"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":90,"y":440,"wires":[["d5eaa68e.d5e5c8"]]},{"id":"d5eaa68e.d5e5c8","type":"function","z":"4bf109a5.a97ad8","name":"Create signStr","func":"var creds = flow.get(\"tuya\");\nvar access_token = creds.access_token;\nvar device_id = flow.get(\"device_id\");\nvar t = msg.time;\nvar client_id = flow.get(\"tuya_client_id\");\n//var token = access_token;\n\nvar method = \"GET\";\nvar sign_url = \"/v1.0/devices/\" + device_id +\"/status\";\nvar content_hash = \"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\";\n\nvar string_to_sign = method+\"\\n\"+content_hash+\"\\n\"+\"\"+\"\\n\"+sign_url;\nvar signStr = client_id + access_token + t + string_to_sign;\n\nmsg.debug = {\n \"access_token\": access_token,\n \"device_id\": device_id,\n \"t\": t,\n \"client_id\": client_id,\n \"method\": method,\n \"sign_url\": sign_url,\n \"string_to_sign\": string_to_sign,\n \"signStr\": signStr\n}\n\nmsg.payload = signStr;\nmsg.time = msg.time;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":260,"y":440,"wires":[["f6881316.41cdb"]]},{"id":"f6881316.41cdb","type":"hmac","z":"4bf109a5.a97ad8","name":"Sign signStr with secret","algorithm":"HmacSHA256","key":"58fb24515a07454886120147b4225450","x":490,"y":440,"wires":[["5313998d.974bb8"]]},{"id":"f811e1b6.ee796","type":"function","z":"4bf109a5.a97ad8","name":"","func":"var url = \"https://openapi.tuyaeu.com/v1.0/token?grant_type=1\";\nvar t = msg.time;\nvar sign = msg.payload;\nvar client_id = flow.get(\"tuya_client_id\");\n\nmsg.headers ={\n \"sign_method\": \"HMAC-SHA256\",\n \"client_id\" : client_id,\n \"t\": t.toString(),\n \"sign\": sign.toUpperCase(),\n },\n \n msg.payload = '';\n msg.url = url;\n msg.method = \"GET\";\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":720,"y":140,"wires":[["1bfa922b.aad55e"]]},{"id":"1bfa922b.aad55e","type":"http request","z":"4bf109a5.a97ad8","name":"","method":"use","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","x":890,"y":140,"wires":[["74db8d4a.eee2c4"]]},{"id":"3023a9a8.6133e6","type":"inject","z":"4bf109a5.a97ad8","name":"","props":[{"p":"time","v":"","vt":"date"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":90,"y":140,"wires":[["26588c1b.dcec54"]]},{"id":"26588c1b.dcec54","type":"function","z":"4bf109a5.a97ad8","name":"Create signStr","func":"var client_id = flow.get(\"tuya_client_id\");\nvar t = msg.time;\n\n\nvar method = \"GET\";\nvar sign_url = \"/v1.0/token?grant_type=1\";\n\n// Couldn't get nodered to process an empty string so this is a hash of an empty file\nvar content_hash = \"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\";\nvar string_to_sign = method+\"\\n\"+content_hash+\"\\n\"+\"\"+\"\\n\"+sign_url;\nvar signStr = client_id+t+string_to_sign;\n\nmsg.payload = signStr;\nmsg.time = msg.time;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":260,"y":140,"wires":[["5eeed491.cd055c"]]},{"id":"5eeed491.cd055c","type":"hmac","z":"4bf109a5.a97ad8","name":"Sign signStr with secret","algorithm":"HmacSHA256","key":"58fb24515a07454886120147b4225450","x":490,"y":140,"wires":[["f811e1b6.ee796"]]},{"id":"b1615793.fd0548","type":"comment","z":"4bf109a5.a97ad8","name":"Get Access Token","info":"","x":110,"y":100,"wires":[]},{"id":"608b6d1e.a8a874","type":"comment","z":"4bf109a5.a97ad8","name":"Get Status Of Device","info":"","x":120,"y":400,"wires":[]},{"id":"74db8d4a.eee2c4","type":"function","z":"4bf109a5.a97ad8","name":"Extract Token from Response","func":"var data = msg.payload;\nvar access = data.result.access_token;\nvar refresh = data.result.refresh_token;\n\nvar creds ={\n \"access_token\" : access,\n \"refresh_token\" : refresh\n}\nflow.set(\"tuya\", creds);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1120,"y":140,"wires":[["c98fa8a4f17d4a45"]]},{"id":"bbb94560.17a528","type":"function","z":"4bf109a5.a97ad8","name":"Settings CLICK SETUP TAB","func":"\nreturn msg;","outputs":1,"noerr":0,"initialize":"var client_id = \"Votre client_id\";\nvar user_id = \"Votre user_id\";\nvar device_id = \"Votre device_id\";\nflow.set(\"tuya_client_id\", client_id);\nflow.set(\"tuya_user_id\", user_id );\nflow.set(\"device_id\", device_id );","finalize":"","libs":[],"x":340,"y":100,"wires":[[]]},{"id":"14af15b8.86c55a","type":"comment","z":"4bf109a5.a97ad8","name":"Turn Device Off","info":"","x":100,"y":900,"wires":[]},{"id":"ae0294c.e17c268","type":"function","z":"4bf109a5.a97ad8","name":"","func":"var device_id = flow.get(\"device_id\");\nvar url = \"https://openapi.tuyaeu.com/v1.0/devices/\"+device_id+\"/commands\";\nvar t = msg.time;\nvar client_id = flow.get(\"tuya_client_id\");\nvar creds = flow.get(\"tuya\");\nvar access_token = creds.access_token;\nvar sign = msg.payload;\n\nmsg.headers ={\n \"sign_method\": \"HMAC-SHA256\",\n \"client_id\" : client_id,\n \"t\": t.toString(),\n \"mode\" : \"cors\",\n \"Content-Type\": \"application/json\",\n \"sign\": sign.toUpperCase(),\n \"access_token\" : access_token,\n },\n msg.payload = '{\"commands\":[{\"code\":\"switch_1\",\"value\":false}]}';\n msg.url = url;\n msg.method = \"POST\";\n //msg.payload = '';\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":980,"y":960,"wires":[["448c54b6.42427c"]]},{"id":"448c54b6.42427c","type":"http request","z":"4bf109a5.a97ad8","name":"","method":"use","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":1130,"y":960,"wires":[["7c5992c9fc2f493b"]]},{"id":"e5b52f57.cd35e","type":"inject","z":"4bf109a5.a97ad8","name":"","props":[{"p":"time","v":"","vt":"date"},{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"commands\":[{\"code\":\"switch_1\",\"value\":false}]}","payloadType":"str","x":90,"y":960,"wires":[["7bf971b.8e0989"]]},{"id":"7f3ecdbc.908f24","type":"function","z":"4bf109a5.a97ad8","name":"Create signStr","func":"var creds = flow.get(\"tuya\");\nvar access_token = creds.access_token;\nvar device_id = flow.get(\"device_id\");\nvar t = msg.time;\nvar client_id = flow.get(\"tuya_client_id\");\n\nvar method = \"POST\";\nvar sign_url = \"/v1.0/devices/\" + device_id + \"/commands\";\nvar content_hash = msg.payload;\n\nvar string_to_sign = method+\"\\n\"+content_hash+\"\\n\"+\"\"+\"\\n\"+sign_url;\nvar signStr = client_id + access_token + t + string_to_sign;\n\nmsg.payload = signStr;\nmsg.time = msg.time;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":540,"y":960,"wires":[["17bac91b.4b1287"]]},{"id":"17bac91b.4b1287","type":"hmac","z":"4bf109a5.a97ad8","name":"Sign signStr with secret","algorithm":"HmacSHA256","key":"58fb24515a07454886120147b4225450","x":790,"y":960,"wires":[["ae0294c.e17c268"]]},{"id":"9295d1f4.912c5","type":"comment","z":"4bf109a5.a97ad8","name":"Turn Device On","info":"","x":100,"y":1020,"wires":[]},{"id":"c2dcb090.24f8f","type":"function","z":"4bf109a5.a97ad8","name":"","func":"var device_id = flow.get(\"device_id\");\nvar url = \"https://openapi.tuyaeu.com/v1.0/devices/\"+device_id+\"/commands\";\nvar t = msg.time;\nvar client_id = flow.get(\"tuya_client_id\");\nvar creds = flow.get(\"tuya\");\nvar access_token = creds.access_token;\nvar sign = msg.payload;\n\nmsg.headers ={\n \"sign_method\": \"HMAC-SHA256\",\n \"client_id\" : client_id,\n \"t\": t.toString(),\n \"mode\" : \"cors\",\n \"Content-Type\": \"application/json\",\n \"sign\": sign.toUpperCase(),\n \"access_token\" : access_token,\n },\n msg.payload = '{\"commands\":[{\"code\":\"switch_1\",\"value\":true}]}';\n msg.url = url;\n msg.method = \"POST\";\n //msg.payload = '';\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":880,"y":1080,"wires":[["f6260f4c.e8663"]]},{"id":"f6260f4c.e8663","type":"http request","z":"4bf109a5.a97ad8","name":"","method":"use","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","x":1030,"y":1080,"wires":[["377d9f7f4417f343"]]},{"id":"556e864.5344d78","type":"inject","z":"4bf109a5.a97ad8","name":"","props":[{"p":"time","v":"","vt":"date"},{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"commands\":[{\"code\":\"switch_1\",\"value\":true}]}","payloadType":"str","x":90,"y":1080,"wires":[["a21182b6.3a489"]]},{"id":"c4e6dff.719862","type":"function","z":"4bf109a5.a97ad8","name":"Create signStr","func":"var creds = flow.get(\"tuya\");\nvar access_token = creds.access_token;\nvar device_id = flow.get(\"device_id\");\nvar t = msg.time;\nvar client_id = flow.get(\"tuya_client_id\");\n\nvar method = \"POST\";\nvar sign_url = \"/v1.0/devices/\"+device_id+\"/commands\";\nvar content_hash = msg.payload;\n\nvar string_to_sign = method + \"\\n\" + content_hash + \"\\n\" + \"\" + \"\\n\" + sign_url;\nvar signStr = client_id + access_token + t + string_to_sign;\n\nmsg.payload = signStr;\nmsg.time = msg.time;\n\nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":460,"y":1080,"wires":[["552476b9.24cad8"]]},{"id":"552476b9.24cad8","type":"hmac","z":"4bf109a5.a97ad8","name":"Sign signStr with secret","algorithm":"HmacSHA256","key":"58fb24515a07454886120147b4225450","x":690,"y":1080,"wires":[["c2dcb090.24f8f"]]},{"id":"a21182b6.3a489","type":"digest","z":"4bf109a5.a97ad8","name":"Hash the body data","algorithm":"SHA256","x":250,"y":1080,"wires":[["c4e6dff.719862"]]},{"id":"7bf971b.8e0989","type":"digest","z":"4bf109a5.a97ad8","name":"Hash the body data","algorithm":"SHA256","x":310,"y":960,"wires":[["7f3ecdbc.908f24"]]},{"id":"c5c9b72789116e0f","type":"debug","z":"4bf109a5.a97ad8","name":"debug 114","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1110,"y":440,"wires":[]},{"id":"c98fa8a4f17d4a45","type":"debug","z":"4bf109a5.a97ad8","name":"debug 115","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1370,"y":140,"wires":[]},{"id":"377d9f7f4417f343","type":"debug","z":"4bf109a5.a97ad8","name":"debug 117","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1230,"y":1080,"wires":[]},{"id":"7c5992c9fc2f493b","type":"debug","z":"4bf109a5.a97ad8","name":"debug 118","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1330,"y":960,"wires":[]},{"id":"23e99629deccef57","type":"function","z":"4bf109a5.a97ad8","name":"","func":"var device_id = flow.get(\"device_id\");\nvar url = \"https://openapi.tuyaeu.com/v1.0/devices/\" + device_id;\nvar t = msg.time;\nvar method = \"GET\";\nvar client_id = flow.get(\"tuya_client_id\");\nvar creds = flow.get(\"tuya\");\nvar token = creds.access_token;\nvar sign = msg.payload;\nmsg.headers ={\n \"sign_method\": \"HMAC-SHA256\",\n \"client_id\" : client_id,\n \"t\": t.toString(),\n \"mode\" : \"cors\",\n \"Content-Type\": \"application/json\",\n \"sign\": sign.toUpperCase(),\n \"access_token\" : token\n },\n msg.payload = '';\n msg.url = url;\n msg.method = \"GET\";\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":720,"y":540,"wires":[["5e546a662abf2f04"]]},{"id":"5e546a662abf2f04","type":"http request","z":"4bf109a5.a97ad8","name":"","method":"use","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","x":890,"y":540,"wires":[["a4850647bd54dc0f"]]},{"id":"93c23bf263dd9476","type":"inject","z":"4bf109a5.a97ad8","name":"","props":[{"p":"time","v":"","vt":"date"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":90,"y":540,"wires":[["e043d4855d18f0ab"]]},{"id":"e043d4855d18f0ab","type":"function","z":"4bf109a5.a97ad8","name":"Create signStr","func":"var creds = flow.get(\"tuya\");\nvar access_token = creds.access_token;\nvar device_id = flow.get(\"device_id\");\nvar t = msg.time;\nvar client_id = flow.get(\"tuya_client_id\");\n//var token = access_token;\n\nvar method = \"GET\";\nvar sign_url = \"/v1.0/devices/\" + device_id;\nvar content_hash = \"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\";\n\nvar string_to_sign = method+\"\\n\"+content_hash+\"\\n\"+\"\"+\"\\n\"+sign_url;\nvar signStr = client_id + access_token + t + string_to_sign;\n\nmsg.debug = {\n \"access_token\": access_token,\n \"device_id\": device_id,\n \"t\": t,\n \"client_id\": client_id,\n \"method\": method,\n \"sign_url\": sign_url,\n \"string_to_sign\": string_to_sign,\n \"signStr\": signStr\n}\n\nmsg.payload = signStr;\nmsg.time = msg.time;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":260,"y":540,"wires":[["1ad96ee78fd5323c"]]},{"id":"1ad96ee78fd5323c","type":"hmac","z":"4bf109a5.a97ad8","name":"Sign signStr with secret","algorithm":"HmacSHA256","key":"58fb24515a07454886120147b4225450","x":490,"y":540,"wires":[["23e99629deccef57"]]},{"id":"b2fa088976f10c85","type":"comment","z":"4bf109a5.a97ad8","name":"Get Device Information","info":"","x":120,"y":500,"wires":[]},{"id":"a4850647bd54dc0f","type":"debug","z":"4bf109a5.a97ad8","name":"debug 119","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1110,"y":540,"wires":[]},{"id":"f8d92f0bcbbe2951","type":"function","z":"4bf109a5.a97ad8","name":"","func":"var device_id = flow.get(\"device_id\");\nvar url = \"https://openapi.tuyaeu.com/v1.0/functions/dj\";\nvar t = msg.time;\nvar method = \"GET\";\nvar client_id = flow.get(\"tuya_client_id\");\nvar creds = flow.get(\"tuya\");\nvar token = creds.access_token;\nvar sign = msg.payload;\nmsg.headers ={\n \"sign_method\": \"HMAC-SHA256\",\n \"client_id\" : client_id,\n \"t\": t.toString(),\n \"mode\" : \"cors\",\n \"Content-Type\": \"application/json\",\n \"sign\": sign.toUpperCase(),\n \"access_token\" : token\n },\n msg.payload = '';\n msg.url = url;\n msg.method = \"GET\";\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":720,"y":640,"wires":[["e75bc80a537bf083"]]},{"id":"e75bc80a537bf083","type":"http request","z":"4bf109a5.a97ad8","name":"","method":"use","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","x":890,"y":640,"wires":[["207ef8534396b733"]]},{"id":"5e5adc8f77f4a84d","type":"inject","z":"4bf109a5.a97ad8","name":"","props":[{"p":"time","v":"","vt":"date"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":90,"y":640,"wires":[["9890980b77d323a0"]]},{"id":"9890980b77d323a0","type":"function","z":"4bf109a5.a97ad8","name":"Create signStr","func":"var creds = flow.get(\"tuya\");\nvar access_token = creds.access_token;\nvar device_id = flow.get(\"device_id\");\nvar t = msg.time;\nvar client_id = flow.get(\"tuya_client_id\");\n//var token = access_token;\n\nvar method = \"GET\";\nvar sign_url = \"/v1.0/functions/dj\";\nvar content_hash = \"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\";\n\nvar string_to_sign = method+\"\\n\"+content_hash+\"\\n\"+\"\"+\"\\n\"+sign_url;\nvar signStr = client_id + access_token + t + string_to_sign;\n\nmsg.debug = {\n \"access_token\": access_token,\n \"device_id\": device_id,\n \"t\": t,\n \"client_id\": client_id,\n \"method\": method,\n \"sign_url\": sign_url,\n \"string_to_sign\": string_to_sign,\n \"signStr\": signStr\n}\n\nmsg.payload = signStr;\nmsg.time = msg.time;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":260,"y":640,"wires":[["f78bf512cde6a8d0"]]},{"id":"f78bf512cde6a8d0","type":"hmac","z":"4bf109a5.a97ad8","name":"Sign signStr with secret","algorithm":"HmacSHA256","key":"58fb24515a07454886120147b4225450","x":490,"y":640,"wires":[["f8d92f0bcbbe2951"]]},{"id":"b39c69e035eb7213","type":"comment","z":"4bf109a5.a97ad8","name":"Get Function List","info":"","x":100,"y":600,"wires":[]},{"id":"207ef8534396b733","type":"debug","z":"4bf109a5.a97ad8","name":"debug 120","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1110,"y":640,"wires":[]},{"id":"0c0459698d8bb296","type":"function","z":"4bf109a5.a97ad8","name":"","func":"var device_id = flow.get(\"device_id\");\nvar url = \"https://openapi.tuyaeu.com/v1.0/devices/\" + device_id +\"/status\";\nvar t = msg.time;\nvar method = \"GET\";\nvar client_id = flow.get(\"tuya_client_id\");\nvar creds = flow.get(\"tuya\");\nvar token = creds.access_token;\nvar sign = msg.payload;\nmsg.headers ={\n \"sign_method\": \"HMAC-SHA256\",\n \"client_id\" : client_id,\n \"t\": t.toString(),\n \"mode\" : \"cors\",\n \"Content-Type\": \"application/json\",\n \"sign\": sign.toUpperCase(),\n \"access_token\" : token\n },\n msg.payload = '';\n msg.url = url;\n msg.method = \"GET\";\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":720,"y":740,"wires":[["f670e7bcad81de3c"]]},{"id":"f670e7bcad81de3c","type":"http request","z":"4bf109a5.a97ad8","name":"","method":"use","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","x":890,"y":740,"wires":[["12c54aa25fe558fa"]]},{"id":"b4430cf3e3591e56","type":"inject","z":"4bf109a5.a97ad8","name":"","props":[{"p":"time","v":"","vt":"date"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":90,"y":740,"wires":[["87c02ade58431cd2"]]},{"id":"87c02ade58431cd2","type":"function","z":"4bf109a5.a97ad8","name":"Create signStr","func":"var creds = flow.get(\"tuya\");\nvar access_token = creds.access_token;\nvar device_id = flow.get(\"device_id\");\nvar t = msg.time;\nvar client_id = flow.get(\"tuya_client_id\");\n//var token = access_token;\n\nvar method = \"GET\";\nvar sign_url = \"/v1.0/devices/\" + device_id + \"/status\";\nvar content_hash = \"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\";\n\nvar string_to_sign = method+\"\\n\"+content_hash+\"\\n\"+\"\"+\"\\n\"+sign_url;\nvar signStr = client_id + access_token + t + string_to_sign;\n\nmsg.debug = {\n \"access_token\": access_token,\n \"device_id\": device_id,\n \"t\": t,\n \"client_id\": client_id,\n \"method\": method,\n \"sign_url\": sign_url,\n \"string_to_sign\": string_to_sign,\n \"signStr\": signStr\n}\n\nmsg.payload = signStr;\nmsg.time = msg.time;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":260,"y":740,"wires":[["0040e12abf3b9894"]]},{"id":"0040e12abf3b9894","type":"hmac","z":"4bf109a5.a97ad8","name":"Sign signStr with secret","algorithm":"HmacSHA256","key":"58fb24515a07454886120147b4225450","x":490,"y":740,"wires":[["0c0459698d8bb296"]]},{"id":"95f65d994f5acc43","type":"comment","z":"4bf109a5.a97ad8","name":"Get device Data Points","info":"","x":120,"y":700,"wires":[]},{"id":"12c54aa25fe558fa","type":"debug","z":"4bf109a5.a97ad8","name":"debug 121","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1110,"y":740,"wires":[]},{"id":"e66de0857f95a9a8","type":"function","z":"4bf109a5.a97ad8","name":"","func":"var device_id = flow.get(\"device_id\");\nvar url = \"https://openapi.tuyaeu.com/v1.0/devices/\" + device_id +\"/functions\";\nvar t = msg.time;\nvar method = \"GET\";\nvar client_id = flow.get(\"tuya_client_id\");\nvar creds = flow.get(\"tuya\");\nvar token = creds.access_token;\nvar sign = msg.payload;\nmsg.headers ={\n \"sign_method\": \"HMAC-SHA256\",\n \"client_id\" : client_id,\n \"t\": t.toString(),\n \"mode\" : \"cors\",\n \"Content-Type\": \"application/json\",\n \"sign\": sign.toUpperCase(),\n \"access_token\" : token\n },\n msg.payload = '';\n msg.url = url;\n msg.method = \"GET\";\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":720,"y":840,"wires":[["75a8cd4bfd3a6fdd"]]},{"id":"75a8cd4bfd3a6fdd","type":"http request","z":"4bf109a5.a97ad8","name":"","method":"use","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","x":890,"y":840,"wires":[["5ec348212f88adf5"]]},{"id":"ab7ee184a2fe44fa","type":"inject","z":"4bf109a5.a97ad8","name":"","props":[{"p":"time","v":"","vt":"date"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":90,"y":840,"wires":[["0e6e99d81893b1c3"]]},{"id":"0e6e99d81893b1c3","type":"function","z":"4bf109a5.a97ad8","name":"Create signStr","func":"var creds = flow.get(\"tuya\");\nvar access_token = creds.access_token;\nvar device_id = flow.get(\"device_id\");\nvar t = msg.time;\nvar client_id = flow.get(\"tuya_client_id\");\n//var token = access_token;\n\nvar method = \"GET\";\nvar sign_url = \"/v1.0/devices/\" + device_id + \"/functions\";\nvar content_hash = \"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\";\n\nvar string_to_sign = method+\"\\n\"+content_hash+\"\\n\"+\"\"+\"\\n\"+sign_url;\nvar signStr = client_id + access_token + t + string_to_sign;\n\nmsg.debug = {\n \"access_token\": access_token,\n \"device_id\": device_id,\n \"t\": t,\n \"client_id\": client_id,\n \"method\": method,\n \"sign_url\": sign_url,\n \"string_to_sign\": string_to_sign,\n \"signStr\": signStr\n}\n\nmsg.payload = signStr;\nmsg.time = msg.time;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":260,"y":840,"wires":[["13c60cf5b1d73ab9"]]},{"id":"13c60cf5b1d73ab9","type":"hmac","z":"4bf109a5.a97ad8","name":"Sign signStr with secret","algorithm":"HmacSHA256","key":"58fb24515a07454886120147b4225450","x":490,"y":840,"wires":[["e66de0857f95a9a8"]]},{"id":"74b0ef9695dfbc2d","type":"comment","z":"4bf109a5.a97ad8","name":"Query instruction sets supported by the device","info":"","x":190,"y":800,"wires":[]},{"id":"5ec348212f88adf5","type":"debug","z":"4bf109a5.a97ad8","name":"debug 122","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1110,"y":840,"wires":[]},{"id":"3a4846e01f72bc11","type":"comment","z":"4bf109a5.a97ad8","name":"Sources","info":"This flow is the result of a sharing by notenoughtech.\nHere are his web pages:\n\nhttps://github.com/notenoughtech/NodeRED-Projects/tree/master/Tuya%20Cloud%20API\nhttps://notenoughtech.com/home-automation/tuya-cloud-api/\n\nThe use of this flow requires the use of the palette:\nnode-red-contrib-crypto-js-dynamic\n","x":80,"y":40,"wires":[]},{"id":"df0d278f20fc21f6","type":"function","z":"4bf109a5.a97ad8","name":"","func":"var creds = flow.get(\"tuya\");\nvar refresh_token = creds.refresh_token;\nvar t = msg.time;\n\n\nvar url = \"https://openapi.tuyaeu.com/v1.0/token/\" + refresh_token;\nvar sign = msg.payload;\nvar client_id = flow.get(\"tuya_client_id\");\nmsg.headers ={\n \"sign_method\": \"HMAC-SHA256\",\n \"client_id\" : client_id,\n \"t\": t.toString(),\n \"sign\": sign.toUpperCase(),\n },\n msg.payload = '';\n msg.url = url;\n msg.method = \"GET\";\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":720,"y":240,"wires":[["8b69823e8ad4030a"]]},{"id":"8b69823e8ad4030a","type":"http request","z":"4bf109a5.a97ad8","name":"","method":"use","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","x":890,"y":240,"wires":[["83baa287f862c021"]]},{"id":"2a73ddecefdf44a9","type":"inject","z":"4bf109a5.a97ad8","name":"","props":[{"p":"time","v":"","vt":"date"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":90,"y":240,"wires":[["7cf80c54805c3142"]]},{"id":"7cf80c54805c3142","type":"function","z":"4bf109a5.a97ad8","name":"Create signStr","func":"var client_id = flow.get(\"tuya_client_id\");\nvar creds = flow.get(\"tuya\");\nvar refresh_token = creds.refresh_token;\nvar t = msg.time;\n\n\nvar method = \"GET\";\nvar sign_url = \"/v1.0/token/\" + refresh_token;\n\n// Couldn't get nodered to process an empty string so this is a hash of an empty file\nvar content_hash = \"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\";\nvar string_to_sign = method+\"\\n\"+content_hash+\"\\n\"+\"\"+\"\\n\"+sign_url;\nvar signStr = client_id+t+string_to_sign;\n\nmsg.payload = signStr;\nmsg.time = msg.time;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":260,"y":240,"wires":[["e44d5c4aec4df707"]]},{"id":"e44d5c4aec4df707","type":"hmac","z":"4bf109a5.a97ad8","name":"Sign signStr with secret","algorithm":"HmacSHA256","key":"58fb24515a07454886120147b4225450","x":490,"y":240,"wires":[["df0d278f20fc21f6"]]},{"id":"04842d2df13a643b","type":"comment","z":"4bf109a5.a97ad8","name":"Refresh Token","info":"","x":90,"y":200,"wires":[]},{"id":"83baa287f862c021","type":"function","z":"4bf109a5.a97ad8","name":"Extract Token from Response","func":"var data = msg.payload;\nvar access = data.result.access_token;\nvar refresh = data.result.refresh_token;\n\nvar creds ={\n \"access_token\" : access,\n \"refresh_token\" : refresh\n}\nflow.set(\"tuya\", creds);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1120,"y":240,"wires":[["33c389baa65a4fe7"]]},{"id":"33c389baa65a4fe7","type":"debug","z":"4bf109a5.a97ad8","name":"debug 123","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1370,"y":240,"wires":[]},{"id":"02c15c74b19ad952","type":"comment","z":"4bf109a5.a97ad8","name":"Get a list of devices under a specified user","info":"","x":180,"y":300,"wires":[]},{"id":"bfc4359fff1d339a","type":"function","z":"4bf109a5.a97ad8","name":"","func":"var device_id = flow.get(\"device_id\");\nvar client_id = flow.get(\"tuya_client_id\");\nvar tuya_user_id = flow.get(\"tuya_user_id\");\nvar url = \"https://openapi.tuyaeu.com/v1.0/users/\" + tuya_user_id + \"/devices\";\nvar t = msg.time;\nvar method = \"GET\";\nvar creds = flow.get(\"tuya\");\nvar token = creds.access_token;\nvar sign = msg.payload;\n\nmsg.headers ={\n \"sign_method\": \"HMAC-SHA256\",\n \"client_id\" : client_id,\n \"t\": t.toString(),\n \"mode\" : \"cors\",\n \"Content-Type\": \"application/json\",\n \"sign\": sign.toUpperCase(),\n \"access_token\" : token\n },\n \n msg.payload = '';\n msg.url = url;\n msg.method = \"GET\";\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":720,"y":340,"wires":[["106527b0a025f5e4"]]},{"id":"106527b0a025f5e4","type":"http request","z":"4bf109a5.a97ad8","name":"","method":"use","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","x":890,"y":340,"wires":[["d6d85945c72762ce"]]},{"id":"26ad12a9223761f0","type":"inject","z":"4bf109a5.a97ad8","name":"","props":[{"p":"time","v":"","vt":"date"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":90,"y":340,"wires":[["c969c83d52502b9a"]]},{"id":"c969c83d52502b9a","type":"function","z":"4bf109a5.a97ad8","name":"Create signStr","func":"var creds = flow.get(\"tuya\");\nvar access_token = creds.access_token;\nvar device_id = flow.get(\"device_id\");\nvar t = msg.time;\nvar client_id = flow.get(\"tuya_client_id\");\nvar tuya_user_id = flow.get(\"tuya_user_id\");\n//var token = access_token;\n\nvar method = \"GET\";\nvar sign_url = \"/v1.0/users/\" + tuya_user_id + \"/devices\";\nvar content_hash = \"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\";\n\nvar string_to_sign = method+\"\\n\"+content_hash+\"\\n\"+\"\"+\"\\n\"+sign_url;\nvar signStr = client_id + access_token + t + string_to_sign;\n\nmsg.payload = signStr;\nmsg.time = msg.time;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":260,"y":340,"wires":[["90b50f4cb19d6b6f"]]},{"id":"90b50f4cb19d6b6f","type":"hmac","z":"4bf109a5.a97ad8","name":"Sign signStr with secret","algorithm":"HmacSHA256","key":"58fb24515a07454886120147b4225450","x":490,"y":340,"wires":[["bfc4359fff1d339a"]]},{"id":"d6d85945c72762ce","type":"debug","z":"4bf109a5.a97ad8","name":"debug 135","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1110,"y":340,"wires":[]}]
Pas d’inquiétude, j’ai tenté de vous référencer une liste non exhaustive des possibilités.
- Settings CLICK SETUP TAB
Cette fonction set à charger vos valeurs de connexion aux API lors du lancement.
Aller dans l’onglet On Start
var client_id = "votre Client_ID";
var user_id = "Le user";
var device_id = "ID du périphérique";
flow.set("tuya_client_id", client_id);
flow.set("tuya_user_id", user_id );
flow.set("device_id", device_id );
Ces informations sont récupérables comme suit:
Sur le site iot.tuya.com
1. client_id
Se rendre sur
Ouvrir votre projet pour home assistant
Dans l’onglet Overview le client ID:
2. user_id
3. device_id
PS: Une info qui peut avoir son improtance le nombre de requête: ICI
Avec 500 000 /jour on est large