Dimmer widget oh3 and UI design

Tags: #<Tag:0x00007fc8ffe0e1e0> #<Tag:0x00007fc8ffe0e0f0> #<Tag:0x00007fc8ffe0e000>

Hi All,

I’m relatively new to OpenHAB with only very limited experience with programming. However, I’m trying to create some kind of dimmer widget inspired on Crestron:

So far I have put in several hour but a bit stuck on on aligning the UI. Here my work so fare:

It is based on the following code: yaml.txt (2.0 KB)

Another try yesterday:

Can someone provide me with a but of help/guidance to create this? Is there some tool I can use to program widgets?

Some questions I have:

  • How can I align the components?
  • How can I provide a different color to the slider?
  • How can I implement the percentage? To show off when the dimmer is 0

Many thanks!

1 Like

After a day of work I have been able to progress a little. See the screenshots below. Anybody interested to help/contribute to build a nice UI for lights control together?

I’m still looking for a way to group the dimmers in a better way like the example.

Here is my code:
YAML widget.txt (2.7 KB)
overview.txt (3.7 KB)

I worked a bit further, hereby the result. I made some custom widget to click to taps of a room, a cannot get this working however. Does anybody know how you can make the entire thing in a button? Just like the top buttons for the scenes.

Try playing with this code…

uid: LightWidget
tags: []
props:
  parameters:
    - description: title to display
      label: Title
      name: title
      required: false
      type: TEXT
    - context: item
      description: An item to control
      label: Item
      name: item
      required: false
      type: TEXT
  parameterGroups: []
timestamp: Dec 29, 2020, 5:05:47 PM
component: f7-card
config:
  class: lazy
  expandable: false
  style:
    border-radius: 6px
    height: 4em
    width: 17em
slots:
  default:
    - component: oh-icon
      config:
        icon: light
        height: 28
    - component: Label
      config:
        text: "=props.title !== NULL  ? props.title :'' "
        style:
          position: absolute
          left: 2rem
          top: 0.2rem
    - component: oh-button
      config:
        action: group
        actionGroupPopupItem: =(props.item)
        text: Color
        textColor: black
        bgColor: white        
        style:
          position: absolute
          right: 65px
          top: 5px
          width: 60px
          height: 25px
          border-radius: 12px
    - component: oh-toggle
      config:
        item: =(props.item)
        style:
          position: absolute
          right: 5px
          top: 5px
    - component: f7-block
      slots:
        default:
          - component: oh-slider
            config:
              scale: false
              item: =(props.item)

Many thanks! Any thoughts on using a button action on an F7 card?

Here te code I have used:

uid: Card_room
tags: []
props:
  parameters:
    - context: item
      description: An item to control
      label: Item
      name: dimmeritem
      required: false
      type: TEXT
timestamp: Dec 29, 2020, 1:43:48 AM
component: f7-card
config:
  action: navigate
  actionPageTransition: f7-push
  actionPage: page:page_02e8441f35
  noShadow: false
  class:
    - padding
  style:
    box-shadow: 0px 6px 6px hsl(0,0%,90%)
    border-radius: 12px
    overflow: hidden
    -ms-user-select: none
    -moz-user-select: none
    -webkit-user-select: none
    user-select: none
    --card-text-color: black
slots:
  default:
    - component: f7-row
      slots:
        default:
          - component: f7-col
            slots:
              default:
                - component: Label
                  config:
                    text: Rooms
                    style:
                      color: grey
                      font-size: 12px
                      line-height: 15px
                      white-space: nowrap
                      overflow: hidden
                      text-overflow: ellipsis
          - component: f7-col
            config:
              style:
                z-index: 999
                text-align: right
                width: fit-content
                overflow: hidden
    - component: f7-row
      slots:
        default:
          - component: f7-col
            slots:
              default:
                - component: Label
                  config:
                    text: Woonkamer | Keuken
                    style:
                      color: var(--card-text-color)
                      font-size: 15px
                      line-height: 30px
                      white-space: nowrap
                      overflow: hidden
                      text-overflow: ellipsis
          - component: f7-col
            config:
              style:
                z-index: 999
                text-align: right
                width: fit-content
                overflow: hidden
    - component: f7-row
      config:
        class:
          - justify-content-space-around
          - display-flex
          - align-items-center
          - align-content-stretch
    - component: oh-image-card
      config:
        url: http://1167.16652.nl:8080/static/test.jpg
        noShadow: true
      slots: {}

