Working with values, substracting and checking if null

For a history, please check previous topic:

In the end I got the JSON working, values are coming through and I can display them in OpenHAB, however I need to do some data manipulation to show it in an appropriate way.

For example:

  1. the JSON returns a value for the operating hours counter but it is presented in seconds, so to get hours I need to divide by 3600

  2. the JSON returns a value for voltage but the decimal is positioned wrong. (29281 is 292.81 Volts)

So I thought, “well that can’t be hard”… :roll_eyes: Boy was I wrong:

rule "Process JSON from SMA Inverter"
when
    Item JSON_SMA changed
then
     logInfo("RULE", "JSON from SMA inverter changed!")


    val jsonString = JSON_SMA.state.toString

    if (jsonString != null) {
        

        val valTester = transform("JSONPATH","$.result.0156-76BC5229.6400_00462F00.1[0].val", jsonString)
        logInfo("RULE", "Test Value " + valTester)

        var Number valTesterCorrected = (valTester.state as DecimalType).intValue() / 3600
        logInfo("RULE", "Testwaarde correctie " + valTesterCorrected)

VSCode does not point out any errors, syntax wise everything apparently is okay?

But in the logging we’re seeing:

2018-03-19 20:57:38.084 [INFO ] [.eclipse.smarthome.model.script.RULE] - JSON from SMA inverter changed!
2018-03-19 20:57:38.089 [INFO ] [.eclipse.smarthome.model.script.RULE] - Test Value 292819
2018-03-19 20:57:38.090 [ERROR] [.script.engine.ScriptExecutionThread] - Rule ‘Process JSON from SMA Inverter’: An error occured during the script execution: The name ‘.state’ cannot be resolved to an item or type.

Without a .state it doesn’t work either by the way:

2018-03-19 21:21:48.571 [INFO ] [.eclipse.smarthome.model.script.RULE] - JSON from SMA inverter changed!
2018-03-19 21:21:48.572 [INFO ] [.eclipse.smarthome.model.script.RULE] - Test Value 292819
2018-03-19 21:21:48.573 [ERROR] [.script.engine.ScriptExecutionThread] - Rule 'Process JSON from SMA Inverter': org.eclipse.smarthome.core.library.types.DecimalType

What’s going wrong then?

A question that will come up eventually too is how to evaluate if the value extracted from a JSON with JSONPATH is null, because with this kind of “weird” things I can perfectly imagine that the vscode syntax will mark my code as perfectly valid while the rule engine chokes on it because I’m doing my checks wrong “null” vs null due to some weird string conversion…

Sorry to express my frustration here but getting something to work in a rule is never a walk in the park, weird conversions, working with .state (state??? it’s a value…), having to need to convert values while it works fine in items, there’s no consistency here… I do love OpenHAB and everything I eventually got working, works rock solid, but the hell you have to go through to GET something working is very frustrating…

You defined valTester as val which means as the resulting data type from transform. This is to my knowledge a string.

Now a string does not have a .state its not an Item.

var valTesterCorrected = Double.parseDouble(valTester)/3600

But you should be able to convert the string to an Double/Float/Integer with the respective parse call, and then devide this result.

logInfo("RULE", "Testwaarde correctie " + valTesterCorrected )

The print should then work as expected :wink:

Be aware of typos i just typed this and did not test it.

One Remark you should check the valTester after the transform. It has either your result or is NULL. So this will produce errors when your search can not find what you request from the jsonstring.

This is no plain json querry. It is a JSON transformation for openhab!
https://docs.openhab.org/addons/transformations/jsonpath/readme.html

One other thing is if you don’t want to use rules, you could extract the json with the transformation on the thing. And save the result in an Item. As the only thing which concerns is how you read the value, you can make a transformation on the label when displaying the value. I would use javascript transformation for that. No rule needed.

Try:

rule "Process JSON from SMA Inverter"
when
    Item JSON_SMA changed
then
     logInfo("RULE", "JSON from SMA inverter changed!")


    val jsonString = JSON_SMA.state.toString

    if (jsonString != null) {
        

        val valTester = transform("JSONPATH","$.result.0156-76BC5229.6400_00462F00.1[0].val", jsonString)
        logInfo("RULE", "Test Value " + valTester)

        if (!valTester.isNullorEmpty) {
            var Number valTesterCorrected = Integer:parseInt(valTester) / 3600
            logInfo("RULE", "Testwaarde correctie " + valTesterCorrected.toString)
        }

Note the semi-colon Integer:parseInt(valTester) / 3600

Regards

Ha Vincent! Nice to see you again :smiley:

I got it working yesterday buddy, thanks for your input nevertheless here and in the other topics and likewise to @Josar, the Double.parseDouble(valTester)/3600 did the trick for me.

Now… The result :star_struck:

Vermogen = Power
Spanning = Voltage
Stroom = Current
Fasestroom= Current of Phase L1

Third time’s a charm and I’ll be creating a new topic for the persistence in InfluxDB and Grafana, because weird enough everything for KNX and all the other stuff works like a charm and I thought that adding these SMA values to InfluxDB would be a matter of adding the right group tags but that would have been too simple in OpenHAB :wink: . It’s sunny again (very partly cloudy) in Belgium after a couple of grey days so I’m very curious too get some values.

Oh, the “Dagopbrengst EUR” (day yield) is based on the “Dagopbrengst kWh” and is just a multiplication of Wh * 0.0000709 (7.09 eurocents / kWh)

Did you see the conditional test to check if valtester.isNullorEmpty ?

No! Completely read over it but it’s a nice one to remember, I added it to my code-cheatsheet.

This is how I solved it yesterday evening. I have to set the value manually to zero and do the following checks otherwise the logging states that the state cannot be null and stuff, so this seems to work and makes all the values show up correctly in the sitemap instead of the last values before the SMA shut off.

val val_SMA_ACNetfrequentie = transform("JSONPATH","$.result.0156-76BC5229.6100_00465700.1[0].val", jsonString)
        logInfo("RULE", "AC Netfrequentie AC: " + val_SMA_ACNetfrequentie)
        if (val_SMA_ACNetfrequentie !== null) {
            //divide by 100
            postUpdate(number_SMA_ACNetfrequentie, Double.parseDouble(val_SMA_ACNetfrequentie)/100)
            
        } else {
            logInfo("RULE", "In else branch, so setting value to 0")
            postUpdate(number_SMA_ACNetfrequentie,0)
        }

val_SMA_ACNetfrequentie !== null will only work if the string is null but not if the string is empty like ""

You are absolutely correct, but for now it’s the null I want to test for since the JSON should always throw back a null.

Is it possible to make this rule working with a string which is empty like ‘’