Heating widget

Hi @fibu-freak,
I’ll spend some time trying to figure root of problems. Looks like i found something, but, unfortunately, I don’t know how to fix it.
For example, we have in code for example item

display: "=props.exampleModeItem ? '' : 'none'"

So if exampleModeItemnot defined it will be not shown on interface. But code still have

action: command
active: "=(items[props.exampleModeItem].state === loop.buttonlabel ? true : false)"
actionCommand: =loop.buttonlabel
actionItem: =props.exampleModeItem

I think what OH engine still trying to access item with name in exampleModeItem variable, and because it is undefined generate a warning.

1 Like

Hi @doctor64 and @fibu-freak ,

That is not completely right. :wink: The error occurs because I refer to an item in expressions which is not defined.
The error is definitely in my code. I’ve tried to ensure it everywhere but quickly forgot in this new lines.

Your guess is completely correct.
I forgot to include the boolean operator in the expressions here.

I have figure the error out and adapt the correct expression in the code.

It must look like:

active: "=props.heatingModeItem ? (items[props.heatingModeItem].state === loop.buttonlabel ? true : false) : ''"

and

actionItem: "=props.heatingModeItem ? props.heatingModeItem : ''"

this for exampleModeItem and heatingModeItem.

The corrected code can be found here without a new tag version.

I hope this solves the bugs and you have fun agian with the widget. :wink:

2 Likes

Hi @Nico_R
Thank you very much, last update fixes problem with warnings.

Hello together,

I am facing some issue in the widget with rounding the value of temperature:

The item is defined as shown below:

Number:Temperature    SollTemp_Bad                   "Soll Bad [%.1f °C]"                       <temperature>      (gBadOGThermostat, gTemperature)           ["Setpoint", "Temperature"]       {channel="knx:device:MDT_IP:MDT_HS4:SollTemp_Bad", stateDescription=""[pattern="%.1f °C"]}

Any idea how to fix this issue.

Thanks in advance!

Hi @snowy

Please share your yaml and the two items set and current temperature.
Maybe then i can help.

The Item definition

Number:Temperature    ActualTemp_WZ                   "Ist Wohnzimmer [%.1f °C]"                 <temperature>      (gLivingroomThermostat, gTemperature)         ["Measurement", "Temperature"]     {alexa="CurrentTemperature", channel="knx:device:MDT_IP:MDT_HS8:ActualTemp_WZ", stateDescription=""[pattern="%.1f °C"]}
Number:Temperature    SollTemp_WZ                     "Soll Wohnzimmer [%.1f °C]"                <temperature>      (gLivingroomThermostat, gTemperature)         ["Setpoint", "Temperature"]        {channel="knx:device:MDT_IP:MDT_HS8:SollTemp_WZ", stateDescription=""[pattern="%.1f °C"]}


This is the YAML:

uid: widget_TestThermostat
tags: []
props:
  parameters:
    - description: eg. living room
      label: location and widget identifier
      name: location
      required: true
      type: TEXT
    - description: Visual size of the control in px (default 400px), without a size the design is responsive
      label: size [px]
      name: size
      required: false
      type: TEXT
    - description: Minimum value
      label: minTemp
      name: minTemp
      required: true
      type: TEXT
    - description: Maximum value
      label: maxTemp
      name: maxTemp
      required: true
    - context: item
      description: Item to control
      label: Set point Item
      name: setPointItem
      required: true
      type: TEXT
    - context: item
      description: Item to control
      label: Change target value Item
      name: changeTargetSwitchItem
      required: true
      type: TEXT
    - context: item
      label: Item for current temperature
      name: currentPointItem
      required: true
      type: TEXT
    - description: Control item unit eg °C
      label: unit
      name: unit
      required: false
      type: TEXT
    - description: URL or path to a Image (if you use a local img eg. -> http://local-IP-Adress:8080/static/folder/img.svg )
      label: URL or path to image
      name: imgUrl
      required: false
      type: TEXT
      advanced: true
    - description: Heating mode strings as array eg. AUTO,MANU,OFF. The string will be send to the Heating-Mode-Item [String-Item]
      label: Heating Mode Array
      name: heatingModeArray
      required: false
      type: TEXT
      advanced: true
    - description: Example Mode Strings as Array eg. OFF,ON,BOOST. The string will be send to the Example-Mode-Item [String-Item]
      label: Example Mode Array
      name: exampleModeArray
      required: false
      type: TEXT
      advanced: true
    - context: item
      description: Heating Mode Item [String-Item]
      label: Heating Mode Item
      name: heatingModeItem
      required: false
      type: TEXT
      advanced: true
    - context: item
      description: Example Mode Item [String-Item] (eg. State of heating valve)
      label: Example Mode Item
      name: exampleModeItem
      required: false
      type: TEXT
      advanced: true
    - context: item
      description: Valve Item [Switch-Item] (eg. State of heating valve) for Animation
      label: Valve Item
      name: valveItem
      required: false
      type: TEXT
      advanced: true
    - label: Custom font-size current&set-point marker (eg. 1em)
      name: fontSizeMarker
      required: false
      type: TEXT
      groupName: fonts
      advanced: true
    - label: Custom font-Size center (eg. 2em)
      name: fontSizeCenter
      required: false
      type: TEXT
      groupName: fonts
      advanced: true
    - label: Custom font-Size buttons (eg. 1.8em)
      name: fontSizeButtons
      required: false
      type: TEXT
      groupName: fonts
      advanced: true
    - label: Custom font-Size footer (eg. 1em)
      name: fontSizeFooter
      required: false
      type: TEXT
      groupName: fonts
      advanced: true
    - label: Main-Color Thermostat
      name: colorThermostat
      required: false
      type: TEXT
      groupName: colors
      advanced: true
    - label: Color control ring
      name: colorControlRing
      required: false
      type: TEXT
      groupName: colors
      advanced: true
    - label: Color buttons
      name: colorButton
      required: false
      type: TEXT
      groupName: colors
      advanced: true
    - label: Color center
      name: colorCenter
      required: false
      type: TEXT
      groupName: colors
      advanced: true
    - label: Color Typo
      name: colorTypo
      required: false
      type: TEXT
      groupName: colors
      advanced: true
    - label: Color setPoint Marker
      name: colorSetMarker
      required: false
      type: TEXT
      groupName: colors
      advanced: true
    - label: Color currentPoint Marker
      name: colorCurrentMarker
      required: false
      type: TEXT
      groupName: colors
      advanced: true
    - label: Color bar linear gradient startPoint
      name: colorBarStartPoint
      required: false
      type: TEXT
      groupName: colors
      advanced: true
    - label: Color bar linear gradient endPoint
      name: colorBarEndPoint
      required: false
      type: TEXT
      groupName: colors
      advanced: true
  parameterGroups:
    - name: colors
      label: Color-Settings
    - name: fonts
      label: Font-Settings
timestamp: Mar 3, 2021, 9:30:50 PM
component: f7-card
config:
  title: "=(props.location) ? 'Klima ' + props.location : ''"
slots:
  default:
    - component: f7-card-content
      slots:
        default:
          - component: f7-row
            config:
              resizableFixed: true
              resizable-absolute: true
              class:
                - justify-content-center
            slots:
              default:
                - component: f7-block
                  config:
                    class: thermostat
                    style:
                      flex-shrink: 0
                      --f7-block-margin-vertical: 0px
                      --f7-block-padding-vertical: 0px
                      --f7-block-padding-horizontal: 0px
                      padding-left: 0px
                      padding-top: "=props.size ? props.size + 'px': '100%'"
                      width: "=props.size ? Number(props.size)+'px' : '100%'"
                      background: "=props.colorThermostat ? props.colorThermostat : 'var(--f7-toggle-inactive-color)'"
                      border-radius: 50%
                      box-sizing: content-box
                      border: 2px solid rgb(64, 60, 77)
                  slots:
                    default:
                      - component: f7-block
                        config:
                          class: bar
                          style:
                            margin-top: 0px
                            position: absolute
                            width: "=props.size ? (Number(props.size)*0.89) +'px' : '89%'"
                            height: "=props.size ? (Number(props.size)*0.89) +'px' : '89%'"
                            top: 50%
                            left: 50%
                            transform: translate(-50%, -50%)
                            border-radius: 50%
                        slots:
                          default:
                            - component: f7-block
                              config:
                                class: inner_bar
                                style:
                                  margin-top: 0
                                  position: absolute
                                  top: 50%
                                  left: 50%
                                  transform: translate(-50%, -50%)
                                  width: "=props.size ? (Number(props.size)*0.86) +'px' : '97%'"
                                  height: "=props.size ? (Number(props.size)*0.86) +'px' : '97%'"
                                  border-radius: 100%
                                  background-color: "=props.colorThermostat ? props.colorThermostat : 'var(--f7-toggle-inactive-color)'"
                                  z-index: 4 !important
                              slots:
                                default:
                                  - component: f7-block
                                    config:
                                      style:
                                        background: "='conic-gradient(transparent 0deg 160deg, ' + (props.colorThermostat ? props.colorThermostat : 'var(--f7-toggle-inactive-color)') + ' 160deg 200deg, transparent 200deg 360deg)'"
                                        content: ""
                                        display: block
                                        position: absolute
                                        width: 100%
                                        height: 100%
                                        bottom: "=props.size ? '-7px' : '-7px'"
                                        left: 50%
                                        transform: translate(-50%)
                            - component: f7-block
                              config:
                                class: hold left
                                style:
                                  margin-top: 0px
                                  position: absolute
                                  width: 100%
                                  height: 100%
                                  clip-path: "=props.size ? 'inset(0px 0px 0px ' + (Number(props.size)*0.89/2) + 'px)' : 'inset(0% 0% 0% 50%)'"
                                  border-radius: 100%
                                  background-color: rgb(58, 55, 73)
                              slots:
                                default:
                                  - component: f7-block
                                    config:
                                      class: fill fill1
                                      style:
                                        margin-top: 0px
                                        position: absolute
                                        width: 100%
                                        height: 100%
                                        border-radius: 100%
                                        clip-path: "=props.size ? 'inset(0px ' + (Number(props.size)*0.89/2) + 'px 0px 0px)' : 'inset(0% 50% 0% 0%)'"
                                        background: "=props.colorBarStartPoint && props.colorBarEndPoint ? '-webkit-linear-gradient(top, ' + props.colorBarEndPoint + ' 20%,' + props.colorBarEndPoint + ' 100%)' : '-webkit-linear-gradient(top, rgb(255, 73, 0) 20%,rgb(255, 73, 0) 100%)'"
                                        z-index: 1 !important
                                        transition: transform 0.6s
                                        transform: "=(items[props.setPointItem].state.split(' ')[0] >= (((Number(props.maxTemp) - Number(props.minTemp)) / 2) + Number(props.minTemp)) && items[props.setPointItem].state.split(' ')[0] <= Number(props.maxTemp) ? 'rotate('+(320/(Number(props.maxTemp)-Number(props.minTemp))*(items[props.setPointItem].state.split(' ')[0]-Number(props.minTemp))-160)+'deg)' : (items[props.setPointItem].state.split(' ')[0] > Number(props.maxTemp)) ? 'rotate(180deg)' : '')"
                            - component: f7-block
                              config:
                                class: hold right
                                style:
                                  margin-top: 0px
                                  position: absolute
                                  width: 100%
                                  height: 100%
                                  clip-path: "=props.size ? 'inset(0px 0px 0px ' + (Number(props.size)*0.89/2) + 'px)' : 'inset(0% 0% 0% 50%)'"
                                  border-radius: 100%
                                  background-color: rgb(58, 55, 73)
                                  z-index: 3 !important
                                  transform: rotate(180deg)
                              slots:
                                default:
                                  - component: f7-block
                                    config:
                                      class: fill
                                      style:
                                        margin-top: 0px
                                        position: absolute
                                        width: 100%
                                        height: 100%
                                        border-radius: 100%
                                        z-index: 3 !important
                                        animation: right 1s linear both
                                        transition: transform 0.6s
                                  - component: f7-block
                                    config:
                                      class: fill fill2
                                      style:
                                        position: absolute
                                        margin-top: 0px
                                        width: 100%
                                        height: 100%
                                        border-radius: 50%
                                        z-index: 3 !important
                                        clip-path: "=props.size ? 'inset(0px '+ (Number(props.size)*0.89/2) + 'px 0px 0px)' : 'inset(0% 50% 0% 0%)'"
                                        background: "=props.colorBarStartPoint && props.colorBarEndPoint ? '-webkit-linear-gradient(top, ' + props.colorBarEndPoint + ' 40%,' + props.colorBarStartPoint + ' 100%)' : '-webkit-linear-gradient(top, rgb(255, 73, 0) 40%,rgb(255, 158, 35) 100%)'"
                                        transform: "=(items[props.setPointItem].state.split(' ')[0] <= (((Number(props.maxTemp) - Number(props.minTemp)) / 2) + Number(props.minTemp)) && items[props.setPointItem].state.split(' ')[0] >= Number(props.minTemp) ? 'rotate('+(320/(Number(props.maxTemp)-Number(props.minTemp))*(items[props.setPointItem].state.split(' ')[0]-Number(props.minTemp))+20)+'deg)' : (items[props.setPointItem].state.split(' ')[0] > (((Number(props.maxTemp) - Number(props.minTemp)) / 2) + Number(props.minTemp))) ? 'rotate(180deg)' :  '')"
                            - component: f7-block
                              config:
                                class: span
                                style:
                                  margin-top: 0px
                                  width: "=props.size ? (Number(props.size)*0.89) +'px' : '100%'"
                                  font-weight: "=props.size ? (Number(props.size)*2) +'px' : 'calc(var(--f7-list-item-title-font-weight)*2)'"
                                  position: absolute
                                  bottom: 0px
                                  text-align: center
                                  text-transform: uppercase
                                  font-size: "=props.fontSizeFooter ? props.fontSizeFooter : '1em'"
                                  color: "=props.colorTypo ? props.colorTypo : 'rgb(87, 84, 95)'"
                                  z-index: 99 !important
                              slots:
                                default:
                                  - component: Label
                                    config:
                                      text: Heating
                      - component: f7-block
                        config:
                          class: shadow
                          style:
                            margin-top: 0px
                            position: absolute
                            top: 50%
                            left: 50%
                            transform: "=(items[props.setPointItem].state.split(' ')[0] >= Number(props.minTemp) && items[props.setPointItem].state.split(' ')[0] <= Number(props.maxTemp) ? 'translate(-50%, -50%) rotate('+(320/(Number(props.maxTemp)-Number(props.minTemp))*(items[props.setPointItem].state.split(' ')[0]-Number(props.minTemp))-160)+'deg)' : 'translate(-50%, -50%) rotate(0deg)')"
                            width: "=props.size ? (Number(props.size)*0.0625) +'px' : '6.25%'"
                            height: 86%
                            text-align: center
                            transition: 0.7s ease
                            animation: shadow 1.4s ease-out both
                        slots:
                          default:
                            - component: f7-block
                              config:
                                class: shadow-cube
                                style:
                                  margin-top: 0px
                                  position: absolute
                                  top: 0
                                  width: "=props.size ? (Number(props.size)*0.0625) +'px' : '100%'"
                                  height: 0px
                                  box-shadow: "=props.size ? '0 0 ' + (Number(props.size)*0.1125) +'px ' + (Number(props.size)*0.0325) + 'px ' + (props.colorSetMarker ? props.colorSetMarker : 'rgba(255, 158, 35, 0.5)'): '0 0 45px 13px rgba(255, 158, 35, 0.5)'"
                      - component: f7-block
                        config:
                          class: markerContainer
                          style:
                            pointer-events: none
                            margin-top: 0px
                            position: absolute
                            top: 50%
                            left: 50%
                            transform: "=(items[props.currentPointItem].state.split(' ')[0] >= Number(props.minTemp) && items[props.currentPointItem].state.split(' ')[0] <= Number(props.maxTemp) ? 'translate(-50%, -50%) rotate('+(320/(Number(props.maxTemp)-Number(props.minTemp))*(items[props.currentPointItem].state.split(' ')[0]-Number(props.minTemp))-160)+'deg)' : 'translate(-50%, -50%) rotate(0deg)')"
                            width: "=props.size ? (Number(props.size)*0.1) +'px' : '10%'"
                            height: 100%
                            text-align: center
                            transition: 0.7s ease
                            opacity: 1
                            z-index: 99 !important
                        slots:
                          default:
                            - component: f7-block
                              config:
                                class: markerCurrent
                                style:
                                  margin-top: 0px
                                  width: "=props.size ? (Number(props.size)*0.1) +'px' : '100%'"
                                  height: "=props.size ? (Number(props.size)*0.1) +'px' : ''"
                                  padding-top: "=props.size ? '' : '100%'"
                                  background: "=props.colorCurrentMarker ? props.colorCurrentMarker : 'rgb(33, 150, 243)'"
                                  position: absolute
                                  transform: translate(-50%,-50%) rotate(45deg)
                                  left: 50%
                                  top: "=props.size ? (Number(props.size)*0.14) +'px' : '15%'"
                                  border-radius: 0% 50% 50% 50%
                                  box-shadow: 0 0 5px 1px rgb(48, 46, 56)
                              slots:
                                default:
                                  - component: f7-block
                                    config:
                                      class: number
                                      style:
                                        margin-top: 0px
                                        position: absolute
                                        top: 50%
                                        left: 50%
                                        transform: translate(-50%, -50%) rotate(-45deg)
                                        text-align: center
                                    slots:
                                      default:
                                        - component: Label
                                          config:
                                            text: =items[props.currentPointItem].state.split(' ')[0]
                                            style:
                                              font-size: "=props.fontSizeMarker ? props.fontSizeMarker : '1em'"
                                              color: white
                                              font-weight: bold
                      - component: f7-block
                        config:
                          class: markerContainer
                          style:
                            pointer-events: none
                            margin-top: 0px
                            position: absolute
                            top: 50%
                            left: 50%
                            transform: "=(items[props.setPointItem].state.split(' ')[0] >= Number(props.minTemp) && items[props.setPointItem].state.split(' ')[0] <= Number(props.maxTemp) ? 'translate(-50%, -50%) rotate('+(320/(Number(props.maxTemp)-Number(props.minTemp))*(items[props.setPointItem].state.split(' ')[0]-Number(props.minTemp))-160)+'deg)' : 'translate(-50%, -50%) rotate(0deg)')"
                            width: "=props.size ? (Number(props.size)*0.1) +'px' : '10%'"
                            height: 100%
                            text-align: center
                            transition: 0.7s ease
                            opacity: 1
                            z-index: 99 !important
                        slots:
                          default:
                            - component: f7-block
                              config:
                                class: markerSet
                                style:
                                  margin-top: 0px
                                  width: "=props.size ? (Number(props.size)*0.1) +'px' : '100%'"
                                  height: "=props.size ? (Number(props.size)*0.1) +'px' : ''"
                                  padding-top: "=props.size ? '' : '100%'"
                                  background: "=props.colorSetMarker ? props.colorSetMarker : 'rgb(230, 74, 25)'"
                                  position: absolute
                                  transform: translate(-50%,-50%) rotate(-45deg)
                                  left: 50%
                                  top: "=props.size ?  (Number(props.size)*Number(-0.0125)) +'px': '-2%'"
                                  border-radius: 50% 50% 50% 0
                                  box-shadow: 0 0 5px 1px rgb(48, 46, 56)
                                  z-index: 100 !important
                              slots:
                                default:
                                  - component: f7-block
                                    config:
                                      class: number
                                      style:
                                        margin-top: 0px
                                        position: absolute
                                        top: 50%
                                        left: 50%
                                        transform: translate(-50%, -50%) rotate(45deg)
                                        text-align: center
                                    slots:
                                      default:
                                        - component: Label
                                          config:
                                            text: =items[props.setPointItem].state.split(' ')[0]
                                            style:
                                              font-size: "=props.fontSizeMarker ? props.fontSizeMarker : '1em'"
                                              color: white
                                              font-weight: bold
                      - component: f7-block
                        config:
                          class: center
                          style:
                            margin-top: 0px
                            position: absolute
                            width: "=props.size ? (Number(props.size)*0.65) +'px' : '65%'"
                            height: "=props.size ? (Number(props.size)*0.65) +'px' : '65%'"
                            background: "=props.colorControlRing ? props.colorControlRing : 'rgb(227, 228, 237)'"
                            top: 50%
                            left: 50%
                            transform: translate(-50%, -50%)
                            border-radius: 50%
                            box-shadow: 0px 15px 35px 11px rgba(46, 44, 58,0.60)
                        slots:
                          default:
                            - component: f7-block
                              config:
                                class: buttonContainer
                                style:
                                  display: "=props.heatingModeItem ? '' : 'none'"
                                  margin-top: 0px
                                  position: absolute
                                  top: 50%
                                  left: 50%
                                  transform: "=props.exampleModeItem ? 'translate(-50%, -50%) rotate(30deg)' : 'translate(-50%, -50%)'"
                                  width: "=props.size ? (Number(props.size)*0.15) +'px' : '15%'"
                                  height: 100%
                                  text-align: center
                                  transition: 0.7s ease
                                  opacity: 1
                                  z-index: 99 !important
                              slots:
                                default:
                                  - component: oh-button
                                    config:
                                      popoverOpen: ='.' + props.location + '.popoverHeatingMode'
                                      style:
                                        width: 100%
                                        height: 20%
                                        position: absolute
                                        bottom: 0%
                                        left: 50%
                                        transform: translate(-50%)
                                        color: "=props.colorButton ? props.colorButton + ' !important': ''"
                                    slots:
                                      default:
                                        - component: f7-icon
                                          config:
                                            f7: "=props.heatingModeItem ? (items[props.heatingModeItem].state ==  props.heatingModeArray.split(',')[0] ? 'hand_raised' : items[props.heatingModeItem].state == props.heatingModeArray.split(',')[1] ? 'arrow_2_squarepath' : items[props.heatingModeItem].state == props.heatingModeArray.split(',')[2] ? 'airplane' : 'thermometer') : ''"
                                            style:
                                              font-size: "=props.fontSizeButtons ? props.fontSizeButtons : '2em'"
                                              position: absolute
                                              transform: translate(-50%, -50%)
                                              top: 50%
                                              margin-top: auto
                                        - component: f7-popover
                                          config:
                                            class: =props.location + ' popoverHeatingMode'
                                          slots:
                                            default:
                                              - component: f7-card
                                                config:
                                                  noShadow: true
                                                  class:
                                                    - popover-close
                                                  action: variable
                                                  actionVariable: myVar
                                                  clearVariable: true
                                                  actionVariableValue: success
                                                slots:
                                                  default:
                                                    - component: f7-row
                                                      config: {}
                                                      slots:
                                                        default:
                                                          - component: f7-col
                                                            slots:
                                                              default:
                                                                - component: oh-repeater
                                                                  config:
                                                                    for: buttonlabel
                                                                    in: =props.heatingModeArray.split(",")
                                                                    containerStyle:
                                                                      width: 100%
                                                                  slots:
                                                                    default:
                                                                      - component: oh-button
                                                                        config:
                                                                          color: "=props.colorButton ? props.colorButton : ''"
                                                                          class: margin
                                                                          text: =loop.buttonlabel
                                                                          outline: true
                                                                          action: command
                                                                          active: "=props.heatingModeItem ? (items[props.heatingModeItem].state === loop.buttonlabel ? true : false) : ''"
                                                                          actionCommand: =loop.buttonlabel
                                                                          actionItem: "=props.heatingModeItem ? props.heatingModeItem : ''"
                            - component: f7-block
                              config:
                                class: buttonContainer
                                style:
                                  display: "=props.exampleModeItem ? '' : 'none'"
                                  margin-top: 0px
                                  position: absolute
                                  top: 50%
                                  left: 50%
                                  transform: "=props.heatingModeItem ? 'translate(-50%, -50%) rotate(-30deg)' : 'translate(-50%, -50%)'"
                                  width: "=props.size ? (Number(props.size)*0.15) +'px' : '15%'"
                                  height: 100%
                                  text-align: center
                                  transition: 0.7s ease
                                  opacity: 1
                                  z-index: 99 !important
                              slots:
                                default:
                                  - component: oh-button
                                    config:
                                      popoverOpen: ='.' + props.location + '.popoverExampleMode'
                                      style:
                                        width: 100%
                                        height: 20%
                                        position: absolute
                                        bottom: 0%
                                        left: 50%
                                        transform: translate(-50%)
                                        color: "=props.colorButton ? props.colorButton + ' !important': ''"
                                    slots:
                                      default:
                                        - component: f7-icon
                                          config:
                                            f7: wrench
                                            style:
                                              font-size: "=props.fontSizeButtons ? props.fontSizeButtons : '2em'"
                                              position: absolute
                                              transform: translate(-50%, -50%)
                                              top: 50%
                                              margin-top: auto
                                        - component: f7-popover
                                          config:
                                            class: =props.location + ' popoverExampleMode'
                                          slots:
                                            default:
                                              - component: f7-card
                                                config:
                                                  noShadow: true
                                                  class:
                                                    - popover-close
                                                  action: variable
                                                  actionVariable: myVar
                                                  clearVariable: true
                                                  actionVariableValue: success
                                                slots:
                                                  default:
                                                    - component: f7-row
                                                      config: {}
                                                      slots:
                                                        default:
                                                          - component: f7-col
                                                            slots:
                                                              default:
                                                                - component: oh-repeater
                                                                  config:
                                                                    for: buttonlabel
                                                                    in: =props.exampleModeArray.split(",")
                                                                    containerStyle:
                                                                      width: 100%
                                                                  slots:
                                                                    default:
                                                                      - component: oh-button
                                                                        config:
                                                                          color: "=props.colorButton ? props.colorButton : ''"
                                                                          class: margin
                                                                          text: =loop.buttonlabel
                                                                          outline: true
                                                                          action: command
                                                                          active: "=props.exampleModeItem ? (items[props.exampleModeItem].state === loop.buttonlabel ? true : false) : ''"
                                                                          actionCommand: =loop.buttonlabel
                                                                          actionItem: "=props.exampleModeItem ? props.exampleModeItem : ''"
                            - component: oh-button
                              config:
                                style:
                                  width: 30%
                                  height: 50%
                                  position: absolute
                                  margin-top: 0px
                                  top: 50%
                                  left: 10%
                                  transform: translate(-50%, -50%)
                                  color: "=props.colorButton ? props.colorButton : ''"
                                action: command
                                actionItem: =props.changeTargetSwitchItem
                                actionCommand: OFF
                              slots:
                                default:
                                  - component: f7-icon
                                    config:
                                      style:
                                        font-size: "=props.fontSizeButtons ? props.fontSizeButtons : '2em'"
                                        position: absolute
                                        transform: translate(-50%, -50%)
                                        top: 50%
                                        margin-top: auto
                                      f7: arrow_turn_left_down
                            - component: oh-button
                              config:
                                style:
                                  width: 30%
                                  height: 50%
                                  position: relative
                                  margin-top: 0px
                                  top: 50%
                                  left: 90%
                                  transform: translate(-50%, -50%)
                                  color: "=props.colorButton ? props.colorButton : ''"
                                action: command
                                actionItem: =props.changeTargetSwitchItem
                                actionCommand: ON
                              slots:
                                default:
                                  - component: f7-icon
                                    config:
                                      style:
                                        font-size: "=props.fontSizeButtons ? props.fontSizeButtons : '2em'"
                                        position: absolute
                                        transform: translate(-50%, -50%)
                                        top: 50%
                                        margin-top: auto
                                      f7: arrow_turn_right_up
                            - component: f7-block
                              config:
                                class: valveAnimation
                                style:
                                  z-index: -100 !important
                                  pointer-events: none
                                  display: "=(props.valveItem && items[props.valveItem].state == 'ON' )? '' : 'none'"
                                  background: "=props.colorSetMarker ? 'radial-gradient(' + props.colorSetMarker +' 30%, transparent 50%)' : 'radial-gradient(var(--f7-theme-color) 30%, transparent 50%)'"
                                  margin-top: 0px
                                  position: absolute
                                  transform: translate(-50%, -50%)
                                  width: 100%
                                  height: 100%
                                  top: 50%
                                  left: 50%
                                  border-radius: 50%
                                  animation: skeleton-effect-fade 2s linear infinite
                            - component: f7-block
                              config:
                                class: small
                                style:
                                  z-index: 100 !important
                                  margin-top: 0px
                                  position: absolute
                                  width: "=props.size ? (Number(props.size)*0.375) +'px' : '57.6%'"
                                  height: "=props.size ? (Number(props.size)*0.375) +'px' : '57.6%'"
                                  background: "=props.colorCenter ? props.colorCenter : 'rgb(248, 249, 250)'"
                                  text-align: center
                                  animation: bound-in-small 0.6s ease forwards
                                  top: 50%
                                  left: 50%
                                  transform: translate(-50%, -50%)
                                  border-radius: 50%
                                  box-shadow: 0px 5px 10px 5px rgba(96, 93, 111,0.19)
                              slots:
                                default:
                                  - component: f7-block
                                    config:
                                      class: heat
                                      style:
                                        font-size: "=props.size ? (Number(props.size)*0.0375) +'px' : '14px'"
                                        color: "=props.colorTypo ? props.colorTypo : 'rgb(87, 84, 95)'"
                                        font-weight: 300
                                    slots:
                                      default:
                                        - component: Label
                                          config:
                                            text: =props.location
                                  - component: f7-block
                                    config:
                                      class: heat
                                      style:
                                        font-size: "=props.fontSizeCenter ? props.fontSizeCenter : '2em'"
                                        color: "=props.colorTypo ? props.colorTypo : 'rgb(87, 84, 95)'"
                                        font-weight: 300
                                    slots:
                                      default:
                                        - component: Label
                                          config:
                                            text: "=props.unit ? items[props.setPointItem].state.split(' ')[0] + '' + props.unit : items[props.setPointItem].state.split(' ')[0]"
                                  - component: oh-image
                                    config:
                                      url: "=props.imgUrl ? props.imgUrl : 'https://community-openhab-org.s3-eu-central-1.amazonaws.com/original/2X/7/7d388a86c95471f89b1bb911d96d7609a3e3a059.svg'"
                                      style:
                                        position: absolute
                                        transform: translate(-50%)
                                        left: 50%
                                        width: 40%

Hi @snowy

use .displayState instead of .state

Then for example the line 460 in your yaml looks like:

Now:
text: =items[props.setPointItem].state.split(' ')[0]

After:

text: =items[props.setPointItem].displayState.split(' ')[0]

all the best,

Nico

If I change it to displayState i get this Iissue:

Any idea?

Please take a Scennshot of you logtail where the item change is displayed.

EDIT: better is an Export with the rest.api. so i can see the different states and maybe i can understand the issue.

I moved to openhab 3.1.0 M2 and the issue is gone. I will test it for couple hours and then I can report the result. I am currently not sure if this issue caused by the widget, opnehab or knx binding.

Hi Nico,

issue still exist - please find the item Change below:

Item 'ActualTemp_Buero' changed from 19.2 °C to 19.400000000000002 °C
Item 'ActualTemp_Flur' changed from 18.900000000000002 °C to 19.0 °C
Item 'ActualTemp_Kueche' changed from 19.8 °C to 19.900000000000002 °C

Item definition is:

Number:Temperature    ActualTemp_WZ                   "Ist Wohnzimmer [%.1f °C]"                 <temperature>      (gLivingroomThermostat, gTemperature)               ["Measurement", "Temperature"]     {alexa="CurrentTemperature", channel="knx:device:MDT_IP:MDT_HS8:ActualTemp_WZ", stateDescription=""[pattern="%.1f °C"]}
Number:Temperature    SollTemp_WZ                     "Soll Wohnzimmer [%.1f °C]"                <temperature>      (gLivingroomThermostat, gTemperature)               ["Setpoint", "Temperature"]        {channel="knx:device:MDT_IP:MDT_HS8:SollTemp_WZ", stateDescription=""[pattern="%.1f °C"]}

I wondering why the temperature change to the huge number of digits, in the Item definition it is limited to one digit - %.1f. Is this an issue which caused by the KNX binding?

Try with this at line 460

text: =Number(items[props.setPointItem].state.split(' ')[0]).toFixed(2)

Nico

1 Like

Thank you very much - I guess this works!!!

Your welcome!
Good news that we find a solution for your issue. :wink:

1 Like

Hi,

thank you very much for this great work. Did you ever considered using some kind of mapping for the heatingModeItem/exampleModeItem?

My heating e.g. only accepts numbers as input/output. I use standard widgets combined with command options and state description in order to map this to strings (0=Auto,1=Manuel). With the exampleModeItem it is the same (1=Standard,2=Vacation,3=Third option)

I am happy with my solution, but yours is definitely (very much) superior and if you find a possibility for the mapping, your solution would be universal.

BR
Peter

Hi,

your widget is too complex for me to do it directly, but here is an example how it could work:

uid: TestPK
tags: []
props:
  parameters:
    - description: The Name of the Test
      label: Name
      name: nameTest
      required: false
      type: TEXT
      groupName: heatingMode
  parameterGroups:
    - name: heatingMode
      context: action
      label: Heating Mode Action
timestamp: Mar 16, 2021, 8:34:03 PM
component: f7-card
slots:
  content:
    - component: oh-label-card
      config:
        title: ="The current State is " + items[props.heatingMode_actionItem].state
        actionPropsParameterGroup: heatingMode
        item: =(props.heatingMode_actionItem)
        footer: ="For the choice of the Icons you could use, that the first actionOption is " + props.heatingMode_actionOptions.split(',')[0].split('=')[0] + "; the second is " + props.heatingMode_actionOptions.split(',')[1].split('=')[0] + "... and so on"

The props will look like that:

and the widget for this example is:

[edit]
Please note, that the state of the item in the example is the displayState which I configured in the item itself that 1=Manuel,…

As you don’t use the state of the Item, this might be a bad example… sorry.

On the other hand… if the Command Option is configured in the item itself, one could even skip this configuration.

Hi everyone,

I have bring the widget to the next level. :wink:
In the first post ist the new release v2.0.0 with some new features.
20210417_105935

Now is the humidity in the widget. :wink:

Have fun,

all the best,
Nico

6 Likes

Hi Nico,

thanks for awesome widget, but I have some problems with the latest version (2.0.0), former version work great:

error

I am using openhab 3.0.2, do you have any idea?

Thanks in advance

Do you have renew the editor preview?

Yes, I did. I solved the NAN and TypeError.

Temperature is received as string with unit (Bosch smart home), therefore I changed the line:

=Number(items[props.currentPointItem].state).toFixed(1)
=>
=Number(items[props.currentPointItem].state.split(’ ').[0]).toFixed(1)

And I needed to insert an unit, then the undefined disappered. Now only the outer ring problem is existing, I did a renew still not visible.

When i add a fixed size, the output is even more strange: