codetheweb / tuyapi

🌧 An easy-to-use API for devices that use Tuya's cloud services. Documentation: https://codetheweb.github.io/tuyapi.
MIT License
2.05k stars 337 forks source link

Message parser error #325

Open dragonpiper opened 4 years ago

dragonpiper commented 4 years ago

Controlling lights by increasing / decreasing brightness with a for loop over brightness levels to smooth dimming / lighting. Sometimes it works often times i get

RangeError [ERR_BUFFER_OUT_OF_BOUNDS]: Attempt to access memory outside buffer bounds at boundsError (internal/buffer.js:70:11) at Buffer.readUInt32BE (internal/buffer.js:295:5) at MessageParser.parsePacket (F:\WebProjects\javascript-playground\node_modules\tuyapi\lib\message-parser.js:120:27) at MessageParser.parseRecursive (F:\WebProjects\javascript-playground\node_modules\tuyapi\lib\message-parser.js:211:25) at MessageParser.parseRecursive (F:\WebProjects\javascript-playground\node_modules\tuyapi\lib\message-parser.js:218:19) at MessageParser.parseRecursive (F:\WebProjects\javascript-playground\node_modules\tuyapi\lib\message-parser.js:218:19) at MessageParser.parseRecursive (F:\WebProjects\javascript-playground\node_modules\tuyapi\lib\message-parser.js:218:19) at MessageParser.parseRecursive (F:\WebProjects\javascript-playground\node_modules\tuyapi\lib\message-parser.js:218:19) at MessageParser.parseRecursive (F:\WebProjects\javascript-playground\node_modules\tuyapi\lib\message-parser.js:218:19) at MessageParser.parseRecursive (F:\WebProjects\javascript-playground\node_modules\tuyapi\lib\message-parser.js:218:19) at MessageParser.parseRecursive (F:\WebProjects\javascript-playground\node_modules\tuyapi\lib\message-parser.js:218:19) at MessageParser.parseRecursive (F:\WebProjects\javascript-playground\node_modules\tuyapi\lib\message-parser.js:218:19) at MessageParser.parseRecursive (F:\WebProjects\javascript-playground\node_modules\tuyapi\lib\message-parser.js:218:19) at MessageParser.parseRecursive (F:\WebProjects\javascript-playground\node_modules\tuyapi\lib\message-parser.js:218:19) at MessageParser.parseRecursive (F:\WebProjects\javascript-playground\node_modules\tuyapi\lib\message-parser.js:218:19) at MessageParser.parseRecursive (F:\WebProjects\javascript-playground\node_modules\tuyapi\lib\message-parser.js:218:19) { code: 'ERR_BUFFER_OUT_OF_BOUNDS' }

or

TypeError: Prefix does not match: 21497c0000aa55000055aa000000fe0000000

or

Error: Error from socket

Sometimes they can be quickly be resolved by rebooting the application, however trying to reconnect within the app using find -> device.connect() will fail until the whole app is restarted or it will continue throwing socket errors for an extended period of time when trying to reconect

kueblc commented 4 years ago

I think I see what's happening.

If we receive a partial message, this line will return -1 since we don't have the suffix yet. -1 isn't handled properly and causes trouble a few lines down.

What we should do in that case is store the buffer for later when we receive the rest of the message.

We could also be a bit smarter about how we handle prefix validation and scan for the prefix, like we do with the suffix. This way we continue processing messages in the event there is junk before the actual message.

dragonpiper commented 4 years ago

I see. There is also something up with the reconnect code. I create a device once. And operate on that device during the lifetime of the application however reconnected after a certain amount of time will fail and just through Error: Error from socket. if i restart my application, connection will work immediately so not sure what's going there..

codetheweb commented 4 years ago

I think @kueblc is right, ideally we would be appending all received data to a buffer that we then can scan for packets.

It's possible to get the device into a bad state by sending invalid packets / too many, which is why the re-connection sometimes doesn't work.

I would recommend waiting for an ACK for your SET command before sending another; from personal experience with sending commands as continuously as possible it should work.

dragonpiper commented 4 years ago

Are there any upcoming planned releases ?

codetheweb commented 4 years ago

If you're asking for any releases specifically addressing this issue, no. This issue can be worked around in user-land and I don't currently have enough bandwidth to do a complete overhaul of the way messages are handled.

'v6' of TuyAPI exists here, and while it's incomplete, lacking documentation, and at the moment currently parses messages the same way; that's where I would implement this. PRs are welcome. 😉

Also see: https://github.com/codetheweb/tuyapi/issues/169.

shellcatt commented 6 months ago

Has anyone managed to tackle this issue?

I get a Prefix does not match: error when trying to connect to some devices over WiFi, specifically light bulbs (protocol varies between 3.1 and 3.4). Sockets work fine though.

@codetheweb I wonder - what does issue can be worked around in user-land mean?

P.S.: Props for this awesome piece of RevEng! I wish I could contribute, but I'm new to this project and IoT in general, so it'll take me quite some time.

kueblc commented 6 months ago

issue can be worked around in user-land

Means you can work around the problem by accounting for it in your own code, without making changes to the library. @codetheweb recommended the following:

I would recommend waiting for an ACK for your SET command before sending another; from personal experience with sending commands as continuously as possible it should work.

I get a Prefix does not match: error when trying to connect to some devices over WiFi

If you're getting this issue while attempting a new connection, then something else might be going on. If you can gather some more debugging information, open a new issue and we can take a look.

caitken-com commented 6 months ago

I have the same issue as @shellcatt. Newly added Smart Bulb to Tuya Smart iOS app (works in app).

I'm using Tuya Smart Device within Node-RED which makes use of this library. But it's not happy about this smart bulb when trying to connect, throws Prefix does not match: ...

It shows up in the CLI wizard (front light):

$ tuya-cli wizard
  {
    name: 'Front light',
    id: 'bf...',
    key: '|Q...'
  },
  {
    name: 'Lounge Dimmer',
    id: 'bf...',
    key: '$...'
  },
  ...

But errors with the CLI get command, first result is lounge dimmer to check/prove the tool works:

$ tuya-cli get --id "bf..." --key "$..." --full
{ dps: { '1': false, '2': 1000, '3': 10, '6': 0 } }

$ tuya-cli get --id "bf..." --key "|Q..." --full
-bash: !6: event not found

I could post the whole (seemingly invalid) packet that's throwing the error? Or, if there's a Discord server and someone has time to debug with me that would be very appreciated?

All my other tuya devices are smart dimmers, they all work fine via the api. This is my first (and only) smart bulb.

Update: I unpaired and repaired in Tuya Smart iOS app to see if an updated key would help, it did not.