# ref https://github.com/Elecrow-RD/CrowPanel-ESP32-Display-Course-File/blob/main/CrowPanel_ESP32_Tutorial/Code/V3.0/Lesson%2013%20ESPHome/Yaml%20Code/3.5HMI.yaml
esphome:
  name: crowpanel
  friendly_name: Crowpanel

esp32:
  board: esp32dev
  framework:
    type: esp-idf

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: !secret api_key

ota:
  - platform: esphome
    password: !secret ota_pass

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

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Crowpanel Fallback Hotspot"
    password: !secret wifi_ap_pass

captive_portal:

psram:
  mode: quad
  speed: 80MHz

spi:
  clk_pin: GPIO14
  mosi_pin: GPIO13
  miso_pin: GPIO12
  interface: hardware

display:
  - platform: mipi_spi
    model: ILI9488_A
    id: display1
    dc_pin: GPIO2
    cs_pin: GPIO15
    invert_colors: false
    show_test_card: false
    auto_clear_enabled: false
    update_interval: never
    data_rate: 40MHz
    spi_mode: mode0
    transform:
      swap_xy: false
      mirror_x: false
      mirror_y: true

lvgl:
    pages:
      - id: main_page
        layout:
          type: flex
          flex_flow: column
          flex_align_main: space_around
          flex_align_track: center
          flex_align_cross: center
        widgets:
          - label:
              height: 30
              width: 320
              id: show_time
              text: "YYYY-MM-DD HH:MM"
              text_font: montserrat_28
              text_align: CENTER
              align: CENTER
          - container:
              height: 180
              width: 320
              widgets:
                - meter:
                    align: CENTER
                    height: 180
                    width: 180
                    scales:
                      - range_from: 0 # scale for the value labels
                        range_to: 110
                        angle_range: 240
                        rotation: 150
                        ticks:
                          width: 1
                          count: 56
                          length: 10
                          color: 0x000000
                          major:
                            stride: 5
                            width: 2
                            length: 10
                            color: 0x404040
                            label_gap: 10
                        indicators:
                          - tick_style:
                              start_value: 0
                              end_value: 110
                              color_start: 0x0000bd
                              color_end: 0xbd0000
                              width: 1
                      - range_from: 0 # scale for the needle value
                        range_to: 110
                        angle_range: 240
                        rotation: 150
                        indicators:
                          - line:
                              id: temperature_needle
                              width: 2
                              color: 0xFF0000
                              length: 96%
                    widgets:
                      - label:
                          id: temperature_text
                          text: "-.-°F"
                          align: CENTER
                          y: 45
                      - label:
                          text: "Outdoor"
                          align: CENTER
                          y: 65
          - container:
              height: 200
              width: 320
              widgets:
                - meter:
                    height: 180
                    width: 180
                    y: 0
                    border_width: 0
                    bg_opa: TRANSP
                    indicator:
                      bg_opa: TRANSP
                    align: CENTER
                    scales:
                      - range_from: -10
                        range_to: 10
                        angle_range: 180 # sets the total angle to 180 = starts mid left and ends mid right
                        indicators:
                          - arc: # first half of the scale background
                              color: 0x00FF00
                              width: 31
                              start_value: -10
                              end_value: 0
                          - arc: # second half of the scale background
                              color: 0xFF3000
                              width: 31
                              start_value: 0
                              end_value: 10
                          - line: # consumption
                              id: val_needle
                              width: 8
                              value: 0
                              rounded: false
                              length: 55
                              radial_offset: 5
                          - line: # production
                              id: val_solar
                              width: 8
                              value: 0
                              rounded: false
                              length: 45
                              radial_offset: 5
                              color: 0xFFFF00
                          - line: # charger
                              id: val_charger
                              width: 5
                              value: 0
                              rounded: false
                              length: 20
                              radial_offset: 70
                              color: 0x0000FF
                - label: # lower range indicator
                    text_font: montserrat_18
                    align: CENTER
                    y: 0
                    x: -90
                    text: "-10"
                - label: # higher range indicator
                    text_font: montserrat_18
                    align: CENTER
                    y: 0
                    x: 90
                    text: "+10"
                - label: # gauge numeric indicator
                    id: val_text
                    y: 20
                    text_font: montserrat_30
                    align: CENTER
                    text: ""
          - label:
              height: 30
              width: 320
              id: val_soc
              text: ""
              text_font: montserrat_28
              text_align: CENTER
              align: CENTER

# Define a PWM output on the ESP32
output:
  - platform: ledc
    pin: GPIO27
    id: backlight_pwm

# Define a monochromatic, dimmable light for the backlight
light:
  - platform: monochromatic
    output: backlight_pwm
    name: "Display Backlight"
    id: back_light
    restore_mode: ALWAYS_ON

sensor:
  - platform: homeassistant
    name: "Outdoor Temperature"
    entity_id: sensor.gw1200b_outdoor_temperature
    on_value:
      then:
        - lvgl.indicator.update:
            id: temperature_needle
            value: !lambda return x;
        - lvgl.label.update:
            id: temperature_text
            text:
              format: "%.1f°F"
              args: [ 'x' ]
  - platform: homeassistant
    name: "Net Power Import"
    entity_id: sensor.envoy_1234_current_net_power_consumption
    on_value:
      then:
        - lvgl.indicator.update:
            id: val_needle
            value: !lambda return x;
        - lvgl.label.update:
            id: val_text
            text:
              format: "%.1f kW"
              args: [ 'x' ]
  - platform: homeassistant
    name: "Solar Production"
    entity_id: sensor.envoy_1234_current_power_production
    on_value:
      then:
        - lvgl.indicator.update:
            id: val_solar
            value: !lambda return -1.0 * x;
  - platform: homeassistant
    name: "Car Charge"
    entity_id: sensor.charger_power_active_import
    on_value:
      then:
        - lvgl.indicator.update:
            id: val_charger
            value: !lambda return x;
  - platform: homeassistant
    name: "Car SOC"
    entity_id: sensor.fordpass_3vin2345
    on_value:
      then:
        - lvgl.label.update:
            id: val_soc
            text:
              format: "SOC %.1f%%"
              args: [ 'x' ]

touchscreen:
  platform: xpt2046
  id: touchscreen1
  cs_pin: GPIO33
  interrupt_pin: GPIO36
  update_interval: 50ms
  threshold: 400
  transform:
    mirror_x: true
  calibration:
    x_min: 300
    x_max: 3800
    y_min: 300
    y_max: 3900

time:
  - platform: sntp
    id: sntp_time
    on_time:
      - seconds: 0
        minutes: '*'
        then:
          - lvgl.label.update:
              id: show_time
              text:
                  time_format: "%Y-%m-%d %I:%M %p"

    on_time_sync:
      then:
        - lvgl.label.update:
            id: show_time
            text:
                time_format: "%Y-%m-%d %I:%M %p"
