I want to trigger an HA action (or set of actions) from another system (which could be another local server as well as a remote phone app). I was assuming Webhooks would be the right way to do so, but now I’ve started using the API interface to query state, and I see I can easily execute a script via an API call to api/services/script.
Can anyone explain the differences and pros/cons of these two methods? ie: when using the API, you must supply a Bearer Token, which seems like a pro over the unprotected Webhook interface.
Also, is there is a way – using either method or yet a different method – to return a response (eg: json payload) to the remote invoking system?
Using the API interface to trigger Home Assistant actions offers greater control, better security with Bearer Tokens, and flexibility for complex tasks, but it requires more setup compared to simple brightspace oneonta Webhooks. Webhooks are easy to set up and great for real-time notifications, but they lack security and control. You can return responses using API calls with response variables in HA scripts.
Thank you for the insights @Avis682Holmes. I have the API working calling a script. It currently returns the default json structure with the entity_id, state, last_changed timestamp, etc – and executes the action I’ve configured. But I can’t figure out how to return a value. I’ve searched for examples, but am officially lost. If I just use:
- stop: End
response_variable: message (where message is an input variable used in the action)
It saves correctly (so syntactically valid)., but I don’t see the value of “message” in the API response.
A few web pages say the result needs to be a dictionary, but I can’t get that to work – perhaps due to not understanding how to correctly form the dictionary inside the script.
I tried the following:
alias: Test email with parameters
description: ""
sequence:
- variables:
var1:
a: 'a'
b: 'b'
- action: notify.gmail_los_altos
data:
title: "{{subject}}"
message: "{{message}}"
- stop: End
response_variable: var1
But it says
Message malformed: expected a dictionary for dictionary value @ data['sequence'][0]['variables']
Can you point me to, or supply, a super simple example of a script that executes an action and returns a result back to the API caller?
My apologies. I bought HA a week ago, wrote my first script today, and this is my first attempt at variables other than script input variables. A number of pages I found show what I think is exactly what I did: nesting it inside the sequence exactly like the action that follows it. So I’m unsure what’s wrong? Sadly, it’s not ‘obvious’ to me yet.
I see other examples that set variables this way:
alias: Test email with parameters
description: ""
variables:
var1:
a: "1"
b: "2"
sequence:
- action: notify.gmail_los_altos
data:
title: "{{subject}}"
message: "{{message}}"
- stop: End
response_variable: var1
This doesn’t throw a syntax error. But it also doesn’t succeed in what I’m attempting to do, which is return a value to the external app that invoked this via the API.
Your examples are not the same. YAML is a positional language. Look at the indentation of the whole var1 block in relation to its parent variables, it differs by two spaces. That indentation matters.
Have you read the documentation? I’ve never used the REST API but did just read the documentation. It makes no mention of being able to provide a response, so I’d say things are working as intended. It just isn’t capable of doing what you want it to do.
You are not directly executing a script, you are executing a service call. The vast vast majority of HASS service calls do not provide any kind of response. Except potentially throw an error, if shit hits the fan.
But what it does seem to do is return a list of all state objects which were changed by the service call. The easiest way to make use of this would be for you to create a text helper (Settings > Devices > Helpers) and in your script fill the text helper with the value you want to return. That should make it show up in the API response.
Text helpers are limited to 255 characters though, so if you want to provide longer responses you’d need a more involved workaround. Such as a custom template entity sensor with your values stored as attributes, which can hold much more data and also natively support other data types (while the state is always just a string).
I too didn’t find it in the official documentation. But @Avis682Holmes mentioned this can be done with “response variables” (any help @Avis682Holmes?) so I turned to google. Unfortunately, I suspect I went down a few rabbit holes.
I read up on text helpers (new to me), and implemented a test case: I have my script append an additional “X” to the string stored in the helper. I can inspect the helper in HA and can see the script is updating it. However, the helper value change is not returned to the API caller.
In case I’m still misunderstanding (I’m definitely still learning), here’s my code:
This gave me an idea on a workaround: I can make a second API call to fetch the state of the text helper. Having it non-atomic could cause issues, but for my current use case, this might be good enough.
If anyone has additional thoughts or insights on how to return a value via the script API call, I’d love to hear it!