mlfunston / node-red-contrib-broadlink-control

Set of node-red nodes to manage the Broadlink home automation device suite
MIT License
44 stars 24 forks source link

Support to make sending RF commands with RM4 pro work #72

Open sprotznock opened 3 years ago

sprotznock commented 3 years ago

I own a Broadlink RM4 pro (ID 0x649b) and like to send RF commands to a roller shutter. I know that currently this isn't offically supported and in fact it is not working. I am using node-red-contrib-broadlink-control v2.1.4.

I like to help with this but probably need some support.

What I have done so far:

I found some tutorials grabbing the commands from the app's filesystem but they don't work anymore - obviously the app has changed meanwhile.

But I have root access to my Android device and was able to find the appropriate files in the cache directory (simply using grep -r on all folders named like "*broadlink*" after I gave my commands some unique names in the app).

I attached the file to this issue.: broadlink-app-codes.json.gz

I put one of the extracted commands into the function node of the example flow (converted to a byte array using this little Perl script: hex2bytes.gz). But when I run the flow nothing happens except that I am told that the data has been sent.

Here is the complete flow: broadlink-flow.json.gz

So I am stucked. And I have some questions ;)

Is there a difference in the UDP API between sending IR or RF commands?

I couldn't find one in the source code. The RM node just sends a payload. Obviously the difference comes from the payload itself? I mean that the payload has some information on which the RM4 device can decide if the command is IR or RF?

So probably we need to construct the UDP packet in a different way to make it work the RM4 pro devices? Since IR learning did work the basic communication obviously works so I don't believe that the low level protocol has changed in major fashion, especially encryption.

Can we solve this by reverse engineering?

I think you extracted the algorithm of packing the UDP protocol packets from the app? The packets are encrypted with constant key and iv and have a randomly initialized counter part. I think to prevent simple replay attacks. So reverse engineering the protocol just by wire is not possible.

As mentioned above I don't think the encryption itself didn't change. So is it worth to try to listen to the UDP packets send from the app to the device, decrypt them and try to change / extend the RM Node to reconstruct the packets accordingly?

Or would you try to reverse engineer the app code to see what has changed?

I fear the latter may be beyond my capabilities. I see that the app uses a WebView for the frontend (easily debuggable with Chrome developer console). I didn't go deeper into it to see if a framework like Cordova is used here, which could make things easier. But I am no Android expert.

What can I do to help you?

If there is anything I can do to support you in solving this problem, just tell me. If you need such a piece of hardware I would donate one.

sprotznock commented 3 years ago

I have an update: I tried python-broadlink with success.

I was able to use the CLI tool with --rfscanlearn option to learn RF commands and --send to control my roller shutter.

I compared the scanned codes with the codes I grabbed from the app's filesystem: they differ!

Next I used the codes from broadlink_cli in the node-red RM function node: still without success.

Should this work? Any idea why it's not working?

But the good news are: no further reverse engineering is necessary ;)

nickwild-999 commented 2 years ago

I can confirm that I was able to get the Base64 code from the standard HA integration method (and can also send with this method,) but including this in an RM Node in send mode does not work