[OH3] Main UI Examples

Technically those are the 2 equivalences:

@<name>    <=>    items[<name>].displayState !== undefined ? items[<name>].displayState : items[<name>].state

@@<name>   <=>    items[<name>].state

@ et @@ are unary operators so due to their precedences parentheses may be useful, but not always.
For instance @props.itemName alone is fine, but beware of the differences between:

@@itemsPrefix + '_Suffix`      <=>    items[itemsPrefix].state + '_Suffix'

and

@@(itemsPrefix + '_Suffix`)    <=>    items[itemsPrefix + '_Suffix'].state
5 Likes

Hi Andras,

many thanks for you Examples, especially the room Card. Quite useful as I was searching for a card that could open a group action…

bkumio

Finally I feel comfortable enough to post my example so far. Have had some great inspiration from @Integer and @BG56 but I’m also inspired by the great design of @Dimitris in the new main widget topic. Thank you all.

I really like the simpleness of the Apple Home app and I try to copy that part, too. When Items are off they are semi-transparent and when one they become white. In some cases I will enable them to become a special color, for example the AlarmPartitionStatus may become red when there is an alarm.

The LightControl widget can be collapsed and expanded by clicking on the title and depending on the set properties will display a slider to dim, two sliders for dim and white tone or will display the color control with three sliders and a set of pre-defined colors.

My HarmonyControl will show the current activity when on and it then also features an off button. It can be expanded when off, but it automatically expanded when on.

I’m currently working on a new widget for displaying status from the thermostate and a player widget for my future Chromecast.

1 Like

Would you mind sharing the code of your widgets ?

1 Like

Sure!

LightControl:

uid: LightControl
tags: []
props:
  parameters:
    - description: Header icon
      label: Icon
      name: iconHeader
      required: false
      type: TEXT
      groupName: header
    - description: Header text
      label: Header
      name: header
      required: false
      type: TEXT
      groupName: header
    - context: item
      description: Item to control on/off
      label: Item ON OFF
      name: itemSwitch
      required: true
      type: TEXT
      groupName: setup
    - context: item
      description: Item to control brightness
      label: Item brightness
      name: itemBrightness
      required: false
      type: TEXT
      groupName: setup
    - context: item
      description: Item to control color temperature
      label: Item light temperature
      name: itemLightTemperature
      required: false
      type: TEXT
      groupName: setup
    - context: item
      description: Item to control color
      label: Item light color
      name: itemColor
      required: false
      type: TEXT
      groupName: setup
  parameterGroups:
    - name: header
      description: Widget general settings
    - name: setup
      description: Widget specific settings
timestamp: Dec 29, 2022, 10:55:04 PM
component: f7-card
config:
  style:
    background-color: "=items[props.itemSwitch].state === 'ON' ? 'rgba(255, 255, 255, 1)' : 'rgba(34, 34, 34, 0.3)'"
    border-radius: 15px
    box-shadow: 0px 0px
    margin: 5px 5px
slots:
  content:
    - component: f7-row
      config:
        style:
          justify-content: left
      slots:
        default:
          - component: oh-image
            config:
              url: ='/static/icons/' + props.iconHeader + '.svg'
              style:
                height: 25px
                margin-right: 10px
                filter: '=items[props.itemSwitch].state === "ON" ? "brightness(1)" : "brightness(0) invert(1)"'
              visible: "=props.iconHeader ? true : false"
          - component: Label
            config:
              text: "=props.header ? props.header : 'Set header title'"
              style:
                font-size: var(--f7-card-header-font-size)
                font-weight: var(--f7-card-header-font-weight)
                color: '=items[props.itemSwitch].state === "ON" ? "black" : "white"'
                --f7-list-item-after-text-color: '=items[props.itemSwitch].state === "ON" ? "black" : "white"'
          - component: oh-toggle
            config:
              item: =props.itemSwitch
              style:
                position: absolute
                top: 20px
                right: 20px
                z-index: 100
                --f7-toggle-active-color: "#F8BB00"
                --f7-toggle-inactive-color: "#ccc"
    - component: oh-link
      config:
        action: variable
        actionVariable: visiblePart
        actionVariableValue: "=vars.visiblePart === true ? false : true"
        style:
          position: absolute
          top: 0
          left: 0
          height: 55px
          width: 100%
          actionPosition: center
    - component: f7-row
      config:
        style:
          justify-content: center
          margin-top: 25px
        visible: =vars.visiblePart === true && props.itemBrightness !== Null
      slots:
        default:
          - component: oh-slider
            config:
              item: =props.itemBrightness
              min: 0
              max: 100
              style:
                width: calc(100% - 20px)
                --f7-range-bar-size: 10px
                --f7-range-bar-border-radius: 8px
                --f7-range-knob-size: 20px
                --f7-range-knob-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3)
    - component: f7-row
      config:
        style:
          justify-content: center
          margin-top: 10px
        visible: =vars.visiblePart === true && props.itemLightTemperature !== Null
      slots:
        default:
          - component: oh-slider
            config:
              item: =props.itemLightTemperature
              min: 0
              max: 100
              style:
                width: calc(100% - 20px)
                --f7-range-bar-size: 10px
                --f7-range-bar-border-radius: 10px
                --f7-range-knob-size: 20px
                --f7-range-bar-active-bg-color: transparent
                --f7-range-bar-bg-color: linear-gradient(to right, rgba(215, 226, 255), rgba(224, 238, 238),rgba(255, 215, 44, 0.5),rgba(255, 215, 44, 0.8))
                --f7-range-knob-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3)
                --f7-range-label-text-color: black
    - component: f7-row
      config:
        style:
          justify-content: center
          margin-top: 10px
          --f7-range-bar-size: 10px
          --f7-range-bar-border-radius: 10px
          --f7-range-knob-size: 20px
          --f7-range-bar-active-bg-color: transparent
          --f7-range-bar-bg-color: linear-gradient(to right, rgba(246,158,81,0.8), rgba(246,158,81,0))
          --f7-range-knob-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3)
          --f7-range-label-text-color: black
          --f7-color-picker-slider-size: 10px
          --f7-color-picker-slider-knob-size: 20px
          width: 100%
        visible: =vars.visiblePart === true && props.itemColor !== Null
      slots:
        default:
          - component: oh-colorpicker
            config:
              color: red
              label: true
              item: =props.itemColor
              modules:
                - hsb-sliders
    - component: f7-row
      config:
        style:
          justify-content: center
          margin-top: 10px
        visible: =vars.visiblePart === true && props.itemColor !== Null
      slots:
        default:
          - component: oh-button
            config:
              iconColor: yellow
              iconF7: app_fill
              iconSize: 25
              action: command
              actionItem: =props.itemColor
              actionCommand: 60,100,100
              style:
                padding: 0px 5px
                height: 35px
                background: transparent
          - component: oh-button
            config:
              iconColor: orange
              iconF7: app_fill
              iconSize: 25
              action: command
              actionItem: =props.itemColor
              actionCommand: 30,100,100
              style:
                padding: 0px 5px
                height: 35px
                background: transparent
          - component: oh-button
            config:
              iconColor: deeporange
              iconF7: app_fill
              iconSize: 25
              action: command
              actionItem: =props.itemColor
              actionCommand: 15,100,100
              style:
                padding: 0px 5px
                height: 35px
                background: transparent
          - component: oh-button
            config:
              iconColor: red
              iconF7: app_fill
              iconSize: 25
              action: command
              actionItem: =props.itemColor
              actionCommand: 0,100,100
              style:
                padding: 0px 5px
                height: 35px
                background: transparent
          - component: oh-button
            config:
              iconColor: purple
              iconF7: app_fill
              iconSize: 25
              action: command
              actionItem: =props.itemColor
              actionCommand: 300,100,100
              style:
                padding: 0px 5px
                height: 35px
                background: transparent
          - component: oh-button
            config:
              iconColor: blue
              iconF7: app_fill
              iconSize: 25
              action: command
              actionItem: =props.itemColor
              actionCommand: 240,100,100
              style:
                padding: 0px 5px
                height: 35px
                background: transparent
          - component: oh-button
            config:
              iconColor: lightblue
              iconF7: app_fill
              iconSize: 25
              action: command
              actionItem: =props.itemColor
              actionCommand: 180,100,100
              style:
                padding: 0px 5px
                height: 35px
                background: transparent
          - component: oh-button
            config:
              iconColor: green
              iconF7: app_fill
              iconSize: 25
              action: command
              actionItem: =props.itemColor
              actionCommand: 120,100,100
              style:
                padding: 0px 5px
                height: 35px
                background: transparent

