#include <WiFi.h>
#include <WebServer.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <ESP32Servo.h>
// ====== WiFi ======
const char* WIFI_SSID = "Wokwi-GUEST";
const char* WIFI_PASSWORD = "";
const char* API_KEY = "b453666eb3d04c1fa7c608375d88f7fc";
// ====== Azure OpenAI ======
const char* ENDPOINT = "artificialintelligence.openai.azure.com";
const char* DEPLOYMENT = "test";
const char* API_VERSION = "2023-05-15";
// ====== Сервер ======
WebServer server(80);
// ====== Піни ======
const int LED1 = 26;
const int LED2 = 27;
const int SERVO_PIN = 16;
Servo myServo;
bool led1State = false;
bool led2State = false;
bool doorOpen = false;
// ====== Виконання дій з JSON ======
void executeAction(const String& action, const String& value) {
if (action == "led1") {
led1State = (value == "on");
digitalWrite(LED1, led1State);
}
else if (action == "led2") {
led2State = (value == "on");
digitalWrite(LED2, led2State);
}
else if (action == "door") {
if (value == "open") {
myServo.write(90);
doorOpen = true;
}
else if (value == "close") {
myServo.write(0);
doorOpen = false;
}
}
}
// ====== Виклик ШІ через Azure OpenAI ======
String askAI(const String& input){
DynamicJsonDocument req(2048);
req["model"] = "gpt-3.5-turbo"; // назва ігнорується в Azure
JsonArray msgs = req.createNestedArray("messages");
JsonObject sys = msgs.createNestedObject();
sys["role"] = "system";
sys["content"] = "You are a smart home AI assistant. Respond ONLY in JSON with {action:'led1/led2/door', value:'on/off/open/close'}.";
JsonObject usr = msgs.createNestedObject();
usr["role"] = "user";
usr["content"] = input;
// Перевірка DNS
IPAddress ip;
if (!WiFi.hostByName(ENDPOINT, ip)) {
Serial.println("DNS lookup failed!");
return "{}";
}
Serial.print("Resolved IP: ");
Serial.println(ip);
String url = "https://" + String(ENDPOINT) + "/openai/deployments/" + DEPLOYMENT +
"/chat/completions?api-version=" + API_VERSION;
HTTPClient http;
http.begin(url);
// http.setInsecure(); // 🔥 ігноруємо TLS-сертифікати
http.addHeader("Content-Type","application/json");
http.addHeader("api-key", API_KEY);
String body;
serializeJson(req, body);
int code = http.POST(body);
String aiResp = "{}";
if (code == 200) {
DynamicJsonDocument resp(4096);
deserializeJson(resp, http.getString());
aiResp = resp["choices"][0]["message"]["content"].as<String>();
Serial.println("AI said: " + aiResp);
} else {
Serial.println("AI HTTP error: " + String(code));
}
http.end();
return aiResp;
}
// ====== Веб-інтерфейс ======
void handleRoot() {
String html = R"rawliteral(
<!DOCTYPE html><html>
<head><meta charset="utf-8"><title>ESP32 AI Control</title></head>
<body style="font-family:sans-serif;text-align:center;">
<h2>🤖 AI Controlled ESP32</h2>
<form action="/command" method="POST">
<input type="text" name="cmd" placeholder="Введіть команду" style="width:300px;height:30px;font-size:18px;">
<input type="submit" value="Відправити" style="height:35px;">
</form>
<p>LED1: %LED1%</p>
<p>LED2: %LED2%</p>
<p>Door: %DOOR%</p>
</body></html>
)rawliteral";
html.replace("%LED1%", led1State ? "ON" : "OFF");
html.replace("%LED2%", led2State ? "ON" : "OFF");
html.replace("%DOOR%", doorOpen ? "OPEN" : "CLOSED");
server.send(200, "text/html", html);
}
void handleCommand() {
if (server.hasArg("cmd")) {
String cmd = server.arg("cmd");
Serial.println("User command: " + cmd);
String aiResp = askAI(cmd);
// Парсимо JSON
DynamicJsonDocument doc(512);
DeserializationError err = deserializeJson(doc, aiResp);
if (!err) {
String action = doc["action"];
String value = doc["value"];
executeAction(action, value);
} else {
Serial.println("JSON parse error: " + String(err.c_str()));
}
server.sendHeader("Location", "/");
server.send(303);
} else {
server.send(400, "text/plain", "No command");
}
}
// ====== Setup ======
void setup() {
Serial.begin(115200);
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
myServo.attach(SERVO_PIN);
myServo.write(0);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(200);
Serial.print(".");
}
Serial.println("\nWiFi connected!");
Serial.println(WiFi.localIP());
server.on("/", handleRoot);
server.on("/command", HTTP_POST, handleCommand);
server.begin();
Serial.println("Web server started");
}
void loop() {
server.handleClient();
}