Keep a template result as a string, even if it could be converted to a number

the “working” templates include newlines, that’s why the result is a string

do you get a string with leading + from my template?

I’ve tried multiple different ways to make this work in the template editor, but I can also only get the result of number. I think this needs to be raised as a bug, if you explicitly cast to a string, it should not be getting converted to a number.

1 Like

Then why doesn’t this work?

{% set w = "+393331234567\n" %}
{{ (w) }}

This returns a number???

It’s even worse than that - try this:

{% set w  = "+3912345678901234567890"|string %}
{{ w }}

3.9123456789012346e+21
??

Even specifically casting to a string, the value is still automagically converted to a number, and now you can’t even get access to the original value.

try this:

{{"{}\x00".format('+12345') }}

I got that from petro a while back when trying to keep the word “None” as a string since the interpreter was trying to convert it to “null”.

the “\x00” acts as a hidden string character which forces the result to a string.

it doesn’t solve the other issues it seems are going on but it’s a fairly easy way to get the result the OP wants for now.

1 Like

Confirmed, the solution by @finity does work:

{% set x = "+3912345678901234567890"|string %}
{{ "{}\x00".format(x) }}

+3912345678901234567890

2 Likes

These “tricks” (hidden string character, embedded newlines) works at retuning a string but that string is not more a phone number in international notation and is not more accepted as is by subsequent service calls.

So I think there is still need to keep string as string. I’m not sure where this implict conversion to number happens, not in template, I think later in HA…

i’m not sure I follow…

the returned value is a string and I think it should be in the same format as you entered it into the template.

what service are you using it in that it gets rejected?

I tried ages ago. Apparently this is the expected behaviour.

Note this is only an issue with how the template editor interprets results.

For entity states they will always be strings, no matter what the template editor says. Only attributes can have other types.

1 Like

The question is though - would the state be stored in a string that says “3.9123456789012346e+21” or “+3912345678901234567890” ?

The only way to know for sure is to create the entity and look in Developer Tools / States.

All templates are typed after resolution. Where are you trying to use this string and for what? There may be other ways to avoid the typing, but lets see what you’re trying to do first.

I see now that if the template editor had other things it gives a different output.
I just added the string somewhere in the template editor last time that is why I got it to work it seems.

However, if the string is formatted then it works.
Usually a phone number consists of country code, area code and phone number.
If you add a space in between these parts then it works as expected and generally a space dosn’t make a difference when using the number for calling.

The returned string is not recognized as phone number in international notation because, I suppose, it contains an embedded NUL character. This happens also if the string contain embedded spaces, parenthesis, dash, newlines and so on. Apparently the accepted pattern is something like \+?\d+.

I’m passing this string to the notify.sms service from huawei_lte integration (example in my post) and to another MQTT gateway sms service and both reject such strings.

Unfortunately a string with embedded spaces, newlines, dash, parenthesis is not recognized as phone number by subsequent services.

In the subsequent service remove the space with a template {{ states() | replace(" ", "") }}

this is a possible workaround, but the phone number I receive doens’t necessary have a withespace embedded

I don’t understand all these unnecessary restrictions. I don’t know of a single platform that cannot tell a phone number with dashes in it. Let alone one that requires it to always be just a number. Anyways, even if you just needed a number, you could simply just output a word then a space and the number. This would keep it a string and every platform would recognize it because it would be separated by a space. Unless there’s something you’re not telling us… which is why I asked this question that you glossed over:

{{ 'the number ' ~ '+89374982374983749827349827349872394872398479283479' }}

I already answered: huawei_lte integration, notify.sms service for example. Try by yourself, if you don’t believe me: input a phone with dash or space, try send an sms, and notice that nothing is sent! Not the only one btw, I tried also with a proprietary MQTT service to accomplish the same and I got the same failure.