SimpleSwitch:

uid: SimpleSwitch
tags: []
props:
  parameters:
    - description: Header icon
      label: Icon
      name: iconHeader
      required: false
      type: TEXT
      groupName: header
    - description: Header text
      label: Header
      name: header
      required: false
      type: TEXT
      groupName: header
    - context: item
      description: Item to control on/off
      label: Item
      name: itemSwitch
      required: false
      type: TEXT
      groupName: setup
  parameterGroups:
    - name: header
      description: Widget general settings
    - name: setup
      description: Widget specific settings
timestamp: Dec 29, 2022, 10:55:19 PM
component: f7-card
config:
  style:
    background-color: "=items[props.itemSwitch].state === 'ON' ? 'rgba(255, 255, 255, 1)' : 'rgba(34, 34, 34, 0.3)'"
    border-radius: 15px
    box-shadow: 0px 0px
    margin: 5px 5px
slots:
  content:
    - component: f7-row
      config:
        style:
          justify-content: left
      slots:
        default:
          - component: oh-image
            config:
              url: ='/static/icons/' + props.iconHeader + '.svg'
              style:
                height: 25px
                margin-right: 10px
                filter: '=items[props.itemSwitch].state === "ON" ? "brightness(1)" : "brightness(0) invert(1)"'
              visible: "=props.iconHeader ? true : false"
          - component: Label
            config:
              text: "=props.header ? props.header : 'Set header title'"
              style:
                font-size: var(--f7-card-header-font-size)
                font-weight: var(--f7-card-header-font-weight)
                color: '=items[props.itemSwitch].state === "ON" ? "black" : "white"'
                --f7-list-item-after-text-color: '=items[props.itemSwitch].state === "ON" ? "black" : "white"'
    - component: f7-row
      config:
        style:
          justify-content: center
          margin-top: 25px
      slots:
        default:
          - component: oh-toggle
            config:
              item: =props.itemSwitch
              style:
                --f7-toggle-active-color: "#F8BB00"
                --f7-toggle-inactive-color: "#ccc"

Let me double check my HarmonyControl first before I post it here. Want to make sure that it’s fully functioning :slight_smile:

1 Like

Very nice! Looks like the one i’ve made too :slight_smile:

I will take from your widget, the preset line colors,i forgot to add that could be useful.

Thanks!

Here is the code for the Harmony widget:

uid: HarmonyControl
tags: []
props:
  parameters:
    - description: Header icon
      label: Icon
      name: iconHeader
      required: false
      type: TEXT
      groupName: header
    - description: Header text
      label: Header
      name: header
      required: false
      type: TEXT
      groupName: header
    - context: item
      description: Item to control Harmony
      label: Item current activity
      name: itemCurrentActivity
      required: true
      type: TEXT
      groupName: setup
    - description: 'Use JSON format [{"label": "Label", "icon": "Icon", "command": "Command to send"}, ...}]'
      label: Activities
      name: activities
      required: true
      type: TEXT
      groupName: setup
  parameterGroups:
    - name: header
      description: Widget general settings
    - name: setup
      description: Widget specific settings
timestamp: Jan 8, 2023, 10:53:50 PM
component: f7-card
config:
  style:
    background-color: "=items[props.itemCurrentActivity].state !== 'PowerOff' ? 'rgba(255, 255, 255, 1)' : 'rgba(34, 34, 34, 0.3)'"
    border-radius: 15px
    box-shadow: 0px 0px
    margin: 5px 5px
slots:
  content:
    - component: f7-row
      config:
        style:
          justify-content: left
      slots:
        default:
          - component: oh-image
            config:
              url: ='/static/icons/' + props.iconHeader + '.svg'
              style:
                height: 25px
                margin-right: 10px
                filter: '=items[props.itemCurrentActivity].state !== "PowerOff" ? "brightness(1)" : "brightness(0) invert(1)"'
              visible: "=props.iconHeader ? true : false"
          - component: Label
            config:
              text: "=props.header ? props.header : 'Set header title'"
              style:
                font-size: var(--f7-card-header-font-size)
                font-weight: var(--f7-card-header-font-weight)
                color: '=items[props.itemCurrentActivity].state !== "PowerOff" ? "black" : "white"'
                --f7-list-item-after-text-color: '=items[props.itemCurrentActivity].state !== "PowerOff" ? "black" : "white"'
          - component: oh-link
            config:
              action: command
              actionItem: =props.itemCurrentActivity
              actionCommand: PowerOff
              actionFeedback: Uitgeschakeld
              style:
                position: absolute
                top: 20px
                right: 20px
                z-index: 100
              visible: "=items[props.itemCurrentActivity].state !== 'PowerOff' ? true : false"
            slots:
              default:
                - component: oh-image
                  config:
                    url: ='/static/icons/power-off.svg'
                    style:
                      height: 18px
    - component: oh-link
      config:
        action: variable
        actionVariable: visiblePart
        actionVariableValue: "=vars.visiblePart === true ? false : true"
        style:
          position: absolute
          top: 0
          left: 0
          height: 55px
          width: 100%
          actionPosition: center
    - component: f7-row
      config:
        style:
          justify-content: left
          margin-top: 10px
          margin-bottom: 10px
      slots:
        default:
          - component: f7-chip
            config:
              text: "=items[props.itemCurrentActivity].state === 'PowerOff' ? 'Uitgeschakeld' : items[props.itemCurrentActivity].state"
              style:
                background-color: "=items[props.itemCurrentActivity].state !== 'PowerOff' ? '#F8BB00' : '#8c8c8c'"
                color: "#fff"
                margin-left: 35px
                font-size: 10px
                height: 18px
    - component: f7-row
      config:
        visible: "=items[props.itemCurrentActivity].state !== 'PowerOff' || vars.visiblePart === true ? true : false"
        style:
          margin-top: 20px
        class:
          - text-align-center
      slots:
        default:
          - component: oh-repeater
            config:
              for: activity
              sourceType: array
              fragment: true
              in: '=JSON.parse(props.activities)'
            slots:
              default:
                - component: f7-col
                  config:
                  slots:
                    default:
                      - component: oh-link
                        config:
                          action: command
                          actionItem: =props.itemCurrentActivity
                          actionCommand: =loop.activity.command
                          actionFeedback: =loop.activity.label + " gestart"
                        slots:
                          default:
                            - component: oh-image
                              config:
                                url: ='/static/icons/' + loop.activity.icon + '.svg'
                                style:
                                  height: 18px
    - component: f7-row
      config:
        visible: "=items[props.itemCurrentActivity].state !== 'PowerOff' || vars.visiblePart === true ? true : false"
        style:
          margin-top: 10px
        class:
          - text-align-center
      slots:
        default:
          - component: oh-repeater
            config:
              for: activity
              sourceType: array
              fragment: true
              in: '=JSON.parse(props.activities)'
            slots:
              default:
                - component: f7-col
                  config:
                  slots:
                    default:
                      - component: oh-link
                        config:
                          action: command
                          actionItem: =props.itemCurrentActivity
                          actionCommand: =loop.activity.command
                          actionFeedback: =loop.activity.label + " gestart"
                        slots:
                          default:
                            - component: Label
                              config:
                                text: =loop.activity.label
                                style:
                                  font-size: 11px
                                  color: '=items[props.itemCurrentActivity].state !== "PowerOff" ? "black" : "white"'

