vinodsr / node-red-contrib-tuya-smart-device

a node-red module for managing tuya smart devices
https://flows.nodered.org/node/node-red-contrib-tuya-smart-device
MIT License
43 stars 15 forks source link

standard behavior of node-red-contrib-tuya-smart-device (4.1.connection issue) #67

Closed msillano closed 3 years ago

msillano commented 3 years ago

node-red-contrib-tuya-smart-device used:

tuya-smart-device.zip It is a modified version to meet requirements.

TEST flow used:

Devices tested: Wifi Plug: passed, Power Strip: passed, LED 700ml Humidifier: passed.

These devices are chosen because all accept SCHEMA. Tuya devices can present many variations to expected behavior.


Expected behavior REFRESH

9/6/2021, 11:04:11node: Device INPUT
msg.payload : Object
object
   operation: "REFRESH"
   requestedDPS: array[7]
        0: 1
        1: 9
        2: 6
        3: 17
        4: 18
        5: 19
        6: 20

9/6/2021, 11:04:11node: Device Data
msg.payload.data.dps : Object
{ 18: 62, 19: 53 }  // ERROR !!!, expected 1,9,6,17,18,19,20 DPS, found only 18,19

note: The expected behavior is not provided by ANY device because the 'tuyAPI' definitions are equivocal, and the tuyAPI implementation is not consistent with the definitions. The RULES I found on all my devices are, see ISSUE#469:

  • The REFRESH causes an immediate re-sampling and all data are re-calculated.
  • In output are sent ALWAYS only the CHANGED dps (not all (SCHEMA) or requestedDPS !).
  • REFRESH, REFRESH SCHEMA, REFRESH DPS works ALL the same way: i.e. exists only one REFRESH function (at least, with the implementation under the test of tuyAPI ver. 7.1.0 ).

In applications I use only one vanilla REFRESH, applying previous rules, and it works as expected.


Expected behavior STARTUP, device ON, Disable auto-connect on start: false

9/6/2021, 13:20:41node: Node State
msg.payload : Object
{ state: "DISCONNECTED" }

9/6/2021, 13:20:42node: Node State
msg.payload : Object
{ state: "CONNECTING" }

9/6/2021, 13:20:43node: Node State
msg.payload : Object
{ state: "ERROR", context: object }

9/6/2021, 13:20:43node: Node State
msg.payload : Object
{ state: "DISCONNECTED" }

..... more

9/6/2021, 13:20:50node: Node State
msg.payload : Object
{ state: "CONNECTING" }

9/6/2021, 13:20:51node: Node State
msg.payload : Object
{ state: "CONNECTED" }

note:

9/6/2021, 17:15:30node: Device INPUT msg.payload : Object { operation: "CONTROL", action: "CONNECT" }

9/6/2021, 17:15:31node: Device State msg.payload : Object { state: "CONNECTING" }

9/6/2021, 17:15:33node: Device State msg.payload : Object { state: "CONNECTED" }

 note:
- 'Disable auto-connect on start' is for only the first start after Deploy or Restart flows.
    If later the device goes OFF then back ON, the device is auto-connected.

- Required: user CONTROL 'CONNECT'|'RECONNECT' and the final 'CONNECTED'.

 ---------------------------------------------
 ### Expected behavior STARTUP, device _OFF_, Disable auto-connect on start: _false_

9/6/2021, 12:51:53node: Node State msg.payload : Object { state: "DISCONNECTED" }

9/6/2021, 12:51:54node: Node State msg.payload : Object { state: "CONNECTING" }

9/6/2021, 12:52:14node: Node State msg.payload : Object state: "ERROR" context: object message: "Error: find() timed out. Is the device powered on and the ID or IP correct?" device: "Wifi plug"

9/6/2021, 12:52:14node: Node State msg.payload : Object { state: "DISCONNECTED" }

9/6/2021, 12:52:24node: Node State msg.payload : Object { state: "CONNECTING" }

9/6/2021, 12:52:44node: Node State msg.payload : Object state: "ERROR" context: object message: "Error: find() timed out. Is the device powered on and the ID or IP correct?" device: "Wifi plug" ...... more

note:
- Never-ending loop CONNECTING-ERROR-DISCONNECTED.
- In this case, the ERROR msg is superfluous: enough to ignore it in apps.
    - Between CONNECTING-ERROR, 20s == _findTimeout_
    - Between ERROR-DISCONNECTED  0s
    - Between DISCONNECTED-CONNECTING, 10s == _retryTimeout_

