Split JSON string and BASE64 conversion

Hello everybody,
I am a PLC programmer and the world of Node-Red is completely new to me.
I now want to read data from a small controller, which will be provided to me in a JSON format. The format looks like this:

msg.payload: string [52]
"{" OPERANDS ": {" MWSINGLE ": [{" INDEX ": 10," V ":" 6QI = "}]}}".

I want to show two values on the dashboard now. The "INDEX" value and the data value "V". The data value "V" is sent in a Base64 format and would have to be converted into a string.

It would be very friendly if someone could help me here in the forum.

Thanks and Greetings
Ralf

What have you tried so far?

I can give you some pointers, everything you need is already available in Node-RED. :slightly_smiling_face:

First, use a JSON node to parse your payload into a proper object.

Then use the change node to convert msg.payload.OPERANDS.MWSINGLE[0].V into a string using a JSONata expression (there a function for that called $base64decode(string)). Hope that helps as a starting point.

also read the docs, especially the page on working with messages which you should find useful

rather than a change node - just use a base64 node that is meant for this purpose :-)...

I had that in mind at first, too. But it replaces the payload and would require additional steps to save and restore the original message payload before and after.

With the JSONata and change node solution you can convert the property in place.

it can operate on any property within the message... works just fine.

1 Like

I have seen that, but I thought that it used to specify the input property to operate on, while the output would always be msg.payload (as for most of the other transforming nodes). Thanks for clarifying, works as advertised. :slightly_smiling_face:

It does - but it operates on and replaces the property selected - leaving the rest of payload (or whatever) - intact.

Hello and thank you for your replies.
I am now a good way ahead. As a result, I now get "6QI =" as the value. What I need now is to convert this value into a number. Can I hope again for your help :-).

so now you need to use either the base64 node (https://flows.nodered.org/node/node-red-node-base64) or the change node and the formula from @kuema above. (The base64 node may need to be installed - but would then be simpler to use in the future.)

That should give you a debug that looks like
image

so V is now a two byte buffer which presumably you then need to convert into a number in some way... (usually either 256 * the first, plus the second - or 256 * the second, plus the first) - but we can't guess that.

If it's a Buffer, you could also use its nice helper functions for extracting data, like buf.readInt16LE(0). Depending on your endianess (little/big) and expected data type.

More info here: https://nodejs.org/dist/latest-v10.x/docs/api/buffer.html

This would have to be done in a function node where the other operations could be done as well, but I wanted to give you this option for completeness. :slightly_smiling_face:

1 Like

Hi guys,
I've read a lot of documentation and tried a few things, but I'm too much of a beginner to find the right solution.
The integer value in my control is e.g. 610. The two values in the buffer are then [98,2]. Unfortunately, I fail to convert the values in the buffer back to 610.

I do not want to waste your time, but probably only one example with the full function code will help me.

Assuming your data structure is the same as in your OP and you have converted the base64 property into a Buffer using the base64 node, the following code (in a function node) should replace your Buffer with the decoded value:

let buf = msg.payload.OPERANDS.MWSINGLE[0].V;

msg.payload.OPERANDS.MWSINGLE[0].V = buf.readInt16LE(0);

return msg;

Hi kuema,
I tried your code and get the following error message:

"TypeError: Cannot read property 'MWSINGLE' of undefined".

The function node is behind the base64 node.

Did you try the suggestion by @kuema ?

image

As I said, it goes by the assumption that the input data was the same as in your first post.

The function expects a structure like this:

{
"OPERANDS":{
  "MWSINGLE":[
      {
          "INDEX":10,
          "V":[98,2]
      }
  ]}
}

Where [98,2] is a Buffer.

To demonstrate whats happening here

  • your data is in bytes [98,2].
  • You want integer.

The long hand byte to integer conversion is as the picture below - HOWEVER - Buffer has some nice helper function.

Long hand version to demonstrate how helpful buffer functions are...
image

1 Like

To all those helping - please note that in the OP there were spaces in some of the variable names like " V " for example... which is awful I know but will catch you out in your example code above...

I noticed that and removed them. Thought they were introduced by copy-paste or something.
If there are indeed spaces in there, my code will not work, of course. :expressionless:

To get over the spaces problem if you cannot remove them before they get to node red then use syntax like
msg.payload[" OPERANDS "][" MWSINGLE "][0][" V "]
It would, of course, be much neater if they could be removed at source.