esphome:
  name: display
  friendly_name: DISPLAY

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:
  level: WARN

# Enable Home Assistant API
api:
  encryption:
    key: "S9zpaMdXsTbjQE5QTWJ2SN3sdSlTEnSomw/PnbwyMZc="

ota:
  platform: esphome
  password: !secret ota

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

  ap:
    ssid: "Display Fallback Hotspot"
    password: "ajRx8MZPIszl"
    
spi:
  clk_pin: 18
  mosi_pin: 23
  miso_pin: 19

# Display configuration
display:
  - platform: ili9xxx
    model: st7789v
    dimensions:
      height: 320
      width: 240
      offset_height: 0
      offset_width: 0
    rotation: 0
    color_order: bgr
    invert_colors: false
    data_rate: 80MHz
    cs_pin: 5
    dc_pin: 16
    reset_pin: 4
    lambda: |-
      // Define row positions
      int margin = 5;
      int y_step = 30;
      int screen_width = 240;
      int row_y = margin + 25;
      int col_offset = margin + 25;
      int icon_size = y_step * 0.75;
      int col;

      // Calculate column and row positions
      int col_array[] = {margin, col_offset + y_step, col_offset + y_step * 2, col_offset + y_step * 3, col_offset + y_step * 5, col_offset + y_step * 7};

      // Clear screen
      it.fill(Color(0, 0, 0));

      // Function to calculate row position
      auto row_calc = [&](int row_in) {
        if (row_in == 0) {
          return margin;
        } else {
          return row_y + y_step * (row_in - 1);
        }
      };

      // Function to handle all state conditions
      auto handle_state = [&](int col_index, int row_index, std::string text, std::string type) {

        // Calculate center of column
        int center = ((col_array[col_index] + col_array[col_index + 1]) / 2) - 10;

        // Check if text is a number and add unit        
        if (text != "unavailable" && text != "unknown" && text != "") {
            if (type == "temperature") {
                text = text + "°C";
            } else if (type == "humidity") {
                text = text + "%";
            }
        }
        
        if (text == "unavailable" || text == "unknown") {
          if (id(triangle_visible)) {
            it.filled_triangle(center, row_calc(row_index) + icon_size, center + icon_size, row_calc(row_index) + icon_size, center + (icon_size / 2), row_calc(row_index), Color(255, 0, 0));
            it.print((center + icon_size / 3) + 1, row_calc(row_index), id(my_font), Color(255, 255, 255), "!");
          }
        } else if (text == "" && type == "door" || text == "" && type == "motion") {
          it.filled_rectangle(col_array[col_index], row_calc(row_index), icon_size, icon_size, Color(128, 128, 128));
        } else if (text == "on") {
          it.filled_rectangle(col_array[col_index], row_calc(row_index), icon_size, icon_size, Color(0, 255, 0));
        } else if (text == "off") {
          it.filled_rectangle(col_array[col_index], row_calc(row_index), icon_size, icon_size, Color(255, 0, 0));
        } else if (type == "icon") {
          it.print(center, row_calc(row_index), id(icon_font), Color(255, 255, 255), text.c_str());
        } else {
          it.print(col_array[col_index], row_calc(row_index), id(my_font), Color(255, 255, 255), text.c_str());
        }
      };

      // Room names (column 0)
      col = 0;
      handle_state(col,0, "󰚡", "icon");
      handle_state(col,1, "Bath", "name");
      handle_state(col,2, "Hall", "name");
      handle_state(col,3, "Kitch", "name");;
      handle_state(col,4, "Tom", "name");
      handle_state(col,5, "Mate", "name");

      // Door status (column 1)
      col = 1;
      handle_state(col, 0, "󰠚", "icon");
      handle_state(col, 1, id(bath_door_status).state, "door");
      handle_state(col, 2, id(hall_door_status).state, "door");
      handle_state(col, 3, "", "door");
      handle_state(col, 4, id(tomek_door_status).state, "door");
      handle_state(col, 5, id(mateusz_door_status).state, "door");

      // Motion status (column 2)
      col = 2;
      handle_state(col, 0, "󰶑", "icon");
      handle_state(col, 1, id(bath_motion_status).state, "motion");
      handle_state(col, 2, id(hall_motion_status).state, "motion");
      handle_state(col, 3, id(kitchen_motion_status).state, "motion");
      handle_state(col, 4, "", "motion");
      handle_state(col, 5, "", "motion");

      // Temperature (column 3)
      col = 3;
      handle_state(col, 0, "󰔏", "icon");
      handle_state(col, 1, id(bath_temperature).state, "temperature");
      handle_state(col, 2, id(hall_temperature).state, "temperature");
      handle_state(col, 3, id(kitchen_temperature).state, "temperature");
      handle_state(col, 4, id(tomek_temperature).state, "temperature");
      handle_state(col, 5, id(mateusz_temperature).state, "temperature");

      // Humidity (column 4)
      col = 4;
      handle_state(col, 0, "󰖌", "icon");
      handle_state(col, 1, id(bath_humidity).state, "humidity");
      handle_state(col, 2, id(hall_humidity).state, "humidity");
      handle_state(col, 3, id(kitchen_humidity).state, "humidity");
      handle_state(col, 4, id(tomek_humidity).state, "humidity");
      handle_state(col, 5, id(mateusz_humidity).state, "humidity");

      // 3D Printer variables
      int progress_width = screen_width - (2 * margin) - 120;
      int progress = (atoi(id(octo_prog).state.c_str()) / 100) * progress_width;

      // 3D Printer progress bar
      if (id(octo_state).state == "Printing") {
        it.print(margin, row_calc(6), id(my_font), Color(255, 255, 255), "3D Printer:");
        it.filled_rectangle(margin + 90, row_calc(6), progress, 20, Color(0, 255, 0));
        it.rectangle(margin + 90, row_calc(6), progress_width, 20, Color(255, 255, 255));
      }

      // 3D Printer light status
      if (id(printer_light).state == "on" && id(octo_state).state == "Printing" ) {
        it.print(margin + 90 + progress_width + 10, row_calc(6), id(icon_font), Color(255, 255, 255), "󰖨");
      } else if (id(printer_light).state == "on") {
        it.print(margin, row_calc(6), id(my_font), Color(255, 255, 255), "3D Printer Light On");
      }

