Jsonata help once again please guys

Guys,

Trying to do what i thought would be some basic maths with Jsonata here

In a msg stream i get passed from my inverters Battery Voltage and Battery Amps - this allows me to work out the charging rate for each inverter

I am tryng to use the following Jsonata in a change node

image

The incoming message looks like this

If i reference the values independently of each other i can grab them and set them as globals etc - so i believe the values and paths etc are correct

I feel it is something in the $$.msg part of the jsonata but can not get it

Any one out there feeling smart ?

Craig

Could you try it without the msg ? eg. $$.keyvalues....

Hmmm - will give it a go and let you know

Thanks
Craig

Yep that got it thanks !

I can not ever see myself coming to grips with Jsonata !! :cry: :cry: :cry:

Craig

2 Likes

Neither can I, which is why I use a function node for cases like this. It is all a matter of how one's brain is wired up I think.

3 Likes

Stick with it. It's incredibly powerful. I spent ages getting my head round it, not understanding the structures and the syntax but now it's my go-to for anything that requires processing data in objects and arrays in messages or variables. I much prefer it to writing function nodes. I've done some amazingly complex stuff with nested and higher-order functions.

It pays to build things up in blocks and test as you go though because if it goes wrong it's a nightmare to debug but it really is worth it for writing concise code to process data.

Good luck

Out of curiosity why are you using the root variable $$? You don't need that in the simple expression you have in your example. $round(msg.keyvalues.Battery... works fine. According to the Jsonata docs you only need $$ for complex expressions when you break out of the current context to navigate down a different path (perhaps to set a variable you're going to use later or something).

But as Bakman2 pointed out, you don't need msg. either as Node Red now always assumes that you're dealing with something under the msg object (what else would it be?). msg. is presumably left in for backwards compatability because missing out the msg is, I believe, a fairly recent change.

So $round(keyvalues.Battery... also works fine and is now the standard way to do it,

$$.msg.keyvalues... presumably just confuses the hell out of it because you're not supposed to be referencing the msg object.

Thanks Simon for the additional information - i guess that is the major problem as their is no concise reference for how JSONATA interacts within the NR environment.

So whenever i think i will tackle something with it - i do a search on the forums first to see if i can find something close and then start trying to mangle that to fit what i want. If there is nothing on the forums i then go into the Wild Wild West and start searching and that becomes even more confusing.

Then you come back and feed it into the expression validator - but it does not return anything useful as there is no current message (in the case of the Change node for instance)

What would be nice is if there was a way to tag a message in the debug window and choose to feed that through the expression analyzer

Anyway - you are right - simplified it right down as you suggested and that works just fine.

Craig

Although I fully agree, it can take quite some time to get the data out, depending on the complexity of the in and output. My goto is always: try.jsonata.org, where I can test everything (more) quickly, but keep in mind to always encapsulate the object into {"payload": ...} else it doesn't match with node-red.

1 Like

Exactly! That's what I do. I copy the message from NR into try.jsonata.org and do all my testing in that environment. The error messages and syntax highlighting are vital.

I create what is effectively my intended message object and then a separate object to deal with context variables but try to keep the code very similar to what will end up in node red. I try to keep the amount of translation I need to do to get it to work in NR to a minimum such as replacing a standard prefix with $globalContext(. There's always a bit of debugging to do because I'll always make a mistake or two.

Once in NR, the test function doesn't deal with context variables which makes it a bit cumbersome but I build an object in the example message in the test function with the message and with separate variables that I can define to test how it will work.

If it helps, one of the things I've found most useful in Jsonata is defining functions and variables. You can pull bits of your data out of your message using simple predicate queries and define them as new objects and arrays then apply built-in or your own functions step by step. I've done some very complex translations of data from one format into another.

I have a very promising project creating a flexible human-readable scheduler to control the heating in my house. I'll share it with the class when I'm closer to a finished product (and I have more time).

Can you expand more on how to do this please SImon ? This is where i come unstuck with trying to do stuff in JSONATA is the translation between the NR environment.

For instance here is the debug window from the whole thing that started this thread

Which is the output from Steve's excellent Buffer parser node - how would i take this and "massage" it to get it working in try.jsonata

And as an aside - would it not be better try and get the inbuilt parser/tester in the NR Change Node to be able to suck a message in and use it as input ?

Craig

You can easily copy the message (or even part of the message) from the debug window to the clipboard.

image

Once copied to the clipboard you can paste it into

  • JSONata Exerciser or
  • the Example message tab of the JSONAta Expression Editor of the respective node-red node.
1 Like

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