In the real old world, a physical printer required a carriage return and a line feed to move the printer head to the start of the line, and the paper up one line.
In ASCII we have CR as hex 0d (13) and LF as hex 0a (10). We often call either/both just ‘new line’ as they usually mean much the same end result.
In Unix world, lines are terminated with just the CR. To make life easy, in Unix world this can be given as \r (return) in a string. The \n (newline) also works similarly.
These are escapes - the \ is an escape that says whatever follows is special, and Unix will replace \r with hex 0d character. This happens either at the point of creation, or at the point of use.
In Windows world (and I believe Whatsapp world), lines are terminated with CR and LF. There are also other worlds which use LF and CR, and just LF, and then there is IBM, which is on another planet.
If you create a string in Unix world, to use in Windows world, you need CR LF as two characters. This is “My love is like\r\na red red rose”. However, this has to be decoded from “\r” to %0d, and this has to happen in the Unix world. If the decoding does not take place, you end up with ‘\r’ and not the CR character.
Some bits of Node-RED will understand \r and convert it for you.
Templates are another matter. Jinja engine (as far as I know) does not understand \ and will take a given string (your template) and process it looking for {{ as escape characters. The \ is just another character like any other.
I suspect that, as you have gone to such great lengths to use Jinja templates to both create and manipulate the strings throughout your flow from start to finish, there has been no opportunity for anything to actively convert \r\n in the strings. It is working using the HA notify service, since the \r\n probably gets converted at the point of use there. HA notify service is in Unix world.
I therefore suspect that the solution is to process the string somewhere along the line using something other than mustache templates. As it happens, mustache templates are not that good at building data objects for the call service node either, and I would always look to use JSONata instead. I very rarely use templates outside of HA.
I would like to suggest that you stop using the template node for doing your work, and use a change node and JSONata instead.
Step 1 - current state node, use the output properties to set msg.payload (you don’t need a special name) to ‘entity state’
Step 2 - use a change node with JSONata to set msg.payload to
"Range: " & payload & " km \r\n\r\n"
This will create a string, using msg.payload value, and will insert and convert \r\n for you at the point of creation.
To prove the difference…
msg.payload as number 345 in the inject node, goes through a template and through a change node JSONata. Top is the change node, bottom is the template.
Please note that
- the debug window shows the \n as a special symbol. the \r has been converted but will only show if you click on the output to display as a ‘string’. It does work.
- you must use the J: (expression) option in the change node ‘to the value’ box
That should (I hope) make it work.
Your use of template nodes in step 3b is a conversation for another time.
PS.
I have to declare my interest as a fully paid up member of the JSONata appreciation society. I am, therefore, biased. You are, of course, entirely free to choose.