alandtse / alexa_media_player

This is a custom component to allow control of Amazon Alexa devices in Home Assistant using the unofficial Alexa API.
Apache License 2.0
1.44k stars 277 forks source link

No "Volume Level" attribute upon startup. #2439

Open AdamMonforton opened 1 month ago

AdamMonforton commented 1 month ago

IMPORTANT: Please search the issues, including closed issues, and the FAQ before opening a new issue. The template is mandatory; failure to use it will result in issue closure.

Describe the bug When Home Assistant starts up, the media player does not have the "volume_level" attribute. Only once one of the volume buttons is physically pressed on the device does the attribute show. I use this attribute in a couple automations, so if HA restarts, these automations hang because it can't access the data.

To Reproduce Restart Home Assistant

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior

Screenshots After rebooting Home Assistant Screenshot 2024-08-08 162429

Once a volume button is physically pressed on the Echo Dot. Screenshot 2024-08-08 160625

System details

Logs Please provide logs. Screenshot 2024-08-08 160733

Logger: homeassistant.components.automation.door_alerts Source: components/automation/init.py:776 integration: Automation (documentation, issues) First occurred: 4:25:21 PM (1 occurrences) Last logged: 4:25:21 PM

Error while executing automation automation.door_alerts: expected float for dictionary value @ data['value']

Additional context

danielbrunt57 commented 1 month ago

The volume level attribute appears when a button is pushed due to the http2push connection that's open from HA to Amazon this permitting Amazon to push new commands to HA as they occur, like volume change, equalizer change, media player state changes (playing, paused, etc). When the integration first loads, it's only given the capabilities of the echo devices and not any of the states like volume etc. It's not until the first poll of history records that it can possibly learn what the states are. The polling interval defaults to 60 seconds and then if http2push is active, is multiplied by a factor of 10 becoming 10 minutes until first and subsequent polls. I'm stating this based on my memory of how this all works internally but I will delve back into it with a view to whether my perceptions are correct and whether there's something I've missed/overlooked and possible alternatives to that initial delay. If it is in fact the pulling of history records, AMP only pulls the last 24 hours so if an echo has been idle more than a day, we're SOL. There is no official API for us to access and as far as I can remember, we are retrieving everything we can already. I will follow up though with more review...

danielbrunt57 commented 1 month ago

Actually, now that I'm in front of my computer and not my tiny phone screen, if you write your template this way then you can assign a default value should the attribute not exist:

"{{ state_attr('media_player.office','volume_level') | float(0.37) }}"

thus working around the limitations of AMP & Amazon.

danielbrunt57 commented 1 month ago

In addition to that, you might be able to use the HACS custom component Variables+History to save the echo dot volume levels. The integration's sensors survive restarts so you would always have access to the echo dots' last known volume_level.

Is it the automation's function to save the current volume_level before issuing an alert at a higher volume and then restore the original volume_level when it's done?

AdamMonforton commented 1 month ago

Basically, yes, but backwards. I have it save the current volume level before lowering it for announcements. I use this dot with my Fire Stick as the main sound and I pretty much have to have the volume all the way up to hear it, which is WAY too loud for normal Alexa announcements.

On Thu, Aug 8, 2024, 8:13 PM Daniel @.***> wrote:

In addition to that, you could use the HACS custom component Variables+History to save the echo dot volume levels. The integration's sensors survive restarts so you would always have access to the echo dots' last known volume_level.

Is it the automation's function to save the current volume_level before issuing an alert at a higher volume and then restore the original volume_level when it's done?

— Reply to this email directly, view it on GitHub https://github.com/alandtse/alexa_media_player/issues/2439#issuecomment-2276927676, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADDZTTKFHODK5Z2HHNEDJGTZQQCTTAVCNFSM6AAAAABMHGI6KOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDENZWHEZDONRXGY . You are receiving this because you authored the thread.Message ID: @.***>

danielbrunt57 commented 1 month ago

Further reflection...

AdamMonforton commented 1 month ago

Cool, thanks. I'll look into that tomorrow :)

On Thu, Aug 8, 2024, 8:22 PM Daniel @.***> wrote:

