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

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.

Yes, but show your entire planned workflow. That tells us nothing. All we know is that you’re trying to get some sort of work around to get a number into a string when there very well could be another way. But you refuse to show what you’re trying to do from the HA side. Any notification platform uses message. If there’s a special field that requires just the number, please show that. Otherwise all these arbitrary requirements seem… arbitrary. I don’t use any of these integrations however I do know templates like the back of my hand. I also know the system very well. So instead of focusing on this one small hurdle, please explain the whole picture using automations, scripts, and services.

If it uses a normal notificiation service. I.e. notify.xyz then this will certianly work and have a usable number:

service: notify.sms_or_whatever
data:
  message: >
    {{ 'the number is ' ~ '+38094209343209402934830' }}

EDIT: Also if you just want the number, this may work aswell.

service: notify.sms_or_whatever
data: >
  {{ {'message': '+38972834798237498237' } }}

If you check my original question there is an example of one situation where the number conversion of the template result cause a failure.

     action:
      - service: notify.sms
        data_template:
          target: "{{ states('input_text.phone_number') }}"
          message: "{{ '1234FOFF' }}"

I think is self-explanatory: there is an in input_text where someone input a phone number, with or without + and international prefix, followed by sequence of digits, and at some point an automation call the notify.sms service from huawei_lte integration passing the phone number as target.

Of course, the phone number need to go in the target, not in message. Messagge accept anything.

This service call fails even if the phone number comply to the correct pattern expected by the notify.sms service.

Thanks, that’s what I was looking for. :wink: Could have avoided this whole back and forth expecting people to read minds.

      - service: notify.sms
        data: >
          {{ { 'target': states('input_text.phone_number'), 'message': '1234FOFF' } }}

EDIT: I do see that you had this service in the original post. That’s my fault for missing it. Sorry.

Acceptable workaround for this specific situation.

Another I found in the meanwhile is to embed phone number string in a list. Apparently notify.sms and the other MQTT service accept a list as recipient.

Because everyone focused on providing a workaround, I suppose that there is no way to keep string as string when working with template results, wich was my first question.