Calling a service in a template condition

I want to know if there’s a way to call a service, that returns a boolean value, from a template condtion. I can’t seem to find any examples of this and my understanding of HA isn’t quite that good. What I’d like to acheive:

alias: Do the thing
sequence:
  - conditions: {{ CALL.SERVICE(param1, param2) }}
  - service: alarm_control_panel.alarm_arm_away
    data: {}
    target:
      entity_id: alarm_control_panel.my_alarm
mode: single
icon: mdi:shield

For context, I want to build a script that is given a code from the frontend and if that code matches a list of known codes executes some action, like turning off an alarm. I know there are other ways of doing the checking but doing it through a service means I can add additional configuration around the checking. I’ve already written the basic service that given a code will check it against values in the configuration but I can’t find any examples/documentation of services being called in templates.

You can pass variables to scripts, see: Scripts - Home Assistant

So assuming you passed the variable password that contained the value 1234 you could do this:

alias: Do the thing
sequence:
  - condition: template
    value_template: "{{ password == '1234' }}"
  - service: alarm_control_panel.alarm_arm_away
    data: {}
    target:
      entity_id: alarm_control_panel.my_alarm
mode: single
icon: mdi:shield

You could also use a template macro, here. Macros can be offloaded to a file, both for confidentiality and reusability.

E.g. (untested)

{% macro is_password_ok(password) %}

{% if password=='1234' %}
True
{% elif password=='9999' %}
True
{% else %}
False
{%endif %}

{% endmacro %}
alias: Do the thing
sequence:
  - condition: template
    value_template: "{{ is_password_ok(var_password) }}"
  - service: alarm_control_panel.alarm_arm_away
    data: {}
    target:
      entity_id: alarm_control_panel.my_alarm
mode: single
icon: mdi:shield

Or better yet

value_template: "{{ is_password_ok(password) }}"

If they want to pass the password to the script, in this case stored in the variable ‘password’.

1 Like

Oh, ofc :wink:
Adapted

Those are some interesting ideas, the macro I haven’t seen before and will be good options if using the service is not possible.

However, I’m still looking to find if I can use the service call to validate my code/password as it gives me a lot more flexibility than hard coding passwords in my scripts.

No.

Templates compute a value; they can’t execute an action (like call a service).

The closest approximation to what you want would be a custom Jinja2 macro, like what koying suggested.

1 Like

Hmm. A script is a service and scripts can now return values.

2 Likes

That makes sense, I can see why it would be designed that way.

I was reading more about service calls and I came across this in the documentation: Service calls - Home Assistant

Tryting to call the service from the template was approaching the problem the wrong way but given that documentation it seems like this should be possible:

sequence:
  - service: my_service.check_secret
    data:
      value: NoTaReAlPaSsWoRd
    response_variable: check_result
  - condition: template
    value_template: "{{ check_result }}"
  - service: system_log.write
    data:
      level: info
      message: Check successful

But trying this gives me this error:

Error: Script does not support ‘response_variable’ for service ‘response_variable’ which does not support response data.

It seems like what I’m trying do is possible but I’m missing something

Edit
I’m for sure at least missing this: Integration Services | Home Assistant Developer Docs

If I got it right, response_variable goes together with the new stop verb/action, and that would be set in my_service.check_secret as the variable returned, i.e. True/False in this case.

Not sure why you point to Dev documentation, that’s definitely out of scope here.

well it is the dev docs for populating data in a response from a service call, which is new in 2023.7

1 Like

From an integration…
We’re not talking about a custom component, here :wink:

or python script :wink:

Yeah I should have been more clear. Based on that dev documentation there’s some specifics I need to do on the service side in order for the service to properly respond into the response_variable. It seems like assuming my service is built correctly I can get the result into a varaible and then check the result in a condition

Not sure what you mean. A random python script won’t do a hass.services.async_register :wink:

uh they have full access to the hass object… (it would just be register)

Uh, you’re talking hacking at the worst level, here :rofl:

yah, but it’s semi topical at that point, it at least shows how it’s done

There are several ways to confirm the supplied password is correct (many have already been suggested in this topic) but none can do it the way you initially requested (call a service within a Template Condition).

That’s the confusion I was afraid of.

A service can be a “yaml script”, as Tom pointed out. In that case, the doc is irrelevant.
A service can also be offered by an integration, coded in Python, and there the doc is relevant.

Are you planning to create a custom component in python that will implement your password logic?

1 Like