# Home Assistant integration
text_sensor:
  - platform: homeassistant
    entity_id: binary_sensor.bathroom_door_opening
    id: bath_door_status
  - platform: homeassistant
    entity_id: binary_sensor.entrance_door_opening
    id: hall_door_status
  # - platform: homeassistant
  #   entity_id: binary_sensor.kitchen_door_status
  #   id: kitchen_door_status
  - platform: homeassistant
    entity_id: binary_sensor.tomasz_s_door_opening
    id: tomek_door_status
  - platform: homeassistant
    entity_id: binary_sensor.mateusz_s_door_opening
    id: mateusz_door_status

  - platform: homeassistant
    entity_id: binary_sensor.bathroom_motion_occupancy
    id: bath_motion_status
  - platform: homeassistant
    entity_id: binary_sensor.hall_motion_occupancy
    id: hall_motion_status
  - platform: homeassistant
    entity_id: binary_sensor.kitchen_motion_occupancy
    id: kitchen_motion_status
  # - platform: homeassistant
  #   entity_id: binary_sensor.tomek_motion_sensor
  #   id: tomek_motion_status
  # - platform: homeassistant
  #   entity_id: binary_sensor.mateusz_motion_sensor
  #   id: mateusz_motion_status

  - platform: homeassistant
    entity_id: sensor.bathroom_sensor_temperature
    id: bath_temperature
  - platform: homeassistant
    entity_id: sensor.hall_sensor_temperature
    id: hall_temperature
  - platform: homeassistant
    entity_id: sensor.kitchen_sensor_temperature
    id: kitchen_temperature
  - platform: homeassistant
    entity_id: sensor.t_h_sensor_temperature
    id: tomek_temperature
  - platform: homeassistant
    entity_id: sensor.mateusz_s_room_sensor_temperature
    id: mateusz_temperature

  - platform: homeassistant
    entity_id: sensor.bathroom_sensor_humidity
    id: bath_humidity
  - platform: homeassistant
    entity_id: sensor.hall_sensor_humidity
    id: hall_humidity
  - platform: homeassistant
    entity_id: sensor.kitchen_sensor_humidity
    id: kitchen_humidity
  - platform: homeassistant
    entity_id: sensor.t_h_sensor_humidity
    id: tomek_humidity
  - platform: homeassistant
    entity_id: sensor.mateusz_s_room_sensor_humidity
    id: mateusz_humidity

  - platform: homeassistant
    entity_id: sensor.octoprint_job_percentage
    id: octo_prog
  - platform: homeassistant
    entity_id: sensor.octoprint_current_state
    id: octo_state
  - platform: homeassistant
    entity_id: switch.3d_printer_light
    id: printer_light

font:
  - id: my_font
    file: "fonts/Roboto.ttf"
    size: 20

  - id: icon_font
    file: "fonts/JetBrains.ttf"
    size: 20
    glyphs: [ "󰚡", "󰠚", "󰶑", "󰔏", "󰖌", "󰖨" ]

interval:
  - interval: 1s
    then:
      lambda: |-
        static bool toggle = false;
        toggle = !toggle;
        id(triangle_visible) = toggle;

globals:
  - id: triangle_visible
    type: bool
    restore_value: no
    initial_value: 'true'
