[OH3] Main UI Examples

You should mention in the published widget which type of airconditioner/binding is supported, as you are going to hardcode the speedlevels.
Intesis binding e.g uses numbers 1-4, without any Level String…

mine is Daikin AC, with Daikin Binding. actually is implemted but not working in my widget. maybe i will publish another version specific per daikin binding.
here is documented “fanspeed”:

Daikin - Bindings | openHAB

thanks

Just rename your Widget to be Daikin AC related, no second version needed.

Create a post here and follow the template and instructions you are provided.

Doing this entirely within a widget is a little complex. There are limitations to what you can use in the widget expressions, especially when it comes to array manipulation.

First you need to get an array of the different possible levels. This is most easily achieved by having the array entered as a widget parameter. Just as with things like the item state description:


You can set up parameter to be an array of text lines with the same value=label format.

  parameters:
    - context: text
      description: value=label
      label: Test Array
      name: tArray
      required: false
      type: TEXT
      multiple: true

The key here is the multiple=true property. This allows you to enter an array. In this case your array would just be the command list you posted above:
image

That the easy part. And even though it seems a like an extra step instead of hard coding the array, it means that the widget can be more general as you can use any value=label array.

Now, here’s some sample code that then uses variables to show what the conversion from array element to both command and readable label looks like.

uid: demo:step_array
tags: []
props:
  parameters:
    - context: text
      description: value=label
      label: Test Array
      name: tArray
      required: false
      type: TEXT
      multiple: true
  parameterGroups: []
component: f7-card
config:
  title: "='Readable label: ' + ((vars.arrayResult) ? props.tArray[props.tArray.join('').substring(0,props.tArray.join('').search(vars.arrayResult)).split('=').length-1].split('=')[1] : 'Push a button')"
  footer: "='Command: ' + ((vars.arrayResult) ? vars.arrayResult : 'None')"
slots:
  default:
    - component: oh-button
      config:
        action: variable
        actionVariable: arrayResult
        actionVariableValue: =props.tArray[Math.min(props.tArray.join('').substring(0,props.tArray.join('').search(vars.arrayResult)).split('=').length,props.tArray.length-1)].split('=')[0]
        text: Next Array Element
    - component: oh-button
      config:
        action: variable
        actionVariable: arrayResult
        actionVariableValue: =props.tArray[Math.max(props.tArray.join('').substring(0,props.tArray.join('').search(vars.arrayResult)).split('=').length-2,0)].split('=')[0]
        text: Prev Array Element

step_array

To convert it to send the commands to items you just have to

  1. Change the oh-buttons to use the command action instead of the variable action
  2. Change all the vars.arrayResult to the state of your item
1 Like

thanks a lot for your help! learnt a new thing that will come useful :slight_smile:

but i have an issue. maybe i’m doing something wrong…

when i change this:

    - component: oh-button
      config:
        action: variable
        actionVariable: arrayResult
        actionVariableValue: =props.tArray[Math.min(props.tArray.join('').substring(0,props.tArray.join('').search(vars.arrayResult)).split('=').length,props.tArray.length-1)].split('=')[0]

into this:

    - component: oh-button
      config:
        action: command
        actionItem: =props.set_speed_item
        actionCommand: =props.tArray[Math.min(props.tArray.join('').substring(0,props.tArray.join('').search(vars.arrayResult)).split('=').length,props.tArray.length-1)].split('=')[0]

and adding in props these:

    - context: text
      description: value=label
      label: Array
      name: tArray
      required: false
      type: TEXT
      multiple: true
    - context: item
      label: Set Speed
      name: set_speed_item
      required: false
      type: TEXT

and the label is configured in this way:

    - component: Label
      config:
        visible: "=props.set_speed_item ? true : false"
        text: =items[props.set_speed_item].displayState

i’m not able to move between array elements. or better, i’m only able to move between first and second object of the array.

what i’m doing wrong?

There’s still one more vars.arrayResult that needs to be changed over to the item state in the action Command line.

forgot to tell, but i tried to change also that into this:

actionCommand: =props.tArray[Math.min(props.tArray.join('').substring(0,props.tArray.join('').search(props.set_speed_item)).split('=').length,props.tArray.length-1)].split('=')[0]

it switch only from AUTO to SILENCE and from SILENCE to AUTO.
it won’t read other values…this issue seems to come only when i switch from

action: variable

to

action: command

could be this the issue?

That represents only the name of the item. Not the item state. In order to get the item state, you must use items[props.set_speed_item].state. So, that is what must go into the search method:

search(items[props.set_speed_item].state)
1 Like

oh yes! from test seems to work perfectly! i will test it with real device.

thanks a lot for your support! i was near to set the right item state in code, but i missed “[ ]”. thanks a lot again!

Hey @rubenfuser,

that looks really good.

One question:

Do you have an idea how get the footer colored?

When using the inspector of Chrome, the footer seems not to be at the bottom of the widget.

image

Could you have a look?

Cheers, Nic

Yes i achieved that. I will post the code:


uid: Conditioner Card v2
tags:
  - MadeByEvil
props:
  parameters:
    - description: Small title on top of the card
      label: Title
      name: title
      required: false
      type: TEXT
    - description: Icon on top of the card ( only f7 icons without "f7:" )
      label: Icon
      name: icon
      required: false
      type: TEXT
    - description: in rgba() or HEX or empty
      label: Background Color
      name: bgcolor
      required: false
      type: TEXT
    - context: item
      label: Current Temperature
      name: temp_item
      required: false
      type: TEXT
    - context: item
      label: Set Temperature
      name: set_temp_item
      required: false
      type: TEXT
    - context: text
      description: value=label
      label: Array
      name: tArray
      required: false
      type: TEXT
      multiple: true
    - context: item
      label: Set Speed
      name: set_speed_item
      required: false
      type: TEXT
    - context: item
      label: Power ON/OFF
      name: power
      required: false
      type: TEXT
    - context: item
      description: Modalità item
      label: Modalità
      name: heating_item
      required: false
      type: TEXT
    - context: item
      description: Trendline item
      label: Trendline
      name: widgettrend
      required: false
      type: TEXT
  parameterGroups:
    - name: widgetAction
      context: action
      label: Action
      description: Action to perform when the element is clicked
timestamp: Aug 6, 2022, 4:09:55 PM
component: f7-card
config:
  style:
    noShadow: false
    padding: 0px
    border-radius: var(--f7-card-expandable-border-radius)
    box-shadow: 5px 5px 10px 1px rgba(0,0,0,0.1)
    height: 200px
    margin-left: 5px
    margin-right: 5px
slots:
  content:
    - component: f7-block
      config:
        style:
          position: absolute
          top: -10px
          left: 10px
          flex-direction: row
          display: flex
      slots:
        default:
          - component: f7-icon
            config:
              f7: =props.icon
              size: 18
              style:
                margin-right: 10px
              visible: "=props.icon ? true : false"
          - component: Label
            config:
              text: "=props.title ? props.title : ''"
              style:
                font-size: 12px
                margin-top: 0px
    - component: f7-block
      config:
        style:
          position: absolute
          bottom: -20px
          left: 16px
          flex-direction: row
      slots: {}
    - component: Label
      config:
        text: "=items[props.temp_item].displayState ? items[props.temp_item].displayState : items[props.temp_item].state"
        style:
          font-size: 20px
          font-weight: 400
          margin-left: 0px
          margin-top: 10px
          color: '=items[props.temp_item].state >= "22" ? "red" : items[props.temp_item].state <= "20" ? "blue" :"white"'
    - component: oh-button
      config:
        visible: '=items[props.heating_item].displayState == "Pompa di calore" ? "true" : items[props.heating_item].displayState == "Condizionatore" ? "true" : "false"'
        iconColor: '=items[props.heating_item].displayState == "Deumidificatore" && items[props.power].state == "ON" ? "yellow" : items[props.heating_item].displayState == "Pompa di calore" && items[props.power].state == "ON" ? "red" : items[props.heating_item].displayState == "Condizionatore" && items[props.power].state == "ON" ? "blue" : items[props.heating_item].displayState == "Ventola" && items[props.power].state == "ON" ? "orange" : "gray"'
        iconF7: arrow_up_circle
        iconSize: 35
        action: command
        actionItem: =props.set_temp_item
        actionCommand: =Number(items[props.set_temp_item].state.split(' ')[0]) + 0.5
        style:
          position: absolute
          top: 40px
          right: 0px
          height: 33px
          background: transparent
          z-index: 98
    - component: oh-button
      config:
        visible: '=items[props.heating_item].displayState == "Pompa di calore" ? "true" : items[props.heating_item].displayState == "Condizionatore" ? "true" : "false"'
        iconColor: '=items[props.heating_item].displayState == "Deumidificatore" && items[props.power].state == "ON" ? "yellow" : items[props.heating_item].displayState == "Pompa di calore" && items[props.power].state == "ON" ? "red" : items[props.heating_item].displayState == "Condizionatore" && items[props.power].state == "ON" ? "blue" : items[props.heating_item].displayState == "Ventola" && items[props.power].state == "ON" ? "orange" : "gray"'
        iconF7: arrow_down_circle
        iconSize: 35
        action: command
        actionItem: =props.set_temp_item
        actionCommand: =Number(items[props.set_temp_item].state.split(' ')[0]) - 0.5
        style:
          position: absolute
          top: 104px
          right: 0px
          height: 33px
          background: transparent
          z-index: 98
    - component: Label
      config:
        visible: '=items[props.heating_item].displayState == "Pompa di calore" ? "true" : items[props.heating_item].displayState == "Condizionatore" ? "true" : "false"'
        text: '=items[props.set_temp_item].state == "UNDEF" ? " " : items[props.set_temp_item].state'
        style:
          font-size: 12px
          position: absolute
          right: 8px
          top: 80px
    - component: oh-button
      config:
        visible: "=props.set_speed_item ? true : false"
        iconColor: '=items[props.heating_item].displayState == "Deumidificatore" && items[props.power].state == "ON" ? "yellow" : items[props.heating_item].displayState == "Pompa di calore" && items[props.power].state == "ON" ? "red" : items[props.heating_item].displayState == "Condizionatore" && items[props.power].state == "ON" ? "blue" : items[props.heating_item].displayState == "Ventola" && items[props.power].state == "ON" ? "orange" : "gray"'
        iconF7: arrow_up_circle
        iconSize: 35
        action: command
        actionItem: =props.set_speed_item
        actionCommand: =props.tArray[Math.max(props.tArray.join('').substring(0,props.tArray.join('').search(items[props.set_speed_item].state)).split('=').length-2,0)].split('=')[0]
        style:
          position: absolute
          top: 40px
          right: 40px
          height: 35px
          background: transparent
          z-index: 98
    - component: oh-button
      config:
        visible: "=props.set_speed_item ? true : false"
        iconColor: '=items[props.heating_item].displayState == "Deumidificatore" && items[props.power].state == "ON" ? "yellow" : items[props.heating_item].displayState == "Pompa di calore" && items[props.power].state == "ON" ? "red" : items[props.heating_item].displayState == "Condizionatore" && items[props.power].state == "ON" ? "blue" : items[props.heating_item].displayState == "Ventola" && items[props.power].state == "ON" ? "orange" : "gray"'
        iconF7: arrow_down_circle
        iconSize: 35
        action: command
        actionItem: =props.set_speed_item
        actionCommand: =props.tArray[Math.min(props.tArray.join('').substring(0,props.tArray.join('').search(items[props.set_speed_item].state)).split('=').length,props.tArray.length-1)].split('=')[0]
        style:
          position: absolute
          top: 104px
          right: 40px
          height: 35px
          background: transparent
          z-index: 98
    - component: Label
      config:
        visible: "=props.set_speed_item ? true : false"
        text: "=((items[props.set_speed_item].state) ? props.tArray[props.tArray.join('').substring(0,props.tArray.join('').search(items[props.set_speed_item].state)).split('=').length-1].split('=')[1] : 'Push a button')"
        style:
          color: red
          font-size: 12px
          position: absolute
          right: 58px
          top: 80px
    - component: f7-block
      config:
        style:
          position: absolute
          top: 50px
          left: 15px
          width: "=props.set_temp_item ? 'calc(100% - 55px)' : '100%' "
          height: 120px
      slots:
        default:
          - component: oh-trend
            config:
              trendItem: =props.widgettrend
              trendGradient:
                - "#aa2b1d"
                - "#cc561e"
                - "#ef8d32"
                - "#beca5c"
              style:
                --f7-theme-color-bg-color: transparent
                background: var(--f7-theme-color-bg-color)
                filter: opacity(50%)
                position: absolute
                width: 80%
                height: 100%
                top: 0px
                left: 15px
                z-index: 98
    - component: oh-toggle
      config:
        item: =props.power
        color: '=items[props.heating_item].displayState == "Deumidificatore" && items[props.power].state == "ON" ? "yellow" : items[props.heating_item].displayState == "Pompa di calore" && items[props.power].state == "ON" ? "red" : items[props.heating_item].displayState == "Condizionatore" && items[props.power].state == "ON" ? "blue" : items[props.heating_item].displayState == "Ventola" && items[props.power].state == "ON" ? "orange" : "black"'
        style:
          --f7-toggle-height: 20px
          --f7-toggle-width: 40px
          font-size: 100%
          top: 115px
          z-index: 98
    - component: oh-button
      config:
        iconColor: '=items[props.heating_item].displayState == "Condizionatore" && items[props.power].state == "ON" ? "blue" : "black"'
        iconF7: snow
        iconSize: 25
        action: command
        actionItem: =props.heating_item
        actionCommand: COOL
        style:
          position: absolute
          top: 165px
          left: 25%
          height: 35px
          background: transparent
          z-index: 98
    - component: oh-button
      config:
        iconColor: '=items[props.heating_item].displayState == "Pompa di calore" && items[props.power].state == "ON" ? "red" : "black"'
        iconF7: flame
        iconSize: 20
        action: command
        actionItem: =props.heating_item
        actionCommand: HEAT
        style:
          position: absolute
          top: 165px
          left: 45%
          height: 35px
          background: transparent
          z-index: 98
    - component: oh-button
      config:
        iconColor: '=items[props.heating_item].displayState == "Deumidificatore" && items[props.power].state == "ON" ? "yellow" : "black"'
        iconF7: drop
        iconSize: 20
        action: command
        actionItem: =props.heating_item
        actionCommand: DEHUMIDIFIER
        style:
          position: absolute
          top: 165px
          left: 65%
          height: 35px
          background: transparent
          z-index: 98
    - component: oh-button
      config:
        iconColor: '=items[props.heating_item].displayState == "Ventola" && items[props.power].state == "ON" ? "orange" : "black"'
        iconF7: wind
        iconSize: 20
        action: command
        actionItem: =props.heating_item
        actionCommand: FAN
        style:
          position: absolute
          top: 165px
          left: 85%
          height: 35px
          background: transparent
          z-index: 98
    - component: f7-card-footer
      config:
        style:
          top: 84px
          left: -16px
          width: 110%
          background: '=items[props.heating_item].displayState == "Deumidificatore" && items[props.power].state == "ON" ? "#ffffb3" : items[props.heating_item].displayState == "Pompa di calore" && items[props.power].state == "ON" ? "#ffc2b3" : items[props.heating_item].displayState == "Condizionatore" && items[props.power].state == "ON" ? "#b3b3ff" : items[props.heating_item].displayState == "Ventola" && items[props.power].state == "ON" ? "#ffd9b3" : "#3F3F3F"'
          border-radius: 0 0 var(--f7-card-expandable-border-radius) var(--f7-card-expandable-border-radius)

This is the widget but not completely finished,but you will find what you need for footer :wink: