Change a $tring of letters to have a full stop and a space

I am collecting some flight server data in Node Red and sending the data as a text string to Home Assistant to use with Google TTS speech. The issue I have is that the Callsign part is a string of letters such as RYR1234G, which I want to be spoken as characters not a word. I know that a space and/or a full-stop between each character may do the trick (R .Y .R .1 .2 .3 .4 .G ), but my solution is ugly, due to a lack of knowledge and although it sort of works, I don't know how do this with a random length of characters.
Please can someone show me a better way of doing this or should I be doing something with the Google TTS coding?

[{"id":"da8a6ef0b3c9a5c8","type":"tab","label":"Flow 1","disabled":false,"info":"","env":[]},{"id":"ef9f06be11be1595","type":"inject","z":"da8a6ef0b3c9a5c8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"RYR123G","payloadType":"str","x":350,"y":140,"wires":[["c25bd685916af4ca"]]},{"id":"777ae9cd4da78bd3","type":"debug","z":"da8a6ef0b3c9a5c8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1150,"y":140,"wires":[]},{"id":"c25bd685916af4ca","type":"function","z":"da8a6ef0b3c9a5c8","name":"","func":"var call = msg.payload;\nlet one = call.substr(0,1);\nlet two = call.substr(1,1);\nlet three = call.substr(2,1);\nlet four = call.substr(3,1);\nlet five = call.substr(4,1);\nlet six = call.substr(5,1);\nlet seven = call.substr(6,1);\nlet eight = call.substr(7,1);\n\n\n//return {payload:{one}};\nreturn {payload:{one:one,two:two,three:three,four:four,five:five,six:six,seven:seven,eight:eight}}\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":560,"y":140,"wires":[["0fb13606396dd088"]]},{"id":"0fb13606396dd088","type":"change","z":"da8a6ef0b3c9a5c8","name":"","rules":[{"t":"set","p":"payload.all","pt":"msg","to":"$string(payload.one) & \" .\" & $string(payload.two) & \" .\" & $string(payload.three) & \" .\" & $string(payload.four) & \" .\" & $string(payload.five) & \" .\" & $string(payload.six) & \" .\" & $string(payload.seven) & \" .\" & $string(payload.eight) & \" .\" ","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":750,"y":140,"wires":[["9442164bb3990b3f"]]},{"id":"9442164bb3990b3f","type":"change","z":"da8a6ef0b3c9a5c8","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.all","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":970,"y":140,"wires":[["777ae9cd4da78bd3"]]},{"id":"3da6785dbcb2f779","type":"comment","z":"da8a6ef0b3c9a5c8","name":"Splitup a code with .'s","info":"Splitup a code with .'s","x":360,"y":80,"wires":[]}]
[{"id":"f38450d4577c05fb","type":"inject","z":"da8a6ef0b3c9a5c8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"RYR123G","payloadType":"str","x":390,"y":270,"wires":[["8ba6492f2ca8fe19"]]},{"id":"8ba6492f2ca8fe19","type":"function","z":"da8a6ef0b3c9a5c8","name":"","func":"msg.payload = msg.payload.split('').join('.');\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":570,"y":270,"wires":[["65548732bd8ae057"]]},{"id":"65548732bd8ae057","type":"debug","z":"da8a6ef0b3c9a5c8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":760,"y":270,"wires":[]}]

I am slightly confused your solution is exactly the same as mine. Maybe I am wrong but it looks like my code was still in your clipboard?

Sorry - yes - re-edited above... should just be a function with

msg.payload = msg.payload.split('').join('.');
return msg;

And in a single change node with a JSONata expression

$join( $split( $$.payload, ""), ". ") & "."

Plus adding final period

Phew!!! I thought I was going mad. Thank you so much, that is so simple and exactly what I need. Somehow I seem to always go for the complicated overworked solution.

1 Like

Brilliant!!!. I need to do a bit more reading I think, it's just a complete lack of knowledge on my part, trouble is when you get old you get stuck with what you think you know.

You should also be able to use the JSONata expression in your HA node directly with no need for a function or a change node.

Thanks, the whole thing collects bearing, destination, origin, speed etc... whenever an aircraft is within 10km of my location.
I want those individual items shown as entities, which is all fine. Then I thought afterwards I would send the useful parts of that to my phone for plane spotting as speech. Barmy idea I know and I obviously have too much time on my hands, but it's one way of trying to keep my very old brain active.

3 Likes

Question, why do you use $$.payload as it works fine just using payload?

It's a convention of mine. It reminds me where in the context the property i want to use is. It does not matter so much in simple expressions, but to me it saves time when in more complex expressions. As in a map of an array of objects you would add $$ if you wanted to address the msg context.

JSONata is fancy and many of multistep functionalities look like breeze with it. But the danger is if you'll need to read and understand the syntax let's say a year after tomorrow.

I'd recommend to use plain JavaScript not just for readability but also wider online support and available documentation.

Double dollar is root level selector.

Thank you, both of you. I have only used JSONata for simple operations, mainly to see if I could, as I much prefer Javascript & function nodes (Not the correct Node-red way I know).

I have also checked, using msg.payload also works and is a lot more obvious to a simple sole like myself (although so far I have only ever used 'payload')

it is there to be used... if you're happy - use it.
(I know I do :slight_smile: )

That puts JSONata into compatibility mode, which i find more confusing and i had issues there, can not recall the issues, been a while.

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