substitutions:
  device_friendly_name: "Electric gate"
  device_name: "electric_gate"

esphome:
  name: electric-gate
  on_boot:
    priority: 0
    then:
      - lambda: |-
          if (!id(magnetic_sensor).state && !id(enable_bypass_box)) {
            id(stop_yard_gate).execute();
            id(enable_gate) = 0;
            id(switch_enable_gate).publish_state(false);
          }
      - lambda: |-
          if (id(backup_switch_open).state || id(backup_switch_close).state) {
            id(stop_yard_gate).execute();
            id(enable_gate_backup) = 0;
            id(switch_light).turn_on();
          }
      - script.execute: info_gate_position
      - switch.template.publish:
            id: switch_enable_remote
            state: !lambda |-
              if (id(enable_remote)) {
                return true;
              } else {
                return false;
              }
      - switch.template.publish:
            id: switch_enable_light
            state: !lambda |-
              if (id(enable_light)) {
                return true;
              } else {
                return false;
              }
      - switch.template.publish:
            id: switch_enable_gate
            state: !lambda |-
              if (id(enable_gate)) {
                return true;
              } else {
                return false;
              }
      - switch.template.publish:
            id: switch_enable_bypass_box
            state: !lambda |-
              if (id(enable_bypass_box)) {
                return true;
              } else {
                return false;
              }

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

ota:
  password: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

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

  ap:
    ssid: "${device_name}"
    password: !secret ap_password

captive_portal:

globals:
  - id: enable_gate
    type: int
    restore_value: yes
    initial_value: '1'
  - id: enable_gate_backup
    type: int
    restore_value: no
    initial_value: '1'
  - id: enable_remote
    type: int
    restore_value: yes
    initial_value: '1'
  - id: enable_light
    type: int
    restore_value: yes
    initial_value: '1'
  - id: enable_bypass_box
    type: int
    restore_value: yes
    initial_value: '0'

script:
  - id: open_yard_gate
    then:
      - lambda: |-
          if (id(enable_gate) && id(enable_gate_backup)) {
            if (!id(limit_switch_open).state){
              id(switch_power).turn_off();
              if (id(enable_light)) {id(switch_light).turn_on();}
              delay(500);
              id(switch_direction).turn_off();
              id(switch_power).turn_on();
              id(gate_movement).publish_state("OUVERTURE");
            }
          }

 
  - id: close_yard_gate
    then:
      - lambda: |-
          if (id(enable_gate) && id(enable_gate_backup)) {
            if (!id(limit_switch_close).state && !id(optical_switch).state){
              id(switch_power).turn_off();
              if (id(enable_light)) {id(switch_light).turn_on();}
              delay(500);
              id(switch_direction).turn_on();
              id(switch_power).turn_on();
              id(gate_movement).publish_state("FERMETURE");
            }
          }
         
 
  - id: stop_yard_gate
    then:
      - lambda: |-
          id(switch_light).turn_off();
          id(switch_power).turn_off();
          if(id(limit_switch_open).state || id(limit_switch_close).state) {id(switch_direction).turn_off();}
          id(gate_movement).publish_state("-");
         
         
  - id: info_gate_position
    then:
      - lambda: |-
          if (id(limit_switch_open).state){       id(gate_position).publish_state("OUVERT"); }
          else if (id(limit_switch_close).state){ id(gate_position).publish_state("FERMÉ"); }
          else {                                  id(gate_position).publish_state("MILIEU"); }

sensor:
  - platform: uptime
    name: "${device_friendly_name} Uptime"
    update_interval: 300s
  - platform: wifi_signal
    name: "${device_friendly_name} RSSI"
    update_interval: 300s

text_sensor:
  - platform: wifi_info
    ip_address:
      name: "${device_friendly_name} Adresse IP"
    ssid:
      name: "${device_friendly_name} SSID"
    mac_address:
      name: "${device_friendly_name} Adresse MAC"

  - platform: template
    name: "${device_friendly_name} Position"
    id: gate_position
    lambda: |-
      if (id(limit_switch_open).state){       return {"OUVERT"}; }
      else if (id(limit_switch_close).state){ return {"FERMÉ"}; }
      else {                                  return {"MILIEU"}; }
  - platform: template
    name: "${device_friendly_name} Mouvement"
    id: gate_movement
    lambda: |-
      if (id(switch_power).state) {
        if (id(switch_direction).state) {
          return {"FERMETURE"};
        } else {
          return {"OUVERTURE"};
        }
      } else {
        return {"-"};
      }

button:
  - platform: template
    name: "${device_friendly_name} OUVRIR"
    id: button_open
    on_press:
      then:
        - script.execute: open_yard_gate
  - platform: template
    name: "${device_friendly_name} FERMER"
    id: button_close
    on_press:
      then:
        - script.execute: close_yard_gate
  - platform: template
    name: "${device_friendly_name} STOP"
    id: button_stop
    on_press:
      then:
        - script.execute: stop_yard_gate
        
  - platform: template
    name: "${device_friendly_name} BASCULER"
    id: button_toggle
    on_press:
      then:
        - lambda: |-
            if (id(gate_movement).state == "-") {
              if (id(gate_position).state == "FERMÉ") {
              id(open_yard_gate).execute();
              }
              else if (id(gate_position).state == "OUVERT") {
                id(close_yard_gate).execute();
              }
              else if (id(gate_position).state == "MILIEU") {
                if (id(switch_direction).state) {
                  id(open_yard_gate).execute();
                }
                else {
                  id(close_yard_gate).execute();
                }
              }
            }
            else {
              id(stop_yard_gate).execute();
            }

binary_sensor:
  - platform: gpio
    pin: GPIO34
    name: "${device_friendly_name} Télécommande A"
    on_press:
      then:
        - lambda: |-
            if (id(enable_remote)) {
              if (id(gate_movement).state == "-") {
                if (id(gate_position).state == "FERMÉ") {
                id(open_yard_gate).execute();
                }
                else if (id(gate_position).state == "OUVERT") {
                  id(close_yard_gate).execute();
                }
                else if (id(gate_position).state == "MILIEU") {
                  if (id(switch_direction).state) {
                    id(open_yard_gate).execute();
                  }
                  else {
                    id(close_yard_gate).execute();
                  }
                }
              }
              else {
                id(stop_yard_gate).execute();
              }
            }
           
  - platform: gpio
    pin: GPIO35
    name: "${device_friendly_name} Fin de course OUVERT"
    id: limit_switch_open
    filters:
      - delayed_off: 50ms
    on_state:
      then:
        - script.execute: info_gate_position
    on_press:
      then:
        - script.execute: stop_yard_gate
        - switch.turn_off: switch_direction

  - platform: gpio
    pin: GPIO32
    name: "${device_friendly_name} Fin de course FERMER"
    id: limit_switch_close
    filters:
      - delayed_off: 50ms
    on_state:
      then:
        - script.execute: info_gate_position
    on_press:
      then:
        - script.execute: stop_yard_gate
        - switch.turn_off: switch_direction

  - platform: gpio
    pin: GPIO33
    name: "${device_friendly_name} Cellule photoélectrique"
    id: optical_switch
    on_press:
      then:
        - lambda: !lambda |-
            if (id(gate_movement).state != "OUVERTURE") {
              id(stop_yard_gate).execute();
            }

  - platform: gpio
    pin:
      number: GPIO23
      mode:
        input: true
        pulldown: true
    name: "${device_friendly_name} Capteur magnétique"
    id: magnetic_sensor
    on_release:
      then:
        - if:
            condition:
              lambda: 'return (!id(enable_bypass_box) && id(enable_gate));'
            then:
              - lambda: |-
                  id(stop_yard_gate).execute();
                  id(enable_gate) = 0;
                  id(switch_enable_gate).publish_state(false);
                  id(switch_light).turn_on();
              - delay : 1s
              - lambda : |-
                  id(switch_light).turn_off();
  - platform: gpio
    pin:
      number: GPIO21
      mode:
        input: true
        pulldown: true
    name: "${device_friendly_name} Bouton d'ouverture forcé"
    id: backup_switch_open
    on_press:
      then:
        - script.execute: stop_yard_gate
        - lambda: |-
            id(switch_light).turn_on();
            id(enable_gate_backup) = 0;
    on_release:
      then:
        - script.execute: stop_yard_gate
        - lambda: |-
            id(switch_light).turn_off();
            id(enable_gate_backup) = 1;
    
  - platform: gpio
    pin:
      number: GPIO22
      mode:
        input: true
        pulldown: true
    name: "${device_friendly_name} Bouton de fermeture forcé"
    id: backup_switch_close
    on_press:
      then:
        - script.execute: stop_yard_gate
        - lambda: |-
            id(switch_light).turn_on();
            id(enable_gate_backup) = 0;
    on_release:
      then:
        - script.execute: stop_yard_gate
        - lambda: |-
            id(switch_light).turn_off();
            id(enable_gate_backup) = 1;


switch:
  - platform: restart
    name: "${device_friendly_name} Redémarrage"

  - platform: template
    name: "${device_friendly_name} CONFIG: Télécommande"
    id: switch_enable_remote
    restore_state: true
    turn_on_action:
      - switch.template.publish:
          id: switch_enable_remote
          state: !lambda 'return true;'
    turn_off_action:
      - switch.template.publish:
          id: switch_enable_remote
          state: !lambda 'return false;'

  - platform: template
    name: "${device_friendly_name} CONFIG: Lumière"
    id: switch_enable_light
    restore_state: true
    turn_on_action:
      - switch.template.publish:
          id: switch_enable_light
          state: !lambda 'return true;'
    turn_off_action:
      - switch.template.publish:
          id: switch_enable_light
          state: !lambda 'return false;'
   
  - platform: template
    name: "${device_friendly_name} CONFIG: Portail"
    id: switch_enable_gate
    restore_state: true
    turn_on_action:
      - switch.template.publish:
          id: switch_enable_gate
          state: !lambda 'return true;'
    turn_off_action:
      - switch.template.publish:
          id: switch_enable_gate
          state: !lambda 'return false;'

  - platform: template
    name: "${device_friendly_name} CONFIG: Sécurité magnétique"
    id: switch_enable_bypass_box
    restore_state: true
    turn_on_action:
      - switch.template.publish:
          id: switch_enable_bypass_box
          state: !lambda 'return true;'
    turn_off_action:
      - switch.template.publish:
          id: switch_enable_bypass_box
          state: !lambda 'return false;'

  - platform: gpio
    name: "${device_friendly_name} Relais POWER"
    pin: GPIO16
    restore_mode: ALWAYS_OFF
    id: switch_power

  - platform: gpio
    name: "${device_friendly_name} Relais DIRECTION"
    pin: GPIO17
    restore_mode: ALWAYS_OFF
    id: switch_direction
   
  - platform: gpio
    name: "${device_friendly_name} Relais LIGHT"
    pin: GPIO18
    restore_mode: ALWAYS_OFF
    id: switch_light