/*
Wokwi-GUEST
*/
#include <WiFi.h>
#include <HTTPClient.h>
const char* ssid = "Wokwi-GUEST"; // Replace with your network SSID
const char* password = ""; // Replace with your network password
const char* apiURL = "https://3bb47076-4984-4a3f-b3d1-936e93feabcf-00-23zb62ohp06ip.pike.replit.dev/getotp"; // API URL
const int relayPin = 4;
const int ledPin = 16;
int otpCheckInterval = 20000; // Interval to make API call (20 seconds)
unsigned long previousMillis = 0; // Store the time of the last API call
String latestOtp = ""; // Store the OTP from the API
void setup() {
Serial.begin(115200);
pinMode(relayPin, OUTPUT);
pinMode(ledPin, OUTPUT);
digitalWrite(relayPin, LOW); // Initially set relay OFF
// Connect to WiFi
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi...");
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("Connected!");
}
void loop() {
unsigned long currentMillis = millis();
// Check if it's time to make an API call
if (currentMillis - previousMillis >= otpCheckInterval) {
previousMillis = currentMillis;
// Blink the LED 2 times to indicate an API call is being made
blinkLED(2);
// Fetch the OTP from the API
latestOtp = fetchOTPFromAPI();
Serial.println("Fetched OTP: " + latestOtp);
}
// Check if user entered an OTP from Serial Monitor
if (Serial.available() > 0) {
String userOtp = Serial.readStringUntil('\n'); // Read input from Serial
userOtp.trim(); // Remove any trailing spaces or newline characters
if (userOtp.length() == 4) { // Ensure it's a 4-character string
if (userOtp == latestOtp) {
Serial.println("OTP matched, unlocking door.");
digitalWrite(relayPin, HIGH); // Unlock (turn relay ON)
} else {
Serial.println("Incorrect OTP, door remains locked.");
digitalWrite(relayPin, LOW); // Keep the door locked (relay OFF)
}
} else {
Serial.println("Invalid OTP input. Please enter a 4-digit OTP.");
}
}
delay(10); // Small delay for stability
}
// Function to blink the LED a certain number of times
void blinkLED(int times) {
for (int i = 0; i < times; i++) {
digitalWrite(ledPin, HIGH); // Turn LED on
delay(200);
digitalWrite(ledPin, LOW); // Turn LED off
delay(200);
}
}
// Function to fetch OTP from the API
String fetchOTPFromAPI() {
if (WiFi.status() == WL_CONNECTED) { // Check WiFi connection
HTTPClient http;
http.begin(apiURL); // Specify the URL
int httpResponseCode = http.GET(); // Send GET request
if (httpResponseCode == 200) { // If the response is OK
String responseBody = http.getString(); // Get the response
int otpStart = responseBody.indexOf("\"otp\":\"") + 7; // Find start of OTP
int otpEnd = responseBody.indexOf("\"", otpStart); // Find end of OTP
String otp = responseBody.substring(otpStart, otpEnd); // Extract OTP
http.end(); // Close the connection
return otp;
} else {
Serial.println("Error: Unable to fetch OTP. HTTP response code: " + String(httpResponseCode));
http.end(); // Close the connection
}
} else {
Serial.println("Error: WiFi not connected.");
}
return ""; // Return empty string if something goes wrong
}
/*
FlaskApp.py
from flask import Flask, render_template, request, redirect, url_for, jsonify
import random
import sqlite3
import datetime
app = Flask(__name__)
# Function to initialize the SQLite database (called during app startup)
def init_db():
try:
conn = sqlite3.connect('otp.db')
c = conn.cursor()
# Create table if it doesn't exist
c.execute('''
CREATE TABLE IF NOT EXISTS otps (
id INTEGER PRIMARY KEY AUTOINCREMENT,
timestamp TEXT,
otpvalue TEXT -- Change OTP value to TEXT
)
''')
conn.commit()
except sqlite3.Error as e:
print(f"Error while creating the database or table: {e}")
finally:
if conn:
conn.close()
# Helper function to ensure the table exists
def ensure_table_exists():
try:
conn = sqlite3.connect('otp.db')
c = conn.cursor()
# Ensure the table exists, if not create it
c.execute('''
CREATE TABLE IF NOT EXISTS otps (
id INTEGER PRIMARY KEY AUTOINCREMENT,
timestamp TEXT,
otpvalue TEXT
)
''')
conn.commit()
except sqlite3.Error as e:
print(f"Error ensuring the table exists: {e}")
finally:
if conn:
conn.close()
# Helper function to get the latest OTP if it's less than 10 minutes old
def get_latest_valid_otp():
try:
ensure_table_exists() # Ensure table exists before selecting data
conn = sqlite3.connect('otp.db')
c = conn.cursor()
# Retrieve the latest OTP
c.execute(
'SELECT timestamp, otpvalue FROM otps ORDER BY id DESC LIMIT 1')
result = c.fetchone()
if result:
otp_time = datetime.datetime.strptime(result[0],
'%Y-%m-%d %H:%M:%S')
current_time = datetime.datetime.now()
# Check if the OTP is less than 10 minutes old
if (current_time -
otp_time).seconds < 600: # 600 seconds = 10 minutes
return result[1]
except sqlite3.Error as e:
print(f"Error retrieving the OTP from the database: {e}")
finally:
if conn:
conn.close()
return None
# Route to render the index.html with the OTP if available
@app.route('/')
def index():
otp = get_latest_valid_otp() # Get the latest valid OTP
return render_template('index.html', otp=otp)
# Route to generate OTP
@app.route('/genotp', methods=['POST'])
def generate_otp():
try:
otp = str(random.randint(1000,
9999)) # Generate 4-digit OTP as a string
timestamp = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
ensure_table_exists() # Ensure table exists before inserting data
# Save OTP to SQLite database
conn = sqlite3.connect('otp.db')
c = conn.cursor()
c.execute('INSERT INTO otps (timestamp, otpvalue) VALUES (?, ?)',
(timestamp, otp))
conn.commit()
except sqlite3.Error as e:
print(f"Error inserting OTP into the database: {e}")
finally:
if conn:
conn.close()
return redirect(url_for('index'))
# Route to get the latest OTP
@app.route('/getotp', methods=['GET'])
def get_otp():
conn = sqlite3.connect('otp.db')
c = conn.cursor()
# Retrieve the latest OTP
c.execute('SELECT timestamp, otpvalue FROM otps ORDER BY id DESC LIMIT 1')
result = c.fetchone()
conn.close()
if result:
otp_time = datetime.datetime.strptime(result[0], '%Y-%m-%d %H:%M:%S')
current_time = datetime.datetime.now()
# Check if the OTP is less than 10 seconds old
if (current_time - otp_time).seconds < 1000:
return jsonify({'otp': result[1]}) # Return OTP as string
else:
return jsonify({'otp': "0000"}) # Return default OTP as string
else:
return jsonify({'otp':
"0000"}) # Return default OTP as string if no record
if __name__ == '__main__':
# Initialize the database and ensure table exists on startup
init_db()
app.run(debug=True, host='0.0.0.0', port=5000)
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>OTP Generator</title>
</head>
<body>
<h1>Generate OTP</h1>
<form action="/genotp" method="post">
<button type="submit">Generate OTP</button>
</form>
<h2>Latest OTP:</h2>
{% if otp %}
<p>Your OTP is: <strong>{{ otp }}</strong></p>
{% else %}
<p>No valid OTP available.</p>
{% endif %}
</body>
</html>
*/