Generating a Wallplug widget and need help for switch

Hello,
I created a widget see here

uid: widgetSteckdose
tags:
  - Soll Tag
  - homekit-look
  - in use
props:
  parameters:
    - description: Location?
      label: Prop 1
      name: prop1
      required: false
      type: TEXT
    - description: Thermostate icon f7
      label: f7 icon name
      name: icon1
      required: false
      type: TEXT
    - description: Humidity icon f7
      label: f7 icon name
      name: icon2
      required: false
      type: TEXT
    - context: item
      description: A actual power item to display
      label: Item
      name: itemActualPower
      required: false
      type: TEXT
    - context: item
      description: A total power item to display
      label: Item
      name: itemTotalePower
      required: false
      type: TEXT
    - context: item
      description: A daily total power item to display
      label: Item
      name: itemDailyTotalPower
      required: false
      type: TEXT
    - context: item
      description: the valve state
      label: Item
      name: itemValve
      required: false
      type: TEXT
    - context: item
      description: Item for temperature channel
      label: Ambient temperature
      name: itemAmbientTemp
      required: false
      type: TEXT
    - context: item
      description: Item for outdoor temperature channel
      label: Outdoor temperature
      name: itemOutdoorTemp
      required: false
      type: TEXT
    - context: item
      description: Item for target temperature channel
      label: Target temperature
      name: itemTargetTemp
      required: false
      type: TEXT
  parameterGroups: []
timestamp: Jan 13, 2023, 3:24:34 PM
component: f7-card
config:
  class:
    - card-expandable-animate-width
  expandable: true
  noShadow: false
  style:
    --f7-card-expandable-margin-horizontal: 5px
    --f7-card-expandable-margin-vertical: 10px
    --f7-card-expandable-tablet-border-radius: 2px
    --moz-user-select: none
    --ms-user-select: none
    --webkit-user-select: none
    background-color: '=(Number.parseFloat(items[props.itemDailyTotalPower].state.split(" ")[0]) > 60) ? "white" : (Number.parseFloat(items[props.itemActualPower].state.split(" ")[0]) > 22) ? "white" : "rgba(228,228,228,0.9)"'
    border-radius: var(--f7-card-expandable-border-radius)
    box-shadow: var(--f7-card-expandable-box-shadow)
    display: flex;
    flex-direction: column
    height: 120px
    justify-content: space-between
    max-height: 120px
    max-width: 400px
    min-height: 120px
    min-width: 110px
slots:
  default:
    - component: f7-card-content
      config:
        style:
          width: 100%
      slots:
        default:
          - component: f7-block
            config:
              class:
                - no-padding
              style:
                margin: -4px
            slots:
              default:
                - component: f7-row
                  config:
                    class:
                      - justify-content-left
                  slots:
                    default:
                      - component: f7-icon
                        config:
                          class:
                            - align-self-center
                          f7: =props.icon1
                          size: 22
                          style:
                            color: '=(Number.parseFloat(items[props.itemDailyTotalPower].state.split(" ")[0]) > 60) ? "black" : (Number.parseFloat(items[props.itemActualPower].state.split(" ")[0]) > 22) ? "black" : "rgb(0,0,0,0.5)"'
                            margin-left: -6px
                            margin-top: 0px
                      - component: Label
                        config:
                          style:
                            color: '=(Number.parseFloat(items[props.itemDailyTotalPower].state.split(" ")[0]) > 60) ? "black" : (Number.parseFloat(items[props.itemActualPower].state.split(" ")[0]) > 22) ? "black" : "rgb(0,0,0,0.5)"'
                            font-size: 14px
                            font-weight: 500
                            margin-left: -4px
                            margin-top: 0px
                          text: =props.prop1
                - component: f7-row
                  config:
                    class:
                      - justify-content-left
                  slots:
                    default:
                      - component: Label
                        config:
                          style:
                            color: '=(Number.parseFloat(items[props.itemDailyTotalPower].state.split(" ")[0]) > 60) ? "black" : (Number.parseFloat(items[props.itemitemActualPower].state.split(" ")[0]) > 22) ? "red" : "black"'
                            font-size: 40px
                            font-weight: 350
                            line-height: 1.1
                            margin-left: -2px
                            margin-top: 20px
                          text: =(Number.parseFloat(items[props.itemActualPower].state.split(" ")[0]) * 100 / 100).toFixed(1) + 'W'
                - component: f7-row
                  config:
                    class:
                      - justify-content-left
                  slots:
                    default:
                      - component: f7-icon
                        config:
                          f7: =props.icon2
                          size: 16
                          style:
                            color: '=(Number.parseFloat(items[props.itemDailyTotalPower].state.split(" ")[0]) > 60) ? "red" : "rgb(0,0,0,0.5)"'
                            left: 0px
                            top: 0px
                          visible: =props.itemDailyTotalPower !== undefined
                      - component: Label
                        config:
                          style:
                            color: '=(Number.parseFloat(items[props.itemDailyTotalPower].state.split(" ")[0]) > 60) ? "red" : "rgb(0,0,0,0.5)"'
                            font-size: 13px
                            font-weight: 500
                            left: 0px
                            margin-top: 0px
                          text: =(Number.parseFloat(items[props.itemDailyTotalPower].state)) + 'kWh'
                          visible: =props.itemDailyTotalPower !== undefined
                - component: f7-row
                  config:
                    class:
                      - justify-content-left
                  slots:
                    default:
                      - component: f7-icon
                        config:
                          f7: arrowshape_turn_up_right
                          size: 16
                          style:
                            color: rgb(0,0,0,0.5)
                            opacitiy: 0.5
                            padding-right: 0px
                            padding-top: 83px
                            position: absolute
                            right: 0
                            top: 0
                            z-index: 999
                      - component: f7-chip
                        config:
                          bgColor: "=(items[props.itemValve].displayState) === 'ON') ? 'orange' : (items[props.itemValve].displayState) === 'undefined') ? 'white':'orange'"
                          style:
                            border-radius: 25px 25px 25px 25px
                            color: white
                            margin-top: -7px
                            position: absolute
                            right: -3px
                            size: 20
                            top: 8px
                            z-index: 2
                          text: =items.Z_way_switch_WallPlug21.displayState || items.Z_way_switch_WallPlug21.state//(Number.parseFloat(items[props.itemTotalePower].state))+ 'kWh'
                - component: oh-trend
                  config:
                    style:
                      --f7-theme-color-bg-color: transparent
                      background: var(--f7-theme-color-bg-color)
                      filter: opacity(30%)
                      height: 100%
                      left: 2
                      position: absolute
                      top: 0
                      width: 100%
                      z-index: 1
                    trendItem: =[props.itemActualPower]
                - component: oh-link
                  config:
                    action: group
                    actionGroupPopupItem: =[props.itemGroup]
                    class:
                      - card-prevent-open
                    style:
                      height: 100%
                      left: 0
                      position: absolute
                      top: 0
                      width: 100%
                      z-index: 1

