MyItem.sendCommand(OtherItem.state) stopped working with error

  • Platform information:
    • Hardware: Raspberry Pi 3 Model B
    • OS: openHABianPi
    • Java Runtime Environment: openjdk version “1.8.0_152”
    • openHAB version: openHAB 2.2.0-1 (Release Build)

I have installed the GPIO binding using PaperUI and some rules written for my Switch items, which worked quite well - all in the form

MyItem.sendCommand(OtherItem.state)

Yesterday I installed Network binding using PaperUI, and suddenly GPIO binding got uninstalled automatically. I re-installed it, and everything was fine, rules using GPIO and Network Switch items worked.

Today I restarted my OpenHAB computer, and all my rules stopped working with this error message:

Could not invoke method: org.eclipse.smarthome.model.script.actions.BusEvent.sendCommand(org.eclipse.smarthome.core.items.Item,java.lang.Number) on instance: null

Some testing gave me that

MyItem.sendCommand(ON)
MyItem.sendCommand(OtherItem.state.toString)

both work - but why do I need the “.toString” now which I didn’t need before?
The manual at https://docs.openhab.org/configuration/rules-dsl.html#deeper-dive says:

The benefit of using Objects over primitives is apparent through the following type conversions that are automatically invoked by Object as the context requires. Using the method MyTimes.sendCommand() that is owned by MyItem will use the sendCommand method that is suitable to make the necessary type conversions.

Are you using restoreOnStartup? If not your items become initialized to NULL and you cannot sendCommand using NULL.

@rlkoshak
Hm, I don’t use it on both, I will keep that in mind for startup problems. My problem also happens when both items are not NULL - I added some debug code to the rule and here you go:

rule "Example Rule"
when
    Item OtherItem changed or
    Item VT_DebugTrigger changed to ON
then
    logInfo("debug.rules", "MyItem.state = " + MyItem.state)
    logInfo("debug.rules", "OtherItem.state = " + OtherItem.state)
    MyItem.sendCommand(OtherItem.state)
end

Log output:

==> /var/log/openhab2/events.log <==
2018-02-10 19:24:46.284 [ome.event.ItemCommandEvent] - Item 'VT_DebugTrigger' received command ON
2018-02-10 19:24:46.303 [vent.ItemStateChangedEvent] - VT_DebugTrigger changed from OFF to ON
==> /var/log/openhab2/openhab.log <==
2018-02-10 19:24:46.709 [INFO ] [smarthome.model.script.debug.rules] - MyItem.state = ON
2018-02-10 19:24:46.718 [INFO ] [smarthome.model.script.debug.rules] - OtherItem.state = ON
2018-02-10 19:24:46.723 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Example Rule': 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

I just stumbled across the same problem. And I’m sure it has nothing to do with items that aren’t initialized. Simple example:

rule "PIR Actions"
when
    Item Tasmota_PIR received update
then
    Tasmota_Display.sendCommand(ON) // works
    Tasmota_Display.sendCommand(Tasmota_PIR.state) // does not work
    Tasmota_Display.sendCommand(Tasmota_PIR.state.toString) // works
end

Tasmota_Display is initialized because the first sendCommand() works. Tasmota_PIR must be initialized because it just received an update.

The second sendCommand() throws this error:

Rule 'PIR Actions': 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.String) on instance: null

Where’s the mistake?

What have you done or looked at to confirm this?

What type of Item is Tasmota_Display and Tasmota_PIR?

Well, I thing I explained that in my post. Was my reasoning inaccurate? In that case: how can I improve it?

They are both Switches. Do you need more information?

If it was clear I wouldn’t have asked.

Did you look in events.log? Do you have a Rule showing you when Tasmota_PIR changes state so you know what state it’s in?

All you said was that you are sure that the Item isn’t NULL, but not how you are sure.

When debugging problems, never assume you think you know what is going on or what states your Items are in. Prove it.

In your Rule, log out the state of both Items.

Hope that helps (switching PIR to ON and OFF):

rule "PIR Actions"
when
    Item Tasmota_PIR received update
then
    logInfo("debug", "before")
    if (Tasmota_PIR.state == NULL) {
        logInfo("debug", "Tasmota_PIR.state is NULL")
    } else {
        logInfo("debug", "Tasmota_PIR.state is not NULL")
    }
    logInfo("debug", "Tasmota_PIR.toString is " + Tasmota_PIR.state.toString)

    if (Tasmota_Power.state == NULL) {
        logInfo("debug", "Tasmota_Power.state is NULL")
    } else {
        logInfo("debug", "Tasmota_Power.state is not NULL")
    }
    logInfo("debug", "Tasmota_Power.toString is " + Tasmota_Power.state.toString)


    Tasmota_Power.sendCommand(Tasmota_PIR.state.toString) // does not work without .toString

    logInfo("debug", "after")
    if (Tasmota_PIR.state == NULL) {
        logInfo("debug", "Tasmota_PIR.state is NULL")
    } else {
        logInfo("debug", "Tasmota_PIR.state is not NULL")
    }
    logInfo("debug", "Tasmota_PIR.toString is " + Tasmota_PIR.state.toString)

    if (Tasmota_Power.state == NULL) {
        logInfo("debug", "Tasmota_Power.state is NULL")
    } else {
        logInfo("debug", "Tasmota_Power.state is not NULL")
    }
    logInfo("debug", "Tasmota_Power.toString is " + Tasmota_Power.state.toString)
