# NOTE: This program does NOT log via UART, but only via network socket (esphome logs...)


# ---------------------- Global config ----------------------

esphome:
  name: fabula
  on_boot:
    - priority: 300
      then:
        - dfplayer.set_volume: 10
        - light.turn_on:
          id: status_led
          brightness: 60%
          red: 100%
          green: 0%
          blue: 100%

esp8266:
  board: d1_mini_lite

# Enable logging
logger:
  baud_rate: 0

ota:
  - platform: esphome
    password: ""

wifi:
  ssid: "Pew"
  password: "SediaChinita@Terrazzo2017"


# ---------------------- Global variables ----------------------

globals:
  - id: current_folder
    type: int
    restore_value: no
    initial_value: '0'


# ---------------------- PN532 NFC Reader ----------------------

i2c:
  # I2C config left to default. For ESP8266 is:
  # GPIO5 (D1) -> I2C SCL
  # GPIO4 (D2) -> I2C SDA
  timeout: 13ms #to prevent pn532 timeout

pn532_i2c:
  update_interval: 1s
  on_tag:
    then:
      - dfplayer.play_folder:
          loop: True
          # Crashes somewhere here in the lambda
          folder: !lambda |-
            if (tag.has_ndef_message()) {
              const auto &message = tag.get_ndef_message();
              const auto &records = message->get_records();
              for (const auto &record : records) {
                if (record->get_type().c_str()[0] != 'T') {
                  ESP_LOGD("Fabula", "  Ignoring non-text record %s", record->get_payload().c_str());
                  continue;
                }
                ESP_LOGD("Fabula", "  Found record %s in tag, try to convert to int", record->get_payload().c_str());
                // Note: exception handling is disabled in ESPHome: the following line may crash the microcontroller if a tag with a textual record if scanned
                int folderId = std::stoi(record->get_payload());
                ESP_LOGD("Fabula", "  Found valid record in tag: playing folder %d", folderId);
                id(current_folder) = folderId;
                return folderId;
              }
            }
            ESP_LOGD("Fabula", "  No valid record found in tag. Please add a text field containing the folder number, e.g. 001");
            id(current_folder) = 0;
            return 0;
  on_tag_removed: 
    then:
      - logger.log: "NFC Tag removed"
      - dfplayer.pause


# ---------------------- DFPlayer MP3 Player ----------------------

uart:
  #tx_pin: D8
  #rx_pin: D7
  tx_pin: TX
  rx_pin: RX
  baud_rate: 9600

dfplayer:
  on_finished_playback:
    then:
      logger.log: 'Playback finished event'



binary_sensor:
# ---------------------- NFC TAG Sensor ----------------------
  - platform: pn532
    uid: 74-10-37-94
    name: "PN532 NFC Tag"
# ---------------------- Phisical buttons ----------------------
  - platform: gpio
    pin:
      number: D7
      mode:
        input: true
        pullup: true
    id: "vol_down"
    name: "Volume down"
    filters:
      - invert
      - settle: 10ms
    #  - autorepeat:
    #      time_off: 200ms
    #      time_on: 200ms
    on_press:
      then:
        - dfplayer.volume_down
        - dfplayer.volume_down
        - dfplayer.volume_down
  - platform: gpio
    pin:
      number: D8
      mode:
        input: true
        pullup: true
    id: "vol_up"
    name: "Volume up"
    filters:
      - settle: 10ms
    #  - autorepeat:
    #      time_off: 200ms
    #      time_on: 200ms
    on_press:
      then:
        - dfplayer.volume_up
        - dfplayer.volume_up
        - dfplayer.volume_up
  - platform: gpio
    pin:
      number: D5
      mode:
        input: true
        pullup: true
    id: "trk_prev"
    name: "Previous track"
    filters:
      - invert
      - settle: 10ms
    on_press:
      if:
        condition:
          dfplayer.is_playing
          # Note: this is True only if the dfplayer is playing the track we asked.
          # If it's looping, the following tracks are player with is_playing=false.
        then:
          dfplayer.play_previous
  - platform: gpio
    pin:
      number: D6
      mode:
        input: true
        pullup: true
    id: "trk_next"
    name: "Next track"
    filters:
      - invert
      - settle: 10ms
    on_press:
      if:
        condition:
          dfplayer.is_playing
        then:
          dfplayer.play_next




# ---------------------- Status led ----------------------
output:
  - platform: esp8266_pwm
    id: status_led_red
    pin: D0
  - platform: esp8266_pwm
    id: status_led_green
    pin: D4
  - platform: esp8266_pwm
    id: status_led_blue
    pin: D3

light:
  - platform: rgb
    id: status_led
    name: "Status led"
    red: status_led_red
    green: status_led_green
    blue: status_led_blue




# ---------------------- Battery level sensor ----------------------
sensor:
  - platform: adc
    pin: A0
    name: "Battery level"
    icon: 'mdi:battery'
    update_interval: 1min
    #unit_of_measurement: "%"
    #raw: true
    #filters:
    #  - clamp:
    #      min_value: 500.0
    #      max_value: 850.0
    #  - calibrate_linear:
    #    - 500.0 -> 0.0
    #    - 850.0 -> 100.0
    #  - min:
    #      send_first_at: 3


# ---------------------- REMOVE FROM THERE TO END OF FILE WHEN TESTING FINISHED ----------------------

api:
  # Per eseguire queste actions, andare in Home Assistant dentro Developer Tools -> Actions -> Inserire:
  # action: esphome.fabula_dfplayer_play_folder
  # data: {
  #   "folder": 2, 
  #   "file": 1
  # }

  actions:
  - action: dfplayer_next
    then:
      - dfplayer.play_next:
  - action: dfplayer_previous
    then:
      - dfplayer.play_previous:
  - action: dfplayer_play
    variables:
      file: int
    then:
      - dfplayer.play: !lambda 'return file;'
  - action: dfplayer_play_loop
    variables:
      file: int
      loop_: bool
    then:
      - dfplayer.play:
          file: !lambda 'return file;'
          loop: !lambda 'return loop_;'
  - action: dfplayer_play_folder
    variables:
      folder: int
      file: int
    then:
      - dfplayer.play_folder:
          folder: !lambda 'return folder;'
          file: !lambda 'return file;'

  - action: dfplayer_play_loop_folder
    variables:
      folder: int
    then:
      - dfplayer.play_folder:
          folder: !lambda 'return folder;'
          loop: true

  - action: dfplayer_set_device_tf
    then:
      - dfplayer.set_device: TF_CARD

  - action: dfplayer_set_device_usb
    then:
      - dfplayer.set_device: USB

  - action: dfplayer_set_volume
    variables:
      volume: int
    then:
      - dfplayer.set_volume: !lambda 'return volume;'
  - action: dfplayer_set_eq
    variables:
      preset: int
    then:
      - dfplayer.set_eq: !lambda 'return static_cast<dfplayer::EqPreset>(preset);'

  - action: dfplayer_sleep
    then:
      - dfplayer.sleep

  - action: dfplayer_reset
    then:
      - dfplayer.reset

  - action: dfplayer_start
    then:
      - dfplayer.start

  - action: dfplayer_pause
    then:
      - dfplayer.pause

  - action: dfplayer_stop
    then:
      - dfplayer.stop

  - action: dfplayer_random
    then:
      - dfplayer.random

  - action: dfplayer_volume_up
    then:
      - dfplayer.volume_up

  - action: dfplayer_volume_down
    then:
      - dfplayer.volume_down
  