Broadlink Black Bean (RM 3 Mini) IR Controller - Integration in OpenHAB

Hello!

I’ve made some improvements to the initial Python script and uploaded it to Github. You can find it here:

There is BlackBeanControl.ini file which consists of General and Commands section. General section should contain:

  • IPAddress: IP address of the RM 3 mini device
  • Port: Port of the RM 3 mini device - usually 80
  • DummyCommand: Hex dump of the UDP payload that will be sent before every other command - it should be already learned IR command that is not used, for example, IR command from an old, unused remote control. RM 3 mini does not want to trigger commands if they are sent over UDP more then once consecutively, so, this command is used to bypass this problem

Commands section should contain list of command names (only letters, without blanks) followed by column and a hex dump of the actual command. For example:

TVVolumeUp: [HEX DUMP]
ACTempUp: [HEX DUMP]

A syntax for calling a script is:

BlackBeanControl -c [-i IP Address] [-p Port]

Command name parameter is the name of command already stored in an .ini file
IP Address and Port are optional parameters - used in case there is a need for sending UDP payload to a multiple RM 3 minis in the same network. If value is not assigned to these parameters, values from an .ini file will be used.

I’m not very friendly with java, so I’m not able to make this into regular OpenHAB binding - if that is possible at all. If someone is willing to do that, I’ll help as much as I can.

Best regards,
Davor

3 Likes

That’s fantastic!

How should we get the Hex dump of the command? Should we capture it with wireshark or similar or is there an easier way?

@Mario You have to capture it with Wireshark.

Hello!

Since I don’t have wireless card in my PC, I’ve used tPacketCapture application from playstore (it doesn’t require phone to have root access - I’m using it with stock Samsung ROM). It creates VPN connection and captures all traffic from and to cellphone. You just have to be on the same wireless network as RM 3, otherwise, it will communicate with RM 3 over Internet, instead of communicating directly (it’s easier to detect packages to local IP than random IP address). Besides that, you should start broadlink application first and start tPacketCapture afterwards. After you finish capturing packets, you should transfer them to PC and open it with wireshark. Then just filter traffic by protocol (UDP) and destination address (IP of the RM 3), and copy whole payload section (right click on payload in the upper half of the Wireshark) as hex stream. Than use that steam in BlackBeanControl.ini.

Best regards,
Davor

1 Like

Thank you Davor.

Very easy! I just captured some commands. Let’s open it on wireshark! :slight_smile:

I managed to directly use the OpenHAB TCP/UDP binding: a couple of configurations need to be adjusted. The UDP payload packets are written in a remote.map file. Each binary byte is preceded by \u00: for example byte C6 is written as \u00C6.
I tested it on windows 7 64bit: when trying on different platforms, the behavior of the UDP binding has to be checked: the binary digits above 7F may be truncated (I found these informations in some posts of this forum, concerning the serial binding
https://groups.google.com/forum/m/#!topic/openhab/bX-j9DKvR_A ).

The following steps are therefore necessary

  1. Install the TCP/UDP binding by copying the addon file in the approriate directory of your installation
  2. modify the following TCP/UDP binding in openhab.cfg
    udp:charset=ISO-8859-1
    (that’s the setting that avoids the truncation of bytes above 7F)
    udp:postamble=
    (leave blank: the binding won’t add \u000D\u000F(i.e. LF+CR) at the end of the packet
  3. define a switch item in your .item file as follows

Switch AC_Zona_Notte “Zona Notte” <air_conditioner> (Appliance) {
udp=">[ON:192.168.27.34:80:‘MAP(blackbean1.map)’],>[OFF:192.168.27.34:80:‘MAP(blackbean1.map)’]"}

(replace the Ip number with the one of your blackbean)

  1. create a file blackbean1.map in the configurations\transform directory with the following content

ON:\u00a5\u00c6…
OFF:\u00a5\u00c6…

Where after the colon you have to write the UDP payload that you have intercepted with wireshark. This is a bit annoying but it has to be done once. I use wireshark to copy the payload as a hex stream, then paste it to packet sender (in order to test if the packet works). By copying from packet sender I obtain a sequence of hex bytes separated by spaces(i.e. A5 00 B6 etc). By using the replace function of the windows text editor I replace spaces with \u00 and adjust manually the string. Finally I copy it to the map file. It should remain in one single line, otherwise only the bytes before the line break are sent by the UDP binding.

  1. add the switch item to your sitemap file
    Switch item=AC_Zona_Notte icon=“air_conditioner”

  2. restart openHAB. When pushing the button on the interface the corresponding UDP packet is sent.

Notes & limitations
a) for an air conditioner, the code for ON sends the whole configuration (temperature, fan speed, operating mode, etc). The code for OFF, even if it is operated by the same physical button, is different, therefore it needs to be intercepted. Rules need to implemented in order to properly operate the other remote buttons and I have not figured out, yet how to do that.
b) for my TV or my HiFi Amp, the code for ON & OFF is identical but the Mini only executes it once. You have therefore to intercept two times the ON/OFF packets with wireshark and create an entry in the map file for each intercepted code.
c) The ON/OFF remote button acts as a toggle: there is no way to know if the TV is on or off after the command is sent.

