The generic version of my question is how can I use the Home Assistant area as a variable within an ESPHome config, such that if I change the ESPHome device area within HA the functionality changes?
- homeassistant.service:
service: media_player.play_media
data:
media_content_type: music
media_content_id: https://github.com/esphome/firmware/raw/main/voice-assistant/sounds/timer_finished.wav
target:
area_id: !lambda 'return device_area;' # <- something like this
My specific use case is as follows: I have a number of M5 Stack Atom Echos that I intend to use as voice assistants, but I want the replies to come over media players in the same room as the Echo, I would like to be able to use the same firmware for each, but instead I have to hardcode the media_player.x for each device.
substitutions:
name: m5stack-atom-echo-b836b0
friendly_name: M5Stack Atom Echo b836b0
packages:
m5stack.atom-echo-voice-assistant: github://esphome/firmware/voice-assistant/m5stack-atom-echo.yaml@main
esphome:
name: ${name}
name_add_mac_suffix: false
friendly_name: ${friendly_name}
api:
encryption:
key: +myAPIkey=
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Until https://github.com/esphome/firmware/pull/233 is fixed/merged
update:
- platform: http_request
id: !remove update_http_request
# HarvsG's customisations
speaker:
- platform: i2s_audio
id: !extend echo_speaker
i2s_dout_pin: GPIO21 # <- It is actually on 22, so this disables the speaker
dac_type: external
mode: mono
voice_assistant:
on_tts_end:
- homeassistant.service:
service: media_player.play_media
data:
entity_id: media_player.study_speaker # <- this is hard-coded
media_content_id: !lambda 'return x;'
media_content_type: music
announce: "true"
I’m not sure this achieves what I was looking for - I was hoping to retrieve, and then use, the area of the ESP device from home assistant.
I’m not sure I see an advantage of specifying the value in a separate yaml file is?
Edit:
I now have a better idea of what you are saying -
to use this Home Assistant Text Sensor — ESPHome, however unfortunately area is not an attribute of an entity. And specifying a custom_area for each device is not much better than hard coding it in the ESP home config.
I was just exploring this idea. However again, I’m looking to create a esphome.yaml config that can be shared and does not require much user-config. If I could create the JINJA template helper from within ESPHome - that would be a solution.
But how can I configure it so that a user can input a field in the HA UI in the same way I get specify an input on this drop down menu? What home-assistant would call input_text.
Sorry, I don’t really get your question. Configure what and where in HA or ESPHome ?
FYI: you can also use service in esphome and even create your own service.
The title and the psuedo code in the first post make it clear - I think. I want to use the area of the esphome device in a service call to home assistant.
My aim is to have an esphome.yaml that causes text-to-speech to play on a media player (a google home mini) in the same room as the esphome device. I want to achieve that automatically without having to manually create helpers in home assistant, or hard-code values into esphome.yaml on a per-device basis.
That way if I move the device area in the HA UI, it magically starts replying on a different speaker.
In psuedocode, it would look like this
substitutions:
name: m5stack-atom-echo-b836b0
friendly_name: M5Stack Atom Echo b836b0
packages:
m5stack.atom-echo-voice-assistant: github://esphome/firmware/voice-assistant/m5stack-atom-echo.yaml@main
esphome:
name: ${name}
name_add_mac_suffix: false
friendly_name: ${friendly_name}
api:
encryption:
key: +myAPIkey=
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Until https://github.com/esphome/firmware/pull/233 is fixed/merged
update:
- platform: http_request
id: !remove update_http_request
# HarvsG's customisations
speaker:
- platform: i2s_audio
id: !extend echo_speaker
i2s_dout_pin: GPIO21 # <- It is actually on 22, so this disables the speaker
dac_type: external
mode: mono
voice_assistant:
on_tts_end:
- homeassistant.service:
service: media_player.play_media
data:
media_content_id: !lambda 'return x;'
media_content_type: music
announce: "true"
target:
area_id: !lambda " return thisdevice.homeassistant_area;" # <-pseudo code
And are you sure to have only one media_player in a room ?
Or you want to play on all media_player of that room ? (I saw in one of my room more than one, so just asking)
My question was for the topic just upper, the main goal, I understood
Thank you for your time. But please do read the OP, I am trying to find a way of doing this without having to change the area in the YAML every time my device moves room - which may be multiple times a day - I want it to get it’s own device area from HA, which can easily be adjusted in the UI.
Have you tested the code above?
In the example above, the last “Light Input Text” switch will take the area you enter in the “Media Player” field, so every time you move the device around, you change the “Media Player” field using the UI.
If you don’t want to type the area manually, you can hardcode all areas in a “Template select”
Please accept my unreserved apologies for doing exactly what I accused you of. I didn’t scroll down through your code block to see your example using templates. I have now implemented this and it is working well. Thank you for your time - very helpful.
The home assistant API has an /api/template endpoint which renders and returns a template. So a call to the api with {{area_name('binary_sensor.m5stack_atom_echo_b836b0_assist_in_progress')}} would return the device location. I just need to work out if this has been implemented on the esphome side.