OpenHAB Widget creation
Please read Liability Disclaimer and License Agreement CAREFULLY
In this article we will learn how to create an OpenHAB Widget to display and control information's from OpenHAB Things.
In the example below, I will create a Widget that will control the TV, windows blind from living room and a LED strip.
The goal is to get a Widget that looks like the one in the below image.
For this to work I will need to know the TV Item Channel that is responsible for controlling the TV Apps, I will do this by going into Settings, Things and select Channels in the
TV Thing, here I can see the Application channel that I need to use.
To be able to activate and deactivate the whole thing I need to create a switch Item
Now we navigate to Developer Tools, then select Widgets and click the + button to create a new Widget
Add the code found below "Widget YAML file" (see below) in the code window then press Set Props.
The the window that is open we need to fill the required fields for the widget to work, in this case a Title for the widget, the location of the On state background image, the location of the OFF state background image, the item responsible for turning on and off the Widget and the TV applications Item.
Widget YAML file
uid: Movie
version: 1.3.0
tags:
- TV
- NetFlix
- Plex
- YouTube
props:
parameters:
- description: Scene title
label: Scene title
name: Title
required: true
type: TEXT
- description: "example: /static/cards/scene-movie.jpg"
label: Path of background image for ON state
name: itemPathOn
required: true
type: TEXT
- description: "example: /static/cards/scene-movie.jpg"
label: Path of background image for OFF state
name: itemPathOff
required: true
type: TEXT
- context: item
description: Select the item to swith On/Off
label: Select the item to swith On/Off
name: sceneItem
required: true
type: TEXT
- context: item
description: Select TV Application topic
label: Select TV Application topic
name: appItem
required: true
type: TEXT
timestamp: May 10, 2022, 6:48:49 PM
component: f7-card
config:
noBorder: false
noShadow: false
outline: false
padding: true
style:
--f7-card-border-radius: 12px
--f7-card-box-shadow: 0px 5px 10px rgba(0,0,0,0.15)
--f7-card-content-padding-vertical: 0px
--f7-card-margin-horizontal: 5px
slots:
content:
- component: oh-image
config:
lazy: true
style:
border-radius: 12px
margin: 10px 0px 5px 0px
max-height: 140px
top: 10px
width: 100%
url: '=(items[props.sceneItem].state=="ON") ? props.itemPathOn : props.itemPathOff'
- component: f7-row
config:
class:
- padding-bottom
- justify-content-center
color-theme: white
slots:
default:
- component: f7-col
config:
class:
- justify-content-center
slots:
default:
- component: oh-button
config:
action: command
actionCommand: com.webos.app.hdmi2
actionItem: =props.appItem
large: true
slots:
default:
- component: oh-icon
config:
height: '=(items[props.appItem].state=="com.webos.app.hdmi2") ? 32 : 24'
icon: iconify:pixelarticons:device-tv-smart
color: red
- component: f7-col
config:
class:
- justify-content-center
slots:
default:
- component: oh-button
config:
action: command
actionCommand: netflix
actionItem: =props.appItem
large: true
slots:
default:
- component: oh-icon
config:
height: '=(items[props.appItem].state=="netflix") ? 32 : 24'
icon: iconify:logos:netflix-icon
- component: f7-col
config:
class:
- justify-content-center
slots:
default:
- component: oh-button
config:
action: command
actionCommand: cdp-30
actionItem: =props.appItem
large: true
slots:
default:
- component: oh-icon
config:
height: '=(items[props.appItem].state=="cdp-30") ? 32 : 24'
icon: iconify:mdi:plex
color: red
- component: f7-col
config:
class:
- justify-content-center
slots:
default:
- component: oh-button
config:
action: command
actionCommand: youtube.leanback.v4
actionItem: =props.appItem
large: true
slots:
default:
- component: oh-icon
config:
height: '=(items[props.appItem].state=="youtube.leanback.v4") ? 32 : 24'
icon: iconify:logos:youtube-icon
- component: f7-row
config:
class:
- padding-bottom
color-theme: red
slots:
default:
- component: f7-col
slots:
default:
- component: Label
config:
style:
color: '=(items[props.sceneItem].state=="ON") ? "green" : "red"'
text: =props.Title
- component: f7-col
slots:
default:
- component: Label
config:
style:
color: '=(items[props.sceneItem].state=="ON") ? "green" : "red"'
text: =items[props.sceneItem].state
- component: f7-col
slots:
default:
- component: oh-toggle
config:
item: =props.sceneItem
style:
color: '=(items[props.sceneItem].state=="ON") ? "green" : "red"'
Save the Widget.
For this type of control in Settings, Pages I have created a new Layout Page called Scenes where I keep Widgets that are controlling several sensors or devices.
To add the widget on the page Press the + in a cell and select the widget save above from Personal widgets.
Click on the computer icon at the top right side and set the required fields.
This is the yaml content in my case
component: widget:Movie
config:
Title: Movie
appItem: OLED55CX6LA_Application
itemPathOff: /static/cards/scene-movie-off.jpg
itemPathOn: /static/cards/scene-movie.jpg
sceneItem: MovieScene
In the next step I created a script to control the all the items involved in this widget.
Go to Settings, Rules, click the + button and fill the required information's.
On When branch of the rule select when an item state is changed and select the switch item created above.
On the Then branch I have created a script that is shown below with plenty of comments for understanding.
Rule ECMAScript (ECMA - 262 Edition 5.1)
//var logger = Java.type('org.slf4j.LoggerFactory').getLogger('org.openhab.rule.' + ctx.ruleUID);
//Gget the state of switch
var SwitchState = itemRegistry.getItem("MovieScene").getState()
//Is TV On or Off
var TvState = itemRegistry.getItem("OLED55CX6LA_Power").getState()
//Is LED strip On or Off
var StripState = itemRegistry.getItem("IkeaLedStrip1_IkeaLedStrip1State").getState()
//Get the LED strip brightness
var StripBrightness = itemRegistry.getItem("IkeaLedStrip1_IkeaLedStrip1Brightness").getState()
//TV application identifier
//var startApp = "cdp-30" //Plex
var startApp = "netflix"
//If the Movie is switched On
if(SwitchState == "ON"){
//If the TV is Off we will turn it on
if(TvState == "OFF"){
events.sendCommand("OLED55CX6LA_Power", "ON");
//logger.info("Starting...");
//Wait 5sec for TV to start
java.lang.Thread.sleep(5000);
}
//As long as teh TV is not opening the required application
//we send a new command and wait 1 second
while ((itemRegistry.getItem("OLED55CX6LA_Application").getState() != startApp)){
//logger.info("Waiting...");
events.sendCommand("OLED55CX6LA_Application", startApp);
java.lang.Thread.sleep(1000);
}
//If the LED strip is Off we turn it On
if(StripState == "OFF"){
events.sendCommand("IkeaLedStrip1_IkeaLedStrip1State", "ON");
}
//Set LED strip brightness
events.sendCommand("IkeaLedStrip1_IkeaLedStrip1Brightness", 30);
//Close teh window blinds
events.sendCommand("IkeaWindowBlind1_IkeaWindowBlind1Opening", 100);
events.sendCommand("IkeaWindowBlind2_IkeaWindowBlind2Opening", 100);
//Start the ambient light
events.sendCommand("AmbientLightLeft_AmbientLightLeftPower", "ON");
}
//If the Movie is swithch Off...
if(SwitchState == "OFF"){
events.sendCommand("OLED55CX6LA_Power", "OFF");
events.sendCommand("IkeaLedStrip1_IkeaLedStrip1State", "OFF");
events.sendCommand("IkeaWindowBlind1_IkeaWindowBlind1Opening", 0);
events.sendCommand("IkeaWindowBlind2_IkeaWindowBlind2Opening", 0);
events.sendCommand("AmbientLightLeft_AmbientLightLeftPower", "OFF");
}
To debug the widget use the console of OpenHAB
//Access OpenHAB console
openhab-cli console
defaul password is "habopen"
//Check what is going on on your server
log:tail
Comments powered by CComment