OH3: UI editor quirks; items not showing; comments disappearing

  • openHABian 3.4 on rPi4 with 4GB

I am referring to this: Animated Energy Widget

This is the first time I am working with pages and widgets in the UI editor.
… and I have to say this UI editor is ridiculous! … or I don’t know how to use it.

I massaged this widget and did some testing by setting visibility to true and commented out the formula that determines visibility.
Guess what? It removed all comments, hence, I lost all formulas.

Also, when searching in an file open in the editor with Ctrl-F, it counts one more than there are results in the file. It looks like it counts the search term as well.

Where do people actually edit these yaml files, so that

  1. (ideally) the item names can be selected from a list
  2. comments remain in the file
    Solution for this is, introduce a new property, such as Comment, Note, etc., like so:
Note: line from pv to consumers
visible: true
Comment: "=(Number.parseFloat(items[props.spm_Solar_Total].state) - (Number.parseFloat(items[props.spm_Source_Power].state) + Math.abs(Number.parseFloat(items[props.spm_Battery_Power].state))) > 0) ? true : false"

Why are visibility statements in quotes and text: isn’t?

What is the difference between .displayState and .state?
Answer: Formatting of values in UI / state vs displaystate

Why did some say they had to cast to parseInt instead of parseFloat? This makes no sense. My power values are all integers, hence, I should be be able to cast these to Floats for the purpose of this widget?

However, none of my values show, even when selecting the correct item. What am I missing?


Only have a widget under Developer Tools; not elsewhere. Do I need to?
Does the item selection only work in ‘the other’ location? Wherever that is?!


When saving the icons, my browser picked .png as extension. Are these actually SVGs?


Any hints appreciated.

The yaml is stored by OH as json files. Data in yaml is 100% compatible with the json format (by design), but json does not have comments. So comments in yaml get ignored when going to json and thus, when OH goes back to yaml from the json the comments are gone. This is why this trick

works. You can comment out lines in the yaml editor temporarily while you are designing and testing, you just cannot save and reload the comments.

Due to the structure of vue UI there is actually quite a bit more on many pages than you actually see. The search function, however still finds these hidden things. The discrepancy between the number of search hits and the text is not simple one extra. Here I can get 8 search hits for a word that doesn’t exist in the widget text at all:

This is the best game in town for widget editing. You could use a different text editor and then paste your content into the widget editor pane, but you would loose all content hints, yaml checks, and live preview.

There are many places in the editor where you do indeed get a list item names as along as it is one of the item contexts that the widget editor recognizes (for example, after you type items. or @@). If the list of item names doesn’t come up in these situations you can press ctrl + space to bring up the hint window.

In fact this hint window works for much more than just item names, it will also give you many other hints about available opbjects in the widget expressions.

The yaml sytax requires [key name]:[space][key value], so yaml readers base their parsing on the location of :[space]. Because the widget expressions use a javascript like syntax, there are places where :[space] might appear a second time in a line. The most common example is the javascript ternary operator test ? if true : if false. If you put on of those as the raw value of one of the yaml keys like this:

color: =(items.some_switch.state == 'ON') ? 'green' : 'red'

you will get a yaml parsing error because it thinks you have put two key-value pairs on one line. One solution to this is to put the whole expression (leading = included) inside quotes so that it is clear the full expression string is one value. The other solution is simply to get rid of the space after the : in the expression. For readability, I prefer to use ( ) to set off each part:

color: =(items.some_switch.state == 'ON')?('green'):('red')

There is no requirement here other than whatever the logic of the expression demands. parseInt and parseFloat work exactly as you would expect them to.

Yes, but there’s also no reason to as long as the logic of the rest of the expression can handle integer values.

No one will ever be able to tell you unless you show the code that isn’t working.

All your custom widgets are listed in the widgets section of the developer tools. But that is just for the administration of the widgets. You have to add the widgets to one or more pages to see them in actions in the normal users space of the UI.

1 Like

Awesome; thank you :+1: Lots of great info…

I found the expression editor; it does not work with double quotes; like so:

"=(Number.parseInt(items[props.spm_Battery_SoC].state) > 20) ? true : false"

Removing the quotes always leads to false.

In fact, I can only get this to work, when removing all but:

=items.spm_Battery_SoC.state > 20 ? true : false

… which leads ot the question, do I need [probs] bit?

Yes, I get that :slight_smile: I was referring to the original post… this seems to work for most. I am puzzled, that none of the numbers (labels?) are shown?
I strongly believe that post is correct, and after placing my items in there, none show… which is unexpected, the items exist, and are all numbers (no units; hence, why I removed the split() the author had in there); like so:

Example:
Author:

visible: '=(Number.parseFloat(items[props.netzeinspeisung].state.split(" ")[0]) > 0) ? true : false'

Me:

visible: '=(Number.parseFloat(items[props.spm_Source_Power].state) > 0) ? true : false'

Setting the formulas to true (commenting them out)… All symbols show, but no numbers.
image

I did not change the formula, but only the item name(s).