Or is there perhaps a better way to implement this solution?

Hereby my result after 2 days of work:

the code of the widget:

uid: Dimmer
tags: []
props:
  parameters:
    - context: item
      description: An item to control
      label: Item
      name: dimmeritem
      required: false
      type: TEXT
timestamp: Dec 29, 2020, 4:29:23 PM
component: f7-card
config:
  noShadow: false
  class:
    - padding
  style:
    box-shadow: 0px 6px 6px hsl(0,0%,90%)
    border-radius: 12px
    height: 5em
slots:
  default:
    - component: f7-row
      slots:
        default:
          - component: f7-col
            slots:
              default:
                - component: Label
                  config:
                    text: '=(props.dimmeritem) ? props.dimmeritem : "Set dimmer"'
                    style:
                      color: var(--card-text-color)
                      font-size: 15px
                      line-height: 30px
                      white-space: nowrap
                      overflow: hidden
                      text-overflow: ellipsis
                      position: absolute
                      top: 0.5em
    - component: oh-toggle
      config:
        style:
          position: absolute
          top: 1.2em
          left: calc(100% - 60px)
        color: yellow
        item: =props.dimmeritem
    - component: f7-row
      slots:
        default:
          - component: f7-col
            slots:
              default:
                - component: f7-icon
                  config:
                    style:
                      font-size: 12px
                      line-height: 15px
                      color: grey
                      position: absolute
                      top: 3em
                      left: 1.2em
                    f7: rays
          - component: f7-col
            slots:
              default:
                - component: Label
                  config:
                    text: =items[props.dimmeritem].displayState || items[props.dimmeritem].state
                    style:
                      position: absolute
                      top: 3em
                      left: 3em
                      color: grey
                      font-size: 12px
                      line-height: 15px
                      white-space: nowrap
                      overflow: hidden
                      text-overflow: ellipsis
    - component: oh-slider
      config:
        item: =props.dimmeritem
        max: 100
        Padding: 500px
        label: false
        color: yellow
        scale: false
        noShadow: true
        outline: false
        min: 0
        unit: "%"
        style:
          width: calc(100% - 2em)
          position: absolute
          top: 4.5em
          left: 1em

Anybody still an idea on my previous question? I solved it for now by using the following widget:

uid: Card_room_2
tags: []
props:
  parameters:
    - label: Text header
      name: text_header
      required: false
      type: TEXT
      groupName: general
    - label: Text sub
      name: text_sub
      required: false
      type: TEXT
      groupName: general
  parameterGroups:
    - name: general
      label: General settings
    - name: wording
      label: Wording
timestamp: Dec 29, 2020, 12:16:13 PM
component: oh-cell
config:
  header: '=(props.text_sub) ? props.text_sub : "Set props!"'
  title: '=(props.text_header) ? props.text_header : "Set props!"'
  action: navigate
  actionPageTransition: f7-push
  actionPage: page:page_02e8441f35

This is not ideal because I was not able to add any backround or other text

Really like wat you can do, making a nice UI however requires a lot of works for someone who is not expiericened. Any help is much appreciated :grinning: :grinning:

1 Like

Here my latest work, I integrated the code I found here:


Please note the grey boxed are for privacy only…

Some questions idea’s where som help would be much appreciated:

  • How can make the hight of the oh-card smaller? I would like to make the scenes buttons a bit smaller in size
  • I would like to only expand the lights on to more functions:
    • show the active scene (only when that scene is actually active)
    • Lights off
    • Heating temperature

Any idea how I can implement that I a smart way? Maybe @ysc do you have any idea?

Here the latest code

uid: Card_room_3
tags: []
props:
  parameters:
    - label: Background image-url
      name: backgroundUrl
      required: false
      type: TEXT
      groupName: general
    - description: Background blur
      label: Intensity of the background-blur (0 - 10)
      name: backgroundBlur
      required: false
      type: TEXT
      groupName: general
    - label: Text header
      name: text_header
      required: false
      type: TEXT
      groupName: general
    - label: page
      name: page
      required: true
      groupName: general
    - context: item
      description: select group for status lights
      label: Item
      name: status
      required: false
      type: TEXT
  parameterGroups:
    - name: general
      label: General settings
    - name: wording
      label: Wording
timestamp: Dec 29, 2020, 10:26:48 PM
component: oh-cell
config:
  title: '=(props.text_header) ? props.text_header : "Set props!"'
  action: popup
  actionModal: =props.page
slots:
  background:
    - component: f7-block
      config:
        class:
          - card-opened-fade-out
        style:
          position: absolute
          left: 50%
          bottom: -10px
      slots:
        default:
          - component: f7-card
            config:
              style:
                background-image: "='url(' + props.backgroundUrl.substring(0, (props.backgroundUrl.length -4)) + ((props.itemTimesOfDay === undefined || items[props.itemTimesOfDay].state === 'NULL') ? '' : '_' + items[props.itemTimesOfDay].state) + props.backgroundUrl.substr(-4) + ')'"
                background-size: cover
                background-repeat: no-repeat
                background-position: 100% 50%
                border-radius: 0px
                height: 200px
                width: 20em
    - component: f7-block
      config:
        class:
          - card-opened-fade-out
        style:
          position: absolute
          left: -18px
          bottom: 10px
      slots:
        default:
          - component: f7-chip
            config:
              class:
                - margin-left
              iconF7: lightbulb
              iconColor: yellow
              text: Lights are on
              visible: =items[props.status].state === 'ON'
    - component: f7-block
      config:
        class:
          - card-opened-fade-out
        style:
          position: absolute
          right: 8%
          bottom: 30%
      slots:
        default:
          - component: f7-icon
            config:
              style:
                font-size: 25px
                color: white
                position: absolute
              f7: arrow_right

@Aaron2 Great widget! I made a vertical version and used F7 Typography to scale nicely. Here is my code.

uid: Slider_Vertical_Widget
tags: []
props:
  parameters:
    - context: item
      description: An item to control
      label: Item
      name: dimmerItem
      required: false
      type: TEXT
  parameterGroups: []
timestamp: Dec 31, 2020, 2:33:09 AM
component: f7-card
config:
  class:
    - padding
    - margin
slots:
  default:
    - component: f7-row
      config:
        class:
          - display-flex
          - flex-direction-row
          - justify-content-space-between
          - align-items-center
          - padding
      slots:
        default:
          - component: Label
            config:
              text: '=(props.dimmerItem) ? props.dimmerItem : "Set dimmer"'
          - component: oh-toggle
            config:
              item: =props.dimmerItem
    - component: f7-row
      config:
        class:
          - display-flex
          - flex-direction-row
          - justify-content-flex-start
          - align-items-flex-start
      slots:
        default:
          - component: f7-col
            slots:
              default:
                - component: f7-row
                  config:
                    class:
                      - display-flex
                      - flex-direction-row
                      - justify-content-flex-start
                      - align-items-flex-start
                  slots:
                    default:
                      - component: f7-icon
                        config:
                          f7: rays
                          class:
                           - padding-horizontal
                      - component: Label
                        config:
                          text: =items[props.dimmerItem].displayState || items[props.dimmerItem].state
          - component: oh-slider
            config:
              item: =props.dimmerItem
              vertical: true
              scale: true
              max: 100
              min: 0
              class:
                - padding
                - margin
              style:
                height: 200px

1 Like

This is exactly the kind of widget I was looking for opening a dimmer in a floorplan but I do not get it to work there. Maybe someone has an idea what the issue is?

  1. First I created a widget called “Dimmer” with the above code in the developer section
  2. Then I create a marker in the floorplan and set the action to “open popup”
  3. I then set “Model or Widget” to that “Dimmer”
  4. The I got to the model component configuration which will allows me to choose my item which though is not shown here after picking it:

Then I click on “Done” for editing the marker and get the following error:

Does anyone know what I am doing wrong?

TIA
Stefan

I have found when you use f7-card you also need to define a f7-card-content, issues occur if you dont define the content.

The message “Requested content not found” seems to be the clue here.

Have a look at the camera widgets I created to see how you use f7-card-content as all the examples in this thread appear to be missing it including a post from me.

How do I make a custom widget that controls (or shows state) of 2 or more items?

You basically set props for the two items so that the state can be referenced later on in the widget code.

Look at the code for the ‘uid: Card_room_2’ posted earlier in this thread which shows two text items being set, instead of text items set actual items and then build the widget with the components to reference those items.

1 Like

To control two or more items, you can use a group item, e.g. add all brightness items to be controlled to a group and then control the group item from the widget. You need to define for the group the base member type e.g. switch or dimmer.

To control colors for a group you need to use a dummy color item and the use a rule to make your group follow the dummy. I use this rule

var Dummy = null

rule "Check Color Entre"
when
    Item EntreDummyColor received update
then
    Dummy = EntreDummyColor.state
  
    sendCommand(Entre1_Color, Dummy.toString)
    sendCommand(Entre2_Color, Dummy.toString)
    sendCommand(Entre3_Color, Dummy.toString)
end

I have adjusted Aaron2’s widgets (thanks Aaron2) to (i) a widget that only controls brightness, (ii) one that controls brightness, temperature and has a color picker and (iii) one that controls brightness and temperature:

YAMLs:
Brightness.txt (2.2 KB) BrightnessTemperature.txt (2.7 KB) BrightenssTemperatureColor.txt (2.9 KB)

2 Likes

Really nice! But when I use the toggle the sliders always go to 100% :confused:

@Aaron2 This looks great. I am new to openHAB, not a programmer and I want to control my dimmers. Thanks for sharing your code but i don’t get how to import is. I work via the GUI of openHAB 3. Created a new page and pasted the YAML code into the page. But i only get errors. Can someone get me started?

you will need to go to “Developer Tools” then “Widgets” and add a new widget copying the yaml code into it. Afterwards you can use it in pages.

Thanks, learning new things every day ! I was able to add it to a page. How do i fill it up with code? is there some kind of reference i can read or learn?

As a first step i want to be albe to switch on the light with that on/off button. is that possible?
Currently there is also a caveat, i use a custom code to swith my dimmer on/off. A push-button/Toggle button. Because if i use a default toggle button. The command is only send once every 2 times. So for example only the ON status is send (and means the same for on and off) The Push-button/toggle code fixes this. But maybe this is confusing by giving that information :thinking:
Second i would like to control the dimmer of that light.

Hello,

in the widgetVersion with color where I could configure the “point” for the coloe (rgb) ?

Thank you

1 Like

Hey,

I wanted to share my version of this widget.
image
…If you click the 3 dots in the corner:

I designed this for Shelly RGBW which is having just 4 physical channels therefore I have White and Gain to control brightness based on whether I am using it as a ‘normal’ white light or I’m using it with a certain color set.

First of all i needed a ‘boolean’ to decide in which mode I’m in so I created an Item which then I assigned in the model hierarchy to the proper place:

Then I created a rule like this:

rule "RGBWLedStripDiningRoom Mode Change"
when
    Item RGBWLedStripDiningRoom_ColorMode changed
then
    if (RGBWLedStripDiningRoom_ColorMode.state == ON) {
        RGBWLedStripDiningRoom_White.sendCommand(0)
        RGBWLedStripDiningRoom_Gain.sendCommand(100)
    }
    if (RGBWLedStripDiningRoom_ColorMode.state == OFF) {
        RGBWLedStripDiningRoom_Gain.sendCommand(0)
        RGBWLedStripDiningRoom_White.sendCommand(100)
    }
end

Then I have the helper widget for the popup:

uid: colorpickerPopup
tags: []
props:
  parameters:
    - context: item
      description: An item to control
      label: Item
      name: item
      required: false
      type: TEXT
  parameterGroups: []
timestamp: Feb 12, 2021, 8:20:49 PM
component: f7-page
config:
  style:
    position: relative
    -ms-user-select: none
    -moz-user-select: none
    -webkit-user-select: none
    user-select: none
    background: rgba(42,48,78,1)
    --f7-card-bg-color: none
    backdrop-filter: none
    padding: 0
    margin: 0
slots:
  default:
    - component: oh-colorpicker-card
      config:
        item: =props.item
        noBorder: true
        noShadow: true
        modules:
          - hs-spectrum
          - brightness-slider

…And the widget itself:

uid: Shelly_RGBW
tags: []
props:
  parameters:
    - description: Title
      label: Title
      name: title
      required: false
      type: TEXT
    - context: item
      description: Power item for the widget
      label: Power
      name: power
      required: true
      type: TEXT
    - context: item
      description: Color item for the widget
      label: Color
      name: color
      required: true
      type: TEXT
    - context: item
      description: Gain item for the widget
      label: Gain
      name: gain
      required: true
      type: TEXT
    - context: item
      description: White item for the widget
      label: White
      name: white
      required: true
      type: TEXT
    - context: item
      description: Name of the switch for the Color Mode
      label: Color Mode
      name: colormode
      required: true
      type: TEXT
  parameterGroups: []
timestamp: Feb 16, 2021, 5:18:47 PM
component: f7-card
config:
  style:
    border-radius: 20px
slots:
  content:
    - component: f7-row
      config:
        class:
          - justify-content-center
      slots:
        default:
          - component: oh-toggle
            config:
              item: =props.power
              actionCommand: ON
              actionCommandAlt: OFF
              style:
                position: absolute
                margin-top: 10px
                left: 0
                font-weight: 600
                z-index: 99
                margin-left: 20px
          - component: Label
            config:
              text: =props.title
          - component: oh-button
            config:
              colorTheme: white
              color: white
              iconMaterial: more_horiz
              iconSize: 20px
              action: popup
              actionModal: widget:colorpickerPopup
              actionModalConfig:
                item: =props.color
              style:
                position: absolute
                margin-top: 0px
                margin-right: 20px
                right: 0
                font-weight: 600
                z-index: 99
    - component: f7-row
      config:
        class:
          - margin-left
          - margin-right
          - padding-top
        style:
          margin-top: 10px
      slots:
        default:
          - component: oh-slider
            config:
              visible: =(items[props.colormode].state === "OFF")
              item: =props.white
              min: 0
              max: 100
              unit: "%"
          - component: oh-slider
            config:
              visible: =(items[props.colormode].state === "ON")
              item: =props.gain
              min: 0
              max: 100
              unit: "%"
    - component: f7-row
      config:
        class:
          - padding
      slots:
        default:
          - component: oh-button
            config:
              text: Color Mode
              fill: '=(items[props.colormode].state === "OFF") ? false : true'
              outline: true
              action: toggle
              actionItem: =props.colormode
              actionCommand: ON
              actionCommandAlt: OFF
              style:
                width: 100%

I am pretty new to OH, been using HA for a while now so there might be easier solutions - I’m still exploring. This is my first Widget and along with that I am aware that my UI design skills really suck, but I needed something to be able to control my lights based on Shelly RGBW so here it is. Hope it will be useful for someone :slight_smile:

4 Likes

Hi Everybody

Has anybody an idea if this type of widget could also be implemented as a item list widget?