Rule if error

  • Platform information:
    • Hardware: AMD Atlon 2gb
    • OS: Debian 9.5
    • Java Runtime Environment: (build 1.8.0_212-8u212-b03-2~deb9u1-b03)
    • openHAB version: openHAB 2.4.0 Release Build

Good day.

He created a simple rule that does not change the temperature in order to report on the inclusion or disconnection of hot water:

var Number ControllerDS18B20_notifi_level = 0

rule "Records when device ControllerDS18B20 was last seen"
when
Item test_rule_switch received update or
  Item Temperature_28dd2c3503000064 received update or
  Item Temperature_285ef73403000076 received update or
  Item Temperature_287626350300007d received update or
  Item Temperature_285e0d3b010000b8 received update or
  Item Temperature_28f2602402000022 received update or
  Item Temperature_28ea183b010000cd received update or
  Item Temperature_28e6eb340300008d received update or
  Item Temperature_28a06224020000e1 received update
then
  postUpdate(ControllerDS18B20_LastUpdate, new DateTimeType())

 logInfo("Records when device ControllerDS18B20 was last seen", "Temperature_28a06224020000e1.state=" + Temperature_28a06224020000e1.state)
 logInfo("Records when device ControllerDS18B20 was last seen", "ControllerDS18B20_notifi_level=" + ControllerDS18B20_notifi_level)

if ((ControllerDS18B20_notifi_level < 1 ) && (Temperature_28a06224020000e1.state as Number < 40)){
  SendTextToUsers.apply("Отключили горячую воду: " + Temperature_28a06224020000e1.state +" градусов")
  ControllerDS18B20_notifi_level=1
  logInfo("Records when device ControllerDS18B20 was last seen", "ControllerDS18B20_notifi_level=" + ControllerDS18B20_notifi_level)
}

 if ((ControllerDS18B20_notifi_level > 0) && (Temperature_28a06224020000e1.state as Number>45)){
  SendTextToUsers.apply("Включили горячую воду: " + Temperature_28a06224020000e1.state +" градусов")
  ControllerDS18B20_notifi_level=0
  logInfo("Records when device ControllerDS18B20 was last seen", "ControllerDS18B20_notifi_level=" + ControllerDS18B20_notifi_level)
}

logInfo("Records when device ControllerDS18B20 was last seen", "END")
end

but in the Openhab.log log I get an error:
019-07-01 11:17:30.507 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model 'my.rules' has errors, therefore ignoring it: [45,94]: no viable alternative at input '40'

