OH3 oh-repeater scope set up by variable to prevent "Attempting to send a state update of an item which doesn't exist"

Hi Everyone

I have been working on my CADDX Generic Alarm Widget to try and clean up some errors as follows:

11:18:53.847 [WARN ] [se.internal.SseItemStatesEventBuilder] - Attempting to send a state update of an item which doesn't exist: Partition5_Armed
11:18:53.847 [WARN ] [se.internal.SseItemStatesEventBuilder] - Attempting to send a state update of an item which doesn't exist: Partition6_Armed
11:18:53.847 [WARN ] [se.internal.SseItemStatesEventBuilder] - Attempting to send a state update of an item which doesn't exist: Partition7_Armed
11:18:53.847 [WARN ] [se.internal.SseItemStatesEventBuilder] - Attempting to send a state update of an item which doesn't exist: Partition8_Armed

These are generated by the following bit of YAML:

- component: f7-block
  config:
    style:
      --f7-button-text-color: var(--f7-text-color)
      --f7-button-bg-color: var(--f7-card-bg-color)
      --f7-theme-color-rgb: var(--f7-color-blue-rgb)
      top: 46%
      position: absolute
      width: 100%
      z-index: 999
    class:
      - padding
  slots:
    default:
      - component: f7-row
        config:
          style:
            --f7-theme-color: var(--f7-color-blue)
            --f7-button-bg-color: transparent
          class: no-gap
        slots:
          default:
            - component: oh-repeater
              config:
                fragment: true
                for: partition
                in:
                  - 1
                  - 2
                  - 3
                  - 4
                  - 5
                  - 6
                  - 7
                  - 8
              slots:
                default:
                  - component: f7-row
                    config:
                      width: "10"
                    slots:
                      default:
                        - component: oh-button
                          config:
                            tooltip-trigger: hover
                            tooltip: '=!(props.tooltipEnable) ? false : "Apply Partition to current run"'
                            bgColor: '=(items["Partition" + loop.partition + "_Armed"].state === "-") ? "gray" : (items["Partition" + loop.partition + "_Armed"].state === "ON") ? "red" : "green"'
                            style:
                              --f7-button-hover-bg-color: var(--f7-color-blue-tint)
                              --f7-button-pressed-bg-color: var(--f7-color-blue-tint)
                              border-radius: 12px
                              text-overflow: ellipsis
                              white-space: nowrap
                              overflow: hidden
                              z-index: 999
                            text: =["P" + loop.partition]
                            fill: true
                            textColor: white
                            disabled: '=(items["Partition" + loop.partition + "_Armed"].state === "-") ? true : false'
                            raised: false
                            action: variable
                            actionVariable: selectedPartition
                            actionVariableValue: ='Partition' + loop.partition

Specifically the expressions:

bgColor: '=(items["Partition" + loop.partition + "_Armed"].state === "-") ? "gray" : (items["Partition" + loop.partition + "_Armed"].state === "ON") ? "red" : "green"'

and

disabled: '=(items["Partition" + loop.partition + "_Armed"].state === "-") ? true : false'

The reason is that though the alarm caters for up to 8 Partitions, there may only be 1 or 2 (in my case 4) configured and in use.

I am trying to find a way to fix my expressions to not generate the errors when the missing Partitions are encountered. But I would still like the full 8 partitions to be displayed - with the extra ones just greyed out as disabled:

I would appreciate any ideas on how to achieve this.
Thanks
Mark

First off, these are just warnings and not errors. They do no harm, they are not indicative of any significant problem, and, you can very comfortably just ignore them and go on with your day.

These warnings derive from the way the widgets work. It would be incredibly inefficient for the UI to send the complete list of items to every widget and update that with every item change when most widgets only need the information about a small handful of items. So, as each widget runs, it keeps a list of all the items that are accessed using the items object and just registers those items with the event stream listener in order to be able to track changes to the minimum number of items. If an item is referenced that doesn’t exist, the UI spits out this warning, sets the item’s values to -, and carries on perfectly happily. I suspect the original intent of this warning was just as a check to the widget developer to let you know where to find a potential malfunction in case you are expecting all of the items referenced in the widget to exist.

The upshot here is that as long as you need to run a check about whether or not an item exists in a widget (i.e., there is a chance an item will not exist) you will get this warning.

