How to bind/parse MQTT thing (owntracks) to a Location

I’m using Owntracks to push the location from my phone to my local MQTT instance.
Which is bound to OpenHAB. And the whole MQTT2 part seems to work.

But I’ve created a thing and I’m trying to configure the incoming value transformation to create a Location.
I’ve tried JSONPath queries like: JSONPATH:$.“lat”,∩JSONPATH:$.“lon”,∩JSONPATH:$.“alt”
To get a string which is castable to a location.
But then I get things like this in my log:
2019-11-17 16:07:29.469 [WARN ] [t.generic.ChannelStateTransformation] - Executing the JSONPATH-transformation failed: Invalid path '$."lat",' in '{"_type":"location","acc":8,"alt":-3,"batt":100,"conn":"w","lat":61.7265574,"lon":7.2866586,"tid":"me","tst":1573802344,"vac":16,"vel":45}'

ps. I did modify the coordinates, but besides that it’s the log message I get

Did anybody manage to bind a MQTT thing to a location?

You’re going to have to build a string for the Location Item to parse, something like "22.2,57.9" I think.
It’s probably easier to use a single javascript transform to parse out the JSON and add the comma.

1 Like

This is what I ended up doing. But what’s the point of having a Location type for a MQTT thing if you can’t parse / jsonpath it out of a JSON message :frowning:

Why, what message are you sending it? That’s a rhetorical question; with the “right” message it would work out of the box. With the “wrong” message, there are a whole range of tools available to transform it. As you have found.

When some universal standard format is invented to transmit locations via MQTT, that could probably be accommodated.

No, it’s not the wrong message, it is JSON data that does contain latitude, longitude and altitude.
It’s just not in a format that goes directly into a Location object.
The field conveniently supports JSONPath to get values from JSON. But the location type is an exception from most object types, since it needs more than one “parameter” to it’s constructor or it’s parse-able string representation. And currently JSONPATH doesn’t seem to support that. Which is kind of strange since there is this in the description:

You can chain transformations by separating them with the intersection character ∩.

But I can’t seem get it to work, or find examples anywhere.

That’s right, JSONPATH can extract only one chunk. Chaining is no use to you because it’s too late - the next transform being passed the output of one JSONPATH cannot see the stuff that got thrown away.

Chaining is useful if you want to extract a number from JSON and then multiply it by 100 and then add a string for units. It’s a serial process and is no use to your parallel requirement.

MQTT is not obliged to be in JSON. If you had control of your device/service here and made it send a string “22.5 , 50.6” that could be parsed directly into a Location Item.
Your data comes in a format that is not directly suitable, but there are a range of tools to deal with this. You are apparently using one satisfactorily.
You may not see the uses of the tools that don’t help you, but others will.

I have the same problem with my MQTT broker data. (OH version 2.5.5, Broker Binding 2.5.5, Mosqitto Broker v3.1.1, built on RPi4) Unfortunately I haven’t found a way how to solve it yet.
Could you explain your solution suggestions more exactly, because I don’t know where exactly I can start to solve the problem.
@rossko57 could you specify a particular tool?
@l_grave have you found a way to enter lat and lon (and alt) in openHAB?

Many thanks in advance.


For your problem, you would use JSONPATH
Digging up an old thread as well as your current one will not help.

Thanks for the quick response.
You advise me to open a new thread, if I have understood you correctly?

Unfortunately I also cannot parse the lat and lon as described above by I_grave via JSONPath.

My apologies, I thought you were someone else with a not-very-similar issue.

That’s right, the transformation service can only extract one string.
You will have to do as @l_grave did, and use a JS javascript transform instead.
Within the javascript you can extract as many parts of the JSON as you like, process them as you wish, and return them in a single string.

The solution I use now:

rule "Parse MQTT Owntracks Location"
    Item Car_Raw_Location changed
    logInfo("car", "Car is moving")

    val String json = (Car_Raw_Location.state as StringType).toString

    logInfo("car", json)
    val String type = transform("JSONPATH", "$._type", json)
    if (type == "location") {
        val String lat  = transform("JSONPATH", "$.lat", json)
        val String lon  = transform("JSONPATH", "$.lon", json)

        Car_Location.postUpdate(new PointType(lat + "," + lon))

Thank you very much @l_grave and @rossko57 for your help and a solution how to deal with this. With JavaScript I will go to the problem and try to solve it like I_grave. I will try it out.
Thanks again.
Andy :blush: