esphome / firmware

Holds firmware configuration files for projects that the ESPHome team provides.
https://esphome.io/projects
Apache License 2.0
126 stars 89 forks source link

Feature: Turn off the screen after some time for ESP32-S3-Box-3 #178

Open Gloomyeye opened 3 months ago

Gloomyeye commented 3 months ago

Hello,

it would be great if the screen of the ESP32-S3-Box-3 could be turned off after some time (e.g. 15 sec. after voice execution). In addition, if mute is active, the screen should be off, too.

I added this as an example to the config (marked my lines with "own"):

binary_sensor:
  - platform: gpio
    pin:
      number: GPIO1
      inverted: true
    name: "Mute"
    id: mute_button
    disabled_by_default: true
    entity_category: diagnostic
    on_state: #own
      then:
        - if:
            condition:
              binary_sensor.is_on: mute_button
            then:
              - switch.turn_on: mute
              - light.turn_off: led
            else:
              - switch.turn_off: mute
              - light.turn_on: led

  - platform: gpio
    pin:
      number: GPIO0
      mode: INPUT_PULLUP
      inverted: true
    name: Top Left Button
    disabled_by_default: true
    entity_category: diagnostic
    on_multi_click:
      - timing:
          - ON for at least 10s
        then:
          - button.press: factory_reset_btn
    on_click: #own
      - if:
          condition:
            not:
              - voice_assistant.is_running
          then:
            - if:
                condition:
                  lambda: return id(wake_word_engine_location).state == "In Home Assistant";
                then:
                  # Check if display is off
                  - if:
                      condition:
                        light.is_off: led
                      then:
                        - light.turn_on: led
                  - lambda: id(va).set_use_wake_word(true);
                  - voice_assistant.start_continuous
            - if:
                condition:
                  lambda: return id(wake_word_engine_location).state == "On device";
                then:
                  # Check if display is off
                  - if:
                      condition:
                        light.is_off: led
                      then:
                        - light.turn_on: led
                  - micro_wake_word.stop
                  - delay: 500ms
                  - voice_assistant.start

output:
  - platform: ledc
    pin: GPIO47
    id: backlight_output

light:
  - platform: monochromatic
    id: led
    name: LCD Backlight
    entity_category: config
    output: backlight_output
    restore_mode: RESTORE_DEFAULT_ON
    default_transition_length: 250ms

esp_adf:
  board: esp32s3box3

microphone:
  - platform: esp_adf
    id: box_mic

speaker:
  - platform: esp_adf
    id: box_speaker

micro_wake_word:
  model: ${micro_wake_word_model}
  on_wake_word_detected:
    #own
    # Check if display is off
    - if:
        condition:
          light.is_off: led
        then:
          - light.turn_on: led
    - voice_assistant.start

voice_assistant:
  id: va
  microphone: box_mic
  speaker: box_speaker
  use_wake_word: true
  noise_suppression_level: 2
  auto_gain: 31dBFS
  volume_multiplier: 2.0
  vad_threshold: 3
  on_listening:
    - lambda: id(voice_assistant_phase) = ${voice_assist_listening_phase_id};
    - script.execute: draw_display
  on_stt_vad_end:
    - lambda: id(voice_assistant_phase) = ${voice_assist_thinking_phase_id};
    - script.execute: draw_display
  on_tts_stream_start:
    - lambda: id(voice_assistant_phase) = ${voice_assist_replying_phase_id};
    - script.execute: draw_display
  on_tts_stream_end:
    - lambda: id(voice_assistant_phase) = ${voice_assist_idle_phase_id};
    - script.execute: draw_display
  on_end:
    - if:
        condition:
          and:
            - switch.is_off: mute
            - lambda: return id(wake_word_engine_location).state == "On device";
        then:
          - wait_until:
              not:
                voice_assistant.is_running:
          - micro_wake_word.start:
          - delay: 15s                #own
          - if:
              condition:
                not:
                   - voice_assistant.is_running
              then:
                - light.turn_off: led       #own
  on_error:
    - if:
        condition:
          lambda: return !id(init_in_progress);
        then:
          - lambda: id(voice_assistant_phase) = ${voice_assist_error_phase_id};
          - script.execute: draw_display
          - delay: 1s
          - if:
              condition:
                switch.is_off: mute
              then:
                #own
                # Check if display is off
                - if:
                    condition:
                      light.is_off: led
                    then:
                      - light.turn_on: led
                - lambda: id(voice_assistant_phase) = ${voice_assist_idle_phase_id};
              else:
                - lambda: id(voice_assistant_phase) = ${voice_assist_muted_phase_id};
          - script.execute: draw_display
  on_client_connected:
    - if:
        condition:
          switch.is_off: mute
        then:
          - wait_until:
              not: ble.enabled
          - if:
              condition:
                lambda: return id(wake_word_engine_location).state == "In Home Assistant";
              then:
                - lambda: id(va).set_use_wake_word(true);
                - voice_assistant.start_continuous:
                - delay: 15s                #own
                - if:
                    condition:
                      not:
                        - voice_assistant.is_running
                    then:
                      - light.turn_off: led       #own
          - if:
              condition:
                lambda: return id(wake_word_engine_location).state == "On device";
              then:
                - micro_wake_word.start
                - delay: 15s                #own
                - if:
                    condition:
                      not:
                        - voice_assistant.is_running
                    then:
                      - light.turn_off: led       #own
          - lambda: id(voice_assistant_phase) = ${voice_assist_idle_phase_id};
        else:
          - lambda: id(voice_assistant_phase) = ${voice_assist_muted_phase_id};
    - lambda: id(init_in_progress) = false;
    - script.execute: draw_display
  on_client_disconnected:
    #own
    # Check if display is off
    - if:
        condition:
          light.is_off: led
        then:
          - light.turn_on: led
    - if:
        condition:
          lambda: return id(wake_word_engine_location).state == "In Home Assistant";
        then:
          - lambda: id(va).set_use_wake_word(false);
          - voice_assistant.stop:
    - if:
        condition:
          lambda: return id(wake_word_engine_location).state == "On device";
        then:
          - micro_wake_word.stop
    - lambda: id(voice_assistant_phase) = ${voice_assist_not_ready_phase_id};
    - script.execute: draw_display

Maybe someone can add these features to the ESP32-S3-Box-3 firmware.

cl0ud6uru commented 1 month ago

I wrote an automation that only turns on the screen when assist is in progress, then turns it off a few seconds after assist is no longer in progress. Obviously not part of the firmware, but it's working great for me currently.

alias: Livingroom VA Backlight Control
description: ""
trigger:
  - type: turned_on
    platform: device
    device_id: b40ca6e170336b7ca6a1c16e5e2e52ef
    entity_id: 8709eca0e28b71f644c7576741401433
    domain: binary_sensor
    enabled: true
  - type: turned_off
    platform: device
    device_id: b40ca6e170336b7ca6a1c16e5e2e52ef
    entity_id: 8709eca0e28b71f644c7576741401433
    domain: binary_sensor
    enabled: true
condition: []
action:
  - if:
      - type: is_on
        condition: device
        device_id: b40ca6e170336b7ca6a1c16e5e2e52ef
        entity_id: 8709eca0e28b71f644c7576741401433
        domain: binary_sensor
    then:
      - type: turn_on
        device_id: b40ca6e170336b7ca6a1c16e5e2e52ef
        entity_id: a02e89b34cb689d6bad26e4db25a3b8e
        domain: light
    else:
      - delay:
          hours: 0
          minutes: 0
          seconds: 7
          milliseconds: 0
      - type: turn_off
        device_id: b40ca6e170336b7ca6a1c16e5e2e52ef
        entity_id: a02e89b34cb689d6bad26e4db25a3b8e
        domain: light
mode: single
Gloomyeye commented 1 month ago

Thank you! I created with your template the following automation and this works so far great:

trigger:
  - platform: state
    entity_id:
      - binary_sensor.esp32_s3_voice_assist_01_assist_in_use
    to: "off"
    for:
      hours: 0
      minutes: 0
      seconds: 7
    from: "on"
    id: trigger_turn_off
  - platform: state
    entity_id:
      - binary_sensor.esp32_s3_voice_assist_01_assist_in_use
    to: "on"
    for:
      hours: 0
      minutes: 0
      seconds: 0
    from: "off"
    id: trigger_turn_on
condition: []
action:
  - choose:
      - conditions:
          - condition: and
            conditions:
              - condition: trigger
                id:
                  - trigger_turn_on
              - condition: state
                entity_id: light.esp32_s3_voice_assist_01_lcd_backlight
                state: "off"
        sequence:
          - service: light.turn_on
            metadata: {}
            data: {}
            target:
              entity_id: light.esp32_s3_voice_assist_01_lcd_backlight
        alias: "Trigger: TURN_ON"
      - conditions:
          - condition: and
            conditions:
              - condition: trigger
                id:
                  - trigger_turn_off
              - condition: state
                entity_id: light.esp32_s3_voice_assist_01_lcd_backlight
                state: "on"
        sequence:
          - service: light.turn_off
            metadata: {}
            data: {}
            target:
              entity_id: light.esp32_s3_voice_assist_01_lcd_backlight
        alias: "Trigger: TURN_OFF"
mode: single