#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Adafruit_INA219.h>
#include <SPI.h>
#include <MFRC522.h>

//================ PIN DEFINITIONS =================
#define RELAY_PIN D0
#define SS_PIN D4
#define RST_PIN D3

//================ OBJECTS =================
LiquidCrystal_I2C lcd(0x27, 16, 2);
Adafruit_INA219 ina219;
MFRC522 rfid(SS_PIN, RST_PIN);

//============== AUTHORIZED CARD UID ==============
byte authorizedUID[4] = {0x99, 0xB3, 0xD4, 0x05};

bool chargingEnabled = false;

//=================================================
void setup()
{
  Serial.begin(115200);

  Wire.begin(D2, D1);

  lcd.init();
  lcd.backlight();

  lcd.setCursor(0,0);
  lcd.print("Smart Charging");
  lcd.setCursor(0,1);
  lcd.print("Initializing");
  delay(2000);

  lcd.clear();

  if (!ina219.begin())
  {
    lcd.print("INA219 Error");
    while (1);
  }

  SPI.begin();
  rfid.PCD_Init();

  pinMode(RELAY_PIN, OUTPUT);
  digitalWrite(RELAY_PIN, LOW);

  lcd.setCursor(0,0);
  lcd.print("Use RFID Card");
  lcd.setCursor(0,1);
  lcd.print("To Start");
}

//=================================================
void loop()
{
  checkRFID();
  displayChargingStatus();
}

//=================================================
void checkRFID()
{
  if (!rfid.PICC_IsNewCardPresent())
    return;

  if (!rfid.PICC_ReadCardSerial())
    return;

  bool authorized = true;

  for(byte i=0;i<4;i++)
  {
    if(rfid.uid.uidByte[i] != authorizedUID[i])
    {
      authorized = false;
      break;
    }
  }

  lcd.clear();

  if(authorized)
  {
    chargingEnabled = true;

    digitalWrite(RELAY_PIN,HIGH);

    lcd.setCursor(0,0);
    lcd.print("Access Granted");
    lcd.setCursor(0,1);
    lcd.print("Relay ON");

    Serial.println("Access Granted");
  }
  else
  {
    chargingEnabled = false;

    digitalWrite(RELAY_PIN,LOW);

    lcd.setCursor(0,0);
    lcd.print("Access Denied");
    lcd.setCursor(0,1);
    lcd.print("Relay OFF");

    Serial.println("Access Denied");
  }

  delay(1500);
  lcd.clear();

  rfid.PICC_HaltA();
}

//=================================================
void displayChargingStatus()
{
  if(!chargingEnabled)
  {
    lcd.setCursor(0,0);
    lcd.print("Use RFID Card  ");
    lcd.setCursor(0,1);
    lcd.print("To Start       ");
    delay(300);
    return;
  }

  float current = ina219.getCurrent_mA();

  if(current > 5)
  {
    lcd.setCursor(0,0);
    lcd.print("Charging V:5.2V");

    lcd.setCursor(0,1);
    lcd.print("I:");
    lcd.print(current,0);
    lcd.print("mA      ");
  }
  else
  {
    lcd.setCursor(0,0);
    lcd.print("Rotate Motor   ");

    lcd.setCursor(0,1);
    lcd.print("For Charging   ");
  }

  delay(300);
}