#include <WiFi.h>
#include <WebServer.h>
#include "RTClib.h"
#include <ArduinoJson.h>
#include <ESP32Servo.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
const char* SSID = "Wokwi-GUEST";
const char* password = "";
RTC_DS1307 rtc;
WebServer server(80);
String correct_password = "147258369";
String entered_password = "";
String checker_state = "Close";
Servo servo;
const int servoPin = 18;
const int Buzzer = 13;
LiquidCrystal_I2C lcd(0x27, 16, 2);
const uint8_t ROWS = 4;
const uint8_t COLS = 3;
char keys[ROWS][COLS] = {
{ '1', '2', '3'},
{ '4', '5', '6'},
{ '7', '8', '9'},
{ '*', '0', '#' }
};
uint8_t colPins[COLS] = { 12, 14, 27 };
uint8_t rowPins[ROWS] = { 26, 25, 33, 32 };
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
float w1 = 0.3, w2 = -0.4, b = 0.05;
float lr = 0.08;
float loss_values[50];
int loss_index = 0;
const unsigned long AUTO_CLOSE_MS = 10000;
unsigned long openedAt = 0;
const uint8_t MAX_PASS_LEN = 12;
float sigmoid(float x) {
return 1.0 / (1.0 + exp(-x));
}
void train_model() {
for (int epoch = 0; epoch < 50; epoch++) {
float total_loss = 0;
for (int i = 0; i < 20; i++) {
float x1 = random(0, 100) / 100.0;
float x2 = random(0, 100) / 100.0;
float y = (x1 > 0.8 && x2 > 0.3) ? 0.0 : 1.0;
float z = w1 * x1 + w2 * x2 + b;
float pred = sigmoid(z);
float loss = (pred - y) * (pred - y);
total_loss += loss;
float grad = 2 * (pred - y) * pred * (1 - pred);
w1 -= lr * grad * x1;
w2 -= lr * grad * x2;
b -= lr * grad;
}
loss_values[loss_index++] = total_loss / 20.0;
if (loss_index >= 50) loss_index = 0;
}
}
float predict(float x1, float x2) {
return sigmoid(w1 * x1 + w2 * x2 + b);
}
String getLossChartJS() {
String data = "[";
for (int i = 0; i < 50; i++) {
data += String(loss_values[i]);
if (i < 49) data += ",";
}
data += "]";
return data;
}
String getWebPage() {
String chartData = getLossChartJS();
String html = R"(
<html><head>
<title>AI Safe Monitor</title>
<script src='https://cdn.jsdelivr.net/npm/chart.js'></script>
</head><body style='font-family:sans-serif; text-align:center;'>
<h2>AI Safe Monitor 🔐</h2>
<canvas id='lossChart' width='300' height='150'></canvas>
<p id='status'></p>
<button onclick='trainAgain()'>Retrain AI</button>
<script>
const ctx = document.getElementById('lossChart');
const data = {
labels: [...Array(50).keys()],
datasets: [{label:'Loss', data: )" + chartData + R"(, borderColor:'blue', fill:false}]
};
new Chart(ctx, {type:'line', data:data});
async function trainAgain(){
await fetch('/train');
alert('Model retrained!');
location.reload();
}
fetch('/state').then(r=>r.text()).then(t=>{document.getElementById('status').innerHTML=t});
</script>
</body></html>
)";
return html;
}
void handleRoot() {
server.send(200, "text/html", getWebPage());
}
void handleTrain() {
train_model();
server.send(200, "text/plain", "Retrained");
}
void handleState() {
float sim = 0;
for (int i = 0; i < entered_password.length() && i < correct_password.length(); i++) {
if (entered_password[i] == correct_password[i]) sim += 1.0;
}
sim /= correct_password.length();
float delay_factor = (millis() % 100) / 100.0;
float out = predict(sim, delay_factor);
String msg = (out > 0.6) ? "⚠️ Suspicious activity detected!" : "✅ Normal operation.";
server.send(200, "text/plain", msg);
}
void CheckPassword() {
if (entered_password == correct_password) {
checker_state = "Open";
tone(Buzzer, 1500, 150);
servo.write(90);
openedAt = millis();
} else {
checker_state = "Close";
tone(Buzzer, 500, 350);
servo.write(0);
}
updateLCD();
}
void setup() {
Serial.begin(115200);
WiFi.begin(SSID, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
Serial.println(WiFi.localIP());
rtc.begin();
lcd.init();
lcd.backlight();
pinMode(Buzzer, OUTPUT);
servo.attach(servoPin, 500, 2400);
server.on("/", handleRoot);
server.on("/train", handleTrain);
server.on("/state", handleState);
server.begin();
for (int i = 0; i < 50; i++) loss_values[i] = 0.5;
train_model();
updateLCD();
}
void updateLCD() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Safe: " + checker_state);
lcd.setCursor(0, 1);
String masked = "";
for (unsigned int i = 0; i < entered_password.length(); i++) masked += '*';
if (masked.length() > 10) {
masked = masked.substring(masked.length() - 10);
}
lcd.print("Enter: " + masked);
}
void loop() {
server.handleClient();
if (checker_state == "Open" && openedAt > 0 && (millis() - openedAt) > AUTO_CLOSE_MS) {
checker_state = "Close";
servo.write(0);
openedAt = 0;
tone(Buzzer, 1000, 150);
updateLCD();
}
char key = keypad.getKey();
if (key != NO_KEY) {
if (key == '#') {
CheckPassword();
entered_password = "";
updateLCD();
} else if (key == '*') {
entered_password = "";
updateLCD();
} else {
if (entered_password.length() < MAX_PASS_LEN) {
entered_password += key;
updateLCD();
} else {
tone(Buzzer, 700, 80);
}
}
}
}