And I’ve got an ‘appliance’ widget as well. I use it in conjunction with the HomeConnect binding to display dishwasher and washing machine status.

uid: ApplianceStatus
tags: []
props:
  parameters:
    - description: Header icon
      label: Icon
      name: iconHeader
      required: false
      type: TEXT
      groupName: header
    - description: Header text
      label: Header
      name: header
      required: false
      type: TEXT
      groupName: header
    - context: item
      description: select item for operation state
      label: Item
      name: operationState
      required: false
      type: TEXT
      groupName: setup
    - context: item
      description: select item for active program
      label: Item
      name: activeProgram
      required: false
      type: TEXT
      groupName: setup
    - context: item
      description: select item for remaining time
      label: Item
      name: remainingTime
      required: false
      type: TEXT
      groupName: setup
    - context: item
      description: select item for progress
      label: Item
      name: progress
      required: false
      type: TEXT
      groupName: setup
    - context: item
      description: select item for temperature
      label: Item
      name: temperature
      required: false
      type: TEXT
      groupName: setup
    - context: item
      description: select item for spinspeed
      label: Item
      name: spinSpeed
      required: false
      type: TEXT
      groupName: setup
  parameterGroups:
    - name: header
      description: Widget general settings
    - name: setup
      description: Widget specific settings
timestamp: Jan 8, 2023, 10:12:11 PM
component: f7-card
config:
  style:
    background-color: "=items[props.operationState].state === 'Run' ? 'rgba(255, 255, 255, 1)' : 'rgba(34, 34, 34, 0.3)'"
    border-radius: 15px
    box-shadow: 0px 0px
    margin: 5px 5px
slots:
  content:
    - component: f7-row
      config:
        style:
          justify-content: left
      slots:
        default:
          - component: oh-image
            config:
              url: ='/static/icons/' + props.iconHeader + '.svg'
              style:
                height: 25px
                margin-right: 10px
                filter: '=items[props.operationState].state === "Run" ? "brightness(1)" : "brightness(0) invert(1)"'
              visible: "=props.iconHeader ? true : false"
          - component: Label
            config:
              text: "=props.header ? props.header : 'Set header title'"
              style:
                font-size: var(--f7-card-header-font-size)
                font-weight: var(--f7-card-header-font-weight)
                color: '=items[props.operationState].state === "Run" ? "black" : "white"'
    - component: f7-row
      config:
        style:
          justify-content: left
          margin-top: 10px
          margin-bottom: 10px
      slots:
        default:
          - component: f7-chip
            config:
              text: =items[props.operationState].displayState
              style:
                background-color: "=items[props.operationState].state === 'Run' ? '#F8BB00' : '#8c8c8c'"
                color: "#fff"
                margin-left: 35px
                font-size: 10px
                height: 18px
    - component: f7-row
      config:
        visible: "=items[props.operationState].state === 'Run' ? true : false"
        style:
          justify-content: left
      slots:
        default:
          - component: f7-chip
            config:
              style:
                --f7-chip-bg-color: rgba(255, 255, 255, 0)
              text: =items[props.activeProgram].state
              iconColor: black
              iconF7: info_circle
              iconSize: 17
          - component: f7-chip
            config:
              visible: =items[props.temperature]
              style:
                --f7-chip-bg-color: rgba(255, 255, 255, 0)
              text: =items[props.temperature].displayState
          - component: f7-chip
            config:
              visible: =items[props.spinSpeed]
              style:
                --f7-chip-bg-color: rgba(255, 255, 255, 0)
              text: =items[props.spinSpeed].displayState
    - component: f7-row
      config:
        visible: "=items[props.operationState].state === 'Run' ? true : false"
        style:
          justify-content: left
      slots:
        default:
          - component: f7-chip
            config:
              style:
                --f7-chip-bg-color: rgba(255, 255, 255, 0)
              text: "='Resterende tijd: ' + items[props.remainingTime].state"
              iconColor: black
              iconF7: clock
              iconSize: 17
          - component: f7-chip
            config:
              style:
                --f7-chip-bg-color: rgba(255, 255, 255, 0)
              text: "='Voortgang: ' + (items[props.progress].displayState === 'undefined') ? items[props.progress].displayState : items[props.progress].displayState"
              iconColor: black
              iconF7: percent
              iconSize: 17

Feel free to use or modify them as you wish. This weeks project: thermostat ‘status’ widget to display what my heating actor is doing (per room).

Anything to show already ?

Not yet actually… I’m still thinking about what exactly to display (related to what my KNX actor has available) and how to visualize. Also I don’t have airco or cooling so it’s only for heating.

1 Like

I’ll also share my Main UI. It all started with the ‘room’ widgets which were from the beginning of OH3 I think. Afterwards I added additional widgets for turning on lights, dimmers…and tried to create or modify other ones:
Main screen




Additional window when pressing the wheel on the Media widget
image|385

Example when clicking on a room:


image|385

Example of the charts pages which opens when clicking on one of the numbers in the Energy widget:


Some random widget for checking devices etc (they are all filled by items which gets their values via rules):



Pressing the eye icon in the widgets above will show all items, without my specific filter (eg I only show batteries % below 40%, I only show GitHub releases of the last 15 days…) The list icons shows the complete content of the group without any formatting


image|385

6 Likes

Really beautiful solutions, congratulations! :slight_smile: May I ask, how you realized the water consumption? I want to to do the same - but my research on water-sensors failed (resp only had solutions really expensive or complicated).

I use a simple reed switch. In my case one from Flukso. This is connected to An esp8266 board (nodemcu flashed with tasmota). In the past In also use a reed switch for my gas, connected to the same board, but I have a digital meter now.

The level of my watertank (rainwater) measured with a pressure sensor connected to a Shelly Uni. I bought the pressure sensor some years ago via Ali, was around €60.

1 Like

Is possible to share the yaml code of the widgets ?

Thanks
Artur

Can you please let me know where I can find these icons. Thanks!

They are from flaticon.com

And this is mine !

Basically, almost each element is clickable (Except the Spotify Widget and the todo’s list).
The design is made to fit perfectly on a Amazon Fire Tab10.

HOME : change to AWAY and in red when no one is at home (helped me to figure out what’s going on sometimes haha !)

A click inside the green open a popup that show the status of every member of the family

The meteo widget is based on the weatherCard available here → https://community.openhab.org/t/ui-widget-weather/106842


The TodoList is filled with items created dynamically from an external source (a custom one for my case, but can work well with a Calendar like Google); basically :

  • A Switch item is created for each event of the day
  • During the day, you checked each completed task
  • During the night, a script delete all the checked item

Each button below that is a scene, a flag that help me control my stuff, or a button that open a popup.
Each button can show elements like temperature, presence or not, etc…
Here’s the code of the button widget :

uid: widget_cell
tags: []
props:
  parameters:
    - description: background color
      label: Background Color
      name: bgcolor
      required: true
      type: TEXT
    - context: item
      description: item for state
      label: Item for state
      name: itemForState
      required: false
      type: TEXT
    - description: text color
      label: Text Color
      name: textColor
      required: true
      type: TEXT
    - description: text Header
      label: Text Header
      name: textHeader
      required: false
      type: TEXT
    - description: Icon Header
      label: Icon Header
      name: iconHeader
      required: false
      type: TEXT
    - description: text
      label: Text
      name: text
      required: true
      type: TEXT
    - context: item
      description: item 1 State
      label: Item 1 State
      name: item1State
      required: false
      type: TEXT
    - description: item 1 Unit
      label: Item 1 Unit
      name: item1Unit
      required: false
      type: TEXT
    - context: item
      description: item 2 State
      label: Item 2 State
      name: item2State
      required: false
      type: TEXT
    - description: item 2 Unit
      label: Item 2 Unit
      name: item2Unit
      required: false
      type: TEXT
    - context: item
      description: item 3 State
      label: Item 3 State
      name: item3State
      required: false
      type: TEXT
    - description: item 3 Unit
      label: Item 3 Unit
      name: item3Unit
      required: false
      type: TEXT
    - description: Action to perform
      label: Action
      name: action
      required: true
      type: TEXT
    - context: item
      description: Action item
      label: Action Item
      name: actionItem
      required: false
      type: TEXT
    - description: Action command
      label: Action Command
      name: actionCommand
      required: false
      type: TEXT
    - description: Action command Alt
      label: Action Command Alt
      name: actionCommandAlt
      required: false
      type: TEXT
    - description: Action Page
      label: Action Page
      name: actionPage
      required: false
      type: TEXT
    - description: Action Page Transition
      label: Action Page Transition
      name: actionPageTransition
      required: false
      type: TEXT
    - description: Action Modal
      label: Action Modal
      name: actionModal
      required: false
      type: TEXT
  parameterGroups: []
timestamp: Dec 9, 2023, 2:43:39 PM
component: oh-button
config:
  action: =props.action
  actionCommand: =props.actionCommand
  actionCommandAlt: =props.actionCommandAlt
  actionItem: =props.actionItem
  actionModal: = props.actionModal
  actionPage: =props.actionPage
  actionPageTransition: =props.actionPageTransition
  style:
    --f7-button-bg-color: =props.bgcolor
    --f7-button-hover-bg-color: =props.bgcolor
    --f7-button-text-transform: none
    border-radius: 0px
    height: 80px
    margin-bottom: 8px
    margin-top: 8px
    width: 95%
slots:
  default:
    - component: f7-row
      slots:
        default:
          - component: f7-col
            config:
              style:
                margin-left: 5px
                margin-top: 5px
                width: 50%
            slots:
              default:
                - component: Label
                  config:
                    style:
                      color: =props.textColor
                      font-size: 12px
                      font-weight: normal
                      opacity: 50%
                      text-align: left
                    text: =props.textHeader
                - component: Label
                  config:
                    style:
                      color: =props.textColor
                      font-size: 20px
                      font-weight: normal
                      text-align: left
                    text: =props.text
          - component: f7-col
            config:
              class:
                - align-items-center
                - justify-content-left
              style:
                height: 100%
                margin-top: 5px
                width: 30%
            slots:
              default:
                - component: Label
                  config:
                    style:
                      color: =props.textColor
                      font-size: 12px
                      font-weight: normal
                      height: 18px
                      text-align: right
                    text: '=items[props.item1State].state + " " + (props.item1Unit !== undefined ? props.item1Unit : "")'
                    visible: =items[props.item1State].state !== '-'
                - component: Label
                  config:
                    style:
                      color: =props.textColor
                      font-size: 12px
                      font-weight: normal
                      height: 18px
                      text-align: right
                    text: '=items[props.item2State].state + " " + (props.item2Unit !== undefined ? props.item2Unit : "")'
                    visible: =items[props.item2State].state !== '-'
                - component: Label
                  config:
                    style:
                      color: =props.textColor
                      font-size: 12px
                      font-weight: normal
                      height: 18px
                      text-align: right
                    text: '=items[props.item3State].state + " " + (props.item3Unit !== undefined ? props.item3Unit : "")'
                    visible: =items[props.item3State].state !== '-'
          - component: f7-col
            config:
              class:
                - align-items-center
                - justify-content-left
              style:
                height: 100%
                width: 10%
              visible: =items[props.itemForState].state == 'ON' || props.iconHeader != null
            slots:
              default:
                - component: f7-icon
                  config:
                    f7: circle_fill
                    style:
                      color: =props.textColor
                      float: right
                      font-size: 20px
                      height: 25px
                      margin-top: 10px
                      width: 100%
                    visible: =items[props.itemForState].state == 'ON'
                - component: f7-icon
                  config:
                    f7: =props.iconHeader
                    style:
                      color: =props.textColor
                      float: right
                      font-size: 20px
                      height: 25px
                      margin-top: 10px
                      width: 100%
                    visible: =props.iconHeader != null

Here’s an exemple of the popup (basically another Page) that show on a button click :

Here is the code of the main page (that’s involve some custom CSS) :

config:
  label: Home
  order: "2"
  sidebar: true
  style:
    --f7-card-bg-color: rgba(23,23,23,0.5)
    --f7-card-header-border-color: rgba(23, 23, 23, 0.5)
    --f7-list-item-border-color: rgba(23, 23, 23, 0.5)
    background: url("http://[SERVER_URL]:8080/static/background.jpg") no-repeat 0 50%
    background-size: 100%
  stylesheet: |
    .label-card-content {
      padding-top: 0px;
      padding-bottom: 0px
    } 
    .button{
      --f7-button-bg-color: none
    }
    .button-col-navigate{
      background: rgba(71, 71, 71, 0.5)
    }
    .button-col-flag{
      background: rgba(128,128,128, 0.5)
    }
    .label-card-content .item-inner {
      --f7-list-item-media-margin: 20px;
    }
    :root {
      --f7-popup-tablet-width: 90%;
    }
blocks:
  - component: oh-block
    config: {}
    slots:
      default:
        - component: oh-grid-row
          config: {}
          slots:
            default:
              - component: oh-grid-col
                config: {}
                slots:
                  default:
                    - component: f7-card
                      config:
                        stylesheet: |
                          .card {
                            background: transparent;
                            box-shadow: none;
                          }
                      slots:
                        default:
                          - component: oh-grid-row
                            slots:
                              default:
                                - component: oh-grid-col
                                  config:
                                    stylesheet: |
                                      .card {
                                        background: transparent;
                                        box-shadow: none;
                                        margin-top: 15px;
                                      }
                                    width: "100"
                                  slots:
                                    default:
                                      - component: oh-label-card
                                        config:
                                          action: popup
                                          actionModal: page:page_c1e70f191b
                                          background: '=(items.presence.state == "ON" ? "rgba(45,141,36,0.5)" :
                                            "rgba(196,0,0,0.5)")'
                                          fontSize: 24px
                                          fontWeight: bold
                                          icon: f7:person_3_fill
                                          item: Presence
                                          label: '=(items.presence.state == "ON" ? "HOME" : "AWAY")'
                                          stylesheet: >
                                            .item-inner{
                                              padding-bottom: var(--f7-list-item-padding-vertical) !important;
                                              padding-top: var(--f7-list-item-padding-vertical) !important;
                                              height: 100% !important;
                                              justify-content: left!important;
                                              width: 100% !important;
                                            }
                          - component: oh-grid-row
                            config: {}
                            slots:
                              default:
                                - component: oh-grid-col
                                  config:
                                    style:
                                      margin-left: 0px
                                      margin-right: 0px
                                    width: "35"
                                  slots:
                                    default:
                                      - component: widget:weatherCard_small
                                        config:
                                          itemPrefix: One_Call_API_Weather_and_Forecast_
                                          locationTitle: [CITY]
                                          sunIndicator: true
                                          widget_action: popup
                                          widget_actionModal: widget:weatherCard
                                          widget_actionModalConfig: {}
                                - component: oh-grid-col
                                  config:
                                    width: "35"
                                  slots:
                                    default:
                                      - component: f7-card
                                        config:
                                          stylesheet: |
                                            .card {
                                              background: transparent;
                                              box-shadow: none;
                                            }
                                            .card-content {
                                              min-height: 42px;
                                            }
                                        slots:
                                          default:
                                            - component: widget:multiroom_audio_control
                                              config:
                                                activeDeviceShuffle: Spotify_Player_Bridge_Active_Device_Shuffle
                                                albumArtItem: Spotify_Player_Bridge_AlbumImage
                                                artistItem: Spotify_Player_Bridge_Media_Artist
                                                darkTheme: true
                                                multiroomControlItem: Spotify_Player_Bridge_Active_Devices
                                                playerControlItem: Spotify_Player_Bridge_Media_Control
                                                repeatMode: Spotify_Player_Bridge_Repeat_Mode
                                                trackItem: Spotify_Player_Bridge_Media_Title
                                                trackProgressItem: Spotify_Player_Bridge_Track_Progress_mss
                                                trackTimeItem: Spotify_Player_Bridge_Track_Duration_mss
                                                volumeControlItem: Spotify_Player_Bridge_Volume
                                - component: oh-grid-col
                                  config:
                                    style:
                                      margin-left: 0px
                                      margin-right: 0px
                                    width: "30"
                                  slots:
                                    default:
                                      - component: widget:CalendarEventList
  - component: oh-grid-block
    config: {}
    slots:
      default:
        - component: oh-grid-row
          config: {}
          slots:
            default:
              - component: oh-grid-col
                config:
                  class: button-col-navigate
                slots:
                  default:
                    - component: widget:widget_cell
                      config:
                        action: popup
                        actionModal: page:page_890d955693
                        actionPageTransition: f7-dive
                        item1State: Sensibo_Sky_Current_Temperature
                        item2State: Sensibo_Sky_Current_Humidity
                        item2Unit: "%"
                        item3State: Living_Room_Aqara_Illuminance
                        itemForState: Living_Room_Aqara_Occupancy
                        text: Open Area
                        textColor: white
                        textHeader: Navigate
              - component: oh-grid-col
                config:
                  class: button-col-navigate
                slots:
                  default:
                    - component: widget:widget_cell
                      config:
                        action: popup
                        actionModal: page:page_989c3b7577
                        actionPageTransition: f7-dive
                        item1State: Bathroom_Aqara_Temperature
                        item2State: Bathroom_Aqara_Illuminance
                        itemForState: Bathroom_Aqara_Occupancy
                        text: Bathroom
                        textColor: white
                        textHeader: Navigate
              - component: oh-grid-col
                config:
                  class: button-col-navigate
                slots:
                  default:
                    - component: widget:widget_cell
                      config:
                        action: popup
                        actionModal: page:page_99615e72a6
                        actionPageTransition: f7-dive
                        item1State: Bedroom_Aqara_Temperature
                        item1Unit: °C
                        item2State: Bedroom_Aqara_Illuminance
                        item2Unit: lx
                        itemForState: Bedroom_Aqara_Occupancy
                        text: Bedroom
                        textColor: white
                        textHeader: Navigate
              - component: oh-grid-col
                config:
                  class: button-col-navigate
                slots:
                  default:
                    - component: widget:widget_cell
                      config:
                        action: popup
                        actionModal: page:page_5de8c2b57d
                        actionPageTransition: f7-dive
                        item1State: One_Call_API_Weather_and_Forecast_Current_Temperature
                        item2State: One_Call_API_Weather_and_Forecast_Current_Humidity
                        item3State: One_Call_API_Weather_and_Forecast_Current_Windspeed
                        text: Outside
                        textColor: white
                        textHeader: Navigate
              - component: oh-grid-col
                config:
                  class: button-col-navigate
                slots:
                  default:
                    - component: widget:widget_cell
                      config:
                        action: popup
                        actionModal: page:page_4bceabf774
                        actionPageTransition: f7-dive
                        text: Entry
                        textColor: white
                        textHeader: Navigate
              - component: oh-grid-col
                config:
                  class: button-col-navigate
                slots:
                  default:
                    - component: widget:widget_cell
                      config:
                        action: popup
                        actionModal: page:page_fc65b68977
                        actionPageTransition: f7-dive
                        text: Flags
                        textColor: white
                        textHeader: Navigate
  - component: oh-block
    config: {}
    slots:
      default:
        - component: oh-grid-row
          config: {}
          slots:
            default:
              - component: oh-grid-col
                config:
                  style:
                    background-color: Rgba(255,0,0,.5)
                slots:
                  default:
                    - component: widget:widget_cell
                      config:
                        action: toggle
                        actionCommand: ON
                        actionCommandAlt: OFF
                        actionItem: TRIG_Bedtime
                        itemForState: TRIG_Bedtime
                        text: Bed
                        textColor: white
                        textHeader: Activate Scene
              - component: oh-grid-col
                config:
                  style:
                    background-color: Rgba(30,144,255,.5)
                slots:
                  default:
                    - component: widget:widget_cell
                      config:
                        action: toggle
                        actionCommand: ON
                        actionCommandAlt: OFF
                        actionItem: TRIG_BathTime
                        itemForState: TRIG_BathTime
                        text: Bath
                        textColor: white
                        textHeader: Activate Scene
              - component: oh-grid-col
                config:
                  style:
                    background-color: Rgba(0,128,0,.5)
                slots:
                  default:
                    - component: widget:widget_cell
                      config:
                        action: toggle
                        actionCommand: ON
                        actionCommandAlt: OFF
                        actionItem: TRIG_Wakeup
                        itemForState: TRIG_Wakeup
                        text: Wake Up
                        textColor: white
                        textHeader: Activate Scene
              - component: oh-grid-col
                config:
                  style:
                    background-color: Rgba(255,204,0,.5)
                slots:
                  default:
                    - component: widget:widget_cell
                      config:
                        action: toggle
                        actionCommand: ON
                        actionCommandAlt: OFF
                        actionItem: TRIG_MovieTime
                        itemForState: TRIG_MovieTime
                        text: Movie
                        textColor: white
                        textHeader: Activate Scene
              - component: oh-grid-col
                config:
                  style:
                    background-color: Rgba(255,165,0,.5)
                slots:
                  default:
                    - component: widget:widget_cell
                      config:
                        action: toggle
                        actionCommand: ON
                        actionCommandAlt: OFF
                        actionItem: TRIG_Evening
                        itemForState: TRIG_Evening
                        text: Sunset
                        textColor: white
                        textHeader: Activate Scene
              - component: oh-grid-col
                config:
                  style:
                    background-color: Rgba(184,0,28,.5)
                slots:
                  default:
                    - component: widget:widget_cell
                      config:
                        action: toggle
                        actionCommand: ON
                        actionCommandAlt: OFF
                        actionItem: TRIG_Working
                        itemForState: TRIG_Working
                        text: At Work
                        textColor: white
                        textHeader: Activate Scene
  - component: oh-block
    config: {}
    slots:
      default:
        - component: oh-grid-row
          config: {}
          slots:
            default:
              - component: oh-grid-col
                config:
                  style:
                    background-color: Rgba(170,170,170,.5)
                slots:
                  default:
                    - component: widget:widget_cell
                      config:
                        action: toggle
                        actionCommand: ON
                        actionCommandAlt: OFF
                        actionItem: TRIG_CloseAllLights
                        itemForState: TRIG_CloseAllLights
                        text: Close Lights
                        textColor: white
                        textHeader: Activate Scene
              - component: oh-grid-col
                config:
                  class: button-col-flag
                slots:
                  default:
                    - component: widget:widget_cell
                      config:
                        action: toggle
                        actionCommand: ON
                        actionCommandAlt: OFF
                        actionItem: TRIG_OutForAWalk
                        itemForState: TRIG_OutForAWalk
                        text: Coming Back
                        textColor: Black
                        textHeader: Flag
              - component: oh-grid-col
                config:
                  class: button-col-flag
                slots:
                  default:
                    - component: widget:widget_cell
                      config:
                        action: toggle
                        actionCommand: ON
                        actionCommandAlt: OFF
                        actionItem: TRIG_DogAloneAtHome
                        itemForState: TRIG_DogAloneAtHome
                        text: Dog At Home
                        textColor: Black
                        textHeader: Flag
              - component: oh-grid-col
                config:
                  class: button-col-flag
                slots:
                  default:
                    - component: widget:widget_cell
                      config:
                        action: toggle
                        actionCommand: ON
                        actionCommandAlt: OFF
                        actionItem: TRIG_LivingRoomLight_TurnOnAuto
                        itemForState: TRIG_LivingRoomLight_TurnOnAuto
                        text: Lights Auto
                        textColor: Black
                        textHeader: Flag
              - component: oh-grid-col
                config:
                  class: button-col-flag
                slots:
                  default:
                    - component: widget:widget_cell
                      config:
                        action: toggle
                        actionCommand: ON
                        actionCommandAlt: OFF
                        actionItem: TRIG_AC_TurnOnAuto
                        itemForState: TRIG_AC_TurnOnAuto
                        text: AC Auto
                        textColor: Black
                        textHeader: Flag
              - component: oh-grid-col
                config:
                  class: button-col-flag
                slots:
                  default:
                    - component: widget:widget_cell
                      config:
                        action: toggle
                        actionCommand: ON
                        actionCommandAlt: OFF
                        actionItem: TRIG_WarningTempOutdoorReachIndoor
                        itemForState: TRIG_WarningTempOutdoorReachIndoor
                        text: Temp. In/Out
                        textColor: Black
                        textHeader: Flag
  - component: oh-block
    config: {}
    slots:
      default:
        - component: oh-grid-row
          config: {}
          slots:
            default:
              - component: oh-grid-col
                config:
                  width: "30"
                slots:
                  default: []
              - component: oh-grid-col
                config: {}
                slots:
                  default: []
masonry: null
grid: null
canvas: []

4 Likes

I like the “Dog at home” :grin:

@Integer
It would be nice to have some kind of git repository or central storage for all of your ui examples and widgets, as they could be accessed by everyone and always have the latest version of the widgets. Would be nice to hear from you.

Easiest would be to publish widgets on the marketplace and link to the yaml file hosted e.g. on github.
That’s what I do with the semanticHomeMenu widgets.
Doing this, widgets can be installed easily via MainUI.

Yes, that would be an idea. My thought was only, that here it is almost impossible to get any info about the state of dev of a single widget, because there are so many messages in this thread. So I thought it would be nice, to have some overall storage for the widgets, so if someone is updating or forking it, you can easily see and get updates.