openHAB 3 UI - Badges with visible-condition not loaded at first

Hello,
i’ve put much time into creating custom widgets, being able to have very flexible content and also use oh-repeater to show whats going on in some rooms, dynamically.

Here you see one example where i’ve created a widget for the room “Büro”.
The green badges are ment to show whats going on in this room.
The Problem is (as you see in this gif), that sometimes some badges are not shown.

As i then once go into the “Büro”-specific page (where some other items are shown but you dont see them) and then go back, the missing Badge (“Bildschirm”) is there again.

Nothing changes, i just open a page in the web-gui and go back to the overview.
Same happens if im using the android app.
It seems like it doesnt matter what page i open, when i come back, the missing badges are there again.

Kazam_screencast_00000

The condition showing and hiding the badge is

visible: =items[props.badgeitm.split(";")[loop.int_idx]].state == props.badgecond.split(";")

wich then should be (through oh-repeater) something like

visible: =items["SckOffcPeri_Swt"].state == ON

Here the full code

uid: cLink
tags:
  - link
  - page
  - card
props:
  parameters:
    - description: Text, to be shown as Link
      label: Title
      name: title
      required: false
      type: TEXT
    - description: "example: cPowerConsumption"
      label: Page
      name: link
      required: true
      type: TEXT
    - description: "example: /static/livingroom.jpg"
      label: Background-Image
      name: backgroundurl
      required: false
      type: TEXT
    - description: "example: Off_office;Focus_office;Cinema_office;Chill_office;Party_office;"
      label: Scene List
      name: scene
      required: false
      type: TEXT
    - description: "example: Fernseher;SleepTimer;"
      label: Badge Text List
      name: badgetxt
      required: false
      type: TEXT
    - description: "example: tv;wifi;"
      label: Badge Icon List
      name: badgeico
      required: false
      type: TEXT
    - description: "example: dSckBedRoomTv_Swt;dSckLvngRoomTv_Swt;"
      label: Badge Item List
      name: badgeitm
      required: false
      type: TEXT
    - description: "example: ON;ON;"
      label: Badge Condition List
      name: badgecond
      required: false
      type: TEXT
    - description: "example: green;orange;"
      label: Badge Color List
      name: badgecol
      required: false
      type: TEXT
  parameterGroups: []
timestamp: Jun 9, 2021, 10:41:21 AM
component: f7-card
config:
  style:
    padding: 0px
    border-radius: 7px
    border-width: 1px
    border-color: rgba(255,255,255, 0.2)
    box-shadow: 0px 0px 8px 4px rgba(255, 255, 255, 0.1)
  outline: true
slots:
  default:
    - component: f7-card-content
      config:
        style:
          height: 100px
          padding: 0px
          background-image: ='url(' + props.backgroundurl + ')'
          background-size: cover
          background-postion: center
          border-radius: inherit
      slots:
        default:
          - component: oh-button
            config:
              position: absolute
              action: navigate
              actionPage: ='page:' + props.link
              actionPageTransition: f7-circle
              border-radius: inherit
              style:
                --f7-button-bg-color: rgba(0,0,0,0.3)
                --f7-button-hover-bg-color: transparent
                --f7-button-pressed-bg-color: white
                height: 100%
                width: 100%
                top: 0px
                left: 0px
                padding: 0px
                border-radius: inherit
            slots:
              default:
                - component: oh-button
                  config:
                    style:
                      height: 100%
                      width: 100%
                      background: linear-gradient(20deg, rgba(255,255,255,0.5) 0%, rgba(255,255,255,0.5)5%, rgba(255,255,255,0) 30%,rgba(255,255,255,0) 70%,rgba(255,255,255,0.5) 95%, rgba(255,255,255,0.5) 100%)
          - component: Label
            config:
              text: "=(props.title) ? props.title : props.link"
              style:
                position: absolute
                font-size: 40px
                color: rgba(0,0,0,0.7)
                bottom: 0px
                left: 10px
                font-weight: bold
                pointer-events: none
                no-shadow: false
                text-shadow: 0px 0px 15px rgba(255, 255, 255, 1)
          - component: oh-button
            config:
              visible: "=(props.scene != NULL) ? true : false"
              action: popup
              actionModal: widget:listScenes
              actionModalConfig:
                scenestr: =props.scene
              style:
                position: absolute
                right: 5px
                top: 5px
                width: 50px
                height: 50px
                padding: 0px
                --f7-button-hover-bg-color: rgba(255,255,255,0.5)
                display: flex
                justify-content: center
                flex-wrap: wrap
            slots:
              default:
                - component: f7-icon
                  config:
                    f7: slider_horizontal_3
                    color: black
                    size: 30px
    - component: oh-repeater
      config:
        for: int
        sourceType: array
        in: =props.badgetxt.split(";")
        fragment: true
      slots:
        default:
          - component: f7-badge
            config:
              visible: =items[props.badgeitm.split(";")[loop.int_idx]].state == props.badgecond.split(";")[loop.int_idx]
              textColor: black
              color: =props.badgecol.split(";")[loop.int_idx]
            slots:
              default:
                - component: oh-button
                  config:
                    visible: =(props.badgeico.split(';')[loop.int_idx] != 'NULL')
                    iconF7: =props.badgeico.split(";")[loop.int_idx]
                    iconSize: 13px
                    color: black
                    style:
                      padding: 0px
                - component: Label
                  config:
                    visible: =props.badgetxt.split(';')[loop.int_idx] != 'NULL'
                    text: =props.badgetxt.split(";")[loop.int_idx]

Can anyone tell me, if my widget is too complex, if there are some limitations in how many operations can be done or if its a bug?

Thanks

When I was tinkering around with the widgets and visibility of items, it helped me a lot to put the condition into

