Kaisaron
(Cesare Giuliani)
April 20, 2026, 6:08pm
1
Hi,
today I started trying to control a few IR devices through the RM4 Mini using OpenHab binding. This is what happened:
the iOS app controlling the RM4 works perfectly with all the devices I have added (1 AC unit, 1 amplifier, 1 DVD player, 1 DAC, 1 LG OLED TV).
when moving to OpenHab however, the Binding documentation isn’t clear about how to learn more than 1 command or more devices and their related IR codes. It says I have to set the name of the IR code to be acquired by the RM4. However, even if I do change the name in the channel field, it doesn’t change and stays as DEVICE_ON no matter what.
To bypass the IR code learning from the OpenHab interface, I decided to manually read all the IR codes using a docker application called Broadlink Manager, and adding them into the .json file mentioned in the Binding guide after that. I tried acquiring the same remote control button on both Broadlink Manager and OpenHab. However the two resulting IR codes, (once converted the one obtained from Broadlink Manger from Base64 to Hex) they don’t match. And if I try sending out those codes via Broadlink Manger they both don’t work and the appliance I am using as test, doesn’t turn on.
I’d like to register 6-7 commands for each device and then use a stream deck from Elgato to control an item/rule associated with each IR code to trigger specific remote control functions such as setting up the output volume of my DAC, turning on and off the AC unit and so on.
Any clues on what I am doing wrong? I have the idea that I am misunderstanding some specific element into the workings of this IR transmitter and the related OpenHab Binding.
Suggestions?
Sorry for my English, as usual
Thank you all in advance for your help and support!
clark
(carlos kantt)
April 20, 2026, 6:49pm
2
Hi
I don’t follow your point 3. You learned the codes via Broadlink manager and then you created the json file. After that you should be able to send the IR commands via Openhab, no need to use Broadlink Manager any more. I did the same thing, learn via Broadlink Manager and then importing the codes in openhab, with RF codes using the RM4 pro and had no issues.
Kaisaron
(Cesare Giuliani)
April 21, 2026, 9:01am
3
Sorry I wasn’t able to explain myself correctly. I tried using Broadlink Manager. My first attempt was to read the Power on/off signal for my AC unit. The BM reads a long base64 string. But if I send that string to the RM4 mini the AC doesn’t turn on. Or off. Then I tried using the learning procedure in OH. I opened the .json file and copied the IR string. Converted that into base64 inside BM and tried sending out that code. Nothing happens as well. It says command sent, but no response from AC unit. Since I didn’t know why both methods didn’t work while the iOS app was able to control the AC unit correctly through the RM4 mini, I tried comparing the hex version of the two IR strings, the one acquired by OH and the one acquired by BM. They are not the same. So how can I set up a .json file if I am not even sure these apps are reading the correct IR codes?
clark
(carlos kantt)
April 21, 2026, 2:22pm
4
So if I understand correctly you cannot get BM to work
Then I tried using the learning procedure in OH.
If you were successful in learning the IR code in OH, did you test it to see if it works?
You have to send a command like this
Where Command is the name of the learned IR code. I use blockly to create my rules.
Did you try this?
Kaisaron
(Cesare Giuliani)
April 24, 2026, 5:09pm
5
Sorry Clark I made a big mistake.
All IR devices I wanted to control are in fact functioning and I can acquire the codes in BM and then translate the strings to hex and add them to the .json file. I have created the switches and associated rules on OH and everything works. I can trigger the items using my stream deck as I intended.
I made a mistake however, trying to make the Daikin unit to work. The AC has a complex IR command structure. Whenever you send a command (for example temperature +1 degree) it sends an entire IR string, very long, containing all other informations such as AC mode, fan speed, swing and other parameters such as timers and other things + the updated temperature value. That’s why I couldn’t make it work as I wanted to. And the Acquired IR string seemed wrong or inconsistent when acquired using BM.
I should find a way to buiild on the fly the IR string based on the commands I wanna send, the same way I did with my BTicino MyHome IR3456 in OpenHab.
Thanks for your help Clark
ubeaut
(Greg)
April 24, 2026, 11:29pm
6
I use this:
MQTT client to control BroadLink devices
It send commands like this:
cat channeldown
2600ee004e13281314131413141328131413141328131512141314131400035f4e14271314131413141427131413141427131413141415121300035f5012271314141512151227141314131427141314151214131400035f4e1327141413141314132912151214132714131414131611140002f608605111281314131413141328131413141328131512161116111400035f4e14281214131612131427131413141427131413141415121300016c060001ed4e14291114141314131427141512141327141512151215121400035e4f132912131415121512271415121413291215121512161116000c4f0700027406000d05
I have a rule that reads the stored file and then send to the broadlink.
// === Configuration ===
const TOPIC = "cmnd/tasmotaIR/IRsend";
const FILELOC = "/usr/local/sbin/broadlink-mqtt/commands/mirabella/tv/sony/";
const TIMEOUT = time.Duration.ofSeconds(5);
// === Get filename from triggering item ===
const fileName = event.receivedState?.toString();
// Safety check
if (!fileName || fileName === "NULL" || fileName === "CRAP") {
console.log("IR rule: Invalid or ignored state:", fileName);
return;
}
try {
// Read file contents (IR payload)
const payload = actions.Exec.executeCommandLine(
TIMEOUT,
"/usr/bin/cat",
FILELOC + fileName
).trim();
if (!payload) {
console.log("IR rule: Empty payload for file:", fileName);
return;
}
// Publish to MQTT
actions.get("mqtt", "mqtt:broker:mqttbroker")
.publishMQTT(TOPIC, payload, false);
console.log(`IR rule: Sent ${fileName} to ${TOPIC}`);
} catch (err) {
console.error("IR rule error:", err);
}
// Reset item so restart doesn't resend command
items.getItem(event.itemName).postUpdate("CRAP");
I have a remote widget that sens the tv channel etc.
uid: Remote Sony TV
tags: []
props:
parameters:
- context: item
description: The item to send the command to
label: Item
name: item
required: false
type: TEXT
- description: Type label to display on top of the remote (TV, Sat, Amp etc.)
label: Device Type
name: devicetype
required: false
type: TEXT
timestamp: Jul 3, 2021, 4:04:34 PM
component: f7-card
config:
style:
box-shadow: 2px 3px rgb(150,150,150)
background-color: rgb(192, 192, 192)
--f7-card-margin-horizontal: 0px
border-radius: 30px
width: 15rem
height: 46rem
slots:
default:
- component: oh-button
config:
bgColor: black
style:
position: absolute
left: 20px
top: 20px
width: 60px
height: 40px
border-radius: 12px
display: flex
iconF7: power
iconSize: 25
action: command
actionCommand: power
actionItem: =props.item
- component: oh-link
config:
color: black
style:
font-size: 25px
position: absolute
left: 90px
top: 20px
width: 60px
height: 40px
display: flex
text: '=(props.devicetype) ? props.devicetype : "TV"'
- component: oh-button
config:
bgColor: black
style:
position: absolute
left: 160px
top: 20px
width: 60px
height: 40px
border-radius: 12px
display: flex
iconF7: speaker_slash
iconSize: 25
action: command
actionCommand: volumemute
actionItem: =props.item
- component: oh-button
config:
color: white
bgColor: black
style:
position: absolute
left: 20px
top: 80px
width: 60px
height: 40px
border-radius: 12px
display: flex
text: 1
action: command
actionCommand: one
actionItem: =props.item
- component: oh-button
config:
color: white
bgColor: black
style:
position: absolute
left: 90px
top: 80px
width: 60px
height: 40px
border-radius: 12px
display: flex
text: 2
action: command
actionCommand: two
actionItem: =props.item
- component: oh-button
config:
color: white
bgColor: black
style:
position: absolute
left: 160px
top: 80px
width: 60px
height: 40px
border-radius: 12px
display: flex
text: 3
action: command
actionCommand: three
actionItem: =props.item
- component: oh-button
config:
color: white
bgColor: black
style:
position: absolute
left: 20px
top: 130px
width: 60px
height: 40px
border-radius: 12px
display: flex
text: 4
action: command
actionCommand: four
actionItem: =props.item
- component: oh-button
config:
color: white
bgColor: black
style:
position: absolute
left: 90px
top: 130px
width: 60px
height: 40px
border-radius: 12px
display: flex
text: 5
action: command
actionCommand: five
actionItem: =props.item
- component: oh-button
config:
color: white
bgColor: black
style:
position: absolute
left: 160px
top: 130px
width: 60px
height: 40px
border-radius: 12px
display: flex
text: 6
action: command
actionCommand: six
actionItem: =props.item
- component: oh-button
config:
color: white
bgColor: black
style:
position: absolute
left: 20px
top: 180px
width: 60px
height: 40px
border-radius: 12px
display: flex
text: 7
action: command
actionCommand: seven
actionItem: =props.item
- component: oh-button
config:
color: white
bgColor: black
style:
position: absolute
left: 90px
top: 180px
width: 60px
height: 40px
border-radius: 12px
display: flex
text: 8
action: command
actionCommand: eight
actionItem: =props.item
- component: oh-button
config:
color: white
bgColor: black
style:
position: absolute
left: 160px
top: 180px
width: 60px
height: 40px
border-radius: 12px
display: flex
text: 9
action: command
actionCommand: nine
actionItem: =props.item
- component: oh-button
config:
color: white
bgColor: black
style:
position: absolute
left: 20px
top: 230px
width: 60px
height: 40px
border-radius: 12px
display: flex
color: white
iconF7: house
iconSize: 25
action: command
actionCommand: home
actionItem: =props.item
- component: oh-button
config:
color: white
bgColor: black
style:
position: absolute
left: 90px
top: 230px
width: 60px
height: 40px
border-radius: 12px
display: flex
text: "0"
action: command
actionCommand: zero
actionItem: =props.item
- component: oh-button
config:
color: white
bgColor: black
style:
position: absolute
left: 160px
top: 230px
width: 60px
height: 40px
border-radius: 12px
display: flex
color: white
iconF7: arrow_uturn_left
iconSize: 25
action: command
actionCommand: return
actionItem: =props.item
- component: f7-badge
config:
bgColor: black
style:
position: absolute
left: 40px
top: 290px
width: 160px
height: 160px
transform: rotate(45deg)
border-radius: 30%
z-index: 1
- component: oh-button
config:
color: white
bgColor: black
style:
font-size: 25px
position: absolute
left: 80px
top: 330px
width: 80px
height: 80px
border-radius: 50%
border: gray solid 1px
display: flex
z-index: 2
text: OK
action: command
actionCommand: ok
actionItem: =props.item
- component: oh-button
config:
color: black
bgColor: black
style:
position: absolute
left: 20px
top: 285px
width: 50px
height: 40px
border-radius: 20%
z-index: 1
transform: skew(-45deg)
action: command
actionCommand: volumeup
actionItem: =props.item
- component: oh-link
config:
color: white
style:
position: absolute
left: 35px
top: 290px
display: flex
z-index: 2
iconF7: speaker_3
iconSize: 25
action: command
actionCommand: volumeup
actionItem: =props.item
- component: oh-button
config:
color: white
bgColor: black
style:
position: absolute
left: 100px
top: 285px
width: 40px
height: 40px
display: flex
z-index: 2
iconF7: arrowtriangle_up
iconSize: 35
action: command
actionCommand: up
actionItem: =props.item
- component: oh-button
config:
color: black
bgColor: black
style:
position: absolute
left: 170px
top: 285px
width: 50px
height: 40px
border-radius: 20%
z-index: 1
transform: skew(45deg)
action: command
actionCommand: channelup
actionItem: =props.item
- component: oh-link
config:
color: white
style:
font-size: 20px
position: absolute
left: 180px
top: 290px
display: flex
z-index: 2
text: CH+
action: command
actionCommand: channelup
actionItem: =props.item
- component: oh-button
config:
color: white
bgColor: black
style:
position: absolute
left: 35px
top: 350px
width: 40px
height: 40px
display: flex
z-index: 2
iconF7: arrowtriangle_left
iconSize: 35
action: command
actionCommand: left
actionItem: =props.item
- component: oh-button
config:
color: white
bgColor: black
style:
position: absolute
left: 165px
top: 350px
width: 40px
height: 40px
display: flex
z-index: 2
iconF7: arrowtriangle_right
iconSize: 35
action: command
actionCommand: right
actionItem: =props.item
- component: oh-button
config:
color: black
bgColor: black
style:
position: absolute
left: 20px
top: 415px
width: 50px
height: 40px
border-radius: 20%
z-index: 1
transform: skew(45deg)
action: command
actionCommand: volumedown
actionItem: =props.item
- component: oh-link
config:
color: white
style:
position: absolute
left: 35px
top: 425px
display: flex
z-index: 2
iconF7: speaker_1
iconSize: 25
action: command
actionCommand: volumedown
actionItem: =props.item
- component: oh-button
config:
color: white
bgColor: black
style:
position: absolute
left: 100px
top: 415px
width: 40px
height: 40px
display: flex
z-index: 2
iconF7: arrowtriangle_down
iconSize: 35
action: command
actionCommand: down
actionItem: =props.item
- component: oh-button
config:
color: black
bgColor: black
style:
position: absolute
left: 170px
top: 415px
width: 50px
height: 40px
border-radius: 20%
z-index: 1
transform: skew(-45deg)
action: command
actionCommand: channeldown
actionItem: =props.item
- component: oh-link
config:
color: white
style:
font-size: 20px
position: absolute
left: 178px
top: 420px
display: flex
z-index: 2
text: CH-
action: command
actionCommand: channeldown
actionItem: =props.item
- component: f7-badge
config:
bgColor: gray
style:
position: absolute
left: 15px
top: 465px
width: 70px
height: 100px
border: gray solid 1px
z-index: 0
- component: oh-button
config:
color: black
bgColor: black
style:
position: absolute
left: 20px
top: 415px
width: 50px
height: 40px
border-radius: 20%
z-index: 1
transform: skew(45deg)
action: command
actionCommand: volumedown
actionItem: =props.item
- component: oh-link
config:
color: white
style:
position: absolute
left: 35px
top: 425px
display: flex
z-index: 2
iconF7: speaker_1
iconSize: 25
action: command
actionCommand: volumedown
actionItem: =props.item
- component: oh-button
config:
color: white
bgColor: black
style:
position: absolute
left: 20px
top: 470px
width: 60px
height: 40px
border-radius: 12px
display: flex
z-index: 1
text: Subtitle
iconSize: 30
action: command
actionCommand: subtitle
actionItem: =props.item
- component: oh-button
config:
color: white
bgColor: black
style:
position: absolute
left: 20px
top: 520px
width: 60px
height: 40px
border-radius: 12px
display: flex
z-index: 1
text: Source
iconSize: 30
action: command
actionCommand: source
actionItem: =props.item
- component: oh-button
config:
color: white
bgColor: black
style:
position: absolute
left: 90px
top: 470px
width: 60px
height: 40px
border-radius: 12px
display: flex
text: EPG
action: command
actionCommand: guide
actionItem: =props.item
- component: oh-button
config:
color: white
bgColor: black
style:
position: absolute
left: 90px
top: 520px
width: 60px
height: 40px
border-radius: 12px
display: flex
text: Info
action: command
actionCommand: info
actionItem: =props.item
- component: f7-badge
config:
bgColor: gray
style:
position: absolute
left: 155px
top: 465px
width: 70px
height: 100px
border: gray solid 1px
z-index: 0
- component: oh-button
config:
color: white
bgColor: black
style:
position: absolute
left: 160px
top: 470px
width: 60px
height: 40px
border-radius: 12px
display: flex
iconF7: arrow_2_circlepath
iconSize: 25
action: command
actionCommand: recall
actionItem: =props.item
- component: oh-button
config:
color: white
bgColor: black
style:
position: absolute
left: 160px
top: 520px
width: 60px
height: 40px
border-radius: 12px
display: flex
z-index: 1
text: Option
action: command
actionCommand: options
actionItem: =props.item
- component: oh-button
config:
color: white
bgColor: black
style:
position: absolute
left: 25px
top: 570px
width: 40px
height: 40px
border-radius: 12px
display: flex
color: red
iconF7: circle_fill
iconSize: 25
action: command
actionCommand: red
actionItem: =props.item
- component: oh-button
config:
color: white
bgColor: black
style:
position: absolute
left: 75px
top: 570px
width: 40px
height: 40px
border-radius: 12px
display: flex
color: green
iconF7: circle_fill
iconSize: 25
action: command
actionCommand: green
actionItem: =props.item
- component: oh-button
config:
color: white
bgColor: black
style:
position: absolute
left: 125px
top: 570px
width: 40px
height: 40px
border-radius: 12px
display: flex
color: yellow
iconF7: circle_fill
iconSize: 25
action: command
actionCommand: yellow
actionItem: =props.item
- component: oh-button
config:
color: white
bgColor: black
style:
position: absolute
left: 175px
top: 570px
width: 40px
height: 40px
border-radius: 12px
display: flex
color: blue
iconF7: circle_fill
iconSize: 25
action: command
actionCommand: blue
actionItem: =props.item
- component: f7-badge
config:
bgColor: gray
style:
position: absolute
left: 20px
top: 615px
width: 200px
height: 100px
border: gray solid 1px
z-index: 0
- component: oh-button
config:
color: white
bgColor: black
style:
position: absolute
left: 25px
top: 620px
width: 40px
height: 40px
border-radius: 12px
display: flex
color: white
z-index: 1
iconF7: backward
iconSize: 25
action: command
actionCommand: rewind
actionItem: =props.item
- component: oh-button
config:
color: white
bgColor: black
style:
position: absolute
left: 75px
top: 620px
width: 40px
height: 40px
border-radius: 12px
display: flex
color: white
z-index: 1
iconF7: play_fill
iconSize: 25
action: command
actionCommand: play
actionItem: =props.item
- component: oh-button
config:
color: white
bgColor: black
style:
position: absolute
left: 125px
top: 620px
width: 40px
height: 40px
border-radius: 12px
display: flex
color: white
z-index: 1
iconF7: pause
iconSize: 25
action: command
actionCommand: pause
actionItem: =props.item
- component: oh-button
config:
color: white
bgColor: black
style:
position: absolute
left: 175px
top: 620px
width: 40px
height: 40px
border-radius: 12px
display: flex
color: white
z-index: 1
iconF7: forward
iconSize: 25
action: command
actionCommand: forward
actionItem: =props.item
- component: oh-button
config:
color: white
bgColor: black
style:
position: absolute
left: 25px
top: 670px
width: 40px
height: 40px
border-radius: 12px
display: flex
color: white
z-index: 1
iconF7: backward_end_alt
iconSize: 25
action: command
actionCommand: previous
actionItem: =props.item
- component: oh-button
config:
color: white
bgColor: black
style:
position: absolute
left: 75px
top: 670px
width: 40px
height: 40px
border-radius: 12px
display: flex
color: white
z-index: 1
iconF7: stop_fill
iconSize: 25
action: command
actionCommand: stop
actionItem: =props.item
- component: oh-button
config:
color: white
bgColor: black
style:
position: absolute
left: 125px
top: 670px
width: 40px
height: 40px
border-radius: 12px
display: flex
color: red
z-index: 1
iconF7: circle_fill
iconSize: 20
action: command
actionCommand: record
actionItem: =props.item
- component: oh-button
config:
color: white
bgColor: black
style:
position: absolute
left: 175px
top: 670px
width: 40px
height: 40px
border-radius: 12px
display: flex
color: white
z-index: 1
iconF7: forward_end_alt
iconSize: 25
action: command
actionCommand: next
actionItem: =props.item
There is probably better ways of doing it but it works and I have the one broadlink also controls the heater in the same room as the TV and I have another remote widget for that and also on a floor plan.
Basically I don’t use a binding.