How to turn string with property path to actual object?

I have a NR flow to control heat pump SWW and heating. I would like to share this flow but some names and properties are custom. I have inserted a change node where people can define their properties and names. First of all, perhaps this is not the best way to make the flow universal. I’d appreciate any tips if this is the case.

Anyhow, I can create a full path by concatenating fixed home assistant object paths with some of those strings. Problem being that the result is a string. If I put this in a debug node the path string get’s returned, not the value of the property. I have searched for some time but haven’t gotten any further than $lookup. Not sure if this is the correct function but I haven’t gotten it to work. I set flow.dhwCalendar to “calendar.dhw”. For example:

$lookup(“calendarEventDhw[” & $flowContext(“dhwCalendar”)` & “].events[0]”, “.summary”)

What am I missing?

If flow context named ‘dhwCalendar’ has value “calendar.dhw”

then $flowContext("dhwCalendar")

will return "calendar.dhw" as a string.

"calendarEventDhw[" & $flowContext("dhwCalendar") & "].events[0]"

will therefore return the string "calendarEventDhw[calendar.dhw].events[0]"

although you have an extra ` in there which will mess this up.

I guess that what you are missing is that, whilst this looks like a nice way to reference a JSON object, in JSONata the function $lookup(object, key) works on an object, and uses a key to return the value (if the key exists).

This only works to one level, so if calendarEventDhw is an object and if ‘calendar.dhw’ is a key in that object

$lookup(calendarEventDhw, "calendar.dhw")

will return the value of the key.

If this value returned is itself an object with key “events” then you will need

$lookup($lookup(calendarEventsDhw, "calendar.dhw"), "events")

to return the value of the nested object.

And, if this key returns an array as a value, and you want index 0, and you then want ‘summary’ key value from the final object

$lookup($lookup($lookup(calendarEventsDhw, $flowContext("dhwCalendar")), "events")[0], "summary")

is possibly what you want, although I am not going to place a bet on this without seeing the real data and testing it first. Naturally, if calendarEventDhw is not a JSON object that this will never work.

You can always use function chaining ~> to make this look better, but note that index selection [0] binds more tightly than most of the other operators. Thus foo.bar[0] will return the first item in the array bar within the object foo, but (foo.bar)[0] will return the first item in the array returned by foo.bar, which is not necessarily the same thing.

1 Like

Shorter answer:

If you have a Calendar, with events, and you retrieve the list of current events using an Action node, then you will get (in msg.payload for example)

{
   "calendar.octoplus_saver_sessions":{
      "events":[
         {
            "start":"2025-04-02T14:00:00+01:00",
            "end":"2025-04-02T16:00:00+01:00",
            "summary":"The Summary Text",
            "description":"The Description Text"
         },
         {
            "start":"2025-04-02T15:00:00+01:00",
            "end":"2025-04-02T20:00:00+01:00",
            "summary":"The next event",
            "description":"At three O'clock"
         }
      ]
   }
}

and the path reference to the first event summary text would be

payload["calendar.octoplus_saver_sessions"].events[0].summary

which you can easily get from the debug window output (copy path).

If your goal is to make part of the path reference a variable, then this ends up as

payload[<variable-name>].events[0].summary

with all the kerfuffle above around how to a) lift the variable name from context and b) how to reference and retrieve the end summary string from an object.

However, if your primary requirement is simply to extract the end summary string from a path name with a variable component, then using JSONata the path reference can have any part replaced by a wildcard.

Hence

payload.*.events[0].summary

which works (and is heaps simpler than using $lookup())

1 Like

Once again, thank you for your trouble. Great information. The last solution won’t work as I have several calendars. Because of the complexity I’ll just remove the change node. People will have to fill in their variable names in the corresponding nodes themself. It’s not a huge workflow so not a lot of work. Imho not worth the added complexity and maintenance work to keep it universal.

Possibly put the flow in a subflow. When you click on a subflow node you can create a gui form for the user to enter their information. It is then available in the subflow using the $env variable.

The screenshot ids from this cookbook example.

1 Like

I’ll check it out, thanks.