Extract Lat,Long to use in Geofence node

Trying to use the LAt,Long atribute from a location node to feed into the geofence node. followed a youtube video but my output is not working. The geofence node is asking for this as an input.

This node requires input messages one of the following (checked in order):

  • msg.payload.lat & msg.payload.lon
  • msg.location.lat & msg.location.lon
  • msg.lat & msg.lon

Using a debug node the Lat,Long locations are

data.attributes.latitude,
data.attributes.longitude

The code in a change node that is supposed to work is

{
   "lat": data.attributes.latitude,
   "lon": data.attributes.longitude
}

This gives me an output of this in a debug node


device_tracker.craigs_samsung_s23 : msg : Object

object

payload: object

lat: 49.********

lon: -124.**********

close but not accepted by the geofence node as a location.

I just get this error

msg : string[28]

“No location found in message”

any help appreciated.

Craig

Are you sure on the format for lat and long?
There are different formats!

Not sure of anything. I did find an example flow just using an injection node that used that format though. In that example the lat long were under a topic though

When I am back home I will post that working message and maybe someone will be able to help me convert my message.

I assume the device tracker is in either a current state, event state, or trigger node. In the output set message payload to

{"lat": $entity().attributes.latitude, "lon": $entity().attributes.longitude}

Tried it and got this error

msg : string[62]
"Invalid JSONata expression: Attempted to invoke a non-function"


{
   "lat": $entity().attributes.latitude,
   "lon": $entity().attributes.longitude
}

Here is the debug from the poll state node.

device_tracker.craigs_samsung_s23 : msg : Object
object
payload: "home"
data: object
entity_id: "device_tracker.craigs_samsung_s23"
state: "home"
attributes: object
source_type: "gps"
latitude: 49.********
longitude: -124.********
gps_accuracy: 13
altitude: 123
course: 0
speed: 0
vertical_accuracy: 1
friendly_name: "Craig"

output from a working inject node

2024-03-05, 8:23:35 a.m.node: 3ea269b7.d5a1d6msg : Object
object
_msgid: "97d6b46083dfe12d"
payload: 1709655815373
topic: ""
lat: 51.026751
lon: -1.397258

The message from the debug, is that the way it comes through? A poll state gives me a formatted block like this

{
   "payload":"local",
   "data":{
       "entity_id":"device_tracker.pixel_7_5",
       "state":"local",
       "attributes":{
           "source_type":"gps",
           "latitude":40.xxxx,
           "longitude":-73.xxxx,
           "gps_accuracy":37,
           "altitude":3,
           "course":0,
           "speed":0,
           "vertical_accuracy":3,
           "friendly_name":"Pixel 7"
       },
       "last_changed":"2024-03-05T16:27:07.770229+00:00",
       "last_updated":"2024-03-05T16:27:07.770229+00:00",
       "context":{
           "id":"01HR7Q1CKTCWEN0GXZQBBK0626",
           "parent_id":null,
           "user_id":null
       },
       "timeSinceChangedMs":21312
   },
   "topic":"device_tracker.pixel_7_5",
   "_msgid":"d09be70f934ff5ae"

Is it like what I posted, with the indentations?

[{"id":"8017ecbe0e69b941","type":"poll-state","z":"60f2d2277843c698","name":"","server":"6b1110b5.183a4","version":3,"exposeAsEntityConfig":"","updateInterval":"60","updateIntervalType":"num","updateIntervalUnits":"seconds","outputInitially":true,"outputOnChanged":false,"entityId":"device_tracker.pixel_7_5","stateType":"str","ifState":"","ifStateType":"str","ifStateOperator":"is","outputs":1,"outputProperties":[{"property":"payload","propertyType":"msg","value":"{    \"lat\": $entity().attributes.latitude,    \"lon\": $entity().attributes.longitude }","valueType":"jsonata"}],"x":140,"y":520,"wires":[["67e6f51d077ec7db","8722c67a9f6590c9"]]},{"id":"8722c67a9f6590c9","type":"geofence","z":"60f2d2277843c698","name":"","mode":"circle","inside":"both","rad":27857.23987440595,"points":[],"centre":{"latitude":40.88257907388209,"longitude":-73.88552863150835},"floor":"","ceiling":"","worldmap":false,"outputs":1,"x":420,"y":520,"wires":[["67e6f51d077ec7db"]]},{"id":"6b1110b5.183a4","type":"server","name":"Home Assistant","version":5,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":false,"heartbeat":false,"heartbeatInterval":"30","areaSelector":"friendlyName","deviceSelector":"friendlyName","entitySelector":"friendlyName","statusSeparator":"at: ","statusYear":"hidden","statusMonth":"short","statusDay":"numeric","statusHourCycle":"h23","statusTimeFormat":"h:m","enableGlobalContextStore":true}]

add your device tracker to that flow, for me it works.

Screenshot 2024-03-05 114508

I did a straight copy and paste but I do believe it did have indents similar to yours.

I’m at work now so I only have my phone and it’s very difficult to navigate nodered on a phone.

I appreciate your help if I can pop home during the day I’ll double check what the debug output looks like.

I highlighted with my mouse and copied I should have pressed the copy button that may have kept the formatting

Okay it should be formatted then, that does happen when you highlight and copy vs copying the actual message.

When I put your code in the poll state node it works…thank you…, when i put it in a change node I get a json error. Kinda strange but one less node it good.

Thank you very much

Craig

The $entity() variable is only available in the home assistant nodes. Also when using the nodered nodes the path changes from attributes.longitude to data.attributes.longitude.

image

Inside ha nodes omit data if it is part of the path, in nodered, use it. Most of the time. There are also differences between JSON and Jexpression aka jsonata

[{"id":"2a3de46120e39c8e","type":"api-current-state","z":"60f2d2277843c698","name":"","server":"6b1110b5.183a4","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"device_tracker.pixel_7_5","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"}],"for":"0","forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":440,"y":2620,"wires":[["36ef6e34a902d7ec"]]},{"id":"2a5d383dd1367854","type":"inject","z":"60f2d2277843c698","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":210,"y":2620,"wires":[["2a3de46120e39c8e"]]},{"id":"36ef6e34a902d7ec","type":"change","z":"60f2d2277843c698","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\t   \"lat\": data.attributes.latitude,\t   \"lon\": data.attributes.longitude \t}","tot":"jsonata"},{"t":"delete","p":"data","pt":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":700,"y":2620,"wires":[["1e2e6826354e97f1"]]},{"id":"1e2e6826354e97f1","type":"debug","z":"60f2d2277843c698","name":"debug 32","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":860,"y":2620,"wires":[]},{"id":"6b1110b5.183a4","type":"server","name":"Home Assistant","version":5,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":false,"heartbeat":false,"heartbeatInterval":"30","areaSelector":"friendlyName","deviceSelector":"friendlyName","entitySelector":"friendlyName","statusSeparator":"at: ","statusYear":"hidden","statusMonth":"short","statusDay":"numeric","statusHourCycle":"h23","statusTimeFormat":"h:m","enableGlobalContextStore":true}]

Your change node is the same as the one I was using except you deleted “data” that made it work.
You know at work I am pretty smart but doing this I am an idiot, I’m starting to think maybe I am not smart at work but I just work with a bunch of idiots and the make me look good.

It took me a while to get the rest working because my output was an object into a switch node and I had it set looking for a “string” and had to change it to look for a J: “expression” .

Thanks again for the help we will see if it works tomorrow when I come home

This is difficult, it’s a niche area in a large programing sector. Overall the documentation is pretty good but there are some areas where things are non existent.

Like with when to use data or omit it, I’ve never actually found where this is explained. It’s mainly just through trial and error. The more you use it, the more things will start making some sort of sense.

It is now.

https://zachowj.github.io/node-red-contrib-home-assistant-websocket/cookbook/jsonata/call-service.html#passing-variables-to-websocket-nodes-in-summary

https://zachowj.github.io/node-red-contrib-home-assistant-websocket/cookbook/jsonata/functions.html

It is and it isn’t. For me reading it I understand what Is going on, now. New users not so much. As a new user your interaction with data.state is basically non existent since the HA nodes typ default to put the entities state in the payload position.

User start by using {{payload}} not realizing that they are using actually using data.state from the event object. I know this is explained elsewhere but it still not clear for a new user.

I look forward to reading your improved documentation.

https://zachowj.github.io/node-red-contrib-home-assistant-websocket/guide/documentation.html

Your pulling at one piece of my post. The point is it’s niche and while their may be documentation it’s not always easy to find. Then when you do it may not be explained in a way the reader understands.

Where as if you search something more general like how to push an item to an array in JS there will be hundreds of examples/explanations.