/********* Pleasedontcode.com **********

	Pleasedontcode thanks you for automatic code generation! Enjoy your code!

	- Terms and Conditions:
	You have a non-exclusive, revocable, worldwide, royalty-free license
	for personal and commercial use. Attribution is optional; modifications
	are allowed, but you're responsible for code maintenance. We're not
	liable for any loss or damage. For full terms,
	please visit pleasedontcode.com/termsandconditions.

	- Project: **Sensor Initialization**
	- Source Code NOT compiled for: ESP32 DevKit V1
	- Source Code created on: 2024-10-20 15:57:00

********* Pleasedontcode.com **********/

/****** SYSTEM REQUIREMENTS *****/
/****** SYSTEM REQUIREMENT 1 *****/
	/* merge code. */
/****** END SYSTEM REQUIREMENTS *****/

/* START CODE */

/****** DEFINITION OF LIBRARIES *****/
#include <TinyGPSPlus.h>
#include "ACS712.h"
#include <WiFi.h>
#include <ESPAsyncWebServer.h>
#include <SPIFFS.h>
#include <ArduinoJson.h>
#include <EEPROM.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include "X9C10X.h"

// Instantiate library objects
TinyGPSPlus gps; // GPS object
ACS712 ACS(A0, 5.0, 1023, 100); // Current sensor object
AsyncWebServer server(80); // Web server object
OneWire oneWire(2); // OneWire object for temperature sensors
DallasTemperature sensors(&oneWire); // Temperature sensor object

// Define constants
const char* ssid = "your-ssid"; // WiFi SSID
const char* pass = "your-password"; // WiFi password
const int GPSBaud = 9600; // GPS baud rate
const int ADC_Offset = 512; // ADC offset for ACS712
const int PWM_output_percentage = 50; // PWM output percentage
const int DIGPOT_INC = 4; // Digital potentiometer INC pin
const int DIGPOT_UD = 5; // Digital potentiometer U/D pin
const int DIGPOT_CS = 15; // Digital potentiometer CS pin

/****** FUNCTION PROTOTYPES *****/
void setup(void);
void loop(void);
void updateData(JsonDocument &doc);
void initSPIFFS();
void readMinutesCounterFromEEPROM();
void setCurrentOutput(int output);
void readGPSAndCheckSpeed();
void readCurrent();
void readVoltage();
void readWaterTank();
void readTemp1();
void readTemp2();
void updateMinutesCounter();
void checkRegeneration();

void setup(void)
{
    // put your setup code here, to run once:
    // Start Serial for debugging
    Serial.begin(115200);
    delay(1000);
    Serial.println("ciao");

    // Initialize digital potentiometer
    pot.begin(DIGPOT_INC, DIGPOT_UD, DIGPOT_CS);  //  pulse, direction, select

    //NON TOGLIERE - SERVE PER NON FAR SBARELLARE LA MACCHINA
    for(int i=0; i<10;i++)
    {
        setCurrentOutput(0);
        delay(20);
        setCurrentOutput(100);
        delay(20);
    }

    setCurrentOutput(PWM_output_percentage);
    readMinutesCounterFromEEPROM();

    // Initialize GPS
    ss.begin(GPSBaud);
    Serial.println("ciao2");

    // Initialize temperature sensors
    sensors.begin(); 

    // Delay for GPS to stabilize
    smartDelay(1000);

    // Set ACS712 midpoint
    ACS.setMidPoint(ADC_Offset); 

    Serial.println(F("Access Point Web Server"));

    // Initialize SPIFFS
    initSPIFFS();

    // Set up WiFi access point
    WiFi.mode(WIFI_AP); // Set the ESP32 to access point mode
    if (!WiFi.softAP(ssid, pass)) {
        Serial.println("Soft AP creation failed.");
        while(1);
    }

    // Print the IP address of the access point
    IPAddress IP = WiFi.softAPIP();
    Serial.print("Access Point IP Address: ");
    Serial.println(IP);

    // Serve the JPEG image
    server.on("/background.jpg", HTTP_GET, [](AsyncWebServerRequest *request){
        Serial.println("0");
        request->send(SPIFFS, "/background.jpg", "image/jpeg");
    });

    // Serve the HTML page
    server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
        Serial.println("1");
        request->send(SPIFFS, "/index.html", "text/html");
    });

    server.on("/UPDATEDATA", HTTP_POST, [](AsyncWebServerRequest *request) {
        // Log post request handling

        // Allocate a temporary JsonDocument
        StaticJsonDocument<512> doc;

        // Gather data and populate JSON
        updateData(doc);

        // Convert the JSON document to string and send it in response
        String response;
        serializeJsonPretty(doc, response);

        request->send(200, "application/json", response);
    });

    // Start the server
    server.begin();
}

void loop(void)
{
    // No logic in the loop; the server works asynchronously
    readGPSAndCheckSpeed();
    readCurrent();
    readVoltage();
    readWaterTank();
    readTemp1();
    readTemp2();
    updateMinutesCounter();
    checkRegeneration();
}

// The updateData function to generate the JSON payload
void updateData(JsonDocument &doc) {
    if (velocita > 0.0) {
        doc["speed"] = String(velocita) + String(F(" km/h"));
    } else {
        doc["speed"] = String(F("ERROR"));
    }
    doc["voltageCommandOut"] = String(F("Tensione uscita comando: ")) + String(voltage_output_value) + String(F("/3.3 [V]"));
    doc["percentageCommandOut"] = String(F("Uscita comando PWM: ")) + String(PWM_output_percentage) + String(F(" [%]"));

    doc["waterTankLevel"] = waterLevelEmpty ? String(F("VUOTO")) : String(F("PIENO"));
    doc["powerOnTime"] = String(powerOnTime) + String(F(" min"));
    doc["current"] = String(current) + String(F(" A"));
    doc["voltage"] = String(voltage) + String(F(" V"));
    doc["temperature1"] = String(temperature1) + String(F(" °C"));
    doc["temperature2"] = String(temperature2) + String(F(" °C"));
    doc["set_timer"] = String(F("Timer : ")) + String(set_timer) + String(F(" min"));
}

/* END CODE */