Good morning
I tried to maximise the information in an oh:list widget to show the conditions of all zwave and zigbee devices (battery level, and last seen).
Every device has items like ‘AAnn_LifeCheck’ or ‘AAnn_BatterieLadung’ etc , where AA is like ‘FS’ (Fenster (window)sensor or ‘LED’ (then three letters) and nn counts up from 01 to 09 for every device.
So the group ‘gLifeCheck’ is the loop index. From every loop item I take the name (like ‘FS01’) and add the rest (like 'BatterieLadung’), to find the corresponding item.
For every point ( badge or color) I used the same code, which becomes rather long.
Is there a chance to use a variable like dashPosition := loop.item.name.search("") and use this
here
You cannot do variable assignment in widget expressions. However, in 4.2 an oh-context component has been added:
And you can see examples of how to use its three features in the variables, constants, and custom functions section of the widget help:
This is exactly the use case for a context function. In this case, because you would be using a function and not a variable specific to each loop iteration, you would put the context as the parent of the repeater and define the function once and you could then call it in each of your list-item expressions. Here’s an abbreviated outline:
You cannot just copy and paste the code that I provided, it is incomplete. I just typed it up quickly while replying, to demonstrate the structure of the widget. The error you are getting is because:
component: oh-list-card
- component: oh-context
is an invalid widget definition and invalid yaml syntax. It should be:
Thank‘s for your help, it will keep all silly user like me happy for the next years, when they can search for detailed informations here, even it costs you a lot more work. Thanks‘s again.
Everything works pretty good, I only have problems to ask for fn results been not a number.
This is where the widget expression tester is very helpful. If you open up the developer side bar (press the ? button at the top or press shift + alt + d) and go to Tools and the third tool button you will get this:
Enter example widget expressions in the box and you will see immediate results displayed. So, build up each part of your function to see where the problem is. For example, you know the the items where the result goes badly, so start with the string name of that item and make sure that the search string gets correct results:
(this will show you the whole returned item object, not just the state)
Continue like this until you find the point where the result is not what you expect and you can start to debug the problem from there.
I don’t have your items and your values, so I can’t really do this part for you. But, most likely, the problem is that the states that are being returned from those items are not in a format that Number.parseFloat can handle. If that’s the case, then you’ll have to figure out what state those items do have and a way to either get the state into a more consistent format or expand the complexity of your function to handle those different states.
Sorry, I didn‘t explain it in a correct way. If the fn function gets an item name, which does not exists, the page shows a „-„ , but in the log you get a warning
2024-07-28 22:28:15.749 [WARN ] [e.internal.SseItemStatesEventBuilder] - Attempting to send a state update of an item which doesn’t exist: SD05_BatterieLadung
To avoid that warning, I like to check if the return value of the Funktion is a number. I tried to check for UNDEF but it doesn’t work
Well, the expression tester is your friend here too. Use it to see what the return value of an expression like your function is when an invalid name is entered. You are right, the items object in widget expressions always returns - when an item doesn’t exist or it’s state is UNDEF. But, the items object is not the final process in your function, Number.parseFloat is. So you’ll need use the expression tester to know what that returns when the input is. Notably the answer will never be UNDEF that is specific to OH item states, and not a javascript value.
You can make an educated guess, even if you don’t have access to the expression tester. The screen shot you posted shows that in the case of the missing items, the concatenated string is NaN%-->passiv. Nothing about string concatenation should result in a NaN response so that is most likely the direct result of the function in that case. You can test for for that with Number.isNaN() function.
=Number.isNaN(fn.getBattState(loop.item.name)) ? 'Result is not a number' : 'Result is a number'
2024-09-09 16:10:43.380 [WARN ] [e.internal.SseItemStatesEventBuilder] - Attempting to send a state update of an item which doesn't exist: SD03_BatterieLadung
2024-09-09 16:10:43.381 [WARN ] [e.internal.SseItemStatesEventBuilder] - Attempting to send a state update of an item which doesn't exist: SD04_BatterieLadung
2024-09-09 16:10:43.382 [WARN ] [e.internal.SseItemStatesEventBuilder] - Attempting to send a state update of an item which doesn't exist: SD05_BatterieLadung
The warning tells me, that the item I am looking for does not exists, which is ok.
I think, the warning comes from the function itself and not from displaying the state of the non existing item. How can I avoid that message?
You are correct, and because it is just a warning there is no problem if you just choose to ignore it.
There are times when it can be tricky to avoid this message just because of the nature of the widget build (I myself still have one widget that produces these warnings on occasion as well). You need to have some way to get the information about whether the item exists without polling the item itself. Often this is more trouble than just ignoring the the warning. But, for example, you could add a metadata to each of the base items in your widget that specifies whether there is an associated BatterieLadung item, and only call the function if that metadata (which can be accessed via the repeater’s fetechMetadata property) returns true.
Alternatively, you could simply add the missing items, leave them at a NULL state and handle the null repsonse in the widget function.