esphome:
  name: tab1
  friendly_name: M5Stack Tab5 1

esp32:
  board: esp32-p4-evboard
  flash_size: 16MB
  framework:
    type: esp-idf
    advanced:
      enable_idf_experimental_features: true

esp32_hosted:
  variant: esp32c6
  active_high: true
  clk_pin: GPIO12
  cmd_pin: GPIO13
  d0_pin: GPIO11
  d1_pin: GPIO10
  d2_pin: GPIO9
  d3_pin: GPIO8
  reset_pin: GPIO15
  slot: 1

logger:
  hardware_uart: USB_SERIAL_JTAG

psram:
  mode: hex
  speed: 200MHz

api:

# Touchscreen support
external_components:
  - source: github://pr#12075
    components: [st7123]
    refresh: 1h

ota:
  platform: esphome

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

i2c:
  - id: bsp_bus
    sda: GPIO31
    scl: GPIO32
    frequency: 400kHz

pi4ioe5v6408:
  - id: pi4ioe1
    address: 0x43
    # 0: O - wifi_antenna_int_ext
    # 1: O - speaker_enable
    # 2: O - external_5v_power
    # 3: NC
    # 4: O - lcd reset
    # 5: O - touch panel reset
    # 6: O - camera reset
    # 7: I - headphone detect
  - id: pi4ioe2
    address: 0x44
    # 0: O - wifi_power
    # 1: NC
    # 2: NC
    # 3: O - usb_5v_power
    # 4: O - poweroff pulse
    # 5: O - quick charge enable (inverted)
    # 6: I - charging status
    # 7: O - charge enable

button:
  - platform: restart
    name: "Restart Tablet"

switch:
  - platform: gpio
    id: wifi_power
    name: "WiFi Power"
    pin:
      pi4ioe5v6408: pi4ioe2
      number: 0
    restore_mode: ALWAYS_ON
  - platform: gpio
    id: usb_5v_power
    name: "USB Power"
    pin:
      pi4ioe5v6408: pi4ioe2
      number: 3
  - platform: gpio
    id: quick_charge
    name: "Quick Charge"
    pin:
      pi4ioe5v6408: pi4ioe2
      number: 5
      inverted: true
  - platform: gpio
    id: charge_enable
    name: "Charge Enable"
    pin:
      pi4ioe5v6408: pi4ioe2
      number: 7
  - platform: gpio
    id: wifi_antenna_int_ext
    pin:
      pi4ioe5v6408: pi4ioe1
      number: 0
  - platform: gpio
    id: speaker_enable
    name: "Speaker Enable"
    pin:
      pi4ioe5v6408: pi4ioe1
      number: 1
    restore_mode: ALWAYS_ON
  - platform: gpio
    id: external_5v_power
    name: "External 5V Power"
    pin:
      pi4ioe5v6408: pi4ioe1
      number: 2

binary_sensor:
  - platform: gpio
    id: charging
    name: "Charging Status"
    pin:
      pi4ioe5v6408: pi4ioe2
      number: 6
      mode: INPUT_PULLDOWN

  - platform: gpio
    id: headphone_detect
    name: "Headphone Detect"
    pin:
      pi4ioe5v6408: pi4ioe1
      number: 7

sensor:
  - platform: ina226
    address: 0x41
    adc_averaging: 16
    max_current: 8.192A
    shunt_resistance: 0.005ohm
    bus_voltage:
      id: battery_voltage
      name: "Battery Voltage"
    current:
      id: battery_current
      name: "Battery Current"
      # Positive means discharging
      # Negative means charging

    # Tab5 built-in battery discharges from full (8.23 V) to shutdown threshold (6.0 V)
  - platform: template
    name: "Battery Percentage"
    lambda: |-
      float voltage = id(battery_voltage).state;
      // Adjust these values based on your battery's actual min/max voltage
      float min_voltage = 6.0;  // Discharged voltage
      float max_voltage = 8.23;  // Fully charged voltage
      float percentage = (voltage - min_voltage) / (max_voltage - min_voltage) * 100.0;
      if (percentage > 100.0) return 100.0;
      if (percentage < 0.0) return 0.0;
      return percentage;
    update_interval: 60s
    unit_of_measurement: "%"
    accuracy_decimals: 1

touchscreen:
  - platform: st7123
    i2c_id: bsp_bus
    interrupt_pin: GPIO23
    display: lcd
    update_interval: never
    reset_pin:
      pi4ioe5v6408: pi4ioe1
      number: 5
    calibration:
      x_min: 0
      x_max: 720
      y_min: 0
      y_max: 1280
    id: touch
    on_touch:
      - logger.log: "LVGL resuming"
      - lvgl.resume:
      - light.turn_on: backlight
    on_release:
      - media_player.stop:

esp_ldo:
  - voltage: 2.5V
    channel: 3

