Hi, I’m having difficulty finding the bug in my script. When I try to save it, HA gives the error message: Message malformed: extra keys not allowed @ data[‘script’].**
When I look at the documentation, I see nothing wrong. It’s the first script I’ve written, so I probably did something obviously wrong.
I started with pressing the button to create a new script and then converted a part of an automation in a script because I want to use it many times.
script:
tts_volume_restore:
alias: "Dynamische TTS Met Volume Herstel"
description: "Speelt een bericht af op een gespecificeerde mediaspeler met tijdelijke volumeverhoging en herstelt daarna het volume."
fields:
media_player_entity_id:
name: Mediaspeler Entiteit ID
description: De entity_id van de speler (bv. media_player.keuken).
required: true
example: media_player.aanrecht
selector:
entity:
domain: media_player
target_device_id:
name: Doel Device ID (Optioneel)
description: De device_id van de speler. Wordt gebruikt indien entity_id niet volstaat.
required: false
example: ab5694a6f25b783628746ee723a521e6
selector:
device:
domain: media_player
tts_volume_level:
name: Tijdelijk TTS Volume
description: Het volume tijdens de uitspraak (0.0 tot 1.0).
required: true
example: 0.6
default: 0.6
selector:
number:
min: 0.0
max: 1.0
step: 0.05
mode: box
message_content:
name: Berichten Inhoud
description: De tekst die uitgesproken moet worden.
required: true
example: De droogkast is aangezet.
selector:
text:
sequence:
# STAP 1: Snapshot van huidig volume - Slaat het volume op in een tijdelijke variabele
- variables:
saved_volume_level: "{{ state_attr(media_player_entity_id, 'volume_level') | float(0) }}"
# STAP 2: Mediaspeler inschakelen
- service: media_player.turn_on
target:
entity_id: "{{ media_player_entity_id }}"
# STAP 3: Tijdelijk volume instellen voor TTS
- service: media_player.volume_set
data:
volume_level: "{{ tts_volume_level | float }}"
target:
entity_id: "{{ media_player_entity_id }}"
# STAP 4: Het TTS bericht afspelen
- service: tts.google_translate_say
data:
entity_id: "{{ media_player_entity_id }}"
cache: false
language: nl
message: "{{ message_content }}"
# STAP 5: Herstellen van het oorspronkelijke volume
- service: media_player.volume_set
data:
volume_level: "{{ saved_volume_level }}"
target:
entity_id: "{{ media_player_entity_id }}"
When using the UI Script Editor you do not use the top_level key script… nor do you use the object id (tts_volume_restore) as a key.
Be aware that the UI Editors do not support comments, so all those will be removed if you ever go to review the script’s configuration. Use the alias key for each step if you want to keep them:
alias: "Dynamische TTS Met Volume Herstel"
description: "Speelt een bericht af op een gespecificeerde mediaspeler met tijdelijke volumeverhoging en herstelt daarna het volume."
fields:
media_player_entity_id:
name: Mediaspeler Entiteit ID
description: De entity_id van de speler (bv. media_player.keuken).
required: true
example: media_player.aanrecht
selector:
entity:
filter:
- domain: media_player
target_device_id:
name: Doel Device ID (Optioneel)
description: De device_id van de speler. Wordt gebruikt indien entity_id niet volstaat.
required: false
example: ab5694a6f25b783628746ee723a521e6
selector:
device:
entity:
- domain: media_player
tts_volume_level:
name: Tijdelijk TTS Volume
description: Het volume tijdens de uitspraak (0.0 tot 1.0).
required: true
example: 0.6
default: 0.6
selector:
number:
min: 0.0
max: 1.0
step: 0.05
mode: box
message_content:
name: Berichten Inhoud
description: De tekst die uitgesproken moet worden.
required: true
example: De droogkast is aangezet.
selector:
text:
sequence:
- alias: "STAP 1: Snapshot van huidig volume - Slaat het volume op in een tijdelijke variabele"
variables:
saved_volume_level: "{{ state_attr(media_player_entity_id, 'volume_level') | float(0) }}"
- alias: "STAP 2: Mediaspeler inschakelen"
action: media_player.turn_on
target:
entity_id: "{{ media_player_entity_id }}"
- alias: "STAP 3: Tijdelijk volume instellen voor TTS"
action: media_player.volume_set
data:
volume_level: "{{ tts_volume_level | float }}"
target:
entity_id: "{{ media_player_entity_id }}"
- alias: "STAP 4: Het TTS bericht afspelen"
action: tts.google_translate_say
data:
entity_id: "{{ media_player_entity_id }}"
cache: false
language: nl
message: "{{ message_content }}"
- alias: "STAP 5: Herstellen van het oorspronkelijke volume"
action: media_player.volume_set
data:
volume_level: "{{ saved_volume_level }}"
target:
entity_id: "{{ media_player_entity_id }}"
1 Like
Hi Didgeridrew,
Sorry, that was not the only error, it’s just so a generic message without line number or explanation.
Now I have the following code and won’t save:
tts_volume_restore:
alias: "Dynamische TTS Met Volume Herstel"
description: "Speelt een bericht af op een gespecificeerde mediaspeler met tijdelijke volumeverhoging en herstelt daarna het volume."
fields:
media_player_entity_id:
name: Mediaspeler Entiteit ID
description: De entity_id van de speler (bv. media_player.keuken).
required: true
example: media_player.aanrecht
selector:
entity:
domain: media_player
target_device_id:
name: Doel Device ID (Optioneel)
description: De device_id van de speler. Wordt gebruikt indien entity_id niet volstaat.
required: false
example: ab5694a6f25b783628746ee723a521e6
selector:
device:
domain: media_player
tts_volume_level:
name: Tijdelijk TTS Volume
description: Het volume tijdens de uitspraak (0.0 tot 1.0).
required: true
example: 0.6
default: 0.6
selector:
number:
min: 0.0
max: 1.0
step: 0.05
mode: box
message_content:
name: Berichten Inhoud
description: De tekst die uitgesproken moet worden.
required: true
example: De droogkast is aangezet.
selector:
text:
sequence:
# STAP 1: Snapshot van huidig volume - Slaat het volume op in een tijdelijke variabele
- variables:
saved_volume_level: "{{ state_attr(media_player_entity_id, 'volume_level') | float(0) }}"
# STAP 2: Mediaspeler inschakelen
- service: media_player.turn_on
target:
entity_id: "{{ media_player_entity_id }}"
# STAP 3: Tijdelijk volume instellen voor TTS
- service: media_player.volume_set
data:
volume_level: "{{ tts_volume_level | float }}"
target:
entity_id: "{{ media_player_entity_id }}"
# STAP 4: Het TTS bericht afspelen
- service: tts.google_translate_say
data:
entity_id: "{{ media_player_entity_id }}"
cache: false
language: nl
message: "{{ message_content }}"
# STAP 5: Herstellen van het oorspronkelijke volume
- service: media_player.volume_set
data:
volume_level: "{{ saved_volume_level }}"
target:
entity_id: "{{ media_player_entity_id }}"
I already addressed that… maybe you missed the edit.
It’s line 1, tts_volume_restore: is not valid in the Script Editor.
You’re just missing a key piece of context…
By convention, configuration examples you see in the docs are written as if you are adding them directly to configuration.yaml. The Script and Automation Editors show a simplified configuration in the “Edit in YAML” view, because they are processed a bit differently.
1 Like
Thanks for you quick response, i’ll fix it.
The error is becomming more verbose: “Message malformed: extra keys not allowed @ data[‘fields’][‘target_device_id’][‘selector’][‘domain’]”.
It remembers my on writing Java with an elementery text editor and now I have IntelliJ Ultimate.
alias: "Dynamische TTS Met Volume Herstel"
description: "Speelt een bericht af op een gespecificeerde mediaspeler met tijdelijke volumeverhoging en herstelt daarna het volume."
fields:
media_player_entity_id:
name: Mediaspeler Entiteit ID
description: De entity_id van de speler (bv. media_player.keuken).
required: true
example: media_player.aanrecht
selector:
entity:
domain: media_player
target_device_id:
name: Doel Device ID (Optioneel)
description: De device_id van de speler. Wordt gebruikt indien entity_id niet volstaat.
required: false
example: ab5694a6f25b783628746ee723a521e6
selector:
device:
domain: media_player
tts_volume_level:
name: Tijdelijk TTS Volume
description: Het volume tijdens de uitspraak (0.0 tot 1.0).
required: true
example: 0.6
default: 0.6
selector:
number:
min: 0.0
max: 1.0
step: 0.05
mode: box
message_content:
name: Berichten Inhoud
description: De tekst die uitgesproken moet worden.
required: true
example: De droogkast is aangezet.
selector:
text:
sequence:
- variables:
saved_volume_level: "{{ state_attr(media_player_entity_id, 'volume_level') | float(0) }}"
- service: media_player.turn_on
target:
entity_id: "{{ media_player_entity_id }}"
- service: media_player.volume_set
data:
volume_level: "{{ tts_volume_level | float }}"
target:
entity_id: "{{ media_player_entity_id }}"
- service: tts.google_translate_say
data:
entity_id: "{{ media_player_entity_id }}"
cache: false
language: nl
message: "{{ message_content }}"
- service: media_player.volume_set
data:
volume_level: "{{ saved_volume_level }}"
target:
entity_id: "{{ media_player_entity_id }}"
That is telling you that the issue is in the configuration of the selector for your target_device_id variable. In this case it looks like you are missing the entity key that would allow you to use domain.
target_device_id:
name: Doel Device ID (Optioneel)
description: De device_id van de speler. Wordt gebruikt indien entity_id niet volstaat.
required: false
example: ab5694a6f25b783628746ee723a521e6
selector:
device:
entity:
- domain: media_player
Personally, I would almost never use a device selector where an entity selector would work…
Entity Selector config
target_device_id:
name: Doel Device ID (Optioneel)
description: De device_id van de speler. Wordt gebruikt indien entity_id niet volstaat.
required: false
example: ab5694a6f25b783628746ee723a521e6
selector:
entity:
filter:
- domain: media_player
I finally solved my problems, this is the working script with a helper variable:
alias: Dynamische TTS with Volume restore
description: >-
Plays a message on a specified media player with a temporary volume and
restores the volume afterwards.
fields:
media_player_entity_id:
name: Mediaspeler Entiteit ID
description: Entity_id of the player (bv. media_player.kitchen).
required: true
example: media_player.kitchen
selector:
entity:
domain: media_player
tts_volume_level:
name: Tijdelijk TTS Volume
description: Volume during the message (0.0 to 1.0).
required: true
example: 0.6
default: 0.6
selector:
number:
min: 0
max: 1
step: 0.05
mode: box
message_content:
name: Message content
description: The text.
required: true
example: The tumble dryer is now on.
selector:
text: null
sequence:
- action: media_player.turn_on
metadata: {}
data: {}
target:
entity_id: "{{ media_player_entity_id }}"
- action: input_number.set_value
metadata: {}
data:
value: "{{ state_attr(media_player_entity_id, 'volume_level') | float(0) }}"
target:
entity_id: input_number.vorig_media_volume
- action: media_player.volume_set
metadata: {}
data:
entity_id: "{{ media_player_entity_id }}"
volume_level: "{{ tts_volume_level | float }}"
target:
entity_id: "{{ media_player_entity_id }}"
- action: tts.google_translate_say
data:
entity_id: "{{ media_player_entity_id }}"
cache: false
language: nl
message: "{{ message_content }}"
- wait_for_trigger:
- value_template: "{{ is_state(media_player_entity_id, 'idle') }}"
trigger: template
timeout: "00:00:15"
- data_template:
volume_level: "{{ states('input_number.vorig_media_volume') | float(0) }}"
target:
entity_id: "{{ media_player_entity_id }}"
action: media_player.volume_set