AutoPi Location Conversion (MQTT)

After years I got my AutoPi units up and running, and I have it sending position to MQTT. The topic is /car/{car name}/track/pos and the response has all sorts of data I don’t need, but also has the position info. An example from my Explorer:

/car/explorer/track/pos {“_type”:“pos”,“sog”:0.0,“loc”:{“lat”:39.485855,“lon”:-77.90948833333333},“_stamp”:“2023-07-24T18:49:08.597846”,“alt”:130.1,“nsat_glonass”:4,“utc”:“18:49:08”,“fix”:“3D”,“nsat”:5,“date_utc”:“2023-07-24”,“cog”:244.7}

I need help in getting that to standard OpenHab Location element.

You might want to obfuscate your lat/lon

You don’t mention which OH version.

Assuming OH 3/4 you’ll probably need a SCRIPT transformation on the MQTT Channel to parse the JSON and convert it to <lat>,<lon>,<alt>. Using JS Scripting it would look something like:

(function(data) {
  const parsed = JSON.parse(data);
  return parsed.loc.lat+','+parsed.loc.lon+','+parsed.alt;
})(input)

If OH 2.x you’ll want to use the JS transformation but the code will look very much the same.

Thanks, running 3.4.4.

mqtt.things

Thing mqtt:topic:explorer "Explorer" (mqtt:broker:mosquitto) {
    Channels:
    Type string : Position "Explorer" [ stateTopic="/car/explorer/track/pos" ]                                                                                                      
}

vehicles.items
Location Explorer_Location "Explorer Location [%s]" <explorer> (Explorer, Position) {channel="mqtt:topic:explorer:Position"[profile="transform:JS", toItemScript="location.js" toHandlerScript="location.js" ] }

location.js

(function(data) {
  const parsed = JSON.parse(data);
  return parsed.loc.lat+','+parsed.loc.lon+','+parsed.alt;
})(input)

I have Javascript Transformation INSTALLED, I see no errors, but something must be wrong with the item because it never shows up.

Helps if you use OpenHAB 3.4 syntax, did not notice docs were pointing me to 4.x and I did not even realize it.

This should look better for the .items
Location Explorer_Location "Explorer Location [%s]" <explorer> (Explorer, Position) {channel="mqtt:topic:explorer:Position"[profile="transform:JS", function="location.js"] }

It still does not work, its null even tho I see the thing as:

/car/explorer/track/pos {"_type":"pos","sog":0.0,"loc":{"lat":39.48573666666667,"lon":-77.90973},"_stamp":"2023-07-24T21:08:35.642716","alt":143.8,"nsat_glonass":0,"utc":"21:08:35","fix":"3D","nsat":6,"date_utc":"2023-07-24","cog":101.5}
/car/explorer/track/pos {"_type":"pos","sog":0.0,"loc":{"lat":39.48573666666667,"lon":-77.90972833333333},"_stamp":"2023-07-24T21:08:40.663619","alt":143.6,"nsat_glonass":0,"utc":"21:08:40","fix":"3D","nsat":6,"date_utc":"2023-07-24","cog":101.5}
/car/explorer/track/pos {"_type":"pos","sog":0.0,"loc":{"lat":39.48574166666667,"lon":-77.90972333333333},"_stamp":"2023-07-24T21:08:45.684330","alt":143.2,"nsat_glonass":0,"utc":"21:08:45","fix":"3D","nsat":6,"date_utc":"2023-07-24","cog":101.5}
/car/explorer/track/pos {"_type":"pos","sog":0.0,"loc":{"lat":39.485755,"lon":-77.90970666666666},"_stamp":"2023-07-24T21:08:50.704714","alt":142.2,"nsat_glonass":0,"utc":"21:08:50","fix":"3D","nsat":6,"date_utc":"2023-07-24","cog":101.5}
/car/explorer/track/pos {"_type":"pos","sog":0.0,"loc":{"lat":39.48575666666667,"lon":-77.90971},"_stamp":"2023-07-24T21:08:55.725098","alt":142.7,"nsat_glonass":0,"utc":"21:08:55","fix":"3D","nsat":6,"date_utc":"2023-07-24","cog":101.5}