Further reflection...

  • Use Variables + History & automation(s) triggered by volume_level change to save the current volume_level to the Var+History sensor.
  • Use input_number to save the last volume_level from Var+History sensor
  • Set new volume & Issue alert
  • Restore the volume_level back to the volume_level saved in input_number.

— Reply to this email directly, view it on GitHub https://github.com/alandtse/alexa_media_player/issues/2439#issuecomment-2276935951, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADDZTTLXNFG5YRVKGBONVVDZQQDV3AVCNFSM6AAAAABMHGI6KOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDENZWHEZTKOJVGE . You are receiving this because you authored the thread.Message ID: @.***>

AdamMonforton commented 1 month ago

"{{ state_attr('media_player.office','volume_level') | float(0.37) }}"

I went with this method. I was trying to set up the Variables + History, but I figured it would have the same thing happen when it tried to grab the non-existent volume level. So using the above method seems to do the job nicely.

Thanks.

danielbrunt57 commented 1 month ago

Here is my automation for updating my Variables + History entity where it stores all of my last known echo volume levels.

image

alias: Alexa - Save Last Volume Level
description: ""
trigger:
  - platform: state
    entity_id:
      - media_player.garage_echo_dot
      - media_player.office_echo_dot_left
      - media_player.office_echo_dot_right
      - media_player.kitchen_echo_dot
      - media_player.living_room_echo_dot_left
      - media_player.living_room_echo_dot_right
      - media_player.bedroom_echo_dot_left
      - media_player.bedroom_echo_dot_right
      - media_player.daniel_s_echo
      - media_player.daniel_s_echo_auto
      - media_player.echo_show_8
    attribute: volume_level
    not_from: 0
    not_to: 0
    id: volume
  - platform: state
    entity_id:
      - sensor.last_alexa
    id: last_alexa
    to: null
condition: []
action:
  - choose:
      - conditions:
          - condition: trigger
            id:
              - volume
        sequence:
          - data:
              value: "{{ trigger.to_state.state }}"
              attributes:
                "{{trigger.entity_id}}": "{{ state_attr(trigger.entity_id,'volume_level') }}"
            target:
              entity_id: sensor.last_alexa_volume
            enabled: true
            action: variable.update_sensor
      - conditions:
          - condition: trigger
            id:
              - last_alexa
        sequence:
          - data:
              entity_id: sensor.last_alexa_volume
              value: "{{ trigger.to_state.state }}"
            action: variable.update_sensor
mode: parallel
max: 10

In your case, you would store the sensor.last_alexa_volume attribute for the device volume in question to your input_number, set a new volume level, then restore the volume back to the value saved in input_number.

balubone commented 2 days ago

Here is my automation for updating my Variables + History entity where it stores all of my last known echo volume levels.

image

alias: Alexa - Save Last Volume Level
description: ""
trigger:
  - platform: state
    entity_id:
      - media_player.garage_echo_dot
      - media_player.office_echo_dot_left
      - media_player.office_echo_dot_right
      - media_player.kitchen_echo_dot
      - media_player.living_room_echo_dot_left
      - media_player.living_room_echo_dot_right
      - media_player.bedroom_echo_dot_left
      - media_player.bedroom_echo_dot_right
      - media_player.daniel_s_echo
      - media_player.daniel_s_echo_auto
      - media_player.echo_show_8
    attribute: volume_level
    not_from: 0
    not_to: 0
    id: volume
  - platform: state
    entity_id:
      - sensor.last_alexa
    id: last_alexa
    to: null
condition: []
action:
  - choose:
      - conditions:
          - condition: trigger
            id:
              - volume
        sequence:
          - data:
              value: "{{ trigger.to_state.state }}"
              attributes:
                "{{trigger.entity_id}}": "{{ state_attr(trigger.entity_id,'volume_level') }}"
            target:
              entity_id: sensor.last_alexa_volume
            enabled: true
            action: variable.update_sensor
      - conditions:
          - condition: trigger
            id:
              - last_alexa
        sequence:
          - data:
              entity_id: sensor.last_alexa_volume
              value: "{{ trigger.to_state.state }}"
            action: variable.update_sensor
mode: parallel
max: 10

In your case, you would store the sensor.last_alexa_volume attribute for the device volume in question to your input_number, set a new volume level, then restore the volume back to the value saved in input_number.

Great tip, Daniel.

Thank you very much