Declared variable in rule gives always null

  • Platform information:
    • Hardware: RPI3
    • OS: _Rabian
    • Java Runtime Environment: Whats installed with OpenHAb2
    • openHAB version: 2.5
  • Issue of the topic: I am trying to make a simple rule as follows

var LB1_last_value_dimmer = 0

rule “Aan/Uit LB1”

when

Item LB1_Brightness changed 

then

logInfo("LB1", "LB1 Rule fired")

logInfo("LB1", LB1_Brightness.state.toString)

if (LB1_Brightness.state == 0) {

    logInfo("LB1-Cmd", "LB1-off")

    LB1_last_value_dimmer=LB1_Brightness.previousState()

    logInfo("LB1-LV", LB1_last_value_dimmer)

    sendCommand(LB1_Brightness,0)

    logInfo("LB1-SV", LB1_Brightness.state.toString)

} else {

    if(LB1_Brightness.state == 100) {

        logInfo("LB1-Cmd", "LB1-on")

        sendCommand(LB1_Brightness,LB1_last_value_dimmer)

       // LB1_Brightness.postUpdate(LB1_last_value_dimmer)

        logInfo("LB1-SV", LB1_Brightness.state.toString)

    }

}

end

In the logfile when I switch to ON the following text is seen:
2020-01-15 22:39:09.073 [INFO ] [g.eclipse.smarthome.model.script.LB1] - LB1 Rule fired

2020-01-15 22:39:09.082 [INFO ] [g.eclipse.smarthome.model.script.LB1] - 100

2020-01-15 22:39:09.099 [INFO ] [lipse.smarthome.model.script.LB1-Cmd] - LB1-on

2020-01-15 22:39:09.105 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule ‘Aan/Uit LB1’: An error occurred during the script execution: Could not invoke method: org.eclipse.smarthome.model.script.actions.BusEvent.sendCommand(org.eclipse.smarthome.core.items.Item,java.lang.Number) on instance: null

It doenst seem to see LB1_last_value_dimmer anso when i switch OFF the following is in the log :

2020-01-15 22:41:53.317 [INFO ] [g.eclipse.smarthome.model.script.LB1] - LB1 Rule fired

2020-01-15 22:41:53.325 [INFO ] [g.eclipse.smarthome.model.script.LB1] - 0

2020-01-15 22:41:53.340 [INFO ] [lipse.smarthome.model.script.LB1-Cmd] - LB1-off

2020-01-15 22:41:53.348 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule ‘Aan/Uit LB1’: An error occurred during the script execution: Could not invoke method: org.eclipse.smarthome.model.script.actions.LogAction.logInfo(java.lang.String,java.lang.String,java.lang.Object[]) on instance: null

I have the persistance service running mapdb with the following CFG file:
Strategies {

default = everyUpdate

}

Items {

LB1_Brightness        : strategy = everyUpdate, restoreOnStartup

LB1_ColorTemperature  : strategy = everyUpdate, restoreOnStartup

}

I am a beiginner in rules and tried a lot of combinations they all seem to fail, what am i doing wrong ?

please be detailed explaining your issue

  • Please post configurations (if applicable):
    • Items configuration related to the issue
    • Sitemap configuration related to the issue
    • Rules code related to the issue
    • Services configuration related to the issue
  • If logs where generated please post these here using code fences:

I’d make that global a Number, rather than have rules guess at what you want

var Number LB1_last_value_dimmer = 0

But regardless of it being Number or int or whatever, it is not suitable for this

sendCommand() requires two strings as parameters.
It is I think smart enough to deal with being given an Item object as the first parameter instead.
That doesn’t make it smart about the second, though.

sendCommand(LB1_Brightness,LB1_last_value_dimmer.toString)

This, of course …

requires two strings too

logInfo("LB1-LV", LB1_last_value_dimmer.toString)

Thanks a lot I wasnt aware that sendCommand take strings only No the NULL is gone and it works better however I see the following in the log file
Whan i switch OFF:

2020-01-15 23:32:02.750 [INFO ] [lipse.smarthome.model.script.LB1-Cmd] - LB1-off

2020-01-15 23:32:02.756 [INFO ] [clipse.smarthome.model.script.LB1-LV] - org.openhab.core.persistence.internal.QueryablePersistenceServiceDelegate$1@10b39e4

2020-01-15 23:32:02.763 [INFO ] [clipse.smarthome.model.script.LB1-SV] - 0

And when switching ON:
2020-01-15 23:35:00.888 [INFO ] [g.eclipse.smarthome.model.script.LB1] - LB1 Rule fired

2020-01-15 23:35:00.894 [INFO ] [g.eclipse.smarthome.model.script.LB1] - 100

2020-01-15 23:35:00.912 [INFO ] [lipse.smarthome.model.script.LB1-Cmd] - LB1-on

2020-01-15 23:35:00.918 [WARN ] [rthome.model.script.actions.BusEvent] - Cannot convert ‘org.openhab.core.persistence.internal.QueryablePersistenceServiceDelegate$1@10b39e4’ to a command type which item ‘LB1_Brightness’ accepts: [PercentType, OnOffType, IncreaseDecreaseType, RefreshType].

2020-01-15 23:35:00.924 [INFO ] [clipse.smarthome.model.script.LB1-SV] - 100

do i need to have the variable or the data that comes from the persistence service in a special format to ?

Thanks in advance
Frank

Yes, I’d overlooked that.
As per the docs, someItem.previousState() returns a historic object, not a simple state.
This has extra properties, like the datestamp of that record.
You’d need to extract the state (which you can then use just like an ordinary myItem.state)

LB1_last_value_dimmer=LB1_Brightness.previousState().state

Bear in mind that is a state, not a Number. You might need to cast before doing sums etc.

LB1_last_value_dimmer = LB1_Brightness.previousState().state as Number

Umm, did you know that every rule triggered with changed event has an implicit variable previousState ? This contains the previous state of the triggering Item and does not rely on persistence of any kind.

Simple use

LB1_last_value_dimmer = previousState as Number

A caution with that, immediately after system startup that previous state could be NULL at first run (or UNDEF after a binding error).
Unlike the persisted previousState, which does not record NULL/UNDEF … and so at first run can give you the state from before the reboot or error.

Different complexity and behaviours to choose from, depending on your needs.

To add my grain of salt:

Use this:

        LB1_Brightness.sendCommand(LB1_last_value_dimmer)

Instead of the action command that you use. It is far more flexible and can accept different types of values and the rule engine will not try to convert to a string.
It should work without adding as Number and .toString as explained above.

It is recommended to use the .sendCommand(xxx) method whenever the item is known.

thank you very much for the support, I got de rule running as i wanted now

@ [rossko57] I used :
LB1_last_value_dimmer = previousState as Number
because
LB1_last_value_dimmer = LB1_Brightness.previousState().state as Number always returned 0 , you have any idea why ?

Frank

Depending on the persistence service you are using and also on the strategy how you persist your values, it could be that the previous state really was 0.

You are persisting your item every time it gets updated, that means if the previous value (0) gets updated by a new value (0), .previousState() will return the “previous” 0.

Have a look at this:

What Sascha said.

And remember a lot of openHAB is asynchronous; When you trigger a rule off of an Item changing. will the persistence service have done its work of writing away that same change to the database before you call for previousState()? You don’t know and can’t tell. Will you get the state before the most recent change, or the one from before that?