But I have issues with this line

items.Z_way_switch_WallPlug21.displayState || items.Z_way_switch_WallPlug21.state

In my widget it is displayed undefined

Where is my error. It should sate "ON" in my pages setup I have cleraly defined the item

component: widget:widgetSteckdose
config:
  prop1: Wallplug4
  itemTemp: Z_way_number_WallPlug4_actualpower
  itemActualPower: Z_way_number_WallPlug21_actualpower
  itemDailyTotalPower: number_wallplug21dailytotalenergy
  itemTotalePower: Z_way_number_WallPlug21_totalpower
  itemAmbientTemp: Z_way_number_WallPlug21_actualpower
  itemOutdoorTemp: number_wallplug21dailytotalenergy
  itemTargetTemp: Z_way_number_WallPlug21_actualpower
  itemValve: Z_way_switch_WallPlug21
  itemMode: Z_way_switch_WallPlug21

any help appreciated :slight_smile:

In the text you’ve posted there is additional content in that same expression which is not valid code: the //. Are you sure the error isn’t because of that additional code?

The displayState || state code looks correct, so I don’t think the problem is there. By the way, if you are on the 3.4 release, then you have access to a shortcut:

@'Z_way_switch_WallPlug21'

which is the same as the long form

items.Z_way_switch_WallPlug21.displayState || items.Z_way_switch_WallPlug21.state

Thanks :slight_smile:
I thought a // is a comment :slight_smile:

But I have also an issue with this line

bgColor: "=(items[props.itemValve].state) === 'ON') ? 'orange' : (items[props.itemValve].state) === 'undefined') ? 'white':'orange'"

the background color is not applied.

What is wrong there?

The expression is not actually javascript, it is a yaml string that is then sent to an expression parser that is “javascript-like”. This means that if you want to comment something out, you have to use yaml comments, and the yaml comment character is #. The problem here, is that the way the widget yaml is stored and retrieved, those comments get lost. You can comment out a line or part of a line while you are working in the editor, but once you save the widget and reload it that comment will be gone. If you really want to leave yourself a comment in the widget code, use comment: Your comment here under the config heading for a component.

I think there are a few compound problems here. The first thing to understand is that the items[SomeItemName].state will never be undefined. The items dictionary is somewhat special in that it is dynamically defined within the widget to reduced the computation load on the widget. It is not simply a dictionary of all the item states, that would be huge and transmitting that dozens of times for every widget would result in a terribly slow UI. Instead, the widget tracks which few items it needs to so it knows when those states change, but all invalid references to the items dictionary return -.

It is possible, however, for the expression you are trying to use as a key in items to be undefined. javascript (and the widgets lighter “js-like” expression parser) can return undefined as the result of an expression, but cannot use an undefined expression in something else. So it’s OK for props.itemValue to be undefined and you can test for that, but if it is undefined, then items[props.itemValue].state will throw an error. If you have the possibility of undefined values, you have to be very careful the order in which you make your tests and always test for the existence of a value/expression before you use it in something else.

In this case, you want to test for props.itemValue first, and then (only if it exists) decide what the bgColor should be.

bgColor: "=(props.itemValue) ? 'orange' : 'white'"

This is based on the fact that the line you have posted results in orange no matter what the state of items[props.itemValue].state is. If you really want the color to be dynamic based on that state then you will also have a nested ternary expression in place of just 'orange'.

Thank you a lot :slight_smile: