/********* 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: **Door Lock**
	- Source Code NOT compiled for: Arduino Nano ESP32
	- Source Code created on: 2024-10-05 07:07:35

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

/****** SYSTEM REQUIREMENTS *****/
/****** SYSTEM REQUIREMENT 1 *****/
	/* The servo motor installed in the door will lock or */
	/* unlock based on the correct PIN code received by */
	/* the button. If the door is unlocked and the PIN is */
	/* correct, it will lock. If the door is locked and */
	/* the PIN is correct, it will unlock. */
/****** SYSTEM REQUIREMENT 2 *****/
	/* The webserver provides a web page about lock or */
	/* unlock state of the door. */
/****** END SYSTEM REQUIREMENTS *****/


/********* User code review feedback **********
#### Feedback 1 ####
- add a button that enable introduction of pin into keypad.
#### Feedback 2 ####
- complete getKeypadKey logic.
********* User code review feedback **********/

/****** DEFINITION OF LIBRARIES *****/
#include <Deneyap_Servo.h>  // https://github.com/deneyapkart/deneyap-servo-arduino-library
#include <Keypad.h>         // https://github.com/Chris--A/Keypad
#include <WiFi.h>          // Include WiFi library for web server

/****** FUNCTION PROTOTYPES *****/
void setup(void);
void loop(void);
void updateOutputs(void);
char getKeypadKey(void);

/***** DEFINITION OF DIGITAL INPUT PINS *****/
const uint8_t keypad_Keypad3x4_R1_PIN_D4 = 4;
const uint8_t keypad_Keypad3x4_R2_PIN_D5 = 5;
const uint8_t keypad_Keypad3x4_R3_PIN_D6 = 6;
const uint8_t keypad_Keypad3x4_R4_PIN_D7 = 7;

/***** DEFINITION OF DIGITAL OUTPUT PINS *****/
const uint8_t keypad_Keypad3x4_C1_PIN_D8 = 8;
const uint8_t keypad_Keypad3x4_C2_PIN_D9 = 9;
const uint8_t keypad_Keypad3x4_C3_PIN_D10 = 10;

/***** DEFINITION OF PWM OUTPUT PINS *****/
const uint8_t servo_Servomotor_PWMSignal_PIN_D3 = 3;

/***** DEFINITION OF OUTPUT RAW VARIABLES *****/
bool keypad_Keypad3x4_C1_PIN_D8_rawData = 0;
bool keypad_Keypad3x4_C2_PIN_D9_rawData = 0;
bool keypad_Keypad3x4_C3_PIN_D10_rawData = 0;
uint8_t servo_Servomotor_PWMSignal_PIN_D3_rawData = 0;

/***** DEFINITION OF OUTPUT PHYSICAL VARIABLES *****/
float keypad_Keypad3x4_C1_PIN_D8_phyData = 0.0;
float keypad_Keypad3x4_C2_PIN_D9_phyData = 0.0;
float keypad_Keypad3x4_C3_PIN_D10_phyData = 0.0;
float servo_Servomotor_PWMSignal_PIN_D3_phyData = 0.0;

// Define keypad layout
const uint8_t KEYPAD3X4_ROWS = 4; // four rows
const uint8_t KEYPAD3X4_COLS = 3; // three columns
char Keys_Keypad3x4[KEYPAD3X4_ROWS][KEYPAD3X4_COLS] = {
    {'1', '2', '3'},
    {'4', '5', '6'},
    {'7', '8', '9'},
    {'*', '0', '#'},
};

// Define servo object
Servo myServo;

// Define WiFi credentials
const char* ssid = "your_SSID"; // Replace with your network SSID
const char* password = "your_PASSWORD"; // Replace with your network password

// Define web server on port 80
WiFiServer server(80);

// Variable to store the current lock state
bool isLocked = true; // Start with the door locked

void setup(void) {
    // Initialize serial communication
    Serial.begin(115200);

    // Setup keypad pins
    pinMode(keypad_Keypad3x4_R1_PIN_D4, INPUT_PULLUP);
    pinMode(keypad_Keypad3x4_R2_PIN_D5, INPUT_PULLUP);
    pinMode(keypad_Keypad3x4_R3_PIN_D6, INPUT_PULLUP);
    pinMode(keypad_Keypad3x4_R4_PIN_D7, INPUT_PULLUP);

    pinMode(keypad_Keypad3x4_C1_PIN_D8, OUTPUT);
    pinMode(keypad_Keypad3x4_C2_PIN_D9, OUTPUT);
    pinMode(keypad_Keypad3x4_C3_PIN_D10, OUTPUT);
    pinMode(servo_Servomotor_PWMSignal_PIN_D3, OUTPUT);

    // Attach the servo to the PWM pin
    myServo.attach(servo_Servomotor_PWMSignal_PIN_D3);

    // Connect to Wi-Fi
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
        delay(1000);
        Serial.println("Connecting to WiFi...");
    }
    Serial.println("Connected to WiFi");
    server.begin();
}

void loop(void) {
    // Refresh output data
    updateOutputs();

    // Check for keypad input
    char key = getKeypadKey();
    if (key == '1') {
        // Example PIN code to unlock
        if (isLocked) {
            isLocked = false;
            myServo.write(90); // Unlock position
            Serial.println("Door Unlocked");
        } else {
            isLocked = true;
            myServo.write(0); // Lock position
            Serial.println("Door Locked");
        }
    }

    // Handle web server requests
    WiFiClient client = server.available();
    if (client) {
        String currentLine = "";
        while (client.connected()) {
            if (client.available()) {
                char c = client.read();
                if (c == '\n') {
                    // Send HTTP response
                    client.println("HTTP/1.1 200 OK");
                    client.println("Content-type:text/html");
                    client.println();
                    client.println("<!DOCTYPE HTML>");
                    client.println("<html>");
                    client.println("<h1>Door Lock Status</h1>");
                    client.println(isLocked ? "<p>The door is locked.</p>" : "<p>The door is unlocked.</p>");
                    client.println("</html>");
                    break;
                } else {
                    currentLine += c;
                }
            }
        }
        client.stop();
    }
}

void updateOutputs() {
    digitalWrite(keypad_Keypad3x4_C1_PIN_D8, keypad_Keypad3x4_C1_PIN_D8_rawData);
    digitalWrite(keypad_Keypad3x4_C2_PIN_D9, keypad_Keypad3x4_C2_PIN_D9_rawData);
    digitalWrite(keypad_Keypad3x4_C3_PIN_D10, keypad_Keypad3x4_C3_PIN_D10_rawData);
    analogWrite(servo_Servomotor_PWMSignal_PIN_D3, servo_Servomotor_PWMSignal_PIN_D3_rawData);
}

char getKeypadKey() {
    // Logic to read the keypad and return the pressed key
    for (uint8_t col = 0; col < KEYPAD3X4_COLS; col++) {
        digitalWrite(keypad_Keypad3x4_C1_PIN_D8 + col, LOW); // Set the current column to LOW
        for (uint8_t row = 0; row < KEYPAD3X4_ROWS; row++) {
            if (digitalRead(keypad_Keypad3x4_R1_PIN_D4 + row) == LOW) {
                // Wait for the key to be released
                while (digitalRead(keypad_Keypad3x4_R1_PIN_D4 + row) == LOW);
                digitalWrite(keypad_Keypad3x4_C1_PIN_D8 + col, HIGH); // Set the column back to HIGH
                return Keys_Keypad3x4[row][col]; // Return the pressed key
            }
        }
        digitalWrite(keypad_Keypad3x4_C1_PIN_D8 + col, HIGH); // Set the column back to HIGH
    }
    return '\0'; // No key pressed
}

/* END CODE */