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

Hi @benhelps

In order to follow this path to integrate the mini on openHAB you will need to get your packets going to your device.

Wireshark needs to run on a Linux machine if you want to see all the traffic, not only the one directed to or originated by the Windows laptop.
I actually installed Wireshark for root on the android phone where the broadlink app was installed. I was using a galaxy nexus with a custom Rom with root access. Captured packets were stored in a file that I analyzed on the Windows version of wireshark.

In principle yes, but it is not as straightforward as it seems (at least for me) because the udp packet payload is a relatively long sequence of binary data (a few hundreds of bytes), while the udp binding is designed to send strings.

Once this first problem is solved, the second one is that every command is composed by two udp packets. Therefore some items and rules need to be developed in order for this to work, because AFAIK the tcp/udp binding sends only one packet per command.

The python way is easier but need to be integrated with the exec binding.
Good luck
LionHe

Fair enough, I’ll go grab a linux laptop to try with. Never bothered rooting my phone since the old zte 7" one - can do without the risk of bricking it (esp since this Oppo came from now defunct Dick Smith store). Could the rule to trigger the RM do 2 sendCommand calls for the 2 udp, or would they be too separated that way?

The tcp binding is designed for ASCII traffic, therefore it adds lf + cr at the end of the packets, according to the wiki.
I’m going to use packetsender for windows (It is freeware). I used it to test the packets. It includes the possibility to send through the command line the same packets that have been previously saved in the gui. This seems to me the easiest solution.

@benhelps if the dns320 is based on Linux it may be that you can find a similar packet sending functionality

The separation does not matter. The point is that consecutive packets need to be different, otherwise the mini won’t issue the ir command a second time.

The unlocking of the dns320 hints that it uses Linux under the bonnet, but it doesn’t have build tools or a package manager(or graphical output or a ui for that matter). No surprise given its just a NAS.

So you couldn’t define ON, OFF, and OTHER packets in the mapping file, then have consecutive lines like

sendCommand(thing, OTHER)
sendCommand(thing, ON)

? I’m new to openHAB so I may be totally off base

Yes, you are right, one command per udp packet can be defined. The problem of the lf+cr characters being added at the end of the payload remains, though, even if a solution for properly inserting the packets in openhab is found.
I think that some change in the binding would be required (which is way beyond my capabilities).

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