#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <WiFi.h>
#include <WebServer.h>
WiFiServer server(80);
String httpRequest = "";
LiquidCrystal_I2C lcd(0x27, 20, 4);
#define LUZ_PIN 4
#define PORTAO_PIN 18
#define CAMERA_PIN 19
bool luz = false;
bool portao = false;
bool camera = false;
unsigned long agLuz = 0;
unsigned long agPortao = 0;
unsigned long agCamera = 0;
String ultimoEvento = "Sistema ON";
unsigned long ultimaAtualizacaoLCD = 0;
void atualizarLCD() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("L:");
lcd.print(luz ? "ON " : "OFF");
lcd.setCursor(7, 0);
lcd.print("P:");
lcd.print(portao ? "ON " : "OFF");
lcd.setCursor(14, 0);
lcd.print("C:");
lcd.print(camera ? "ON" : "OFF");
lcd.setCursor(0, 1);
lcd.print("Luz: ");
if (agLuz > millis()) lcd.print((agLuz - millis()) / 1000);
else lcd.print("--");
lcd.print("s");
lcd.setCursor(10, 1);
lcd.print("Port: ");
if (agPortao > millis()) lcd.print((agPortao - millis()) / 1000);
else lcd.print("--");
lcd.print("s");
lcd.setCursor(0, 2);
lcd.print("Cam: ");
if (agCamera > millis()) lcd.print((agCamera - millis()) / 1000);
else lcd.print("--");
lcd.print("s");
lcd.setCursor(0, 3);
lcd.print("Evento: ");
if (ultimoEvento.length() > 12) {
lcd.print(ultimoEvento.substring(0, 12));
} else {
lcd.print(ultimoEvento);
}
}
void atualizarLCDSePreciso() {
bool temContagem =
(agLuz > millis()) ||
(agPortao > millis()) ||
(agCamera > millis());
if (!temContagem) return;
if (millis() - ultimaAtualizacaoLCD >= 1000) {
ultimaAtualizacaoLCD = millis();
atualizarLCD();
}
}
void logEvento(String msg) {
ultimoEvento = msg;
Serial.println(msg);
atualizarLCD();
}
void ligarLuz() {
luz = true; digitalWrite(LUZ_PIN, HIGH);
logEvento("Luz ligada");
}
void desligarLuz() {
luz = false;
digitalWrite(LUZ_PIN, LOW);
logEvento("Luz desligada");
}
void abrirPortao() {
portao = true;
digitalWrite(PORTAO_PIN, HIGH);
logEvento("Portao aberto");
}
void fecharPortao() {
portao = false;
digitalWrite(PORTAO_PIN, LOW);
logEvento("Portao fechado");
}
void ligarCamera() {
camera = true;
digitalWrite(CAMERA_PIN, HIGH);
logEvento("Camera ligada");
}
void desligarCamera() {
camera = false;
digitalWrite(CAMERA_PIN, LOW);
logEvento("Camera desligada");
}
void processarComando(String cmd) {
cmd.toLowerCase();
if (cmd.startsWith("wifi ")) {
String interno = cmd.substring(5);
processarComando(interno);
return;
}
if (cmd.startsWith("agendar")) {
int esp1 = cmd.indexOf(' ');
int esp2 = cmd.indexOf(' ', esp1 + 1);
if (esp1 == -1 || esp2 == -1) {
Serial.println("Formato invalido! Use: agendar luz (Nº em seg.)");
return;
}
String disp = cmd.substring(esp1 + 1, esp2);
int tempo = cmd.substring(esp2 + 1).toInt();
if (tempo <= 0) {
Serial.println("O tempo deve ser positivo.");
return;
}
unsigned long futuro = millis() + tempo * 1000UL;
if (disp == "luz") {
agLuz = futuro;
logEvento("Luz agendada");
}
else if (disp == "portao") {
agPortao = futuro;
logEvento("Portao agendado");
}
else if (disp == "camera") {
agCamera = futuro;
logEvento("Camera agendada");
}
else {
Serial.println("Dispositivo invalido!");
}
atualizarLCD();
return;
}
if (cmd == "luz on") ligarLuz();
else if (cmd == "luz off") desligarLuz();
else if (cmd == "portao on") abrirPortao();
else if (cmd == "portao off") fecharPortao();
else if (cmd == "camera on") ligarCamera();
else if (cmd == "camera off") desligarCamera();
else Serial.println("Comando invalido!");
}
bool wifiConectado = false;
void iniciarWiFiSimulado() {
Serial.println("Conectando ao WiFi...");
delay(800);
Serial.println("WiFi conectado (simulado)!");
Serial.print("IP: ");
Serial.println(WiFi.softAPIP());
Serial.println("Servidor iniciado na porta 80 (simulado)");
Serial.println("Use: wifi <comando>");
Serial.println("Ex: wifi luz on");
wifiConectado = true;
}
void setup() {
Serial.begin(115200);
WiFi.softAP("CasaControl", "12345678");
Serial.println("WiFi criado!");
Serial.print("Acesse: http://");
Serial.println(WiFi.softAPIP());
server.begin();
Serial.println("Servidor iniciado porta 80");
lcd.init();
lcd.backlight();
pinMode(LUZ_PIN, OUTPUT);
pinMode(PORTAO_PIN, OUTPUT);
pinMode(CAMERA_PIN, OUTPUT);
atualizarLCD();
iniciarWiFiSimulado();
Serial.println("Sistema de Controle Doméstico Iniciado!");
Serial.println("Comandos ON/OFF:");
Serial.println(" luz on/off");
Serial.println(" portao on/off");
Serial.println(" camera on/off");
Serial.println("Agendamentos:");
Serial.println(" agendar luz (Nº em seg.)");
Serial.println(" agendar portao (Nº em seg.)");
Serial.println(" agendar camera (Nº em seg.)");
}
void processarHTTP(String req) {
req.toLowerCase();
if (req.indexOf("luz/on") != -1) { ligarLuz(); }
else if (req.indexOf("luz/off") != -1) { desligarLuz(); }
else if (req.indexOf("portao/on") != -1) { abrirPortao(); }
else if (req.indexOf("portao/off") != -1) { fecharPortao(); }
else if (req.indexOf("camera/on") != -1) { ligarCamera(); }
else if (req.indexOf("camera/off") != -1) { desligarCamera(); }
else if (req.indexOf("/agendar/") != -1) {
int p1 = req.indexOf("/agendar/") + 9;
int p2 = req.indexOf('/', p1);
int p3 = req.indexOf(' ', p2);
String dispositivo = req.substring(p1, p2);
int tempo = req.substring(p2 + 1, p3).toInt();
unsigned long agora = millis();
if (dispositivo == "luz") {
agLuz = agora + tempo * 1000UL;
Serial.println("[WEB] Agendamento luz OK");
}
else if (dispositivo == "portao") {
agPortao = agora + tempo * 1000UL;
Serial.println("[WEB] Agendamento portão OK");
}
else if (dispositivo == "camera") {
agCamera = agora + tempo * 1000UL;
Serial.println("[WEB] Agendamento câmera OK");
}
}
else {
Serial.println("[WEB] Comando desconhecido.");
}
}
void loop() {
WiFiClient client = server.available();
if (client) {
String header = "";
while (client.connected()) {
if (client.available()) {
char c = client.read();
header += c;
if (c == '\n') {
if (header.length() > 10) {
processarHTTP(header);
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/plain");
client.println("Connection: close\n");
client.println("Comando recebido!");
}
break;
}
}
}
client.stop();
}
unsigned long agora = millis();
if (agLuz > 0 && agora >= agLuz) {
if (luz) desligarLuz(); else ligarLuz();
agLuz = 0;
}
if (agPortao > 0 && agora >= agPortao) {
if (portao) fecharPortao(); else abrirPortao();
agPortao = 0;
}
if (agCamera > 0 && agora >= agCamera) {
if (camera) desligarCamera(); else ligarCamera();
agCamera = 0;
}
if (Serial.available()) {
String cmd = Serial.readStringUntil('\n');
cmd.trim();
processarComando(cmd);
}
atualizarLCDSePreciso();
}