Universal widget for switch, dimmer, color items

LivarnoLed

My first widget. Thanks for all for their code examples.
This widget can control devices with combination of items: switch, dimmer, color. Also it can display readings from device sensor, signal level and connection status.

Any ideas how to improve it?

Screenshots



Changelog

Version 1.0

  • initial release

Resources

uid: universal_switch_v1
tags:
  - AK
props:
  parameters:
    - description: Name
      label: Header
      name: header1
      required: false
      type: TEXT
    - description: oh:iconName or iconName (openHAB icon), f7:iconName (Framework7 icon), material:iconName (Material icon) or iconify:iconSet:iconName (Iconify icon, requires being online if not in cache)
      label: Main icon
      name: mainIcon
      required: false
      type: TEXT
    - description: HEX or rgba
      label: Main icon color (activ)
      name: micaColor
      required: false
      type: TEXT
    - description: oh:iconName or iconName (openHAB icon), f7:iconName (Framework7 icon), material:iconName (Material icon) or iconify:iconSet:iconName (Iconify icon, requires being online if not in cache)
      label: Header icon
      name: smallIcon
      required: false
      type: TEXT
    - description: HEX or rgba
      label: Header icon color
      name: siColor
      required: false
      type: TEXT
    - description: HEX or rgba
      label: Background color
      name: bgcolor
      required: false
      type: TEXT
    - context: item
      description: Switch item or dimmer item
      label: Switch item
      name: switchItem
      required: false
      type: TEXT
    - context: item
      description: Dimmer item
      label: Dimmer item
      name: dimmerItem
      required: false
      type: TEXT
    - context: item
      description: Color item
      label: Color item
      name: colorItem
      required: false
      type: TEXT
    - context: item
      description: Power item (number)
      label: Power item
      name: powerItem
      required: false
      type: TEXT
    - context: item
      description: Energy item (number)
      label: Energy item
      name: energyItem
      required: false
      type: TEXT
    - context: item
      description: Voltage item (number)
      label: Voltage item
      name: voltageItem
      required: false
      type: TEXT
    - context: item
      description: Current item (number)
      label: Current item
      name: currentItem
      required: false
      type: TEXT
    - context: item
      description: Signal quality item (number)
      label: Link quality item
      name: sigItem
      required: false
      type: TEXT
    - context: item
      description: Reachable item (switch)
      label: Reachable item
      name: connItem
      required: false
      type: TEXT
  parameterGroups: []
timestamp: Dec 30, 2021, 10:51:30 PM
component: f7-card
config:
  style:
    background-image: icon(f7:drop)
    noShadow: false
    margin: 2px
    font-size: 1em
    class:
      - padding
    border-radius: var(--f7-card-expandable-border-radius)
    box-shadow: var(--f7-card-expandable-box-shadow)
    background-color: "=props.bgcolor ? props.bgcolor : ''"
slots:
  content:
    - component: f7-row
      config:
        class:
          - justify-content-flex-start
          - display-flex
        visible: true
        style:
          margin-top: -0.5em
          flex-wrap: nowrap
          overflow: hidden
      slots:
        default:
          - component: oh-icon
            config:
              visible: "=props.smallIcon ? true : false"
              color: "=props.siColor ? props.siColor : props.micaColor"
              icon: =props.smallIcon
              width: 26px
              class:
                - align-self-center
              style:
                margin-left: 0px
          - component: Label
            config:
              text: =props.header1
              class:
                - align-self-center
              style:
                white-space: normal
                line-height: 1rem
                margin-left: 15px
                letter-spacing: .75px
                font-size: min(max(5px, 2.5vw), 18px)
                font-weight: 400
    - component: f7-block
      config:
        class:
          - display-flex
          - flex-direction-column
          - align-items-center
        style:
          width: 100% auto
          height: 100% auto
          margin-top: 0.1em
      slots:
        default:
          - component: oh-link
            config:
              action: toggle
              actionCommand: ON
              actionCommandAlt: OFF
              actionItem: "=props.switchItem ? props.switchItem : props.dimmerItem"
            slots:
              default:
                - component: oh-icon
                  config:
                    color: '=((items[props.switchItem].state == "ON") || (items[props.switchItem].state > 0)) ? props.micaColor : "gray"'
                    icon: '=props.mainIcon ? props.mainIcon : "f7:ant"'
                    width: 10vw
          - component: f7-row
            config:
              visible: "=props.dimmerItem ? true : false"
              width: auto
              class:
                - display-flex
                - justify-content-flex-center
                - align-items-center
              style:
                margin-top: 5px
                white-space: nowrap
                flex-wrap: nowrap
                overflow: hidden
                height: auto
                width: auto
            slots:
              default:
                - component: f7-col
                  config:
                    style:
                      margin-right: 1px
                      margin-left: 1px
                      width: auto
                      height: auto
                    class:
                      - display-flex
                      - justify-content-flex-center
                  slots:
                    default:
                      - component: oh-button
                        config:
                          color: '=((items[props.switchItem].state == "ON") || (items[props.switchItem].state > 0)) ? props.micaColor : "gray"'
                          fill: "=((items[props.dimmerItem].state > 0) && (items[props.dimmerItem].state <= 5)) ? true : false"
                          outline: true
                          round: false
                          small: true
                          action: command
                          actionItem: =props.dimmerItem
                          actionCommand: 5
                          text: 5%
                          style:
                            font-size: min(max(5px, 2.1vw), 20px)
                            width: auto
                            height: auto
                - component: f7-col
                  config:
                    style:
                      margin-right: 1px
                      margin-left: 1px
                      width: auto
                      height: auto
                    class:
                      - display-flex
                      - justify-content-flex-center
                  slots:
                    default:
                      - component: oh-button
                        config:
                          color: '=((items[props.switchItem].state == "ON") || (items[props.switchItem].state > 0)) ? props.micaColor : "gray"'
                          fill: "=((items[props.dimmerItem].state > 5) && (items[props.dimmerItem].state <= 25)) ? true : false"
                          outline: true
                          round: false
                          small: true
                          action: command
                          actionItem: =props.dimmerItem
                          actionCommand: 25
                          text: 25%
                          style:
                            font-size: min(max(5px, 2.1vw), 20px)
                            width: auto
                            height: auto
                - component: f7-col
                  config:
                    style:
                      margin-right: 1px
                      margin-left: 1px
                      width: auto
                      height: auto
                    class:
                      - display-flex
                      - justify-content-flex-center
                  slots:
                    default:
                      - component: oh-button
                        config:
                          color: '=((items[props.switchItem].state == "ON") || (items[props.switchItem].state > 0)) ? props.micaColor : "gray"'
                          fill: "=((items[props.dimmerItem].state > 25) && (items[props.dimmerItem].state <= 50)) ? true : false"
                          outline: true
                          round: false
                          small: true
                          action: command
                          actionItem: =props.dimmerItem
                          actionCommand: 50
                          text: 50%
                          style:
                            font-size: min(max(5px, 2.1vw), 20px)
                            width: auto
                            height: auto
                - component: f7-col
                  config:
                    style:
                      margin-right: 1px
                      margin-left: 1px
                      width: auto
                    class:
                      - display-flex
                      - justify-content-flex-center
                  slots:
                    default:
                      - component: oh-button
                        config:
                          color: '=((items[props.switchItem].state == "ON") || (items[props.switchItem].state > 0)) ? props.micaColor : "gray"'
                          fill: "=((items[props.dimmerItem].state > 50) && (items[props.dimmerItem].state <= 75)) ? true : false"
                          outline: true
                          round: false
                          small: true
                          action: command
                          actionItem: =props.dimmerItem
                          actionCommand: 75
                          text: 75%
                          style:
                            font-size: min(max(5px, 2.1vw), 20px)
          - component: f7-row
            config:
              visible: "=props.dimmerItem ? true : false"
              class:
                - display-flex
                - justify-content-flex-center
                - align-self-center
              style:
                margin-top: 5px
                white-space: nowrap
                flex-wrap: nowrap
                overflow: hidden
                height: auto
                width: auto
            slots:
              default:
                - component: f7-col
                  config:
                    style:
                      margin-right: 1px
                      margin-left: 1px
                      width: auto
                    class:
                      - justify-content-flex-center
                      - display-flex
                  slots:
                    default:
                      - component: oh-button
                        config:
                          color: '=((items[props.switchItem].state == "ON") || (items[props.switchItem].state > 0)) ? props.micaColor : "gray"'
                          textColor: red
                          text: =(Number.parseFloat(items[props.dimmerItem].state.split(" ")[0]) * 100 / 100).toFixed(0)
                          iconF7: light_max
                          outline: true
                          round: false
                          small: true
                          visible: true
                          action: popover
                          popoverOpen: ='.' + props.dimmerItem.split("_")[0] + '.brightPopover'
                          style:
                            font-size: min(max(5px, 2.1vw), 20px)
                        slots:
                          default:
                            - component: f7-popover
                              config:
                                class: =props.dimmerItem.split("_")[0] + ' brightPopover'
                              slots:
                                default:
                                  - component: oh-slider-card
                                    config:
                                      title: Jasność
                                      item: =props.dimmerItem
                                      visible: true
                                      label: true
                                      scale: true
                                      scaleSteps: 10
                                      scaleSubSteps: 2
                                      min: 0
                                      max: 100
                                      step: 1
                                      unit: "%"
                                      vertical: true
                                      releaseOnly: true
                                      style:
                                        width: auto
                                        border-radius: var(--f7-card-expandable-border-radius)
                                        box-shadow: var(--f7-card-expandable-box-shadow)
                                        --f7-range-bar-size: 18px
                                        --f7-range-bar-border-radius: 10px
                                        --f7-range-knob-size: 22px
                                        --f7-range-bar-active-bg-color: rgba(241, 245, 39, 0.8)
                                        --f7-range-bar-bg-color: linear-gradient(to top, rgba(0,0,0,0.9), rgba(246,158,81,0))
                                        --f7-range-knob-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3)
                                        --f7-range-label-text-color: white
                                        --f7-range-scale-font-size: min(max(5px, 2.5vw), 18px)
                                        --f7-range-scale-text-color: gray
                - component: f7-col
                  config:
                    visible: "=props.colorItem ? true : false"
                    style:
                      margin-right: 1px
                      margin-left: 1px
                      width: auto
                    class:
                      - justify-content-flex-center
                      - display-flex
                  slots:
                    default:
                      - component: oh-button
                        config:
                          text: ""
                          iconF7: paintbrush
                          iconSize: min(max(5px, 3vw), 20px)
                          fill: '=((items[props.switchItem].state == "ON") || (items[props.switchItem].state > 0)) ? true : false'
                          outline: true
                          round: false
                          small: true
                          visible: true
                          action: popover
                          popoverOpen: ='.' + props.colorItem.split("_")[0] + '.colorPopover'
                          style:
                            font-size: min(max(5px, 2.1vw), 20px)
                            --f7-button-fill-bg-color: >
                              = "hsl("  + items[props.colorItem].state.split(",")[0]+ "," + ((0 === 100* (Number.parseInt( items[props.colorItem].state.split(",")[2] )/100 * (1-0.5 * Number.parseInt( items[props.colorItem].state.split(",")[1])/100))) || (100 === 100* (Number.parseInt( items[props.colorItem].state.split(",")[2] )/100 * (1-0.5 * Number.parseInt( items[props.colorItem].state.split(",")[1])/100))) ? 0 : 100* ((Number.parseInt( items[props.colorItem].state.split(",")[2] ) - 100* (Number.parseInt( items[props.colorItem].state.split(",")[2] )/100 * (1-0.5 * Number.parseInt( items[props.colorItem].state.split(",")[1])/100))) / Math.min(100* (Number.parseInt( items[props.colorItem].state.split(",")[2] )/100 * (1-0.5 * Number.parseInt( items[props.colorItem].state.split(",")[1])/100)), 100- 100* (Number.parseInt( items[props.colorItem].state.split(",")[2] )/100 * (1-0.5 * Number.parseInt( items[props.colorItem].state.split(",")[1])/100))))) +"%," + 100* (Number.parseInt( items[props.colorItem].state.split(",")[2] )/100 * (1-0.5 * Number.parseInt( items[props.colorItem].state.split(",")[1])/100)) +"%)" 
                            --f7-button-outline-border-color: var(--f7-button-fill-bg-color)
                        slots:
                          default:
                            - component: f7-popover
                              config:
                                class: =props.colorItem.split("_")[0] + ' colorPopover'
                              slots:
                                default:
                                  - component: oh-colorpicker-card
                                    config:
                                      visible: true
                                      modules:
                                        - palette
                                        - hue-slider
                                        - initial-current-colors
                                      item: =props.colorItem
                                      title: Kolor
                                      noBorder: false
                                      style:
                                        height: 50%
                                        width: 50%
    - component: f7-row
      config:
        class:
          - justify-content-flex-start
          - padding-top
          - display-flex
        style:
          height: auto
          width: auto
          margin-top: 0.3em
          margin-bottom: -0.9em
          text-overflow: ellipsis
          overflow: hidden
      slots:
        default:
          - component: Label
            config:
              text: =(Number.parseFloat(items[props.voltageItem].state.split(" ")[0]) * 100 / 100).toFixed(0) + "V"
              visible: "=props.voltageItem ? true : false"
              class:
                - align-self-center
              style:
                margin-left: 0px
                margin-right: 4px
                color: gray
                letter-spacing: .75px
                font-size: min(max(5px, 2.5vw), 18px)
          - component: Label
            config:
              text: =(Number.parseFloat(items[props.currentItem].state.split(" ")[0]) * 100 / 100).toFixed(1) + "A"
              visible: "=props.currentItem ? true : false"
              class:
                - align-self-center
              style:
                margin-left: 4px
                margin-right: 4px
                color: gray
                letter-spacing: .75px
                font-size: min(max(5px, 2.5vw), 18px)
          - component: Label
            config:
              text: =(Number.parseFloat(items[props.powerItem].state.split(" ")[0]) * 100 / 100).toFixed(1) + "W"
              visible: "=props.powerItem ? true : false"
              class:
                - align-self-center
              style:
                margin-left: 4px
                margin-right: 4px
                color: gray
                letter-spacing: .75px
                font-size: min(max(5px, 2.5vw), 18px)
          - component: Label
            config:
              text: =(Number.parseFloat(items[props.energyItem].state.split(" ")[0]) * 100 / 100).toFixed(0) + "kWh"
              visible: "=props.energyItem ? true : false"
              class:
                - align-self-center
              style:
                margin-left: 4px
                margin-right: 4px
                color: gray
                letter-spacing: .75px
                font-size: min(max(5px, 2.5vw), 18px)
          - component: f7-row
            config:
              visible: true
              class:
                - justify-content-flex-start
                - display-flex
            slots:
              default:
                - component: f7-icon
                  config:
                    visible: "=props.connItem ? true : false"
                    f7: '=(items[props.connItem].state == "ON" ? "wifi" : "wifi_exclamationmark")'
                    size: 22
                    tooltip: '=(items[props.connItem].state == "ON" ? "Połączono z siecią" : "Brak połączenia z siecią")'
                    class:
                      - align-self-center
                    style:
                      margin-left: 4px
                      margin-right: 1px
                      color: '=(items[props.connItem].state == "ON" ? "gray" : "red")'
                - component: Label
                  config:
                    text: =(Number.parseFloat(items[props.sigItem].state.split(" ")[0]) * 100 / 100).toFixed(0)
                    visible: "=props.sigItem ? true : false"
                    class:
                      - align-self-center
                    style:
                      margin-left: 1px
                      margin-right: 4px
                      color: gray
                      letter-spacing: .75px
                      font-size: min(max(5px, 2.2vw), 14px)

