Hello,
I created a Remote Control Widget that I use with OH3 to control my TV and Satellite receiver via the
Broadlink Binding
I don’t know if it can be also used in other scenarios, but I thought I’ll share it anyways
So to use the widget, you need to have an item that receives the commands and you need to set the commands to send with the buttons. You can also set a label that will be displayed on top of the remote, e.g. TV, Sat, Amp etc.
In my scenario, I have all codes in a .map file, so the screenshot just shows the key to the codes in the .map file, like “TV_PHILIPS_POWER”
Thanks to @d0t and @Christopher_Hemmings , who shared the code of their remotes. This helped me to understand how to create a remote control widget!
edit:
I created a variant with slightly different layout and some extra buttons. See UniversalRemote2.txt
edit2:
Added some more remotes, specific for my equipment. But maybe they can serve as template for someone.
Here is the .yaml of the widget:
UniversalRemote.txt (21.6 KB)
UniversalRemote2.txt (22.3 KB)
PhilipsTvRemote.txt (19.8 KB)
DenonAmpRemote.txt (29.6 KB)
NubertSubwooferRemote.txt (4.2 KB)
11 Likes
e36Alex
(Alexander)
May 30, 2021, 11:32am
2
Thanks for sharing this remote! Good work!
I think, i will try to adapt it soon to my LG TV with WebOS. If someone already did it before, it would also be great if it could be shared.
That is one extremely cool looking widget!
Awesome job!!!
Max_G
(Max G)
June 12, 2021, 11:07pm
4
Really looks nice.
I wonder what creates these text files?
Is this hand-coded?
Or is there a tool creating these files? Which one?
I use only the widget editor in OH3. Don’t know if there are other tools.
Hello. thank you for the remote control.I have a question! I installed your widget and configured the broadlink remote.when I send commands through the widget the LED on the remote flashes 5 times.The widget sends the command 5 times.This is not convenient.how to make the widget send a command 1 time
Hello, I just checked that my broadlink flashes only once when I press a button on the widget.
There is no special logic in the widget that sends the command multiple times. It just sends what you have configured for the button.
Dan
(Dan Demento)
June 26, 2021, 4:00pm
8
thank you for this wonderful widget…
I don’t use it but it gave me a ton of information what one is able to achive with layout-options on yaml… I will use it as a reference for building own widget stuff…
I wasn’t aware of the ability to use all this css stuff - nice!
really great! love it
1 Like
ubeaut
(Greg)
July 4, 2021, 1:08am
9
Great remote widget.
I changed it and added more buttons and also removed the props for the button commands as I only wanted to use it for my TV.
I have a broadlink RM4 clone and I created an item and a rule to control the TV.
I made the rule to use the same name as the actionCommand to be the name of the remote control command.
I also installed this software to run the broadlink to MQTT
EXAMPLE:
To record the command source
mosquitto_pub -h 192.168.0.164 -t broadlink/tv/sony/source -m “record”
to run the command source:
mosquitto_pub -h 192.168.0.164 -t broadlink/tv/sony/source -m “replay”
The source button on the remote has the actionCommand source
Here is the rule:
//need below to log to openhab.log file
var logger = Java.type('org.slf4j.LoggerFactory').getLogger('org.openhab.rule.' + ctx.ruleUID);
//below is if you are going to use the ececute command
var Exec = Java.type("org.openhab.core.model.script.actions.Exec");
//below is also needed for the execute command
var Duration = Java.type("java.time.Duration");
//var HttpUtil = Java.type("org.openhab.core.io.net.http.HttpUtil");
//var HttpGet = Java.type("org.openhab.core.model.script.actions.HTTP");
var TOPIC = "broadlink/tv/sony/"
var stateof = event.itemState.toString() ;
//logger.info("results = " + stateof);
result = Exec.executeCommandLine(Duration.ofSeconds(5), "/usr/bin/mosquitto_pub","\-h","192.168.0.164","\-t","" + TOPIC + stateof,"\-m","replay");
logger.info('The script ran the command ' + TOPIC + stateof);
Here is the widget code:
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
Thanks to the person who created this remote is so handy.
1 Like
faximan
(Jan Elsner)
July 9, 2021, 11:37am
11
But you dont´neeed this external tool - the new Broadlink binding wich is short for release can do all the Magic now…
I added some more remotes in the first post. They are specific to my equipment, but might serve as templates for someone.
2 Likes
andan
(Andreas)
July 27, 2021, 7:45pm
14
Thank you for sharing your templates from which I’ve built my own variant.
I’m now trying to display the widget standalone as a single page or popup so that it is nicely displayed and centered on the screen. I’ve tried to put it within a column of a page with various center styles options, but so far without success. Do you have any clue on how to achive this?
Create a layout page with a block, one row and 3 columns and put the widget in the middle column.
This works at least on my Desktop PC. Don’t know how it looks on smartphone screens or tablets.
config:
label: Test
sidebar: true
blocks:
- component: oh-block
config: {}
slots:
default:
- component: oh-grid-row
config: {}
slots:
default:
- component: oh-grid-col
config: {}
slots:
default: []
- component: oh-grid-col
config: {}
slots:
default:
- component: widget:UniversalRemote2
config: {}
- component: oh-grid-col
config: {}
slots:
default: []
masonry: null
andan
(Andreas)
July 31, 2021, 1:40pm
16
Thank you for this hint. However, this seems not to work well for smartphone screens.
Instead, I’ve found a solution for the widget where the card component is wrapped inside a row with proper styling
component: f7-row
config:
style:
display: flex
justify-content: space-around
flex-wrap: wrap
slots:
default:
- component: f7-card
config:
style:...
This ensures that the remote control widget is displayed horizontally centered within the page when added to a single column that spans the whole page.
pavkamlc
(Pavel Mlcoch)
April 20, 2022, 10:03am
17
I have problem with installation from marketplace on OH3.2.0-1. In log I get this error:
2022-04-20 12:00:58.217 [ERROR] [munity.CommunityUIWidgetAddonHandler] - Widget from marketplace is invalid: Couldn't find the widget in the add-on entry
DaveG
(Dave Grimm)
December 4, 2022, 11:34pm
18
I really like your remote widget and want to try to adapt it to my LG tv. I created some widgets that will turn on the tv etc, but I can’t figure out what type of command string your widget uses. You state that you put the key codes for items like TV_PHILIPS_POWER into a .mapfile, but I haven’t figured out what the command string would be. Could you post a few of your command strings from your map file?
The .map file is used by the broadlink-binding, which I use to send the IR commands.
See Map - Transformation Services | openHAB
My .map file contains entries like:
TV_PHILIPS_POWER=26002C005B1C101C100D100E101C1E0E0F0E100D100D100E100D100D100E0F0E100D100D100E1E0E101B100E10000D05000000000000000000000000
TV_PHILIPS_VOL_UP=26002A00591E0D1F0D100E0F2C2E0E0F0E0F0E100D100E0F0E100D100E0F0E0F0E101C1E0E100D100E0F0E000D050000000000000000000000000000
TV_PHILIPS_VOL_DOWN=26003000591E0D1F0D100E0F0E1E1C100E0F0E100D100E0F0E0F0E100D100E0F0E100D101C1E0E100D101C000AA2074D08000D050000000000000000
DaveG
(Dave Grimm)
December 7, 2022, 4:29pm
20
Thank you for your quick response. I hadn’t read the documentation on the Broadlink binding since I was using the lgwebos binding. I was thinking I was going to send an item channel command and had spent several hours trying to hack my way through. Your .map file examples helped me move on. However, the universal remote widget sends item channel commands, so I’m looking at the two remote widgets to understand how they function differently. I’m new to the widget development language, so it will take me a while to get up to speed.
Thanks again.