Found the error!
2023-07-24 17:39:37.077 [WARN ] [iles.JavaScriptTransformationProfile] - Could not transform state ‘{“_type”:“pos”,“sog”:0.0,“loc”:{“lat”:39.485861666666665,“lon”:-77.90962166666667},“_stamp”:“2023-07-24T21:39:37.070238”,“alt”:132.7,“nsat_glonass”:0,“utc”:“21:39:37”,“fix”:“3D”,“nsat”:7,“date_utc”:“2023-07-24”,“cog”:289.3}’ with function ‘location.js’ and format ‘%s’

I wouldn’t bother with a Profile for this. I’d apply it at the Channel config.

Unfortunately the error just tells you that the location.js failed (probably threw an exception). You can add some logging to it.

var logger = Java.type("org.slf4j.LoggerFactory").getLogger("org.openhab.transform.location.js");
logger.info("My info log statement");

The only think I can think of is that for some reason it’s not valid JSON and the parse failed.

So it looks like it is not calling location.js at all. In fact if I delete the file there is no difference! Also I like the idea of adding it to the channel config, but I can’t find an example on how to do that. Things | openHAB does not show it as far as I can tell.

That’s one reason why I don’t bother with text file based Things any more. In the UI it’s all self documenting.

But you’ve linked to just the generic “here’s how the Things syntax works” docs. For all the parameters supported by a specific binding you need to see that binding’s docs. MQTT Things and Channels - Bindings | openHAB

Ya, I guess I should switch, just find them so so much easier when you have hundreds of items of the same time.

Thing mqtt:topic:explorer "Explorer" (mqtt:broker:mosquitto) {
    Channels:
    Type string : Position "Explorer" [ stateTopic="/car/explorer/track/pos", transformationPatern="JS:location.js" ]
}

Looks like the right format, but still getting the same error when I had it on items.

2023-07-24 18:25:27.976 [WARN ] [iles.JavaScriptTransformationProfile] - Could not transform state '{"_type":"pos","sog":0.0,"loc":{"lat":39.485861666666665,"lon":-77.90947},"_stamp":"2023-07-24T22:25:27.975077","alt":114.8,"nsat_glonass":2,"utc":"22:25:27","fix":"3D","nsat":7,"date_utc":"2023-07-24","cog":317.8}' with function 'location.js' and format '%s'

The odd part of all this still is that if I delete location.js it still gives me the same error. Its like it is not even reading the file. Also adding the log line did not show up, its like it knows it should look at location.js, it’s just not.

(function(data) {
  const parsed = JSON.parse(data);
  return "test";
  var logger = Java.type("org.slf4j.LoggerFactory").getLogger("org.openhab.transform.location.js");
  logger.info("My info log statement");
})(input)

I have struggled with this using the UI (no experience with textual) and not an expert like @rlkoshak by any means. But two things, maybe

  1. Is this a typo?
  1. Is your location.js in the transform folder?
1 Like

I’m not so sure. If the transformation throws an exception or if the file doesn’t exist, in OH 3.4 at least, it generates the same error. All we can really conclude is something is going wrong. If you delete the file you may or may not be changing what’s going wrong but I wouldn’t expect the error log statement to change.

Add a log statement before the parsing of data. If the JSON isn’t parsable you’d never get to the log statement. Furthermore, any statement after the return statement will never be executed.

good catch

Guys, I feel so stupid!!! It helps if you spell it correctly!

I got:

/car/explorer/track/pos {"_type":"pos","sog":0.0,"loc":{"lat":39.48561,"lon":-77.90946333333333},"_stamp":"2023-07-25T09:40:44.582965","alt":138.0,"nsat_glonass":4,"utc":"09:40:44","fix":"3D","nsat":9,"date_utc":"2023-07-25","cog":163.3}
2023-07-25 05:40:44.684 [WARN ] [t.generic.ChannelStateTransformation] - Executing the JS-transformation failed: An error occurred while loading JavaScript. <eval>:4:2 Expected an operand but found const
  const parsed = JSON.parse(data);

So I changed const to var and it works!

Now I get:

  • 39.48561°N -77.90946166666667°E 137.8m

:slight_smile: I am so happy!

And again:

:grinning:

Ok, ok, good point. I guess it’s time to start moving away from text…

1 Like

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.