1 Like

Hi @Artur1,

Thanks for this widget, I’ve been attempting to use this (starting off simple ON/OFF)

However, for some strange reason the switch/dimmer toggle on the widget does not seem to be working for me. Any ideas?

YAML extract:

component: widget:universal_switch_v1
config:
  mainIcon: f7:lightbulb
  switchItem: JBRoomDeskLamp_Power

Am I missing something obvious here?

It should work without problems.
The cursor changes when you move it over an icon?

This is my current version of this widget:

uid: ak_universal_switch_widget_v1
tags:
  - AK
props:
  parameters:
    - description: Name
      label: Header
      name: header1
      required: false
      type: TEXT
    - description: oh:iconName or iconName (openHAB icon), f7:iconName (Framework7 icon), material:iconName (Material icon) or iconify:iconSet:iconName (Iconify icon, requires being online if not in cache)
      label: Main icon
      name: mainIcon
      required: false
      type: TEXT
    - description: HEX or rgba
      label: Main icon color (activ)
      name: micaColor
      required: false
      type: TEXT
    - description: oh:iconName or iconName (openHAB icon), f7:iconName (Framework7 icon), material:iconName (Material icon) or iconify:iconSet:iconName (Iconify icon, requires being online if not in cache)
      label: Header icon
      name: smallIcon
      required: false
      type: TEXT
    - description: HEX or rgba
      label: Header icon color
      name: siColor
      required: false
      type: TEXT
    - description: HEX or rgba
      label: Background color
      name: bgcolor
      required: false
      type: TEXT
    - context: item
      description: Switch item or dimmer item
      label: Switch item
      name: switchItem
      required: false
      type: TEXT
    - context: item
      description: Dimmer item
      label: Dimmer item
      name: dimmerItem
      required: false
      type: TEXT
    - context: item
      description: Color item
      label: Color item
      name: colorItem
      required: false
      type: TEXT
    - context: item
      description: Color temperature item
      label: Color temperature item
      name: tempItem
      required: false
      type: TEXT
    - context: item
      description: Power item (number)
      label: Power item
      name: powerItem
      required: false
      type: TEXT
    - context: item
      description: Energy item (number)
      label: Energy item
      name: energyItem
      required: false
      type: TEXT
    - context: item
      description: Voltage item (number)
      label: Voltage item
      name: voltageItem
      required: false
      type: TEXT
    - context: item
      description: Current item (number)
      label: Current item
      name: currentItem
      required: false
      type: TEXT
    - context: item
      description: Signal quality item (number)
      label: Link quality item
      name: sigItem
      required: false
      type: TEXT
    - context: item
      description: Reachable item (switch)
      label: Reachable item
      name: connItem
      required: false
      type: TEXT
  parameterGroups: []