- component: Label
    config:
        text: =items[props.badgeitm.split(";")[loop.int_idx]].state == props.badgecond.split(";")

With that you can at least see what happens. And - with complex statements, I often had to use quotes around the expressions - you could try that as well:

visible: '=items[props.badgeitm.split(";")[loop.int_idx]].state == props.badgecond.split(";")'

Thanks @Tetsuo
But i think everything is working well, due to the fact, that no item state changes but sometimes the Badge is not there.

Every time i reload my overview-page i get the frontail log message:

Attempting to send a state update of an item which doesn't exist

In this post
https://community.openhab.org/t/attempting-to-send-a-state-update-of-an-item-which-doesnt-exist/111807/8?u=shured
there is the information, that this should be caused by having components in widgets, with item-definition but the item is not correclty defined.

In my case this is exactly what should cause this message, because im using always strings like:

Bath;Livingroom;Buero;

and im splitting them by “;”
This can lead to have (in the upper example) in array-cell 4 a empty cell.

Thats why (i think):

  1. oh-repeater creates a badge with a not defined item-link
  2. via “visible” config i supress this badge to show up

But for sure its there and can cause the error, but you can’t see it.
Maybe this is a interruption in creating all the items?

Now it gets a little bit off topic:
Can anyone tell me how to use the “filter” option for oh-repeater to only show badges, as defined in my visible-config defined in the badge-configstrong text

I didn’t get it working, since i need the int_idx etc
I would need something like this line of code:
(As you know, the current “visible”-line is not placed at oh-Repeater, but at the badge-component)
(The shown line does NOT work)

...
- component: oh-repeater
     config:
       filter: '(items["lTop_Str"].state.split(";")[loop.int_idx] !== "" && items["lTop_Str"].state.split(";")[loop.int_idx] !== "NULL")'
...

Without your complete code it’s dificult to tell you whats wrong with your filter, but you can try if this helps you:

uid: tetsuo-repo-oh3-widget-repeater-filter-example
props:
tags: []
component: f7-card
slots:
  default:
    - component: oh-repeater
      config:
        for: room
        in: =["Büro", "Schlafzimmer", "Wohnzimmer", ]
        filter: loop.room
        fragment: true
      slots:
        default:
          - component: oh-label-cell
            config:
              label: =loop.room

String split didn’t work in my test, and the filter: loop.room is the short version of filter: loop.room !== undefined

Hope it helps

1 Like

Oh, and what I forgot to mention: Be careful with comparisons like that.

You’re using the type safe !== comparison - “NULL” is a string. so this will always be true, no matter what your left part of the comparison is. (as long as it is not “NULL” :wink: )

1 Like

Thanks!
I hope I can check this in the coming days!

Thanks very much!
This worked, helped to make my code much more cleaner and now i do not have the frontail message

Attempting to send a state update of an item which doesn't exist

anymore! → Very nice!

But it still seems like there are badges missing when i initially load the overview-page.
As i go to another page via navigate-action and back → The Badges appear (as in gif above)

I will further investigate on this and try to post some informations here.
But im still not sure if the problem can be solved by myself or if its a bug.

Glad it was helpful.

I’d first try to split and iterate over the items you are using for your badges and not another string that is not directly related to the items - maybe there is a mismatch “on start”.

Second I’d just add the item states for the badges as labels - always visible for debug purposes - so you can see if it is a problem in the iterator, or maybe some runtime condition with your items and they also don’t show up in the labels.

Good luck! :wink:

Now i had time to check this again:

  • Now i dont get any message like this “Attempting to send a state update of an item which doesn’t exist”
  • I tried to replace each and every visible condition by using the filter option

For this special Widget (Big Buttons for each room) i am generating all badges, but show them only if the item state is for example ON
This way i think all badges are generated always, but not visible if the condition is not given

I just added now labels to show the result of the visible-condition for the badges:

ezgif.com-gif-maker

  • As you see at “Büro”, there are two times the Labels: true → Which should lead to two shown badges
  • If i then open a random page “Aufgaben” (which has nothing to do with related items or something) and go back, the badge is shown …

I added

          - component: Label
            config:
              text: =items[props.badgeitm.split(";")[loop.int_idx]].state == props.badgecond.split(";")[loop.int_idx]

And here in the complete oh-repeater-part you see, that i use exactly this condition for the badge-visible condition

    - component: oh-repeater
      config:
        for: int
        sourceType: array
        in: =props.badgetxt.split(";")
        filter: loop.int != ""
        fragment: true
      slots:
        default:
          - component: Label
            config:
              text: =items[props.badgeitm.split(";")[loop.int_idx]].state == props.badgecond.split(";")[loop.int_idx]
          - component: f7-badge
            config:
              visible: =items[props.badgeitm.split(";")[loop.int_idx]].state == props.badgecond.split(";")[loop.int_idx]
              textColor: black
              color: =props.badgecol.split(";")[loop.int_idx]
              style:
                justify-content: center
            slots:
              default:
                - component: f7-icon
                  config:
                    f7: =props.badgeico.split(";")[loop.int_idx]
                    size: 15px
                    color: black
                - component: Label
                  config:
                    text: =loop.int

And again:
Nothing changes regarding item-states … im just opening a page and go back via mouse-back-button

So this must me some kind of “initial graphical” issue?

I’d first try to split and iterate over the items you are using for your badges and not another string that is not directly related to the items - maybe there is a mismatch “on start”.

Im not sure if i understand what you want me to do. For this badge, which is pre-configured via widget-props, i have to use other strings (than the loop-string) to decide if i want to show the badge or not

Currently im on " openHAB 3.1.0.M5" → Do you think i should go back to main and try again? → I dont think this will solve the issue