Room Detection Using Alexa last_called

Hi All,

My apologies ahead of time for the long post, but I want to make sure I provide as much info as possible.

I have a script that currently runs as a Alexa scene to change my TV Live stream channel on my Roku device, and it works great!

Now I have several Roku devices in the house, and Alexa devices in each room.

I would like to take this script further by having it detect which Alexa device heard me, and depending on the Alexa device, populate a variable for my entity_id’s in the script with the proper Roku device.

Example: From my bedroom, “Alexa, turn on Hallmark Channel”, and Alexa runs the script. The script determines which Alexa device was called, and the entity_id is passed to a variable to make sure the correct Roku device has the channel changed.

I have done some research, and see that this can be accomplished using Alexa last_called attribute for the Alexa devices.

I already have a echo group yaml created for my Alexa devices:

echos:
    name: All Echos
    entities:
      - media_player.master_bedroom_echo
      - media_player.living_room_echo
      - media_player.kitchen_echo_show
      - media_player.guest_room_echo
      - media_player.family_room_echo_dot

And have a sensor created:

template:
  - sensor:
      - name: last_alexa
        state: >
          {{ expand('group.echos') | selectattr('attributes.last_called','eq',True) | map(attribute='entity_id') | first }}
        availability: >
          {{ expand('group.echos') | selectattr('attributes.last_called','eq',True) | first is defined }}

My issue is that I just can’t seem to figure out how to make this work in my script.

What I do know is that the code should be placed before the if statement is called.

I have read through some posts, but I am unable to find anything close enough to what I am trying to do.

Here is my current script:

hallmark_channel:
  alias: Hallmark Channel
  sequence:
  - if:
    - condition: not
      conditions:
      - condition: state
        entity_id: media_player.roku_streambar
        attribute: app_name
        state: Frndly TV
    then:
    - service: media_player.play_media
      target:
        entity_id: media_player.roku_streambar
      data:
        media_content_id: '298229'
        media_content_type: app
      metadata:
        title: Frndly TV
        thumbnail: !secret roku_streambar_thumbnail
        media_class: app
        children_media_class:
        navigateIds:
        - {}
        - media_content_type: apps
          media_content_id: ''
    - delay:
        hours: 0
        minutes: 0
        seconds: 6
        milliseconds: 0
    - service: remote.send_command
      data:
        command: down
        num_repeats: 3
      target:
        entity_id: remote.roku_streambar
    - delay:
        hours: 0
        minutes: 0
        seconds: 2
        milliseconds: 0
    - service: remote.send_command
      data:
        command: select
      target:
        entity_id: remote.roku_streambar
    - delay:
        hours: 0
        minutes: 0
        seconds: 2
        milliseconds: 0
    - service: remote.send_command
      data:
        command: select
      target:
        entity_id: remote.roku_streambar
    else:
    - service: remote.send_command
      data:
        command: down
      target:
        entity_id: remote.roku_streambar
    - delay:
        hours: 0
        minutes: 0
        seconds: 2
        milliseconds: 0
    - service: remote.send_command
      data:
        command: down
      target:
        entity_id: remote.roku_streambar
    - delay:
        hours: 0
        minutes: 0
        seconds: 2
        milliseconds: 0
    - service: remote.send_command
      data:
        command: down
      target:
        entity_id: remote.roku_streambar
    - delay:
        hours: 0
        minutes: 0
        seconds: 2
        milliseconds: 0
    - service: remote.send_command
      data:
        command: select
      target:
        entity_id: remote.roku_streambar
    - delay:
        hours: 0
        minutes: 0
        seconds: 6
        milliseconds: 0
    - service: remote.send_command
      data:
        command: down
        num_repeats: 3
      target:
        entity_id: remote.roku_streambar
    - delay:
        hours: 0
        minutes: 0
        seconds: 2
        milliseconds: 0
    - service: remote.send_command
      data:
        command: select
      target:
        entity_id: remote.roku_streambar
    - delay:
        hours: 0
        minutes: 0
        seconds: 2
        milliseconds: 0
    - service: remote.send_command
      data:
        command: select
      target:
        entity_id: remote.roku_streambar
  mode: single

Can someone possibly point me in the right direction to get to my goal?
Any advice and help would be much appreciated.

Thanks in advance :slight_smile:

There are a number of ways to do this covered in the Room-Aware Automation Examples. Depending on how you set up your Alexas and Rokus in Home Assistant one or more of those methods may be inappropriate. The following automation requires that you assign an area to each of your Alexa devices.

hallmark_channel:
  alias: Hallmark Channel
  variables:
    alexa_area: "{{ area_name(states('sensor.last_alexa')) }}"
    device:
      Living Room: 'roku_streambar'
      Bedroom: 'roku_bedroom'
      Kitchen: 'roku_kitchen'
    active: '{{ device.get(alexa_area) }}'
    roku: 'media_player.{{- active }}'
    remote: 'remote.{{- active }}'
  sequence:
  - if:
    - "{{ not is_state_attr( roku, 'app_name', 'Frndly TV') }}"
    then:
    - service: media_player.play_media
      target:
        entity_id: '{{ roku }}'
      data:
        media_content_id: '298229'
        media_content_type: app
      metadata:
        title: Frndly TV
        thumbnail: !secret {{active}}_thumbnail
        media_class: app
        children_media_class:
        navigateIds:
        - {}
        - media_content_type: apps
          media_content_id: ''
    - delay:
        hours: 0
        minutes: 0
        seconds: 6
        milliseconds: 0
    - service: remote.send_command
      data:
        command: down
        num_repeats: 3
      target:
        entity_id: '{{ remote }}'
    - delay:
        hours: 0
        minutes: 0
        seconds: 2
        milliseconds: 0
    - service: remote.send_command
      data:
        command: select
      target:
        entity_id: '{{ remote }}'
    - delay:
        hours: 0
        minutes: 0
        seconds: 2
        milliseconds: 0
    - service: remote.send_command
      data:
        command: select
      target:
        entity_id: '{{ remote }}'
    else:
    - service: remote.send_command
      data:
        command: down
      target:
        entity_id: '{{ remote }}'
    - delay:
        hours: 0
        minutes: 0
        seconds: 2
        milliseconds: 0
    - service: remote.send_command
      data:
        command: down
      target:
        entity_id: '{{ remote }}'
    - delay:
        hours: 0
        minutes: 0
        seconds: 2
        milliseconds: 0
    - service: remote.send_command
      data:
        command: down
      target:
        entity_id: '{{ remote }}'
    - delay:
        hours: 0
        minutes: 0
        seconds: 2
        milliseconds: 0
    - service: remote.send_command
      data:
        command: select
      target:
        entity_id: '{{ remote }}'
    - delay:
        hours: 0
        minutes: 0
        seconds: 6
        milliseconds: 0
    - service: remote.send_command
      data:
        command: down
        num_repeats: 3
      target:
        entity_id: '{{ remote }}'
    - delay:
        hours: 0
        minutes: 0
        seconds: 2
        milliseconds: 0
    - service: remote.send_command
      data:
        command: select
      target:
        entity_id: '{{ remote }}'
    - delay:
        hours: 0
        minutes: 0
        seconds: 2
        milliseconds: 0
    - service: remote.send_command
      data:
        command: select
      target:
        entity_id: '{{ remote }}'
  mode: single

Hi Didgeridrew,

For some reason I didn’t see the example page. So thank you for the link :slight_smile:

I attempted to try the code you presented, but unfortunately I get the following error:

Invalid config for [script]: Entity {{ roku }} is neither a valid entity ID nor a valid UUID for dictionary value @ data[‘sequence’][0][‘if’][0][‘conditions’][0][‘entity_id’]. Got None. (See /config/configuration.yaml, line 51).

Please paste your actual automation, not the example… you need to make sure that the device variable map has all your areas and their corresponding roku object ids.

I actually figured it out. The issue was actually with a typo in my last_alexa sensor, that was causing everything to fail.

The good news is it seems to work, but I ran into the same issue that appears to be what a lot of people are having with the update of the last_called attribute, where it can take anywhere from a split second up to around 1 minute.

I hope Amazon fixes their api for this issue soon, as it this obviously makes my script pointless.

Thank you so much for your help on this though. You have been very helpful. :slight_smile:

I’ve been playing around and testing the ‘last_alexa’ attribute update issue, and notice that there is 1 attribute called ‘media_position_updated_at’ for my Alexa devices that updates practically immediately once I mention her name.

This got me wondering if anyone thinks that it might be possible to use it somehow through the use of a binary sensor and triggers?

If a custom binary attribute were created for the Alexa devices, would it be possible to monitor the ‘media_position_updated_at’ property for any update change, and if it changes, trigger a script that sets the custom attribute as true for that device, and sets the custom attribute to false for all other Alexa devices.

I’m just spit balling here obviously, and I have yet to try it, but just wondering if anyone had any input?

It may also be that I might be missing something in my logic that will not make this possible.

Any thoughts?

I keep reading about a sensor.last_called for alexa, but this does not exist (anymore?) How tdo we now determine which alexa device was given a command so as to have the same device respond?

What do you mean it doesn’t exist?

I mean, in my list of sensors, I do not have one labeled sensor.last_called

It has always been something you have to configure as a template sensor.

Home · custom-components/alexa_media_player Wiki · GitHub

Do you have one configured and it’s not working, or do you need help setting it up?

It’s downloaded and configured. I have 15 devices. No sensor.last_called

Just to clarify, the sensor is not created automatically just because you have configured the integration. You have to add the configuration of the sensor to your configuration.yaml ot templates.yaml file. If you have added the sensor configuration, restarted HA, and the sensor is not being created you should post your sensor configuration so we can see if there are any issues.

OK Thanks. That’s the issue. How do I add the sensor. I assume there are instructions somewhere.

See the link 4 posts above.

Got it. Thanks for your help.