display:
  - platform: mipi_dsi
    id: lcd
    dimensions:
      height: 1280
      width: 720
    model: M5STACK-TAB5-V2
    reset_pin:
      pi4ioe5v6408: pi4ioe1
      number: 4

output:
  - platform: ledc
    pin: GPIO22
    id: backlight_pwm
    frequency: 1000Hz

light:
  - platform: monochromatic
    output: backlight_pwm
    name: "Display Backlight"
    id: backlight
    restore_mode: ALWAYS_ON
    default_transition_length: 250ms
    initial_state:
      brightness: "100%"
  - platform: lvgl
    widget: listen_led_widget
    name: LVGL light
    id: listen_led

lvgl:
  byte_order: little_endian

  on_idle:
    timeout: 60s
    then:
      - logger.log: "LVGL is idle"
      - light.turn_off:
          id: backlight
          transition_length: 15s
      - lvgl.pause:
  widgets:
    - led:
        id: listen_led_widget
        align: CENTER
        color: 0xFF0000
        brightness: 0%
        height: 100px
        width: 100px
    - label:
        align: TOP_MID
        id: lbl_status
        text_font: montserrat_48
        text: "IDLE"
    - label:
        align: BOTTOM_LEFT
        id: lbl_version
        text_font: montserrat_12
        text: "v0.1"

# The DAC Output select needs to be manually (or with an automation) changed to `LINE1` for the onboard speaker
select:
  - platform: es8388
    dac_output:
      name: DAC Output
    adc_input_mic:
      name: ADC Input Mic

  - platform: template
    id: wifi_antenna_select
    name: "WiFi Antenna"
    options:
      - "Internal"
      - "External"
    optimistic: true
    on_value:
      - if:
          condition:
            lambda: return i == 0;
          then:
            - switch.turn_off: wifi_antenna_int_ext
          else:
            - switch.turn_on: wifi_antenna_int_ext

i2s_audio:
  - id: mic_bus
    i2s_lrclk_pin: GPIO29
    i2s_bclk_pin: GPIO27
    i2s_mclk_pin: GPIO30

audio_adc:
  - platform: es7210
    id: es7210_adc
    bits_per_sample: 16bit
    sample_rate: 16000

microphone:
  - platform: i2s_audio
    id: tab5_microphone
    i2s_din_pin: GPIO28
    sample_rate: 16000
    bits_per_sample: 16bit
    adc_type: external

audio_dac:
  - platform: es8388
    id: es8388_dac

speaker:
  - platform: i2s_audio
    id: tab5_speaker
    i2s_dout_pin: GPIO26
    audio_dac: es8388_dac
    dac_type: external
    channel: mono
    buffer_duration: 100ms
    bits_per_sample: 16bit
    sample_rate: 48000

media_player:
  - platform: speaker
    name: None
    id: tab5_media_player
    announcement_pipeline:
      speaker: tab5_speaker
      format: WAV

micro_wake_word:
  id: mww
  models:
    - okay_nabu
    - hey_mycroft
    - hey_jarvis
  on_wake_word_detected:
    - voice_assistant.start:
        wake_word: !lambda return wake_word;

voice_assistant:
  id: va
  microphone: tab5_microphone
  media_player: tab5_media_player
  micro_wake_word: mww
  on_listening:
    - if:
        condition: lvgl.is_paused
        then:
          - logger.log: "LVGL resuming"
          - lvgl.resume:
          - light.turn_on: backlight
    - light.turn_on:
        id: listen_led
        brightness: 100%
        red: 0%
        green: 100%
        blue: 0%
        effect: "None`"
    - lvgl.label.update:
        id: lbl_status
        text: "LISTENING"
  on_stt_vad_end:
    - light.turn_on:
        id: listen_led
        brightness: 100%
        red: 0%
        green: 0%
        blue: 100%
        effect: "None"
    - lvgl.label.update:
        id: lbl_status
        text: "PROCESSING"
  on_tts_start:
    - light.turn_on:
        id: listen_led
        brightness: 100%
        red: 100%
        green: 0%
        blue: 0%
        effect: "None"
    - lvgl.label.update:
        id: lbl_status
        text: "RESPONDING"
  on_end:
    # Wait a short amount of time to see if an announcement starts
    - wait_until:
        condition:
          - media_player.is_announcing:
        timeout: 0.5s
    # Announcement is finished and the I2S bus is free
    - wait_until:
        - and:
            - not:
                media_player.is_announcing:
            - not:
                speaker.is_playing:
    - micro_wake_word.start:
    - lvgl.led.update:
        id: listen_led_widget
        color: 0x000000
        brightness: "0%"
    - lvgl.label.update:
        id: lbl_status
        text: "IDLE"
    - light.turn_off:
        id: backlight
        transition_length: 15s
  on_client_connected:
    - micro_wake_word.start:
  on_client_disconnected:
    - micro_wake_word.stop:
