I was trying to add a volume setting to my alexa notification service, and was trying to be cute and preserve the old volume of the echo i am calling and then set it back after the notification happens. I am having an issue with setting a variable that always seems to error out with:
Error: TypeError: unhashable type: 'Wrapper'
Here is the part of the script where it fails, specifically at calculating the previous_volume:
alias: HELPER - activate_alexa_actionable_notification
description: Used to call Alexa Actionable Notifications. Sends message to Alexa
sequence:
- alias: alexa actions variables
variables:
echo_device: "{{ alexa_device | default('media_player.living_room_echo') }}"
suppress_ok: "{{ suppress_confirmation | default(false) }}"
echo_volume: "{{ alert_volume | default(0.5) }}"
previous_volume: |-
{% if state_attr(echo_device, 'volume_level') is not none %}
{% set previous_volume = state_attr( echo_device , 'volume_level') %}
{% else %}
{% set previous_volume = 0.4 %}
{% endif %}
{{ previous_volume}}
Here’s the rest of the script, but the traces show the error at the variable declaration section i pasted. The error is definitely in the way i am trying to calculate previous_volume, i am pretty sure i am missing something in the way you use variables inside other variables…
alias: HELPER - activate_alexa_actionable_notification
description: Used to call Alexa Actionable Notifications. Sends message to Alexa
sequence:
- alias: alexa actions variables
variables:
echo_device: "{{ alexa_device | default('media_player.living_room_echo') }}"
suppress_ok: "{{ suppress_confirmation | default(false) }}"
echo_volume: "{{ alert_volume | default(0.5) }}"
previous_volume: |-
{% if state_attr(echo_device, 'volume_level') is not none %}
{% set previous_volume = state_attr( echo_device , 'volume_level') %}
{% else %}
{% set previous_volume = 0.4 %}
{% endif %}
{{ previous_volume}}
- action: input_text.set_value
target:
entity_id: input_text.alexa_actionable_notification
data:
value: >-
{"text": "{{ text }}", "event": "{{ event_id }}",
"suppress_confirmation": "{{ suppress_ok }}"}
- action: media_player.volume_set
metadata: {}
data:
volume_level: "{{ echo_volume }}"
target:
entity_id: "{{ echo_device }}"
- action: media_player.play_media
target:
entity_id: "{{ echo_device }}"
data:
media_content_type: skill
media_content_id: REDACTED
- action: media_player.volume_set
metadata: {}
data:
volume_level: "{{ previous_volume }}"
target:
entity_id: "{{ echo_device }}"
fields:
text:
description: The text you would like alexa to speak.
example: What would you like the thermostat set to?
event_id:
description: Correlation ID for event responses
example: ask_for_temperature
alexa_device:
description: Alexa device you want to trigger
example: media_player.kitchen_echo_show
suppress_confirmation:
description: Set true if you want to suppress 'okay' confirmation
example: "true"
alert_volume:
selector:
number:
min: 0
max: 1
step: 0.01
name: alert_volume
description: The volume for the notification
default: 0.5
mode: queued
max: 20
Loose the “set” in a template in the variable. The set is implied, so to speak…
previous_volume: |-
{% if state_attr(echo_device, 'volume_level') is not none %}
{{ state_attr( echo_device, 'volume_level') | float(0) }}
{% else %}
0.4
May not need the float, but this makes sure it’s a float and also prevents an error by defaulting to something. You can pick other than 0 for the default…
yeah, i was using the set as a last straw, since i didn’t know what was causing the issue. it turns out that casting it to float is what made the difference. since i cast it to float with a default, i can simplify the entire bit to this: