OpenHAB Widget creation

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.

OpenHAB Movie Widget

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.

OpenHAB OLED Thing Channels

To be able to activate and deactivate the whole thing I need to create a switch Item

OpenHAB Movie Rule Item Switch

Now we navigate to Developer Tools, then select Widgets and click the + button to create a new Widget

OpenHAB Movie Configure Cell Configuration

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)

OpenHAB Movie Rule SetUp

//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