- alias: Now playing → ESPHome cover (PNG) triggers: - entity_id: media_player.wrover2 trigger: state conditions: - condition: template value_template: "{{ trigger.from_state and trigger.to_state and\n trigger.from_state.attributes.entity_picture\ \ != trigger.to_state.attributes.entity_picture and\n state_attr('media_player.wrover2','entity_picture')\ \ not in [None, ''] }}\n" actions: - variables: base: http://homeassistant.local:8123 ep: '{{ state_attr(''media_player.wrover2'',''entity_picture'') }}' remote: '{{ state_attr(''media_player.wrover2'',''media_image_url'') }}' remote_ok: '{{ is_state_attr(''media_player.wrover2'',''media_image_remotely_accessible'', true) and remote not in [None, ''''] }}' src_url: "{% if remote_ok %}{{ remote }} {% else %}\n {% if ep.startswith('http')\ \ %}{{ ep }}{% else %}{{ base ~ ep }}{% endif %}\n{% endif %}\n" bust: '{{ now().timestamp() | int }}' final_url: '{{ base ~ ''/local/slides/nowplaying.png?t='' ~ bust }}' - data: url: '{{ src_url }}' subdir: slides filename: _incoming.bin overwrite: true action: downloader.download_file - delay: 00:00:01 - action: shell_command.normalize_image_from_tmp data: {} - action: shell_command.cleanup_incoming data: {} - delay: 00:00:01 - data: url: '{{ final_url }}' action: esphome.esphome_web_0bac48_show_fullscreen_image mode: single - alias: request_response_to_dashboard description: '' triggers: - trigger: state id: request entity_id: sensor.esphome_web_e9f624_text_request - trigger: state id: response entity_id: sensor.esphome_web_e9f624_text_response conditions: [] actions: - choose: - conditions: - condition: trigger id: request - condition: template value_template: '{{ trigger.to_state.state != ''...'' }}' sequence: - action: input_text.set_value target: entity_id: input_text.airesponse data: value: '{{ ''You: '' ~ trigger.to_state.state }}' - conditions: - condition: trigger id: response - condition: template value_template: '{{ trigger.to_state.state != ''...'' }}' sequence: - action: input_text.set_value target: entity_id: input_text.airesponse data: value: '{{ ''AI: '' ~ trigger.to_state.state }}' mode: single type: markdown content: '# {{ states(''input_text.airesponse'') }}' grid_options: columns: 12 rows: 7 - alias: jarvis voice light when thinking description: '' triggers: - trigger: state entity_id: - assist_satellite.jarvis_voice_assist_satellite to: processing conditions: [] actions: - action: light.turn_on metadata: {} data: {} target: entity_id: light.esphome_web_0bac48 - wait_for_trigger: - trigger: state entity_id: - assist_satellite.jarvis_voice_assist_satellite to: responding - action: light.turn_off metadata: {} data: {} target: entity_id: light.esphome_web_0bac48 mode: single - alias: Taichi v1 Swipe description: '' triggers: - trigger: state entity_id: - binary_sensor.esphome_web_e9f624_swipe_left to: 'on' id: left - trigger: state entity_id: - binary_sensor.esphome_web_e9f624_swipe_right to: 'on' id: right - trigger: state entity_id: - binary_sensor.esphome_web_e9f624_swipe_up to: 'on' id: up - trigger: state entity_id: - binary_sensor.esphome_web_e9f624_swipe_down to: 'on' id: down conditions: [] actions: - choose: - conditions: - condition: trigger id: - up sequence: - action: select.select_next metadata: {} data: cycle: true target: entity_id: select.esphome_web_e9f624_clock_wallpaper_online - conditions: - condition: trigger id: - down sequence: - action: switch.toggle metadata: {} data: {} target: entity_id: switch.esphome_web_e9f624_show_battery_status - conditions: - condition: trigger id: - left sequence: - action: select.select_next metadata: {} data: cycle: true target: entity_id: select.esphome_web_e9f624_clock_style - conditions: - condition: trigger id: - right sequence: - action: select.select_previous metadata: {} data: cycle: true target: entity_id: select.esphome_web_e9f624_clock_style mode: single - alias: Talk to (dynamic, Xiaozhi Taichi Pi) mode: single triggers: - trigger: conversation command: - talk to {name} - let me talk to {name} - switch to {name} - i want to talk to {name} variables: select_entity: select.xiaozhi_taichi_pi_assistant spoken_raw: '{{ trigger.slots.name | default(trigger.sentence, true) }}' spoken: '{{ (spoken_raw | lower | trim) }}' opts: '{{ state_attr(select_entity, ''options'') or [] }}' chosen: "{% set s = spoken %} {% set found = namespace(v='') %}\n{# 1) exact (case-insensitive)\ \ #} {% for o in opts %}\n {% if o | lower == s %}\n {% set found.v = o\ \ %}\n {% endif %}\n{% endfor %}\n{# 2) contains / contained-by (handles \"\ harley\", \"harley quinn\") #} {% if not found.v %}\n {% for o in opts %}\n\ \ {% set ol = o | lower %}\n {% if s in ol or ol in s %}\n {% set\ \ found.v = o %}\n {% break %}\n {% endif %}\n {% endfor %}\n{% endif\ \ %}\n{# 3) common nicknames: drop words like \"assistant\" #} {% if not found.v\ \ %}\n {% set s2 = s\n | replace(' assistant','')\n | replace(' the ','\ \ ')\n | trim %}\n {% for o in opts %}\n {% set ol = o | lower %}\n \ \ {% if s2 in ol or ol in s2 %}\n {% set found.v = o %}\n {% break\ \ %}\n {% endif %}\n {% endfor %}\n{% endif %}\n{# 4) fallbacks: \"preferred\"\ \ if present, else first option #} {% if not found.v %}\n {% if 'preferred'\ \ in opts %}\n {% set found.v = 'preferred' %}\n {% else %}\n {% set\ \ found.v = (opts | first) if (opts | count) > 0 else '' %}\n {% endif %}\n\ {% endif %} {{ found.v }}\n" conditions: - condition: template value_template: '{{ chosen | length > 0 }}' actions: - action: select.select_option target: entity_id: '{{ select_entity }}' data: option: '{{ chosen }}' - set_conversation_response: Okay, switching to {{ chosen }}.