end

The output in the log:

2019-04-02 20:25:17.191 [INFO ] [eclipse.smarthome.model.script.debug] - before
2019-04-02 20:25:17.195 [INFO ] [eclipse.smarthome.model.script.debug] - Tasmota_PIR.state is not NULL
2019-04-02 20:25:17.199 [INFO ] [eclipse.smarthome.model.script.debug] - Tasmota_PIR.toString is ON
2019-04-02 20:25:17.202 [INFO ] [eclipse.smarthome.model.script.debug] - Tasmota_Power.state is not NULL
2019-04-02 20:25:17.205 [INFO ] [eclipse.smarthome.model.script.debug] - Tasmota_Power.toString is OFF
2019-04-02 20:25:17.209 [INFO ] [eclipse.smarthome.model.script.debug] - after
2019-04-02 20:25:17.214 [INFO ] [eclipse.smarthome.model.script.debug] - Tasmota_PIR.state is not NULL
2019-04-02 20:25:17.219 [INFO ] [eclipse.smarthome.model.script.debug] - Tasmota_PIR.toString is ON
2019-04-02 20:25:17.224 [INFO ] [eclipse.smarthome.model.script.debug] - Tasmota_Power.state is not NULL
2019-04-02 20:25:17.236 [INFO ] [eclipse.smarthome.model.script.debug] - Tasmota_Power.toString is ON
2019-04-02 20:25:20.230 [INFO ] [eclipse.smarthome.model.script.debug] - before
2019-04-02 20:25:20.237 [INFO ] [eclipse.smarthome.model.script.debug] - Tasmota_PIR.state is not NULL
2019-04-02 20:25:20.245 [INFO ] [eclipse.smarthome.model.script.debug] - Tasmota_PIR.toString is OFF
2019-04-02 20:25:20.251 [INFO ] [eclipse.smarthome.model.script.debug] - Tasmota_Power.state is not NULL
2019-04-02 20:25:20.258 [INFO ] [eclipse.smarthome.model.script.debug] - Tasmota_Power.toString is ON
2019-04-02 20:25:20.266 [INFO ] [eclipse.smarthome.model.script.debug] - after
2019-04-02 20:25:20.274 [INFO ] [eclipse.smarthome.model.script.debug] - Tasmota_PIR.state is not NULL
2019-04-02 20:25:20.287 [INFO ] [eclipse.smarthome.model.script.debug] - Tasmota_PIR.toString is OFF
2019-04-02 20:25:20.295 [INFO ] [eclipse.smarthome.model.script.debug] - Tasmota_Power.state is not NULL
2019-04-02 20:25:20.302 [INFO ] [eclipse.smarthome.model.script.debug] - Tasmota_Power.toString is OFF

And finally when I remove the “.toString”:

2019-04-02 20:29:04.141 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'PIR Actions': 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.String) on instance: null

Hmm. OK, that should work.

At this point we can do the easy thing or the hard thing. The easy thing is to just continue to use .toString. You know that works and when type errors like this occur, using .toString is usually the most expedient solution.

The hard thing is to start to figure out why it isn’t able to convert the State to an OnOffType automatically the way it is supposed to. The first thing try would be to cast the state to an OnOffType.

Tasmota_Power.sendCommand(Tasmota_PIR.state as OnOffType)

Yeah, that works.

What I just remembered: I had the same problem with two items of type “String”. Using .toString solved that, too. So it looks like it’s a general problem to copy the contents of one item to another item of the same type.

My openHAB version is 2.4.0-1 from the repository at https://dl.bintray.com/openhab/apt-repo2 (stable main).

It’s a problem from the underlying language that the Rules DSL is built upon. It’s a loosely typed language (i.e. the types of Objects are not determined until runtime instead of compile time) but it’s not all that good at figuring out the type in some cases without additional hints. Supplying the as OnOffType gave it the hint it needed to treat the state properly.

When you use .toString, you are using a different code path that parses the String passed to it instead of trying to use the Object as is. This is why .toString will almost always solve this error in a postUpdate or sendCommand.

I usually see this error more with Numbers. I think this is the first I’ve seen it from an enum type like OnOffType.

Another place you will see this error is when trying to log it. For example:

logInfo("Test", Tasmota_PIR.state)

will probably generate a similar error. The language isn’t smart enough to know you want the state to be a String.

logInfo("Test", "State = " + Tasmota_PIR.state)

will work because we gave the language the hint that we want the state as a String so it will call .toString for you.