OH3 expression not working as expected

Hi,

I am playing with my first widgets and wanted to create a “Default List Item Widget” for some of my items.
I noticed that for a battery level item this does not work as expected:

Item Type: Number:Dimensionless
Semantic Class: Battery
State Description: not set
Item value: 76 %

While using the “Widgets Expression Tester” I get the following results:
=(items.og_linus_l_batterylevel.state < ‘6’) = false
=(items.og_linus_l_batterylevel.state < ‘7’) = false
=(items.og_linus_l_batterylevel.state < ‘8’) = true
=(items.og_linus_l_batterylevel.state < ‘9’) = true
=(items.og_linus_l_batterylevel.state < ‘10’) =true

This does not really make sense to me.
Also tried with a different syntax, but I get the same result.

=(items.og_linus_l_batterylevel.state < ‘8|%’) = true

Am I doing something wrong here?

Hi,

I think you are comparing an integer to a char. For me this works:

items.Ups01_Batterycapacity.state = 100

=(items.Ups01_Batterycapacity.state > 35)     >   true

while this doesn’t:

=(items.Ups01_Batterycapacity.state > '35')    >  false

There are a few things that can trip you up. As Tom points out you are comparing the state with a String. So it’s doing a string comparison. Alphabetically, ‘8’ is after (greater than) ‘76’. That’s one trip up.

Usually, if the Item is a Number (with no units) you should be able to compare it to a number in an expression.

= (items.og_l_batterylevel.state < 6) = false

Next we have units of measurement. You say the Item value is “76 %”. If that is literally the value of the Item (i.e. it’s a Number:Dimensionless) than that value of the state is in fact the string “76 %”. You’ll need to convert that to a number to do a proper comparison. To do that you need to extract the units and parse the number.

Number.parseInt(items.og_I_batterylevel.state.split(" ")[0])
2 Likes

There is no need for split since parseInt:

If parseInt encounters a character that is not a numeral in the specified radix , it ignores it and all succeeding characters and returns the integer value parsed up to that point.

So

Number.parseInt(items.og_I_batterylevel.state)

should work for both

76

and

76 %

In both cases parseInt should give back 76.

3 Likes

That will work, without parsing or conversion, without the stringy quotemarks.
(items.og_linus_l_batterylevel.state < 8|%)

This actually throws an error in the Widgets Expression Tester
Error: Expected expression after < at character 42

Thank you @crnjan,
That worked perfectly!

I am still wrapping my head around if I even need UoMs or if I just should leave everything as a number.
i think to me (or my setup) UoMs are not that important or I just do not understand the value behind it…

Many of the bindings will force-feed your Items Quantity Types, so it’s best to get to grips with it.

Yes, of course - I’d completely forgotten we were in widget code, sorry.

1 Like

This is probably a really dumb question, but I just cant figure it out myself…

I am playing around with widgets and the expressions which can be used in these widgets using the “Widgets Expression Tester” in the sidebar.

I have two Number item:

Number:Temperature   OWM_Current_Temperature "OWM - Temperatur [%.1f %unit%]" <temperature>       (gWeatherOWM, gWeatherValues, gSemWeatherDataOWM) ["Measurement", "Temperature"]  { channel="openweathermap:onecall:api:local:current#temperature" }
Number:Dimensionless Dryer_State "State Dryer [%d]"    (gStateItems, gLaundry)

Booth items are defined, when logging them in a rule like

log.info("State: {} {}".format(items['Dryer_State'], type(items['Dryer_State']) ) )
log.info("Temp: {} {}".format(items['OWM_Current_Temperature'], type(items['OWM_Current_Temperature']) ) )

this results in

State: 10.0 <type 'org.openhab.core.library.types.QuantityType'>
Temp: 10.9 °C <type 'org.openhab.core.library.types.QuantityType'>

But when using these items in the expression Tester, only for the temperature item a valid state is displayed:

=items.OWM_Current_Temperature

results in

{ "state": "10.9 °C", "displayState": "10,9 °C" }

This looks goof for me, even if I am wondering why a display state is shown when I have not defined it.

whereas

