[OH3] Main UI - New „main_widget“ - development and testing [deprecated]

Yes- a new topic seems a good idea.

I am on Holiday this week- so i poorly can not wohl this week on pur ideas/widgets.

But if you could start the new Thread - this would be Great . Perhaps we start with a collection of Designs and codes we allready have .

1 Like

i’ve tried both widgets and none are shown correctly.
i think you can start from this widget that is quite similar to what you need to accomplish.
it’s not finished, but i have a lots of limits, so someone could correct the line on the top of the card, and force a different color to footer…i’m a little bit lost :wink:

uid: Conditioner Card
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: 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 1, 2022, 2:51:58 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)
    background-color: "=props.bgcolor ? props.bgcolor : ''"
    height: 200px
    margin-left: 5px
    margin-right: 5px
slots:
  default:
    - component: oh-link
      config:
        actionPropsParameterGroup: widgetAction
        color: white
        class:
          - no-padding
          - no-margin
        style:
          max-height: 192px
          width: 80%
          height: 80%
          position: absolute
          top: 0
          left: 0
          z-index: 98
  content:
    - component: f7-block
      config:
        style:
          position: absolute
          top: -5px
          left: 16px
          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:
        default:
          - component: Label
            config:
              text: "=items[props.temp_item].displayState ? items[props.temp_item].displayState : items[props.temp_item].state"
              style:
                font-size: 22px
                font-weight: 400
                margin-left: 0px
                margin-top: 0px
                
                
    - component: oh-button
      config:
        visible: "=props.set_temp_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_temp_item
        actionCommand: =Number(items[props.set_temp_item].state.split(' ')[0]) + 0.5
        style:
          position: absolute
          top: 12px
          right: 10px
          height: 35px
          background: transparent
    - component: oh-button
      config:
        visible: "=props.set_temp_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_temp_item
        actionCommand: =Number(items[props.set_temp_item].state.split(' ')[0]) - 0.5
        style:
          position: absolute
          top: 74px
          right: 10px
          height: 35px
          background: transparent
          
          
    - component: Label
      config:
        visible: "=props.set_temp_item ? true : false"
        text: =items[props.set_temp_item].state
        style:
          font-size: 12px
          position: absolute
          right: 15px
          top: 50px
    - component: f7-block
      config:
        style:
          position: absolute
          top: 15px
          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: 100%
                height: 100%
                top: 0px
                left: 0px
                z-index: 1
  footer:
    - 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" : "grey"'
        style:
          top: 120px
    - component: f7-icon
      config:
        f7: snow
        size: 30
        color: '=items[props.heating_item].displayState == "Condizionatore" && items[props.power].state == "ON" ? "blue" : "gray"'
        style:
          top: 120px
          #left: -150px

    - component: f7-icon
      config:
        f7: flame
        size: 30
        color: '=items[props.heating_item].displayState == "Pompa di calore" && items[props.power].state == "ON" ? "red" : "gray"'
        style:
          top: 120px
          #left: -150px

    - component: f7-icon
      config:
        f7: drop
        size: 30
        color: '=items[props.heating_item].displayState == "Deumidificatore" && items[props.power].state == "ON" ? "yellow" : "gray"'
        style:
          top: 120px
          #left: -150px
          
    - component: f7-icon
      config:
        f7: wind
        size: 30
        color: '=items[props.heating_item].displayState == "Ventola" ? "orange" : "gray"'
        style:
          top: 120px
          #left: -150px              

1 Like

Nice designs! Here’s a quick attempt to implement @Dimitris’ card design (card style + sliders only, not the whole thermostat settings). Remember to always to try to use as many CSS variables as possible, even if they’re unrelated, find one that suits, it’s always better than hardcoded colors etc. Otherwise it might not look good if you e.g. switch to dark mode or change the theme (and try with the 6 theme/dark mode combinations regularly).

uid: Cell_Light_Card_1
tags: []
props:
  parameters: []
  parameterGroups: []
timestamp: Aug 1, 2022, 6:37:08 PM
component: f7-card
config:
  noShadow: false
  padding: false
  style:
    padding: 0px
    border-radius: var(--f7-card-expandable-border-radius)
    box-shadow: 5px 5px 15px 1px rgba(0,0,0,0.05)
    margin-left: 5px
    margin-right: 5px
  stylesheet: >
    .card-header:after {
      display: none;
    }
slots:
  content:
    - component: f7-card-header
      config:
        style:
          height: 4rem
      slots:
        default:
          - component: oh-icon
            config:
              icon: f7:rectangle_grid_1x2
              height: 36
              style:
                position: absolute
                top: 15px
                left: 20px
          - component: oh-toggle
            config:
              item: aaa_Sw
              color: yellow
              style:
                position: absolute
                top: 15px
                right: 20px
                --f7-toggle-height: 30px
                --f7-toggle-width: 60px
          - component: f7-block
            config:
              style:
                flex-direction: row
                margin-left: 2.5rem
            slots:
              default:
                - component: Label
                  config:
                    text: Hue Play
                    style:
                      font-size: 15px
                      font-weight: 600
                      margin-left: 0px
                      margin-top: 0px
                      line-height: 1.1
                - component: Label
                  config:
                    text: Living Room Lights
                    style:
                      color: var(--f7-list-item-footer-text-color)
                      font-size: 15px
                      font-weight: 400
                      margin-left: 0px
                      margin-top: 0px
                      line-height: 1.2
    - component: f7-card-content
      config:
        style:
          margin-bottom: -1rem
          --f7-range-bar-size: 2px
          --f7-range-bar-border-radius: 0
          --f7-range-bar-border-color: rgba(0, 0, 0, 0.2)
          --f7-range-knob-size: 30px
          --f7-range-knob-color: white
          --f7-range-knob-box-shadow: none
          --f7-range-bar-active-bg-color: transparent
        stylesheet: >
          .range-bar  {
            opacity: 0.3;
          } .range-knob {
            border-color: rgba(0, 0, 0, 0.3);
            border-width: 2px;
            border-style: solid;
          }
      slots:
        default:
          - component: Label
            config:
              text: Brightness
              style:
                color: var(--f7-list-item-footer-text-color)
                font-size: 13px
                font-weight: var(--f7-list-item-footer-font-weight)
                margin-left: 2rem
                margin-top: 0px
                margin-bottom: -1rem
                line-height: 0.5
          - component: oh-slider
            config:
              item: TestDimmer
              min: 0
              max: 100
              style:
                margin: 2rem
                width: calc(100% - 4rem)
          - component: Label
            config:
              text: Red
              style:
                color: var(--f7-list-item-footer-text-color)
                font-size: 13px
                font-weight: var(--f7-list-item-footer-font-weight)
                margin-left: 2rem
                margin-top: 0px
                margin-bottom: -1rem
                line-height: 0.5
          - component: oh-slider
            config:
              item: TestDimmer
              min: 0
              max: 100
              style:
                margin: 2rem
                width: calc(100% - 4rem)
                --f7-range-knob-color: var(--f7-color-red)
                --f7-range-bar-active-bg-color: var(--f7-color-red)
          - component: Label
            config:
              text: Green
              style:
                color: var(--f7-list-item-footer-text-color)
                font-size: 13px
                font-weight: var(--f7-list-item-footer-font-weight)
                margin-left: 2rem
                margin-top: 0px
                margin-bottom: -1rem
                line-height: 0.5
          - component: oh-slider
            config:
              item: TestDimmer
              min: 0
              max: 100
              style:
                margin: 2rem
                width: calc(100% - 4rem)
                --f7-range-knob-color: var(--f7-color-green)
                --f7-range-bar-active-bg-color: var(--f7-color-green)
          - component: Label
            config:
              text: Blue
              style:
                color: var(--f7-list-item-footer-text-color)
                font-size: 13px
                font-weight: var(--f7-list-item-footer-font-weight)
                margin-left: 2rem
                margin-top: 0px
                margin-bottom: -1rem
                line-height: 0.5
          - component: oh-slider
            config:
              item: TestDimmer
              min: 0
              max: 100
              style:
                margin: 2rem
                width: calc(100% - 4rem)
                --f7-range-knob-color: var(--f7-color-blue)
                --f7-range-bar-active-bg-color: var(--f7-color-blue)
    - component: f7-card-footer
      config:
        style:
          background: "=(vars.footercolor) ? 'rgba(var(--f7-color-' + vars.footercolor + '-rgb), 0.1)' : 'var(--f7-bars-bg-color)'"
          border-radius: 0 0 var(--f7-card-expandable-border-radius) var(--f7-card-expandable-border-radius)
          padding: 1rem 2rem
      slots:
        default:
          - component: oh-toggle
            config:
              color: =vars.footercolor || 'gray'
              style:
                --f7-toggle-height: 25px
                --f7-toggle-width: 50px
          - component: f7-block
            config:
              style:
                width: 130px
                padding: 0
                display: flex
                justify-content: space-between
            slots:
              default:
                - component: oh-link
                  config:
                    iconF7: snow
                    iconSize: 30
                    height: 30px
                    width: 30px
                    color: "=vars.footercolor === 'lightblue' ? 'lightblue' : 'gray'"
                    action: variable
                    actionVariable: footercolor
                    actionVariableValue: lightblue
                - component: oh-link
                  config:
                    iconF7: flame
                    iconSize: 30
                    height: 30px
                    width: 30px
                    color: "=vars.footercolor === 'red' ? 'red' : 'gray'"
                    action: variable
                    actionVariable: footercolor
                    actionVariableValue: red
                - component: oh-link
                  config:
                    iconF7: wind
                    iconSize: 30
                    height: 30px
                    width: 30px
                    color: "=vars.footercolor === 'yellow' ? 'yellow' : 'gray'"
                    action: variable
                    actionVariable: footercolor
                    actionVariableValue: yellow

Nothing is mapped to props but you can try the icons in the footer to change the color (with a variable).
You can remove the f7-card-content & f7-card-footer components if you want a simpler card.

image

3 Likes

Hey @ysc,

Looks great.

Do you have a hint how to get the two up/down buttons on the right side? In which Slot should the oh-buttons be inserted? And should they be wrapped in a f7-col?

Yees, Please do so! :wink:

Oh man. Clearly, this is a show-off!! I’m appreciate your contribution and real-life / hands-on engagement to this project. It seems that there is a huge coding-power lives in this group! Now, I need to apologize for my limited time this period. You all know that he have to balance between business and entertainment, right ? So, my commitment is to present a graphical -only :innocent: solution before Aug 20. I’m deeply appreciate your efforts guys.
@ysc Is there any chance to make a widget “dynamic”? ie when the equipment is OFF shows only the on-off button- when it’s on reveals the full controls? Yep, this is Apple-like UI design, but i think is the only way to balance between a geek user control and real life / every day home control…

Most fields in the YAML will support Expressions.

based on your suggestions, i’ve ended my new widget:

image

with setpoint arrows visible only when “cool” and “heat” icons are clicked:

image

icons colored only when active:

image

and with setpoint active for cooling mode.

image

4 Likes

Looks like a widget that would make a great addition to the Market Place. :wink:

2 Likes

Hi,

Can you share the yaml code .

Thanks
// Artur

so glad to hear this! estetichally should be nice, but in code, maybe something need to be corrected (i’m not a programmer). if someone that know better than me yaml code, would like to adjust what’s not correct, i’ll appreciate.

@rlkoshak, eventually, how can i upload to the marketplace?

@tonicoveiro, following the code:

NOTE: the layout is optimized to be shown on apple iphone, not yet checked for other devices,but if anyone wants to improve layout, feel free to do so.

uid: Conditioner Card
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: 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 3, 2022, 6:58:42 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:
  default:
    - component: oh-link
      config:
        actionPropsParameterGroup: widgetAction
        color: white
        class:
          - no-padding
          - no-margin
        style:
          max-height: 192px
          width: 80%
          height: 80%
          position: absolute
          top: 0
          left: 0
          z-index: 98
  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:
        default:
          - 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: 0px
                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: =Number(items[props.set_speed_item].displayState.split(' ')[0]) + 1
        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: COOL
        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
        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: 100%
                height: 100%
                top: 0px
                left: 15px
                z-index: 98
  footer:
    - 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" : "grey"'
        style:
          --f7-toggle-height: 20px
          --f7-toggle-width: 40px
          font-size: 100%
          top: 125px
    - component: oh-button
      config:
        iconColor: '=items[props.heating_item].displayState == "Condizionatore" && items[props.power].state == "ON" ? "blue" : "gray"'
        iconF7: snow
        iconSize: 25
        action: command
        actionItem: =props.heating_item
        actionCommand: COLD
        style:
          position: absolute
          top: 133px
          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" : "gray"'
        iconF7: flame
        iconSize: 20
        action: command
        actionItem: =props.heating_item
        actionCommand: HEAT
        style:
          position: absolute
          top: 133px
          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" : "gray"'
        iconF7: drop
        iconSize: 20
        action: command
        actionItem: =props.heating_item
        actionCommand: DEHUMIDIFIER
        style:
          position: absolute
          top: 133px
          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" : "gray"'
        iconF7: wind
        iconSize: 20
        action: command
        actionItem: =props.heating_item
        actionCommand: FAN
        style:
          position: absolute
          top: 133px
          left: 85%
          height: 35px
          background: transparent
          z-index: 98

There’s a visible property available in most components, which accepts expressions and therefore allows to conditionally display the component. See: Building Pages - Components & Widgets | openHAB.
I actually use this in my overview page where sections of the page (oh-block components) are displayed based on the current scene (selectable with buttons above them), but it also works within a widget.

I think @rubenfuser answered this question better than I could with his latest post!

@ysc , you look skilled programmer…can i ask you to suggest me how to manage FAN speed (you can see on my widget code) using UP&DOWN arrows? i have to manage SPEED named by binding with these names (and display name as follows):

AUTO=Automatica
SILENCE=Silenziosa
LEVEL 1=Velocità 1
LEVEL 2=Velocità 2
LEVEL 3=Velocità 3
LEVEL 4=Velocità 4
LEVEL 5=Velocità 5

i’m not able to tell the up arrow icon to move from one level to upper one, and down arrow to lower one. i’ve found only how to manage between “number + 1” and “number - 1”, but not with values with words :frowning:

any hint?

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.