Main UI Widget development structured information needed

Tags: #<Tag:0x00007fc8f4e99db8>

Hi all,

i try really hard to dig into all this widget stuff. There are many examples, but often an example does not give any explanation. Actual i have two questions:

1.) If i add a property to a widget the is the type key. What types are possible. Until now i found only TEXT

2.) How do i implement loops. The Sonos widget uses loops, but from the example it is hard to understand the general idea. Is there somewhere a documentation about this.

Thanks
Thomas

1 Like

I second this

one more

Hi!

You’re right, all those new cool features seem to still lack proper documentation, I also had a hard time when I started digging into OH3.

Although I’m not to deep into this yet, I’ll try to help you by trying to read the code :slight_smile:

1.) there seem to be: TEXT, INTEGER, BOOLEAN and DECIMAL

2.) hm, more complicated than I thought. Even though I probably shouldn’t do this, I’ll try to explain what I read from the code (and to learn about it myself :wink: ):

The general idea is to display components in a “foreach” manner, i.e. iterate over a source and display a component(-tree) for each element. For this you need to set a component “oh-repeater” and set its config:

  • sourcetype, possible values:
    • range: iterate over numbers, additional config for this:
      • rangeStart: number to start from
      • rangeStop: number to stop at
      • rangeStep: number to add with each iteration
    • itemsWithTags: iterate over all items with certain tags, additional config:
      • itemTags (required): comma separated list of tags (to be confirmed)
      • fetchMetadata: comma separated list of metadata (to be confirmed)
    • itemsInGroup: iterate over items in a specific group
      • groupItem: group to get the items from
      • itemTags: comma separated list of tags (to be confirmed)
      • fetchMetadata: comma separated list of metadata (to be confirmed)
    • itemStateOptions: iterate over predefined states an item can be set to
      • itemOptions: item to get states from
    • itemCommandOptions: iterate over predefined commands an item can be set to
      • itemOptions: item to get commands from
    • unset: iterate over a provided array of string
      • in: array of string to iterate over
  • for: name of the variable to assign current iteration value to (see below) (though from the code it seems there’s more to it, perhaps an array of variables is possible, didn’t quite get that yet)
  • filter: boolean expression (without preceding “=“) to filter for
  • map: expression returning value to use instead of original array’s value

Styling options:

  • listContainer (boolean): if true, wrap each resulting component(-tree) in a <ul> tag
  • fragment (boolean): if true, do not wrap component(-tree) in any container tag (ignored of listContainer is true)
  • none of the above present: wrap in <div>
  • containerClasses: classes to apply to <ul> or <div>
  • containerStyle: styles to apply to <ul> or <div>

Then, In child components the following variables are available to be used in a expression:

  • loop.<name_of_for_value_in_config>: iteration’s current value
  • loop.<name_of_for_value_in_config>_idx: iteration’s current index
  • loop.<name_of_for_value_in_config>_source: complete iteration array

While writing this up I found a bunch of examples as part of the original pull request: here
Though please note that “vars” has been replaced by “loop”.

Wow, this ended up to as quite some cheatsheet… Though no limit or warranty to the information given here :wink:

6 Likes

You got it right, I’m probably going to borrow that for the docs :slight_smile:

Im struggling with the filter :frowning:

I just want to iterate over items with a certain state:

- component: oh-repeater
  config:
    for: item
    sourceType: itemsWithTags
    itemTags: LowBattery
    fetchMetadata: semantics,widgetOrder 
    filter: (loop.item.state == ON)

The above lead to empty result. What am I doing wrong?
Is there some examples how to benefit from the filter option?

Can answer myself meanwhile :wink:

This works:

- component: oh-repeater
  config:
    for: item
    sourceType: itemsWithTags
    itemTags: LowBattery
    fetchMetadata: semantics,widgetOrder
    filter: loop.item.state != "OFF"

BUT: Need to mention, that changes of the filter expression in the widget editor does not always trigger an update on the preview. This confused me at first.

So I had right expressions multiple times already without noticing it :wink:

Then I started playing with:

filter: true and filter: false

to convince myself, that the filter feature does affect the iteration at all.
Once this has worked; I’ve started with the “complications” … :wink:

Hint:

If the filter expression seems not working properly: Save the widget code and reload it …

It has become a habit to always hit CTRL+R a couple of times… :grinning:

Well, lesson learned too :wink:

BTW: Any idea how to access the “parent equipment group” of an item found by:

sourceType: itemsWithTags
itemTags: <tag>

If the found items have all the same label (“Temperature”, “Battery low”, etc.) it would be nice to determine, what equipment group in the model is belongs to.

EDIT:
@ysc, may I ask you directly if there is an option deriving and finally accessing the equipment (and/or location) parent group item a certain tagged-item belongs to?

Obvious use case is selecting items with specific state having a certain semantic class attached to it:

  • LowBattery and *.state == "ON"
  • Alarm and *.state == "ON"
  • Status and *.state == "OFFLINE"
  • OpenState

… and then display them on UI elements enriched by information (mainly the Label) taken from the parent semantic group(s) (equipment, location) of the items found by class and filter…

There is none AFAIR, this would require additional requests to get the data.

I’ve describe an idea how to circumvent:

I simply gather the information upfront and store them in metadata. Then I can access the parent group labels even from inside the widget code: