Alexa Speak entity attributes. A Speech Engine

Tags: #<Tag:0x00007f739eb95528>

Thanks for updating the code. I think the b & B is reversed. With the code below, the numbers match with the entity attributes.

- (e08f) light is (e08B) % brightness with brightness level set at (e08b)

I have also adjust the code to fit my needs. Some of the friendly names have _ underscores. I adjust the code with replace('_', ' ') here:

{% set obj = state_attr(ent,"friendly_name")|replace('_', '  ')  %}

Some of the temperature sensors outputs as 29.64. I adjusted the code to omit the last digit with [0:4] here:

{% set enum = obj[2:4]|int %}
{% set ent = elist[enum] %}
{% set state = states(ent)[0:4] %}
{% if state == None %}

I have added the dummy light to emulated hue. Set up some routines. It plays, but it is playing from the last device set in HA and not from the device I am talking to.

Yes quite right with b and B will update the docs not sure now might have a bug let me check

Good idea on friendly_name, I will add that to the code.

Try using {% set state = states(ent)|round(1) %}. The state result does not have to be a number but could be a string, your code would restrict all states lengths… Round() does not apper to have any effect on a string value . It will also give a correct rounded result .

The last Alexa sensor determines the last device spoken to. You need to check this is working. You can of course fix the code to speak to a single device. I have had no issues with this sensor , but I only have three devices

I also have 3 alexa devices and have checked the alexa_media.update_last_called in developer tool. It does list the last device called. Maybe I am not understanding what this code is doing. Can you break down this code especially where it says first? I am not sure what that do.

{{ states.media_player | selectattr('attributes.last_called','eq',True) | map(attribute='entity_id') | first }}

As I am reading your other post, the more I think last_alexa is working as it should, but I am expecting it to do what I want and it cannot.

So, what I am hoping it does is to reply back from the device and I am talking to and not to the device stated in sensor.last_alexa.

That is if the last call is B device. I am talking to A device, it will reply from B device. Is that how it works?

I am thinking whichever device I am talking too (A), it will reply from that same device(A) regardless if the last device is from a different location (B).

NO is should work as you expected , the last alexa should be the alexa you triggered the routine from.

Much as I would to take credit the last alexa sensor is not my work ,

@petro came up with this elegant solution, much better than my attempt. It now in included in the Wiki for the alexa component

I have never had an issue whenever I call a routine from alexa , the last alexa sensor always seems to work… How bad is the lag ? . Are you sure the Entity_id match your alexa media players ?

Edit: have a look at calling the service alexa_media.update_last_called might force an update

@lonebaggie
I knew I wasn’t losing my mind. Before I setup your speech engine, I have the last _alexa sensor setup and I knew it was working for that few days of testing. From then and now, I added your script and a few updates of supervisor and HassOS it broke the alexa_media.update_last_called I wasn’t aware of.

There was an update of HassOS 4.13 today. I figure I would update and to see it this will fix the issue. It did!! Now, I call the routine from any devices and it reply from the same device.

Thanks for the support.

1 Like

No . Thankyou your suggestions have improved and found various bugs in my code.

Can I ask if you think this approach is correct trying to make generic code or is the code and setup to complex to make the effort worthwile ? . I had a lot of fun coding and “bending” the YAML automation to manage this, but I keep thinking about “sledgehammers” and “nuts”
:slight_smile:

I think there is a typo in the code. garage-door should be garage_door ??

            {% if devtype in ["opening","window","door","garage-door"] %}
              {% set obj = obj|replace('off','closed') %}
              {% set obj = obj|replace('on','open') %}
            {% endif %}

Correct again will update :slight_smile:

At first, I thought it is a bit much for one or 2 lines. But it may benefit down the road when you add more devices. Instead of adding bits of codes in several different files, you need to add it to one file.

The counting of the lines confuses me at times especially when i edit the the entity_id and the # order changes. This is a learning curve for me away.

I was trying to study the code and customize one of the entity, but unsuccessful. I created a bed sensor that detects if someone is in bed or not. I wanted to change the states to

off = not sleeping
on = sleeping

So I tried adding this code, but it is still saying on or off.

             {% if devtype in ["problem"] %}
              {% set obj = obj|replace('off','not sleeping') %}
              {% set obj = obj|replace('on','sleeping') %}
            {% endif %}

group.bed_sensors:

entity_id:
  - binary_sensor.top
  - binary_sensor.middle
order: 27
friendly_name: Bed Sensors
device_id: problem

This is based on device class see

You could try customizing the device_class attribute in the bed sensor to “problem” , or just change the replace clause on an existing device_class . You must ensure your bed sensor has a device_class set.

PS If you set the device_class for all your entries you expose to Alexa , you get the correct icon in the app

Yea, I did customize a device_class to problem for the sensor. In the developer tools I see the change. While testing, it still say on / off.

I was looking at the same link. That was how I found the typo.

Have had a major rewrite of the code . Reduced the size by about 30 lines . Have rewritten the loop . Rather than chop everything into words to find the () .It now finds the positions of the () directly , this reduces the of loops to the minimum required. This was tricky as Jinja 2 does not support while loops, and there is no fixed number of () you can have in a sentence . NO new features , but hopefully a little quicker, and the logic is much simpler.

Looking to see if I can use the new variables feature in Yaml scripting. May be able to create scripts that accept the numerical value to trigger the input select.

I didn’t see the new post until now. Will try out the new code. Are on 0.115+? I cannot find the reload automation button anymore. We need to restart HA for any automation change in yaml file now?

Nevermind. The automation tab is back when I updated to 0.115.2.

I think you have a typo in your first post. :smiley:

{td) = Current date <----

s= state with unit of measure added
$= Sate only <-----
f= friendly name
b= brightness (%)
B= brightness (level)
[0-9] = attribute number

The new code is working on my end. :+1:
Really need to find a way to parse the , . as a pause. A nice enhancement to the speech engine.

Thanks again, Will update

If you switch to the announce feature all punctuation including SSLM will work.

- service: notify.alexa_media_lr_echo
    data_template:
      data: {"type":"announce", "method":"all"}
      message: >

Ive tried playing with adding pauses in the automation for the TTS , but this involes sending two+ messages to Alexa and this slow things down too much, as it neeeds about 2 seconds to ‘digest’ and start speaking , that why I add a ‘please wait’ response from the Alexa app routine before I trigger the dummy bulb , to cover the silence.

If you have any ideas , I can have a look

Keen to give this a go, have got as far as setting up Last Alexa and now have no idea what is going on.

Any chance you could dumb this down just to trigger one reply so I can (hopefully) get a grip of what is going on and scale up from there?

No problem.

It works in two parts .

first part

Item select to speak.yaml

This automation use two input selects to hold the data and extracts the attributes from the entities listed (entity_list ) and convents them into a readable format for alexa to speak (speak list).

The entity_list

Holds all the entities you want alexa to speak . These are referenced from 0 so in my example list entity 0 (e00) is binary_sensor.front_door and entity 4 (e04) is light.living_room

The speak list

This holds the sentences you want alexa to speak . Every thing inside the brackets is replaced with data from the entities list or HA time and date. Again the list starts from 0. The first entry in speak list must be do not use. as it is used by the automation . So the real trick here is you have 99 different messages you can call from the input select or use a number from 1 to 99 to select the message.

The codes inside the brackets will extract information from the entities in the entity_list.

So normally if you were sending a message to alexa or anything else you would need some coding wizardry to extract the data . So you can replace

“The patio door is {{states.binary_sensor.patio_door.state|replace(‘off’,‘closed’)|replace(‘on’,‘open’)}}”

with

“The patio door is (e01s)”

My code handles all device types and unit of measure . It can also be polite and say morning, afternoon or evening depending on time of day.

Second part

Dummy lights to item select.yaml

This automation uses the dummy light trick . If you create a template light with nothing in it. You can use the brightness level 1 to 99 to trigger the input select , so brightness 1 selects input select speak_list option 1 and so on

If you get Alexa to recognise this light ( Alexa cannot see input selects). You can use the alexa app on your phone to program a routine to trigger the bulb.

So in your alexa app you can program for example “is the patio door open” and get the alexa app to set the bulb to brightness that matches the speak_list “The patio door is (e01s)”

So now you can get alexa to speak any attribute without coding . You can change the lists in the file editor and test simply by selecting the speak_list in lovelace.

Simple example

entity_list:
    name : Entity List
    options:
      - binary_sensor.front_door
speak_list:
    name: Speak List
    options:
      - do not use
      - Good (gr) the (e00f) is currently (e00s)

This will send the following message “Good evening the front door is currently closed”

1 Like

Much appreciated, will let you know how I get on :+1:

Have added new chain option which link two or more speak lines together . It will also add a pause if you play with the delay option in the automation.

cool beans. will test it out when I get the chance.