if replaced:
if ((ControllerDS18B20_notifi_level < 1 ) && (Temperature_28a06224020000e1.state as Number < 40)){

on
if ((ControllerDS18B20_notifi_level < 1 ) && (Temperature_28a06224020000e1.state < 40)){

no error:
2019-07-01 11:19:34.431 [INFO ] [el.core.internal.ModelRepositoryImpl] - Loading model ‘my.rules’
2019-07-01 11:19:40.391 [INFO ] [e.smarthome.model.script.Initializer] - Initialize all items …

in the logs I noticed that for this item the dimension is appended to the dimension, for others there is no such thing:
2019-07-01 11:21:29.785 [INFO ] [vice ControllerDS18B20 was last seen] - Temperature_28a06224020000e1.state=56.0 °C
2019-07-01 11:21:29.786 [INFO ] [vice ControllerDS18B20 was last seen] - ControllerDS18B20_notifi_level=0
2019-07-01 11:21:29.788 [INFO ] [vice ControllerDS18B20 was last seen] - END

I configure the items via the GUI (/var/lib/openhab2/jsondb/org.eclipse.smarthome.core.items.Item.json
):
“Temperature_28a06224020000e1”: {
“class”: “org.eclipse.smarthome.core.items.ManagedItemProvider$PersistedItem”,
“value”: {
“groupNames”: [
“gHome”
],
“itemType”: “Number:Temperature”,
“tags”: [],
“label”: “Bathroom Hot Water [%.1f °C]”,
“category”: “temperature”
}
},

Where am I wrong? Why do the values of Number need to be converted into a condition again into a number?

Try:

if ((ControllerDS18B20_notifi_level.state < 1 ) && (Temperature_28a06224020000e1.state < 40)){

In another rule, type conversion is mandatory, without it does not work. This is how the condition mobile4_notifi_level = 1 does not work

All rule:

rule "Records when device mobile4 was last seen"
when
 Item test_rule_switch received update or
  Item PPM_8502000000000000 received update or
  Item Voltage_8502000000000000 received update
then
  postUpdate(Mobile4_LastUpdate, new DateTimeType())
  logInfo("Records when device mobile4 was last seen", "PPM_8502000000000000.state=" + PPM_8502000000000000.state)
  logInfo("Records when device mobile4 was last seen", "mobile4_notifi_level=" + mobile4_notifi_level)

  var Number PPM_8502000000000000_state = PPM_8502000000000000.state
  logInfo("Records when device mobile4 was last seen", "PPM_8502000000000000_state=" + PPM_8502000000000000_state)

   if (PPM_8502000000000000.state <=600){
        if (mobile4_notifi_level>0){
            SendTextToUsers.apply("Ура, проветрили спальню! " + PPM_8502000000000000.state +" ppm")
        }
        mobile4_notifi_level = 0
 }

 if ((PPM_8502000000000000.state > 600) && (mobile4_notifi_level < 1 )){
  mobile4_notifi_level=1
  //SendTextToUsers.apply("Проветрите спальню!! " + PPM_8502000000000000.state +" ppm")
  logInfo("Records when device mobile4 was last seen", "mobile4_notifi_level=" + mobile4_notifi_level)
}

 if ((PPM_8502000000000000.state as Number > 800) && (mobile4_notifi_level<2)){
  mobile4_notifi_level=2
  SendTextToUsers.apply("Срочно проветрите спальню!! "  + PPM_8502000000000000.state +" ppm")
  logInfo("Records when device mobile4 was last seen", "mobile4_notifi_level=" + mobile4_notifi_level)
}
 if ((PPM_8502000000000000.state as Number >1000) && (mobile4_notifi_level<3)){
  mobile4_notifi_level=3
  SendTextToUsers.apply("Незамедлительно проветрите спальню!!! "  + PPM_8502000000000000.state +" ppm")
  logInfo("Records when device mobile4 was last seen", "mobile4_notifi_level=" + mobile4_notifi_level)
}
logInfo("Records when device mobile4 was last seen", "END")
end

If you replace the condition:
if ((PPM_8502000000000000.state> 600) && (mobile4_notifi_level <1)) {

on:
if ((PPM_8502000000000000.state as Number> 600) && (mobile4_notifi_level <1)) {

This rule works with this condition.

log when not working:
2019-07-01 13: 38: 51.510 [INFO] [ds when device mobile4 was last seen] - PPM_8502000000000000.state = 648.0
2019-07-01 13: 38: 51.511 [INFO] [ds when the device mobile4 was last seen] - mobile4_notifi_level = 0
2019-07-01 13: 38: 51.513 [INFO] [ds when device mobile4 was last seen] - END

Log success works:
2019-07-01 13: 43: 54.250 [INFO] [ds when the device mobile4 was last seen] - PPM_8502000000000000.state = 615.0
2019-07-01 13: 43: 54.250 [INFO] [ds when the device mobile4 was last seen] - mobile4_notifi_level = 0
2019-07-01 13: 43: 54.253 [INFO] [ds when the device mobile4 was last seen] - mobile4_notifi_level = 1
2019-07-01 13: 43: 54.254 [INFO] [ds when device mobile4 was last seen] - END

Can you please use code fences? This is becoming pretty unreadable… :slight_smile:

1 Like

Did so:

rule "Records when device ControllerDS18B20 was last seen"
when
Item test_rule_switch received update or
  Item Temperature_28dd2c3503000064 received update or
  Item Temperature_285ef73403000076 received update or
  Item Temperature_287626350300007d received update or
  Item Temperature_285e0d3b010000b8 received update or
  Item Temperature_28f2602402000022 received update or
  Item Temperature_28ea183b010000cd received update or
  Item Temperature_28e6eb340300008d received update or
  Item Temperature_28a06224020000e1 received update
then

  postUpdate(ControllerDS18B20_LastUpdate, new DateTimeType())

 logInfo("Records when device ControllerDS18B20 was last seen", "Temperature_28a06224020000e1.state=" + Temperature_28a06224020000e1.state)
 logInfo("Records when device ControllerDS18B20 was last seen", "ControllerDS18B20_notifi_level=" + ControllerDS18B20_notifi_level)

if ((ControllerDS18B20_notifi_level.state < 1 ) && (Temperature_28a06224020000e1.state < 40)){
  SendTextToUsers.apply("Отключили горячую воду: " + Temperature_28a06224020000e1.state +" градусов")
  ControllerDS18B20_notifi_level=1
  logInfo("Records when device ControllerDS18B20 was last seen", "ControllerDS18B20_notifi_level=" + ControllerDS18B20_notifi_level)
}

 if ((ControllerDS18B20_notifi_level.state > 0) && (Temperature_28a06224020000e1.state > 45)){
  SendTextToUsers.apply("Включили горячую воду: " + Temperature_28a06224020000e1.state +" градусов")
  ControllerDS18B20_notifi_level=0
  logInfo("Records when device ControllerDS18B20 was last seen", "ControllerDS18B20_notifi_level=" + ControllerDS18B20_notifi_level)
}

logInfo("Records when device ControllerDS18B20 was last seen", "END")
end

in the logs:
2019-07-01 14:05:50.319 [INFO ] [vice ControllerDS18B20 was last seen] - Temperature_28a06224020000e1.state=56.31 °C
2019-07-01 14:05:50.320 [INFO ] [vice ControllerDS18B20 was last seen] - ControllerDS18B20_notifi_level=0
2019-07-01 14:05:50.320 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule ‘Records when device ControllerDS18B20 was last seen’: ‘state’ is not a member of ‘java.lang.Number’; line 45, column 6, length 36

There is no state property for variables like this has always been the case.

Ок. Thanx =)

Your Item is a Number:Temperature. Number:Temperature and Number are not the same thing. You can’t just make comparisons to a Number:Temperature (or any of the other Units of Measure) without providing the units to the number you are trying to compare it to. Assuming °C you need to change your if statement to

&& (Temperature_28a06224020000e1.state < 40|°C)){

I checked it, and it works.
The documentation just does not describe …

How to deal with other types of items, for example:
“itemType”: “Number: Pressure”,
“itemType”: “Number: Dimensionless”,
“itemType”: “Number: Power”,
“itemType”: “Number: Energy”,

For part of the items, I do not define the dimension in the label, does it also require to know and compare values?

Not too sure what you mean there.
Let’s say you have a
Number:Temperature someItem "my sensor []"
There is a default unit, guided by system settings, for C or F
If it is linked to a binding, the binding can also supply units, usually guided by the originating device.

Let’s say you have a
Number someItem "my sensor [%d °C]"
that’s just a number that gets some string placed after it in most displays

In rules, if you are comparing them to a fixed number, then yes you need to know the units or you need to convert the quantity type to a plain old number. All the units are documented at https://www.openhab.org/docs/concepts/units-of-measurement.html#list-of-units

So for pressure you would use something like 123|mmHg for millimeters of mercury.

How to deal with the type of Dimensionless, it is already a plain number and you do not need to convert it?

Dimensionless doesn’t mean unit-less. Dimensionless can have units like % , db , ppm
Generally in OH it’ll be a percentage

Yes I too think a better English name would be Proportion, but I think this is an SI usage.

how many interesting things I learned …

If you do not specify the type in the Items, write the icon and the dimension in the sitemap:
Text item = Pressure label = “Pressure [%.1f %%]”
This will allow not to lead and not think about the types in the rules?

What goes on in the sitemap does not affect the contents of the Item.

What you put in the formatter [ ] in the real Item definition can sometimes affect the Item state.
If it’s a UoM Item, Number:xxxx, it will use whatever is found in [ ] and looks appropriate as the default unit for this Item.
Otherwise there are system defaults, or bindings can override those.
So there are always units.

Can I set up an item so that it does not have a dimension, but need to be displayed in basicui with a need for an icon and dimension?

All this in order to work with items without dimension, but to display for the user with dimension (%, ppm, mmHg, etc.)

That would be a Number type.
Binding channels may need to be linked to dimensioned Items, and may not work with plain Number.

It is impossible to deduce dimension in sitemap for the item.
It was not possible to compare the state of the item as a number, the rules for the comparison of the state of the item and the number do not work in the rules.

Settings:
/var/lib/openhab2/jsondb/org.eclipse.smarthome.core.items.Item.json

  "Temperature_8302000000000000": {
    "class": "org.eclipse.smarthome.core.items.ManagedItemProvider$PersistedItem",
    "value": {
      "groupNames": [
        "gHome"
      ],
      "itemType": "Number:Dimensionless",
      "tags": [],
      "label": "Bedroom",
      "category": "temperature"
    }
  },

/etc/openhab2/sitemaps/my.sitemap

sitemap my label="My home automation" {

    // Спальня
    Frame label="Спальня сенсоры" {
       // Text   item=Temperature_8302000000000000 label="Bedroom [%.1f °C]" valuecolor=[Mobile1_LastUpdate=="Uninitialized"="gray",>=25="orange", >=15="green", 0="white", <15="blue"]
       // Text   item=Temperature_8302000000000000 valuecolor=[Mobile1_LastUpdate=="Uninitialized"="gray",>=25="orange", >=15="green", 0="white", <15="blue"]
          Text   item=Temperature_8302000000000000 label="Bedroom1 [%s °C]"
        Text   item=Humidity_8302000000000000 valuecolor=[Mobile1_LastUpdate=="Uninitialized"="gray",>=25="orange", >=15="green", 0="white", <15="blue"]
        Text   item=PPM_8502000000000000 valuecolor=[Mobile4_LastUpdate=="Uninitialized"="gray",>=25="orange", >=15="green", 0="white", <15="blue"]

                Text   item=Voltage_8502000000000000 labelcolor=[LowPower_8502000000000000==ON="red"] valuecolor=[LowPower_8502000000000000==OFF="green"]
                Text   item=Mobile4_LastUpdate valuecolor=[Mobile4_LastUpdate=="Uninitialized"="gray",>=25="orange", >=15="green", 0="white", <15="blue"]
                //Switch item=LowPower_8502000000000000

                Text   item=Voltage_8302000000000000  labelcolor=[LowPower_8302000000000000==ON="red"] valuecolor=[LowPower_8502000000000000==OFF="green"]
                Text   item=Mobile1_LastUpdate valuecolor=[Mobile1_LastUpdate=="Uninitialized"="gray",>=25="orange", >=15="green", 0="white", <15="blue"]
                //Switch item=LowPower_8302000000000000
    }
}

/etc/openhab2/rules/my.rules

rule "Records when device mobile1 was last seen"
when
  Item Temperature_8302000000000000 received update or
  Item Humidity_8302000000000000 received update or
  Item Voltage_8302000000000000 received update
then
 logInfo("Records when device mobile1 was last seen", "Temperature_8302000000000000.state=" + Temperature_8302000000000000.state)
  postUpdate(Mobile1_LastUpdate, new DateTimeType())
 if (Temperature_8302000000000000.state < 40){
  logInfo("Records when device mobile1 was last seen", "Temperature_8302000000000000.state=" + Temperature_8302000000000000.state , " IF")
}
end

/var/log/openhab2/openhab.log

2019-07-05 10:42:53.583 [INFO ] [ds when device mobile1 was last seen] - BEGIN
2019-07-05 10:42:53.584 [INFO ] [ds when device mobile1 was last seen] - Temperature_8302000000000000.state=16.0
2019-07-05 10:42:53.585 [INFO ] [ds when device mobile1 was last seen] - END

From the log you can see that the comparison test does not work

if (Temperature_8302000000000000.state <40)

If you add a comparison with the dimension:

if (Temperature_8302000000000000.state <40 | ° C)

I get the error:

2019-07-05 10: 35: 48.644 [ERROR] [ntime.internal.engine.RuleEngineImpl] —Rule 'Records when the device mobile1 was last seen: Can not compare incompatible units

.

If the sitemap to use the transformation with the dimension, it stops working basicui

/etc/openhab2/sitemaps/my.sitemap

Text item=Temperature_8302000000000000 label="Bedroom [%.1f °C]" valuecolor=[Mobile1_LastUpdate=="Uninitialized"="gray",>=25="orange", >=15="green", 0="white", <15="blue"]

/var/log/openhab2/openhab.log

2019-07-05 10:43:54.246 [WARN ] [pse.smarthome.core.items.GenericItem] - failed notifying listener 'org.eclipse.smarthome.io.rest.sitemap.internal.PageChangeListener@507f0a6e' about state update of item Mobile1_LastUpdate: null
java.lang.NullPointerException: null
at org.eclipse.smarthome.ui.internal.items.ItemUIRegistryImpl.convertStateToWidgetUnit(ItemUIRegistryImpl.java:431) ~[?:?]
at org.eclipse.smarthome.ui.internal.items.ItemUIRegistryImpl.getLabel(ItemUIRegistryImpl.java:404) ~[?:?]
at org.eclipse.smarthome.io.rest.sitemap.internal.PageChangeListener.constructSitemapEvents(PageChangeListener.java:229) ~[?:?]
at org.eclipse.smarthome.io.rest.sitemap.internal.PageChangeListener.constructSitemapEvents(PageChangeListener.java:216) ~[?:?]
at org.eclipse.smarthome.io.rest.sitemap.internal.PageChangeListener.constructAndSendEvents(PageChangeListener.java:174) ~[?:?]
at org.eclipse.smarthome.io.rest.sitemap.internal.PageChangeListener.stateChanged(PageChangeListener.java:188) ~[?:?]
at org.eclipse.smarthome.core.items.GenericItem$1.run(GenericItem.java:251) [102:org.eclipse.smarthome.core:0.10.0.oh240]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:?]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:?]
at java.lang.Thread.run(Thread.java:748) [?:?]

I think this is as simple as a typo. There should be no space character inside the unit °C

The error complains about Item Mobile1_LastUpdate, so I guess you mean the valuecolor= part.
I cannot see what is wrong with your sitemap line.

There are working examples of using valuecolor with Number:Temperature Items, so it is not a general problem