Required:   
   - the initial 'DISCONNECTED'.
   - Infinite loop CONNECTING-(ERROR)-DISCONNECTED.
   - No `node.error` messages.

---------------------------------------------    
 ### Expected behavior  device _OFF => ON_

9/6/2021, 13:37:53node: Node State msg.payload : Object { state: "DISCONNECTED" } // ---- here device goes ON

9/6/2021, 13:37:58node: Node State msg.payload : Object { state: "CONNECTING" }

9/6/2021, 13:38:03node: Node State msg.payload : Object state: "ERROR" context: object message: "Error: find() timed out. Is the device powered on and the ID or IP correct?" device: "Wifi plug"

9/6/2021, 13:38:03node: Node State msg.payload : Object { state: "DISCONNECTED" }

9/6/2021, 13:38:08node: Node State msg.payload : Object { state: "CONNECTING" }

9/6/2021, 13:38:10node: Node State msg.payload : Object { state: "CONNECTED" }

9/6/2021, 13:38:32node: Device Data msg.payload.data.dps : Object { 18: 62, 19: 53, 20: 2295 }

note:
- Required: the final 'CONNECTED'.

---------------------------------------------    
 ### Expected behavior  device ON => OFF

9/6/2021, 13:50:21node: Device Data msg.payload.data.dps : Object { 18: 62, 19: 53, 20: 2299 } //---- here device goes OFF

9/6/2021, 13:50:32node: Node State msg.payload : Object { state: "DISCONNECTED" }

9/6/2021, 13:50:37node: Node State msg.payload : Object { state: "CONNECTING" }

9/6/2021, 13:50:42node: Node State msg.payload : Object { state: "DISCONNECTED" }

9/6/2021, 13:50:52node: Node State msg.payload : Object { state: "CONNECTING" }

9/6/2021, 13:50:57node: Node State msg.payload : Object { state: "DISCONNECTED" }

9/6/2021, 13:51:07node: Node State msg.payload : Object { state: "CONNECTING" } .......... more

note:
- Never-ending loop CONNECTING-DISCONNECTED.
- difference from STARTUP-OFF case: the STATE ERROR message is now missed: no problem, it is superfluous.
    - Between CONNECTING-DISCONNECTED  5s ==  _findTimeout_
    - Between DISCONNECTED-CONNECTING, 10s == _retryTimeout_

Required:
  - Infinite loop CONNECTING-(ERROR)-DISCONNECTED.
  - No 'node.error' messages.

---------------------------------------------    
 ### Expected behavior  CONNECT/DISCONNECT/RECONNECT
 start condition:  _STARTUP_, device _ON_

9/6/2021, 14:03:39node: Node State msg.payload : Object { state: "DISCONNECTED" }

9/6/2021, 14:03:40node: Node State msg.payload : Object { state: "CONNECTING" }

9/6/2021, 14:03:43node: Node State msg.payload : Object { state: "CONNECTED" } ------- now CONTROL DISCONNECT

9/6/2021, 14:03:48node: Device INPUT msg.payload : Object { operation: "CONTROL", action: "DISCONNECT" }

9/6/2021, 14:03:48node: Node State msg.payload : Object { state: "DISCONNECTED" } OK, done ---- now more CONTROL DISCONNECT

9/6/2021, 14:04:13node: Device INPUT msg.payload : Object { operation: "CONTROL", action: "DISCONNECT" } OK, no effect ---- now CONTROL CONNECT

9/6/2021, 14:04:24node: Device INPUT msg.payload : Object { operation: "CONTROL", action: "CONNECT" }

9/6/2021, 14:04:25node: Node State msg.payload : Object { state: "CONNECTING" }

9/6/2021, 14:04:26node: Node State msg.payload : Object { state: "CONNECTED" } // OK, done ---- now more CONTROL CONNECT

9/6/2021, 14:04:31node: Device INPUT msg.payload : Object { operation: "CONTROL", action: "CONNECT" } // OK, no effect --- now CONTROL RECONNECT

9/6/2021, 14:04:44node: Device INPUT msg.payload : Object { operation: "CONTROL", action: "RECONNECT" }

9/6/2021, 14:04:44node: Node State msg.payload : Object { state: "DISCONNECTED" }

9/6/2021, 14:04:45node: Node State msg.payload : Object { state: "CONNECTING" }

9/6/2021, 14:04:45node: Node State msg.payload : Object { state: "CONNECTED" } // OK, done --- now second CONTROL RECONNECT

9/6/2021, 14:04:50node: Device INPUT msg.payload : Object { operation: "CONTROL", action: "RECONNECT" }

9/6/2021, 14:04:50node: Node State msg.payload : Object { state: "DISCONNECTED" }

9/6/2021, 14:04:51node: Node State msg.payload : Object { state: "CONNECTING" } // ok, re-done ..... ........... more

9/6/2021, 15:36:55node: Node State msg.payload : Object { state: "DISCONNECTED" } ------------ now RECONNECT (but device DISCONNECTED)

9/6/2021, 15:36:57node: Device INPUT msg.payload : Object { operation: "CONTROL", action: "RECONNECT" }

9/6/2021, 15:36:59node: Node State msg.payload : Object { state: "CONNECTING" }

9/6/2021, 15:37:00node: Node State msg.payload : Object { state: "CONNECTED" } // OK, done: connected

Required:
  - CONNECT; connects the device, if DISCONNECTED, else does nothing.
 - DISCONNECT; disconnects the device, if CONNECTED, else does nothing.
 - RECONNECT: disconnects the device, if CONNECTED, then (re)connects them.

### Expected behavior SET/GET/SCHEMA

//------------ SET 1, true 9/6/2021, 15:59:47node: Device INPUT msg.payload : Object { dps: 1, set: true }

9/6/2021, 15:59:47node: Device Data msg.payload.data.dps : Object { 1: true } // OK: as expected --- SET 1, false

9/6/2021, 15:59:49node: Device INPUT msg.payload : Object { dps: 1, set: false } 9/6/2021, 15:59:49node: Device Data msg.payload.data.dps : Object { 1: false } // OK: as expected --- GET 1

9/6/2021, 15:59:55node: Device INPUT msg.payload : Object { operation: "GET", dps: 1 }

9/6/2021, 15:59:55node: Device Data msg.payload.data.dps : Object { 1: false 9: 0 17: 2 18: 0 19: 0 20: 2299 21: 1 22: 627 23: 29228 24: 17033 25: 2460 26: 0 38: "memory" 41: "" 42: "" 46: false } // ** Device quirk: the GET answer is like 'SCHEMA' //--------- else using: SET 1, null

9/6/2021, 16:06:10node: Device INPUT msg.payload : Object { dps: 1, set: null } 9/6/2021, 16:06:10node: Device Data msg.payload.data.dps : Object { 1: true } // OK, as expected ----- with this device use alway 'SET dp, null' in place of 'GET dp' // now-------- SCHEMA

9/6/2021, 16:06:16node: Device INPUT msg.payload : Object { operation: "GET", schema: true }

9/6/2021, 16:06:16node: Device Data msg.payload.data.dps : Object object 1: true 9: 0 17: 2 18: 0 19: 0 20: 2299 21: 1 22: 627 23: 29228 24: 17033 25: 2460 26: 0 38: "memory" 41: "" 42: "" 46: false } // OK, as expected


note:
-  The unusual behavior of the 'Wifi Plug' in the case 'GET 1' was  [known](https://github.com/msillano/tuyaDAEMON/blob/main/devices/Wifi_Plug/device_Wifi_Plug.pdf).
- The SET/GET/SCHEMA device behavior is complicated by the presence of some fallbacks on `tuyAPI` implementation, so an unexpected result can become from the devices but also from tuyAPI.
- As `tuyAPI` users, we must accept the `tuyAPI + device` as a unique black-block, ready to accept possibles differences in the behavior for every new version.
vinodsr commented 3 years ago

Thanks Can you please submit this as a PR ?

msillano commented 3 years ago

I will try: never done before. Hope in some days.

Best regards m.s.

vinodsr commented 3 years ago

Also check if the latest version solves any of these issues.

On Fri, 11 Jun, 2021, 10:06 am Marco Sillano, @.***> wrote:

I will try: never done before. Hope in some days.

Best regards m.s.

— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub https://github.com/vinodsr/node-red-contrib-tuya-smart-device/issues/67#issuecomment-859258043, or unsubscribe https://github.com/notifications/unsubscribe-auth/AADQ6OHBWIR463HK22F36PLTSGHFZANCNFSM46MM35UA .