Use MQTT values in rules

Hey

I’m working with a HappyBubbles presence detect which sends json objects like this one:

Client mosqsub/9758-raspberryp received PUBLISH (d0, q0, r0, m0, 'happy-bubbles/presence/ha/happy-bubble', ... (99 bytes))
{"id":"e2c56db5dffb48d2b060d0f5a71096e0_0000_0000","name":"iBeacon","distance":0.06810391947790942}

to the broker. I have already set up an Item to read out the distance and display it in a sitemap:

String distance "Distanz[%s]" <line> {mqtt="<[broker:happy-bubbles/presence/ha/happy-bubble:state:JSONPATH($.distance)]"}

which works reliably. Now I want to set up a rule which acts depending on the distance, i.e. when the distance is greater than 10, do x and when the distance is smaller, do x.

For some reason, I cannot get the distance into the rule. I have tried printing it with logInfo, but it always says the variable is empty.

Rule:

rule "test 2"
when
        Item motion_sensor changed from OFF to ON
then
        var String stringo = distance.state
        logInfo("log", stringo)
end

Logging output:

16:22:33.804 [ERROR] [.script.engine.ScriptExecutionThread] - Rule 'test 2': 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

What am I doing wrong and how can I get the value?

Also, any other pointers in this regard? I’m really struggling with the documentation.

can you check what a

println(distance)

returns on the console (replace the loginfo for the moment - as this is more robust in case there is something with the item) …

Where am I supposed to get the output of println? It doesn’t show in the karaf console.

ist this a remote console … you only see it if OH is started from the script in the window that opens

you can try the loginfo as well; but pass directly “distance” as parameter - this should serialize the object

hm no, doesn’t work. im still getting the same error.

Rule 'test 2': 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

heres the code line in the .rules file:

        logInfo("distanz", mqtt_json_distance)

and here’s the code line in the .items file

String mqtt_json_distance "Distanz[%s]" <line> {mqtt="<[broker:happy-bubbles/presence/ha/happy-bubble:state:JSONPATH($.distance)]"}

#HOWEVER

When I do the json transformation directly in the rules script, instead of in the items file, it works:

import java.lang.Double

rule "test 2"
when
        Item motion_sensor changed from OFF to ON
then
        var String json = mqtt_json.state.toString
        var String distance = transform("JSONPATH", "$.distance", json)
        var Double dis = Double.parseDouble(distance)
        if(dis > 1)
                logInfo("log", "greater than1")
        else
                logInfo("log", "smaller than 1")
end


So I guess it works then? I still don’t understand what I’m doing wrong

I wonder if the item “mqtt_json”, or “distance” after a rule change is not yet initialized; that´s why I tried to see that with println … this shows the item as object. Do you persist the item states (e.g. mapdb)? That´s the only thing I can think of.

No, not that I’m aware of.

First thing I would try is to force the conversion from a State to a String by calling toString. Remember that .state returns a State object which is not a String, even for String Items. A lot of times the Rules language is able to make the conversion for you but this may be one where it can’t.

var String stringo = distance.state.toString