It is possible to work around this? Sure, I could conceive of a couple of different ways of refactoring this widget to not have to reference non-existent items. The problem is that all of them would be way more complicated and/or require extra pieces (possibly an additional rule, or proxy items…or both). Because this is just a warning this extra effort really isn’t worth it. If it really bothers you to see these in your logs it’s almost certainly less effort to edit your logging to filter them out.

On an unrelated note: if you’d like to clean up the widget code just the tiniest bit, it’s not necessary to list out a number array like that in a repeater. Repeaters have a range option for sourceType which lets you specify a rangeStart and rangeStop property to get a numerical list like this.

Thanks Justin. Once again your explanation etc. makes perfect sense. I guess I must just suppress my OCD tendencies

You suggestion did however spark an idea that I tried.

I set up a property for the range

props:
  parameters:
    - default: 8
      description: Numbers of Partitions in System
      label: Numbers of Partitions in System
      name: numberPartitions
      required: false
      type: TEXT

and then set up the oh-repeater as follows:

    - component: f7-block
      config:
        style:
          --f7-button-text-color: var(--f7-text-color)
          --f7-button-bg-color: var(--f7-card-bg-color)
          --f7-theme-color-rgb: var(--f7-color-blue-rgb)
          top: 46%
          position: absolute
          width: 100%
          z-index: 999
        class:
          - padding
      slots:
        default:
          - component: f7-row
            config:
              style:
                --f7-theme-color: var(--f7-color-blue)
                --f7-button-bg-color: transparent
              class: no-gap
            slots:
              default:
                - component: oh-repeater
                  config:
                    fragment: true
                    sourceType: range
                    for: partition
                    rangeStart: 1
                    rangeStop: =props.numberPartitions
                  slots:
                    default:
                      - component: f7-row
                        config:
                          width: "10"
                        slots:
                          default:
                            - component: oh-button
                              config:
                                tooltip-trigger: hover
                                tooltip: '=!(props.tooltipEnable) ? false : "Apply Partition to current run"'
                                bgColor: '=(items["Partition" + loop.partition + "_Armed"].state === "-") ? "gray" : (items["Partition" + loop.partition + "_Armed"].state === "ON") ? "red" : "green"'
                                style:
                                  --f7-button-hover-bg-color: var(--f7-color-blue-tint)
                                  --f7-button-pressed-bg-color: var(--f7-color-blue-tint)
                                  border-radius: 12px
                                  text-overflow: ellipsis
                                  white-space: nowrap
                                  overflow: hidden
                                  z-index: 999
                                text: =["P" + loop.partition]
                                fill: true
                                textColor: white
                                disabled: '=(items["Partition" + loop.partition + "_Armed"].state === "-") ? true : false'
                                raised: false
                                action: variable
                                actionVariable: selectedPartition
                                actionVariableValue: ='Partition' + loop.partition

When using the default value - 8 the plan works perfectly. However if I enter a value via Props the rangeStop expression seems to give an incorrect value - this is always 10x the value entered.

If I use:

          - component: Label
            config:
              text: =props.numberPartitions 

The output is the expected value entered?

EDIT: Also, if I do not enter a value for the props - the default appears to be 10. And entering 0 produces the expected 0.

EDIT 2: So it seems the following ALMOST works:

    - default: 8
      description: Numbers of Partitions in System
      label: Numbers of Partitions in System
      name: numberPartitions
      required: true
      type: INTEGER

The problem is now that when I save the widget, exit the widget editor and go back in the default: 8 has been changed to default: "8" which breaks the whole thing?
Any ideas?

EDIT 3: This seems to be specific to the Widget Editor. When the widget is called from a oh-cell etc the correct prop is used.

Strange. Sounds like it’s time for a GitHub big report.

Logged as :

Response from Yannick Schaus on Github:

Prop parameters are serialized as ConfigDescriptionParameter in the JSONDB and thus default values are always Strings:
https://www.openhab.org/javadoc/latest/org/openhab/core/config/core/configdescriptionparameter#getDefault()

So it’s not an issue with the UI per se - not necessarily unfixable but this is the wrong repo.

You could use:

              rangeStop: =Number.parseInt(props.numberPartitions)

in your oh-repeater.

This works nicely