timestamp: Jan 4, 2022, 8:38:16 PM
component: f7-card
config:
  style:
    background-image: icon(f7:drop)
    noShadow: false
    margin: 2px
    font-size: 1em
    class:
      - padding
    border-radius: var(--f7-card-expandable-border-radius)
    box-shadow: var(--f7-card-expandable-box-shadow)
    background-color: "=props.bgcolor ? props.bgcolor : ''"
slots:
  content:
    - component: f7-row
      config:
        class:
          - justify-content-flex-start
          - display-flex
        visible: true
        style:
          margin-top: -0.5em
          flex-wrap: nowrap
          overflow: hidden
      slots:
        default:
          - component: oh-icon
            config:
              visible: "=props.smallIcon ? true : false"
              color: "=props.siColor ? props.siColor : props.micaColor"
              icon: '=props.smallIcon ? props.smallIcon : "f7:light_max"'
              width: min(max(5px, 4vw), 22px)
              class:
                - align-self-center
              style:
                margin-left: 0px
          - component: Label
            config:
              text: =props.header1
              class:
                - align-self-center
              style:
                white-space: normal
                line-height: 1rem
                margin-left: 15px
                letter-spacing: .75px
                font-size: min(max(5px, 2.5vw), 18px)
                font-weight: 400
    - component: f7-block
      config:
        class:
          - display-flex
          - flex-direction-column
          - align-items-center
        style:
          width: 100% auto
          height: 100% auto
          margin-top: 0.1em
      slots:
        default:
          - component: oh-link
            config:
              action: toggle
              actionCommand: ON
              actionCommandAlt: OFF
              actionItem: "=props.switchItem ? props.switchItem : props.dimmerItem"
            slots:
              default:
                - component: oh-icon
                  config:
                    color: '=((items[props.switchItem].state == "ON") || (items[props.switchItem].state > 0) || (items[props.dimmerItem].state > 0)) ? props.micaColor : "gray"'
                    icon: '=props.mainIcon ? props.mainIcon : "f7:lightbulb"'
                    width: 10vw
          - component: f7-row
            config:
              visible: "=props.dimmerItem ? true : false"
              width: auto
              class:
                - display-flex
                - justify-content-flex-center
                - align-items-center
              style:
                margin-top: 5px
                white-space: nowrap
                flex-wrap: nowrap
                overflow: hidden
                height: auto
                width: auto
            slots:
              default:
                - component: f7-col
                  config:
                    style:
                      margin-right: 1px
                      margin-left: 1px
                      width: auto
                      height: auto
                    class:
                      - display-flex
                      - justify-content-flex-center
                  slots:
                    default:
                      - component: oh-button
                        config:
                          textColor: '=((items[props.dimmerItem].state > 0)) ? props.micaColor : "gray"'
                          outline: true
                          round: false
                          small: true
                          action: command
                          actionItem: =props.dimmerItem
                          actionCommand: 5
                          text: 5%
                          style:
                            font-size: min(max(5px, 3vw), 22px)
                            --f7-button-outline-border-width: 1px
                            --f7-button-outline-border-color: rgba(163, 161, 159, 0.9)
                            --f7-button-small-font-weight: 400
                - component: f7-col
                  config:
                    style:
                      margin-right: 1px
                      margin-left: 1px
                      width: auto
                      height: auto
                    class:
                      - display-flex
                      - justify-content-flex-center
                  slots:
                    default:
                      - component: oh-button
                        config:
                          color: '=((items[props.switchItem].state == "ON") || (items[props.switchItem].state > 0) || (items[props.dimmerItem].state > 0)) ? "gray" : "gray"'
                          textColor: '=((items[props.dimmerItem].state >= 25)) ? props.micaColor : "gray"'
                          outline: true
                          round: false
                          small: true
                          action: command
                          actionItem: =props.dimmerItem
                          actionCommand: 25
                          text: 25%
                          style:
                            font-size: min(max(5px, 3vw), 22px)
                            --f7-button-outline-border-width: 1px
                            --f7-button-outline-border-color: rgba(163, 161, 159, 0.9)
                            --f7-button-small-font-weight: 400
                - component: f7-col
                  config:
                    style:
                      margin-right: 1px
                      margin-left: 1px
                      width: auto
                      height: auto
                    class:
                      - display-flex
                      - justify-content-flex-center
                  slots:
                    default:
                      - component: oh-button
                        config:
                          color: '=((items[props.switchItem].state == "ON") || (items[props.switchItem].state > 0) || (items[props.dimmerItem].state > 0)) ? "gray" : "gray"'
                          textColor: '=((items[props.dimmerItem].state >= 50)) ? props.micaColor : "gray"'
                          outline: true
                          round: false
                          small: true
                          action: command
                          actionItem: =props.dimmerItem
                          actionCommand: 50
                          text: 50%
                          style:
                            font-size: min(max(5px, 3vw), 22px)
                            --f7-button-outline-border-width: 1px
                            --f7-button-outline-border-color: rgba(163, 161, 159, 0.9)
                            --f7-button-small-font-weight: 400
                - component: f7-col
                  config:
                    style:
                      margin-right: 1px
                      margin-left: 1px
                      width: auto
                    class:
                      - display-flex
                      - justify-content-flex-center
                  slots:
                    default:
                      - component: oh-button
                        config:
                          color: '=((items[props.switchItem].state == "ON") || (items[props.switchItem].state > 0) || (items[props.dimmerItem].state > 0)) ? "gray" : "gray"'
                          textColor: '=((items[props.dimmerItem].state >= 75)) ? props.micaColor : "gray"'
                          outline: true
                          round: false
                          small: true
                          action: command
                          actionItem: =props.dimmerItem
                          actionCommand: 75
                          text: 75%
                          style:
                            font-size: min(max(5px, 3vw), 22px)
                            --f7-button-outline-border-width: 1px
                            --f7-button-outline-border-color: rgba(163, 161, 159, 0.9)
                            --f7-button-small-font-weight: 400
          - component: f7-row
            config:
              visible: "=(props.dimmerItem ? true : false) || (props.tempItem ? true : false)  || (props.colorItem ? true : false)"
              class:
                - display-flex
                - justify-content-flex-center
                - align-self-center
              style:
                margin-top: 5px
                white-space: nowrap
                flex-wrap: nowrap
                overflow: hidden
            slots:
              default:
                - component: f7-col
                  config:
                    visible: "=props.dimmerItem ? true : false"
                    style:
                      margin-right: 1px
                      margin-left: 1px
                      width: auto
                    class:
                      - justify-content-flex-center
                      - display-flex
                  slots:
                    default:
                      - component: oh-button
                        config:
                          color: '=((items[props.switchItem].state == "ON") || (items[props.switchItem].state > 0) || (items[props.dimmerItem].state > 0)) ? "gray" : "gray"'
                          textColor: '=((items[props.dimmerItem].state > 95) && (items[props.dimmerItem].state <= 100)) ? props.micaColor : "gray"'
                          text: =(Number.parseFloat(items[props.dimmerItem].state.split(" ")[0]) * 100 / 100).toFixed(0)
                          iconF7: light_max
                          iconSize: min(max(5px, 3vw), 20px)
                          outline: true
                          round: false
                          small: true
                          action: popover
                          popoverOpen: ='.' + props.dimmerItem.split("_")[0] + '.brightPopover'
                          style:
                            font-size: min(max(5px, 3vw), 22px)
                            --f7-button-outline-border-width: 1px
                            --f7-button-outline-border-color: rgba(163, 161, 159, 0.9)
                            --f7-button-small-font-weight: 400
                        slots:
                          default:
                            - component: f7-popover
                              config:
                                class: =props.dimmerItem.split("_")[0] + ' brightPopover'
                                style:
                                  --f7-popover-border-radius: 10px
                              slots:
                                default:
                                  - component: oh-slider-card
                                    config:
                                      title: Jasność
                                      item: =props.dimmerItem
                                      visible: true
                                      label: true
                                      scale: true
                                      scaleSteps: 10
                                      scaleSubSteps: 2
                                      min: 0
                                      max: 100
                                      step: 1
                                      unit: "%"
                                      vertical: true
                                      releaseOnly: true
                                      style:
                                        width: auto
                                        border-radius: var(--f7-card-expandable-border-radius)
                                        box-shadow: var(--f7-card-expandable-box-shadow)
                                        --f7-range-bar-size: 18px
                                        --f7-range-bar-border-radius: 10px
                                        --f7-range-knob-size: 22px
                                        --f7-range-bar-active-bg-color: rgba(241, 245, 39, 0.8)
                                        --f7-range-bar-bg-color: linear-gradient(to top, rgba(0,0,0,0.9), rgba(246,158,81,0))
                                        --f7-range-knob-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3)
                                        --f7-range-label-text-color: white
                                        --f7-range-scale-font-size: min(max(5px, 2.5vw), 18px)
                                        --f7-range-scale-text-color: gray
                - component: f7-col
                  config:
                    visible: "=props.tempItem ? true : false"
                    style:
                      margin-right: 1px
                      margin-left: 1px
                      width: auto
                    class:
                      - justify-content-flex-center
                      - display-flex
                  slots:
                    default:
                      - component: oh-button
                        config:
                          color: '=((items[props.switchItem].state == "ON") || (items[props.switchItem].state > 0)) ? "gray" : "gray"'
                          textColor: '=((items[props.switchItem].state == "ON") || (items[props.switchItem].state > 0) || (items[props.dimmerItem].state > 0)) ? "orange" : "gray"'
                          text: =(Number.parseFloat(items[props.tempItem].state.split(" ")[0]) * 100 / 100).toFixed(0)
                          iconF7: thermometer_sun
                          iconSize: min(max(5px, 3vw), 20px)
                          outline: true
                          round: false
                          small: true
                          action: popover
                          popoverOpen: ='.' + props.tempItem.split("_")[0] + '.tempPopover'
                          style:
                            font-size: min(max(5px, 3vw), 22px)
                            --f7-button-outline-border-width: 1px
                            --f7-button-outline-border-color: rgba(163, 161, 159, 0.9)
                            --f7-button-small-font-weight: 400
                        slots:
                          default:
                            - component: f7-popover
                              config:
                                class: =props.tempItem.split("_")[0] + ' tempPopover'
                                style:
                                  --f7-popover-border-radius: 10px
                              slots:
                                default:
                                  - component: oh-slider-card
                                    config:
                                      title: Ciepło koloru
                                      item: =props.tempItem
                                      visible: true
                                      label: true
                                      scale: true
                                      scaleSteps: 10
                                      scaleSubSteps: 2
                                      min: 0
                                      max: 100
                                      step: 1
                                      unit: "%"
                                      vertical: true
                                      releaseOnly: true
                                      style:
                                        width: auto
                                        border-radius: var(--f7-card-expandable-border-radius)
                                        box-shadow: var(--f7-card-expandable-box-shadow)
                                        --f7-range-bar-size: 18px
                                        --f7-range-bar-border-radius: 10px
                                        --f7-range-knob-size: 22px
                                        --f7-range-bar-active-bg-color: transparent
                                        --f7-range-bar-bg-color: linear-gradient(to top, rgba(254, 254, 254, 1), rgba(236, 172, 17, 1))
                                        --f7-range-knob-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3)
                                        --f7-range-label-text-color: white
                                        --f7-range-scale-font-size: min(max(5px, 2.5vw), 18px)
                                        --f7-range-scale-text-color: gray
                - component: f7-col
                  config:
                    visible: "=props.colorItem ? true : false"
                    style:
                      margin-right: 1px
                      margin-left: 1px
                      width: auto
                    class:
                      - justify-content-flex-center
                      - display-flex
                  slots:
                    default:
                      - component: oh-button
                        config:
                          iconF7: paintbrush
                          iconSize: min(max(5px, 3.5vw), 20px)
                          fill: '=((items[props.switchItem].state == "ON") || (items[props.switchItem].state > 0) || (items[props.dimmerItem].state > 0)) ? true : false'
                          outline: true
                          round: false
                          small: true
                          visible: true
                          action: popover
                          popoverOpen: ='.' + props.colorItem.split("_")[0] + '.colorPopover'
                          style:
                            font-size: min(max(5px, 3vw), 22px)
                            --f7-button-fill-bg-color: >
                              = "hsl("  + items[props.colorItem].state.split(",")[0]+ "," + ((0 === 100* (Number.parseInt( items[props.colorItem].state.split(",")[2] )/100 * (1-0.5 * Number.parseInt( items[props.colorItem].state.split(",")[1])/100))) || (100 === 100* (Number.parseInt( items[props.colorItem].state.split(",")[2] )/100 * (1-0.5 * Number.parseInt( items[props.colorItem].state.split(",")[1])/100))) ? 0 : 100* ((Number.parseInt( items[props.colorItem].state.split(",")[2] ) - 100* (Number.parseInt( items[props.colorItem].state.split(",")[2] )/100 * (1-0.5 * Number.parseInt( items[props.colorItem].state.split(",")[1])/100))) / Math.min(100* (Number.parseInt( items[props.colorItem].state.split(",")[2] )/100 * (1-0.5 * Number.parseInt( items[props.colorItem].state.split(",")[1])/100)), 100- 100* (Number.parseInt( items[props.colorItem].state.split(",")[2] )/100 * (1-0.5 * Number.parseInt( items[props.colorItem].state.split(",")[1])/100))))) +"%," + 100* (Number.parseInt( items[props.colorItem].state.split(",")[2] )/100 * (1-0.5 * Number.parseInt( items[props.colorItem].state.split(",")[1])/100)) +"%)" 
                            --f7-button-outline-border-color: var(--f7-button-fill-bg-color)
                            --f7-button-outline-border-width: 1px
                            --f7-button-small-font-weight: 400
                        slots:
                          default:
                            - component: f7-popover
                              config:
                                class: =props.colorItem.split("_")[0] + ' colorPopover'
                                style:
                                  --f7-popover-border-radius: 10px
                              slots:
                                default:
                                  - component: oh-colorpicker-card
                                    config:
                                      visible: true
                                      modules:
                                        - palette
                                        - hue-slider
                                        - initial-current-colors
                                      item: =props.colorItem
                                      title: Kolor
                                      noBorder: false
    - component: f7-row
      config:
        class:
          - justify-content-flex-start
          - padding-top
          - display-flex
          - justify-content-space-around
        style:
          margin-top: 0.3em
          margin-bottom: -0.9em
          text-overflow: ellipsis
          overflow: hidden
      slots:
        default:
          - component: f7-row
            config:
              visible: "=props.connItem ? true : (props.sigItem ? true : false)"
              class:
                - justify-content-flex-start
                - display-flex
            slots:
              default:
                - component: f7-icon
                  config:
                    f7: '=(props.connItem ? (items[props.connItem].state == "ON" ? "wifi" : "wifi_slash") : "wifi")'
                    size: min(max(5px, 4vw), 22px)
                    tooltip: '=(props.connItem ? (items[props.connItem].state == "ON" ? "Połączono z siecią" : "Brak połączenia z siecią") : "Siła sygnału")'
                    class:
                      - align-self-center
                    style:
                      color: '=(props.connItem ? (items[props.connItem].state == "ON" ? "gray" : "red") : "gray")'
                      margin-left: 0px
                      margin-right: 1px
                - component: Label
                  config:
                    text: =(Number.parseFloat(items[props.sigItem].state.split(" ")[0]) * 100 / 100).toFixed(0)
                    visible: "=props.sigItem ? true : false"
                    class:
                      - align-self-center
                    style:
                      margin-left: 1px
                      margin-right: 1px
                      color: gray
                      font-size: min(max(5px, 2.2vw), 14px)
          - component: Label
            config:
              text: =(Number.parseFloat(items[props.voltageItem].state.split(" ")[0]) * 100 / 100).toFixed(0) + "V"
              visible: "=props.voltageItem ? true : false"
              class:
                - align-self-center
              style:
                margin-left: 1px
                margin-right: 1px
                color: gray
                letter-spacing: .75px
                font-size: min(max(5px, 2.5vw), 18px)
          - component: Label
            config:
              text: =(Number.parseFloat(items[props.currentItem].state.split(" ")[0]) * 100 / 100).toFixed(1) + "A"
              visible: "=props.currentItem ? true : false"
              class:
                - align-self-center
              style:
                margin-left: 1px
                margin-right: 1px
                color: gray
                letter-spacing: .75px
                font-size: min(max(5px, 2.5vw), 18px)
          - component: Label
            config:
              text: =(Number.parseFloat(items[props.powerItem].state.split(" ")[0]) * 100 / 100).toFixed(1) + "W"
              visible: "=props.powerItem ? true : false"
              class:
                - align-self-center
              style:
                margin-left: 1px
                margin-right: 1px
                color: gray
                letter-spacing: .75px
                font-size: min(max(5px, 2.5vw), 18px)
          - component: Label
            config:
              text: =(Number.parseFloat(items[props.energyItem].state.split(" ")[0]) * 100 / 100).toFixed(1) + "kWh"
              visible: "=props.energyItem ? true : false"
              class:
                - align-self-center
              style:
                margin-left: 1px
                margin-right: 0px
                color: gray
                letter-spacing: .75px
                font-size: min(max(5px, 2.5vw), 18px)

Right now, I’ve created a new widget using the above YAML and seems to work as expected, so thank you!

Maybe the Marketplace needs to be updated with the above?

Hi Artur
Thanks for a great widget.
Been trying to implement in to my system - but not sure about the above expression.
When the lights are OFF the icon is gray - as expected.
When the lights are ON the icon is a redish color - but I cannot see where this DEFAULT color is defined?
I am trying to match the colors in my “calling cell”
Thanks
Mark
EDIT: After messing around is the Chrome Developer tools where there is no icon color for the ON state I seem to have achieved what i was after as follows:

iconColor: '=(items.LoungeRoom_Switch.state === "ON") ? "null" : "gray"'

Putting color as empty string sets it to F7 Framework default color.
Take a look at CSS Variables Reference.

props.micaColor if not set is empty string.
You may change it to:

props.micaColor ? props.micaColor : "null"

Then if not set you will get color “null”
But maybe is better to use F7 CSS Variables.

1 Like

You don’t need to directly specify items in the code, use widget settings.

Thanks, I am in the actual widget, but I am trying to call the widget from an oh-cell with options for three different rooms - see OH3 oh-cell popup from f7-chip or oh-button

So I was trying to have a list of Rooms and then select each room with its valid props set. Thought it would be nice to show the current state of the switchItem in the list. But now have a different issue.