d) In order to debug the installation it is useful to have wireshark installed on the machine where openhab is installed, so that you can immediately figure out if the packet is correctly sent or not.

This is what I have found for now, I hope it will be useful for somebody else,
LionHe

3 Likes

Hello!

It’s a nice alternative, but, for my taste, it’s a bit complicated to hold all the codes in Items file. I’ve stared a more detailed analysis of UDP packets, and I will try to intercept communication between RM 3, their servers and Android application while learning new commands. This could lead to custom application for programming and storing codes in settings file for usage with Python script and OpenHAB exec binding. I will also try to split hex dump of the existing command inside the Python script, change the part that holds timestamp and counter, and then try sending it multiple times to RM 3. Theoretically, this could be the solution that will replace sending of dummy code before the real code.

Best regards,
Davor

1 Like

HI

The advantage of using OpenHAB only is that it is almost platform independent (with the exception of character encoding, but that’s a Java trouble): when I will migrate from windows to Raspberry, in principle I won’t need nothing different.
Actually codes are store in MAP files not in ITEMS file, but clearly your final goal is much more flexible than the pure OpenHAB.

I’m wondering weather the learning process actually requires the connection with the Broadlink servers: probably only for accessing the database of remote codes. I will try to see if the Mini is able to learn a code without Internet access.
EDIT: I’ve tried to isolate the Mini and the smartphone from the Internet. The result is that when learning an Air Conditioner it cannot use the pre-defined templates. In this case the user makes the mini learn the combinations he likes. I prefer this way to operate because I am sure of the commands being learnt, instead of relying on some cloud template that I have no direct way to test.

Hi,
Thanks for the research!
I wonder if you can help me - using your github project and your guide, i have recorded some traffic on my phone, and copied the information on wireshark.
However, when i’m trying to broadcast to the blackbean i get “126 destination unreachable”.
I’m using the same ip and port from the recorded data, and the device is responsive using these params.
I tested the differences between the the mobile device udp call and the one generated by your script (on wireshark) and saw that under QUIC->Public Flags-> CID there is some data for the call from the mobile device. That field is empty when using the script.

Any ideas?

Thanks!

You have to extract all the UDP payload: in principle the first part include the QUIC data. I tested it with packet sender for windows and then with both UDP binding and a Raspberry with python and it was accepted.
You have to send the packet to the local ip of the blackbean on port 80. If it gives “destination unreachable” there is something wrong with your network settings.
Best wishes
LionHe

Just an off-topic: how about you all also write to support@ibroadlink.com to open an API for the RM mini 3? I wrote them an email today and got back “I will put in your feedback to our tech-department later. They will assess further.”

Maybe if more people write in?

Hi, i need some help please with my black bean rm 3 mini… this are the packets i captured as davorf suggested few posts up:

69 8.430398 10.8.0.1 192.168.1.245 QUIC 178 Public Reset, CID: 24113000182295205

and this is the hex stream

001a11000002001a110000010800450000a450ae400040111cf50a080001c0a801f5a1290050009005555aa5aa555aa5aa55000000000000000000000000000000000000000000000000bcec000037276a0088835d28e40d43b401000000f0c600000bfdaad200a1e1a1ab38d9f35a49b354b8bd5a2903625de48c770a583bcbbf8a840e5253f0233b67f8497e1b3f2e781856665429430ccfd855500b43bc1d194158ef35dba23932896682d6d4fa4933bb

i tried to use packet sender to send via udp on port 80 but no luck… if anyone can suggest anything please do.

Thanks

I recall a couple of things that initially caught me when getting mine working:

  1. Not sending as hex. I had to open my packet scrape on a Windows machine to convert it to hex (couldn’t find a good converter on Android).
  2. Sending via internet. From memory if I wasn’t on the same Wi-Fi as the device, it sent via their cloud service.
1 Like

You have to send only the payload part of the intercepted packet, not the entire content. The wireshark application for windows easily highlights the payload.

Hi Lionello, i tried to send only the payload, no luck, this was the payload :

55000000000000000000000000000000000000000000000000bcec000037276a0088835d28e40d43b401000000f0c600000bfdaad200a1e1a1ab38d9f35a49b354b8bd5a2903625de48c770a583bcbbf8a840e5253f0233b67f8497e1b3f2e781856665429430ccfd855500b43bc1d194158ef35dba23932896682d6d4fa4933bb

I could send you a .pcap file if you wish to take a look.

Thanks

You have to send the payload of the UDP packet, not the QUIC one. By looking at the wireshark window I realize that the only place where you can find the “payload” string is inside the QUIC part, and this is confusing.
You have to select the QUIC line, and all the bytes that you need to send will appear: I guess they will start from 5a a5 … (at least my packets start with these numbers).

for me capturing the codes is not very clear…

1 pushed 3 buttons on the app.
1: 3 times
2: 4 times
3: 2 times
and got this:

5aa5aa555aa5aa5500000000000000000000000000000000000000000000000024f2000037276a005e80cf1ee40d43b40100000073c60000e19a157bb2ebf75adff415f7f8764f2c2f3066aad6ddae8f78ab58c5350fc389a62e7838eda0be1d6226b12879d4941d39f918fff2d012d63283ca6c194d4f826951e659babcebce2a212a4ce54bef6c
5aa5aa555aa5aa5500000000000000000000000000000000000000000000000017f2000037276a004e83cf1ee40d43b40100000073c60000e19a157bb2ebf75adff415f7f8764f2c2f3066aad6ddae8f78ab58c5350fc389a62e7838eda0be1d6226b12879d4941d39f918fff2d012d63283ca6c194d4f826951e659babcebce2a212a4ce54bef6c
5aa5aa555aa5aa55000000000000000000000000000000000000000000000000e8f1000037276a002280cf1ee40d43b40100000073c60000e19a157bb2ebf75adff415f7f8764f2c2f3066aad6ddae8f78ab58c5350fc389a62e7838eda0be1d6226b12879d4941d39f918fff2d012d63283ca6c194d4f826951e659babcebce2a212a4ce54bef6c
5aa5aa555aa5aa55000000000000000000000000000000000000000000000000d5f4000037276a000480cf1ee40d43b40100000074c6000054d411c45ce1b0c972dd0116fea3bcda6885ba57b5128cb5b87b946529c240b59b8bed235aef386f074cec4331af96da9650c2378197ef947dda6361c843d7fa30fca49fa58192dc08e7d0d9b59c9a7d
5aa5aa555aa5aa5500000000000000000000000000000000000000000000000030f5000037276a005e81cf1ee40d43b40100000074c6000054d411c45ce1b0c972dd0116fea3bcda6885ba57b5128cb5b87b946529c240b59b8bed235aef386f074cec4331af96da9650c2378197ef947dda6361c843d7fa30fca49fa58192dc08e7d0d9b59c9a7d
5aa5aa555aa5aa5500000000000000000000000000000000000000000000000091f5000037276a00be82cf1ee40d43b40100000074c6000054d411c45ce1b0c972dd0116fea3bcda6885ba57b5128cb5b87b946529c240b59b8bed235aef386f074cec4331af96da9650c2378197ef947dda6361c843d7fa30fca49fa58192dc08e7d0d9b59c9a7d
5aa5aa555aa5aa55000000000000000000000000000000000000000000000000daf4000037276a000782cf1ee40d43b40100000074c6000054d411c45ce1b0c972dd0116fea3bcda6885ba57b5128cb5b87b946529c240b59b8bed235aef386f074cec4331af96da9650c2378197ef947dda6361c843d7fa30fca49fa58192dc08e7d0d9b59c9a7d
5aa5aa555aa5aa55000000000000000000000000000000000000000000000000cef0000037276a001d82cf1ee40d43b40100000075c6000054d411c45ce1b0c972dd0116fea3bcdac50cb755c49c95e02ea6d5810df7c3b976ef0f736e88279f0fd810713b35583d505a7e6ce5aa4e5a2c26ebbdddb69d09b063aa138f5ff9bf7537cd36d04b9b16
5aa5aa555aa5aa5500000000000000000000000000000000000000000000000051f1000037276a009f83cf1ee40d43b40100000075c6000054d411c45ce1b0c972dd0116fea3bcdac50cb755c49c95e02ea6d5810df7c3b976ef0f736e88279f0fd810713b35583d505a7e6ce5aa4e5a2c26ebbdddb69d09b063aa138f5ff9bf7537cd36d04b9b16

is this correct?
what is the max length? and how must I use this stings? (convert?)

Hello all!

I’m sorry I wasn’t able to participate here, but it was rather busy few months, and I really had no time for the side projects. @Lionello_Marrelli and @benhelps, thank you for stepping in and helping other users. I hope the other issues but the last are resolved. Regarding the last question, your payload looks OK, just copy the whole string for each command (only once) and put it in the configuration file, name it (without blanks), and then call the application with that command as parameter. It should do the trick. I hope in the next month or so I will be able to get back to this and try to make an app that will make learning and programming codes much easier.

Best regards,
Davor

@remb0. Sorry for not answering earlier. The sequences look right. If you use “packet sender” for windows you have to copy one sequence in the “hex” window and then sendo to the ip address of the mini (using udp)

Hello!

I finally had some free time to get back to this, so, before I start with a learning commands part of the app, I wanted to clean the mess and confusion Dummy command did. I’ve managed to isolate the parts which should be different every time, and replace them with randomly generated hex code. There are two parts of the learned command, two bytes long each. Long story short - I’ve removed DummyCommand from the Settings.py and the .ini file, and there is no need to send two commands each time, anymore. I’ve uploaded changes to the github repository. If you encounter any problems, you can open an issue on github, or write about it here. The next step should be a part which would make learning IR commands directly from a command line into an .ini file possible.

Best regards,
Davor

1 Like