[SOLVED] Custom Widget w/ oh-repeater, use expression on item.name

Hi all,

I’ve dug into creating my own widgets lately and I’m trying to create a list containing temperatures. This does work neatly after some struggles, even with a slight use of expressions, but I was wondering wether I could also apply expressions to the name of the processed item?

It does work on the label, contrary to some still open github issue, but no matter what I insert as expression, the list will only show dashes.

uid: list_temp
tags: []
props:
  parameterGroups: []
timestamp: Jun 13, 2022, 11:06:37 PM
component: f7-card
config:
  title: Temperatur
slots:
  default:
    - component: oh-list
      slots:
        default:
          - component: oh-repeater
            config:
              fragment: true
              for: item
              sourceType: itemsInGroup
              groupItem: avgTemp
            slots:
              default:
                - component: oh-label-item
                  config:
                    iconColor: gray
                    color: green
                    title: =(loop.item.label.split("(")[1]).split(")")[0]
                    item: =loop.item.name

I want the temperatures to be both rounded and have the unit attached, sadly all of those examples will only grant me “- °C” in every room. I’ve tested them all in the side panel, not with loop.item obviously but with some distinct item.

                    item: =Math.round(loop.item.name * 10)/10 + " °C" 
                    item: =loop.item.name + " C"
                    item: =Number.parseFloat(loop.item.name)

Wether or not the part after the : is in ’ does not make any difference. Is this intended or am I not seeing something?

Picture shows the status quo (with which I am unhappy) and the result of me trying to apply any sort of expression.

I think your confusion stems from this line:

This line is not passing the value that the label displays. This line tells the oh-label-item to populate its label with the state that it gets from an item with a name that matches whatever the value of the loop.item.name variable is.

So you need to make sure that you are clear on the difference between the name of an item and the state of an item. The name of an item is a unique combination of letters, numbers, and underscore that identifies the item. On an item details page, its the part at the top:
image
In the case above, the item name is AutomationTime (no space, because spaces are not allowed in names), the item label is Automation Time. Neither of these are the item state which is the value that the item currently holds.

Many of the OH specific widgets will have an item property which takes the item name so that the internal widget code can dynamically look up the item state for use in the widget.

The repeater variable does have access to the item state (loop.item.state) but you don’t want this either because this is just a snapshot of the state at the time the repeater was created, and it won’t change if the item changes. What you want it to use the items object in the expression. The items object will remain linked to the real-time state of the item so that changes will be reflected in your widget. To use the items object you have to call the object property that matches the name of the item but you have that already in your’ loop variable. That means to get the item state it would look something like this:

items[loop.item.name].state

That will always be a string, however, so you won’t be able to doing and math or rounding with it until you convert it to a number, which is just one of the previous things you’ve already tried.

Number.parseFloat(items[loop.item.name].state)
1 Like

I do realize there’s a difference between .name and other properties likes item.state, I feel like my misunderstanding here leads from somewhere else.

It seems as if the widget internally finds the state to display if not explicitely stated. I just changed the widgets code to item: =items[loop.item.name].state. This leads to having no proper display, again just a dash. If I understand this correctly, the item: part solely states which item (or object) to display within the ob-label-item.

But how would I format the label then, if not through the item: entry?

Correct. I didn’t say to set the item property to that value, only that’s how to format the item’s state value to get the text you wanted.

Correct. No more, no less.

In the component docs, you can see that the oh-label-item has an after property that allows you to provide a custom text in place of the item property.

If you need more than that you will have to dig deeper. The oh widgets are intended to be as low-code, simple configuration as possible, but this means that they are also not very flexible. If you want the ability to control more aspects of of the widget then you have to find a more generic version and build your own equivalent from combinations of other components. In this case, the more generic version would be an oh-list-item. There are many examples throughout the forum where you can find more advanced list item components that people have developed from the oh-list-item or it’s even more generic version the f7-list-item that all the oh items are based on.

1 Like

That did work, at least somehow. The formatting is now in order. But there is still an appended dash for which I don’t have any explanation. The current config looks like this:

                - component: oh-label-item
                  config:
                    item: loop.item.name
                    title: =(loop.item.label.split("(")[1]).split(")")[0]
                    after: =Math.round(items[loop.item.name].state*10)/10 + " °C"

whereas the resulting list looks like this:
Screenshot 2022-06-15 at 21-57-52 openHAB

The list works just fine without the item: loop.item.name part, the dash remains though. Any idea on this?

As far as items go, I mainly copied an example from the docs. It should’ve been the “all lights” code example, as described here: Pages - Custom Widgets | openHAB . As soon as I manage to get this going, I will try to implement your input, which is greatly appreciated. Got to figure out the formatting first, though, because this bugs me.

The dash is resulting from this line:

item: loop.item.name

If you’re going to use a variable in the yaml, then you need to always start the expression with an = or the yaml thinks it’s just the real value. So right now each item in the list is trying to show you the value of an item actually named loop.item.name. This item, of course, doesn’t exist, so the widget returns a dash as a placeholder.

The good news is that you can just get rid of this line altogether. You don’t need it because you’re using the item state directly via the expression in the after property. You don’t need the widget’s internal code to try and get the item state for you.

1 Like

As I said, the dash persists even without that line. I did, just for the fun of it, just change oh-label-item to oh-list-item and it’s gone. So I guess I am all set now. Thanks for the help!

That’s strange. It shouldn’t do that. In even a most minimal example:

uid: widget_list_test
props:
  parameterGroups: []
  parameters: []
tags: []
component: oh-list-card
config:
  title: List Test
slots:
  default:
    - component: oh-label-item
      config:
        title: Title here
        after: =(['Expression','here']).join(' ')

You get no dash if the item property is omitted.
image

After you removed the item line from the widget did you manually refresh the widget display? I find that on occasion changes to item calls will require the manual refresh to display properly.

Well, while I am pretty sure that I did in fact refresh the preview and the page, there is now no more dash. Weird. But I am noticing the UI acting weird all over, so it might just be that. Don’t really know how to put the Weirdness into words, but something’s off.

just curious… what platform are you running openHAB on?

Currently on a Pi with Debian Buster.

pi:~>>>uname -a
Linux rpi 5.15.32-v7l+ #1538 SMP Thu Mar 31 19:39:41 BST 2022 armv7l GNU/Linux
pi:~>>>apt search openhab
openhab/stable,now 3.2.0-1 all [installed]
  openhab