I REALLY like your widget. Have you noticed the following though:
image

The brightness is set to 85%, however the brightness % buttons only highlight 5%?

textColor: '=((items[props.dimmerItem].state > 0)) ? props.micaColor : "gray"'

or

textColor: '=((items[props.dimmerItem].state >= 75)) ? props.micaColor : "gray"'

Shouldn’t 5%, 25%, 50% and 75% be set to micaColor since the is >75%

To be honest I have not looked too much at that yet - but since you were online I thought I would ask.

Cheers
Mark

Is dimmeritem set to dimmer type item :slight_smile:
I have this widget set with different devices and it seems to work correctly.
Is your item reporting just number or number with unit (%)?

Yes, the dimmer item is set to a dimmer type item. :slight_smile:
Seems to be reporting just a number. I have added the following to test:

          - component: Label
            config:
              text: '=props.header1 + " " + items[props.dimmerItem].state'

and get:

image

As you see code is quite simple and it looks correctly. I have no idea why it doesn’t work for you.

text: ‘=props.header1 + " " + items[props.dimmerItem].state + “after”’
Check that there is no character (e.g. white space) after the number.

No problem. Will see if I can work it out. I suspect this has something to do with strings vs numbers?

As far as I recall the .state of an item is a string - so the expression would be a problem as comparing a string to a number?

So I found the issue. It seems that these two expressions conflict (and are not present on the 5% components:

color: '=((items[props.switchItem].state == "ON") || (items[props.switchItem].state > 0) || (items[props.dimmerItem].state > 0)) ? "gray" : "gray"'
textColor: '=((items[props.dimmerItem].state >= 25)) ? props.micaColor : "gray"'

Removing the color: '=((items[pro... fixes what I was seeing.

Maybe .state is "85 " so is not equal 85. Maybe 85 should stated as string: “85”.

I found this in some widgets:

(Number.parseFloat(items[props.pmItem].state.split(" ")[0]) * 100 / 100).toFixed(0)

This code formats number: removes “unit” part (usually after white space) and sets number of digits after decimal point.

Have you set dimmeritem and switchitem in the widget settings?
Missing one can cause the condition in color: to not work.

Use of:
Dimmer type item in switchitem switches light to 0% and 100%
Switch type item in switchitem switches light to 0% and last dimmer value (can be 0% - light ON but no light)
This is the behaviour I have observed.
Both settings should always be set for dimmer items.

I have set all the relevant props (light related).
The color expression seems to not makes sense TO ME. The result is always “gray”?

If I manually set the color to anything color: green it overrides the textColor:.

Why is the color: not set for the 5% column?

This is a remnant of the previous version. Previously the colour of the button border also changed and now only the colour of the text changes.

1 Like

I agree with Mark.

it works for me too