Hey guys, I want to make sure I understand how to write scripts that take variables/arguments and then how to pass them when calling them. I’ve read the documentation on scripts but, if I’m being honest, I can’t make too terribly much of the documentation yet. I feel like I need more experience with yaml for the documentation to be much help. From studying other peoples’ code, here’s what I’ve deduced. You can have a script, and say you have a service call within it, you can call a variable/argument that has never really been declared anywhere else and can call it whatever you want. For example, argument1. Then, by writing that into your script, you have essentially created argument that can be passed when calling the variable. Sample yaml below.
Thus, just by putting argument1 in that script, I have essentiall created it as an input. It doesn’t really exist outside the script, but when calling the script I need to pass something for that argument for it to do anything. And then passing the variable happens as follows:
automation:
...
action:
service: script.script_name_here
data:
**argument1**: *<<whatever I want to pass to the script here>>*
Am I understanding this correctly? I keep seeing scripts that are passing things like “who:” which I can’t find documentation on, and I am just now piecing together that these may be self-defined arguments that their scripts can take. Please tell me I’m understanding this correctly :).
When you set your argument in the call of the script you can use that in the called script as a variable.
That is an example where I call a script for TTS. The message and the device are passed to the script. In that case to target media_player is optional. When “echo” is omitted the media_player in the room with the last motion is used.
script:
ha_started:
alias: "HA started"
sequence:
- service: script.alexa_tts
data:
echo: "livingroom"
message: "Home Assistant has been started."
alexa_tts:
alias: "Alexa TTS"
sequence:
- service: notify.alexa_media
data:
data:
type: tts
target: >-
{% set lastMotion = states('sensor.last_motion') %}
{% if echo is defined and echo|length %}
media_player.echo_{{ echo }}
{% elif lastMotion == None %}
media_player.echo_livingroom
{% else %}
media_player.echo_{{ lastMotion }}
{% endif %}
message: >-
{{ message }}
Thank, this is a helpful example. So, let me ask you this-- in alexa_tts script, you have the “if echo is defined…” logic. Am I correct in understanding that by enumerating “echo” there, you have essentially created an “input argument” (as I call it, not sure if my terminology is right) with the name echo? Meaning, you could have called that variable whatever you want and it would still work as long as you edited the other script to pass it with the new name? So I could make the follow modification and it would still work?
script:
ha_started:
alias: "HA started"
sequence:
- service: script.alexa_tts
data:
PURPLECOW: "livingroom"
message: "Home Assistant has been started."
alexa_tts:
alias: "Alexa TTS"
sequence:
- service: notify.alexa_media
data:
data:
type: tts
target: >-
{% set lastMotion = states('sensor.last_motion') %}
{% if PURPLECOW is defined and PURPLECOW|length %}
media_player.echo_{{ PURPLECOW }}
{% elif lastMotion == None %}
media_player.echo_livingroom
{% else %}
media_player.echo_{{ lastMotion }}
{% endif %}
message: >-
{{ message }}
That’s to confirm the script was passed a variable named echo.
Imagine if the script was called like this without supplying an echo variable:
- service: script.alexa_tts
data:
message: "Home Assistant has been started."
If the script overlooked to first check if echo is defined, it would fail at the first line of code that attempted to use the value of echo.
By first confirming it exists, it can reliably refer to its value. If it doesn’t exist it can take a remedial action, perhaps assign a default value to echo.
Yeah, I understand that. I’m just trying to understand if “echo” is some universal HA argument, or something he defined. I see things like this in scripts often, for example in the script below there is the “who” variable. Is this something the author defined, or a universal HA argument? If it’s a universal HA argument, I can’t find any data on it. How do people know about these secret script variables/inputs?
- service: >
{% if voice == 'nabu' %}
script.nabu_voice
... a lot more if logic .....
{% endif %}
{% endif %}
data:
who: '{{ who }}'
message: >
{{ message }}
You can’t find it because it doesn’t exist. There’s no “universal HA argument”. What gave you the impression such a concept exists in Home Assistant?
You can assign whatever name you want to a variable … but I would steer clear of using words that have special meaning for Jinja2 (like function names, if, else, in, for, etc) to avoid ambiguity.
What are you referring to when you say “secret script variables/inputs”? Everything explained in this topic can be found in the documentation.
I appreciate your replies. It has helped clarify my understanding. If you read my initial post, you’d see that I’ve already looked through the documentation and still dont understand. It’s possible the answer is there, I’m not disputing that. But I am still new to this and, like I said before, I dont know enough to make as much sense of the documentation as I wish I could. What gave me the impression universal arguments exist? Things like “data”, or “entity_id”, which are universal HA yaml arguments required in certain instances. For all I know, “echo” could be tied to the amazon integration. That’s what I was trying to suss out. Is that what echo is in the above user script, or is it something he created for his own purposes? From what you are saying, it sounds like my initial understanding was accurate. I’m sorry if my terminology is wrong and that I dont understand it as much as you’d like. Believe me, I wish I knew more too.
You’re mixing up language directives (the reserved words or “HA YAML arguments” you described) with variable names. A reserved word like data is set in stone whereas a variable’s name is whatever you choose it to be.
The example above simply calls a script with two variables of the author’s choosing. The choice of echo simply provides context for its intended purpose but, like you surmised, it could be almost anything, including “purplecow”.
Got it, thanks! Yes, “reserved word” was what I was meaning. Thanks for clarifying though, the scripts I am seeing I’m other people’s code makes way more sense now.