Note: line from pv to consumers
visible: "=(Number.parseFloat(items[props.spm_Solar_Total].state) - (Number.parseFloat(items[props.spm_Source_Power].state) + Math.abs(Number.parseFloat(items[props.spm_Battery_Power].state))) > 0) ? true : false"```

I didn’t think I can bugger this up as I seemingly did.

The short of it: setting visibility to true will work, using the formula doesn’t.


Alright: simple things… I have to redraw the widget when changing these formulas. It never occurred to me, because when changing symbol-related code, it did make the changes in the preview.

DANG! :frowning:

The top of the widget you are looking at (and, in deed, the top of 99.99999% of widgets) contains a list of the widget properties, or props.

uid: SMA_widget
tags: []
props:
  parameters:
    - context: item
      label: Netzeinspeisung
      name: netzeinspeisung
      required: true
      type: TEXT
    - context: item
      label: Netzbezug
      name: netzbezug
      required: true
      type: TEXT
+ many more

These can call be configured to whatever values you like. In the widget editor you do this by pressing the set props button at the bottom of the window. When you are adding the widget to a page you do it by putting the values in the widget’s config object.

The whole point of these props in widgets is that you shouldn’t have to change the code of the widget at all to to make it work with your system, you just configure the widget properties with the names of your own items.

You will set prop netzeinspeisung to the name of your item that represents the outgoing power of your system. You will set prop netzbezug to the name of your item that represent the incoming power of your system. etc.

If, for some reason, you really want to change the widget expressions, then you need to understand what the expression actually is:

visible: '=(Number.parseFloat(items[props.netzeinspeisung].state.split(" ")[0]) > 0) ? true : false'
  • props.netzeinspeisung evaluates to a string that conatins the name of the items set as that property
  • items[some_string].state retrieves the current state of the item with the name that is held in the string variable/expression some_string.

If you want to get the state of an item that you know the name of (and will never change as far as the expression is concerned) you can use the dot syntax instead items.exact_name_of_item_here.state.

In the epxressions you will see the [ ] syntax more often because the name of the item is being generated as a string by some other expression, such as getting the value of the netzeinspeisung property.

1 Like

Thank you again!

I am making progress…

I have now figured that I need to redraw the widget after making a change, but do not need to save it first. OK.

I also figured, removing the props[] part will produce numbers and working formulas.

I will make an effort to understand what your props[] explanation means.
→ Got it. Set Props link at bottom (as you indicated).

One thing missing…

When I “Set Props”, I get an item list, and make the relevant associations.

Ctrl-R will redraw the widget, and it looks as it should.

What do I need to do next?

I reloaded the widget and was ‘uninitialised’ as in the associations were gone.

Repeated the associations, and hit save; reloaded and the association was gone.

How do I make this permanent?

You do not use the widget editor to deploy this widget. This is just for development of the general widget template, which is why the props are not saved. If you want a permanent version of the widget you have to add it to a page (where you will have a chance to configure the properties you want to see for the widget on that particular page).

Each one of the custom widgets can be reused as many times as you like on as many different UI pages as you like with different configured properties each time. It would defeat the purpose of the widgets if you had to use the widget editor tosave only one set of properties.

1 Like

Again, I am very grateful for your support!

Thanks again; I got it now.

For all others, this is (I am) an example of someone who has never before touched yaml, f7, widgets and the UI editor in openHAB. It has nothing to do with the ‘traditional’ (pre OH3) way of knowledge. Completely different kettle of fish.

Enjoy.

image

The Developer Sidebar (alt-shift-d) can also search for, pin, and let you copy Item names, Thing IDs, etc… This works in cases where the inline hint window doesn’t work or is otherwise unavailable.

I want to caution on the use of “cast” here. This is not a correct usage of this term. In programming languages that support Object Oriented Programming there is a concept called “polymorphism”. This concept means that you can have a hierarchy of “is a” relationships that any single Object can have. For example:

Object -> Number -> BigDecimal
    |        |----> Integer
    |        |----> Double
    |---> String

Given the above, Double, Integer and BigDecimal are all dependents of Number. This means all three actually are Numbers and therefore you can “cast” each of them to become Number.

However, this casting only goes up or down, not side to side. You cannot cast a BigDecimal to a Double, for example. Given that, you cannot simply cast a String to a Number because Number is not in the hierarchy for String.

In order to convert types in cases where casting is not possible requires a transformation. In this case, you’d parse the String to create a new Number. This transformation is not a cast.

I don’t want to be pedantic here but avoid confusion because casting is a fundamentally different type of operation from a type transformation and if they are mentally treated the same you will run into trouble and confusion down the line.

This point cannot be stressed enough for both end users and for those coding widgets and rule templates. Every effort should be made to make it so that end users do not have to edit the widgets so as many things that can be configured through a property should be configured that way.

I’ll also add they can be used in “default X widget” Item metadata. That’s actually how I uses custom widgets the most.

One thing I like to do with widgets like this is to set it as the “default stand-alone widget” of the Equipment Group. Then I can just put that Group Item on the page and it will use that stand alone widget instead of putting the widget on the page directly.

If you want to change how it appears on the Overview page’s tabs, set the “default list item widget”.

1 Like