=items.Dryer_State

results in

{ "state": "-" }

This happens with other items I have tested too.

And I really can’t figure out why…

And while I am at it:

In the widgets here in the forum a see two different expressions for accessing the item state in a widget, like above items.ItemName.state and items[].state. I assume, that these are interchangeable, is this correct?

Thanks for your help!

Oh yes you did

[%.1f %unit%] is the Item’s default state presentation.
Most of the other UIs will use that - however I think MainUI unhelpfully ignores it.
This Item is also linked to a binding channel. Channels can suggest presentation formats, they show up as presentation options I think in the Item’s JSON when examined with API explorer.

You should be able to see the difference with the the other Item now.

But, I wonder if you are misusing Number:Dimensionless type. This is not a number without units (that would be just Number type) but a ratio,usually given in % or dB units. a “blank” unit is treated as ratio e.g. 10:1 or 10 to 1.

Thanks for claryfing the display state!

Amazing, is there anything you do not know about openHAB :wink:

Thanks for pointing this out too! But it was just a test because the expression tester does not display anything useful for that item and I tried to eliminate the differences. Originally the item was defined just as “Number” and I will change this back.

Regarding my problem, that some items where not correctly displayed in the expression tester: I just restarted openhab and now the items that failed before are displayed correctly, without changing anything else…

=items.Dryer_State
{ "state": "10.0", "displayState": "10" }

Very strange…

Just to provide a little more info. I suspect the displayState is coming from the binding. Bindings can provide a default display format for the Items linked to them which of course can be overridden. But these defaults can and often do differ from the default that will be displayed by the Item based on it’s Item type.

Your second Item isn’t linked to a Channel so it’s just using the default state based on the Item type. Also, it appears that your second Item doesn’t have a state (i.e. -) or more properly its state is NULL or UNDEF. I’m not sure what happens in that case but I would not be surprised if the display state gets suppressed.

One thing I’ve noticed when accessing my OH through a reverse proxy is that after a time the SSE feed stops updating the developer sidebar. I don’t know if this is an OH problem or a problem with my specific machines or my work network and I’ve not had time to look into it further. Perhaps that was happening here and it’s why the Item showed up as -.

I am not sure, if I understand you correctly, you are referring to the missing display state and not to the state shown as “-” ?

I did some more testing:

The item is not bound to a channel, but it contained a valid number, as I confirmed by logging its state. I also tried to set the value explicitly in a rule. Nonetheless the expession tester in the developer sidebar did not show it, as described above.

After restarting openHAB, without changing anything else (the item is configured to be restored on startup via mapdb) it worked es expected and showed the correct state and a display state.

Than I removed the “Dimensionless” from the item definition, after that the state of the item is shown without the display state, but with the correct value:

{ "state": "10" }

I double checked this. When adding “Dimensionless” again, the display state is also shown again. So there seems to happen some magic in the background for quantity types. Regarding the definition of the display state you are probably right with your first guess, that the display state is derived from the default label, as I defined nothing else for this item.

One thing I’ve noticed when accessing my OH through a reverse proxy is that after a time the SSE feed stops updating the developer sidebar. I don’t know if this is an OH problem or a problem with my specific machines or my work network and I’ve not had time to look into it further. Perhaps that was happening here and it’s why the Item showed up as -.

This might be an explanation, I am accessing openHAB via nginx. But the wrong state was only shown for some items, not all, I tested about 15-20 items, but could not figure out any pattern. Between the tests I tried reloading the UI in the browser.

Thanks again for your help!

I encounter a problem with an expression where I check the status of an Item of type “String” I used the “point” mode, the problem is that the gold of the condition === it does not work ? need to do some formatting?

attached the condition:

=items.OpenhabNucRemote_ItemluminosityOutState.displayState === 'Sombre' ? 'blue' : 'yellow'

the item must be “blue” .
do you have an idea ? Thanks for your help.

Maybe try =items.OpenhabNucRemote_ItemluminosityOutState.state

What do you get in the expression tester with just
=items.OpenhabNucRemote_ItemluminosityOutState
?

is a simple test the complete expression have mutltiple condition yes