Загрузка данных


#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>

// ========== НАСТРОЙКИ ==========
const char* ssid = "ВАШ_WIFI_SSID";         // Имя WiFi сети
const char* password = "ВАШ_ПАРОЛЬ";        // Пароль WiFi

const char* apiKey = "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";
const char* url = "https://api.groq.com/openai/v1/chat/completions";

// Другие настройки
const int maxHistorySize = 20;  // Максимум сообщений в истории
// =================================

// Буферы для сообщений
String systemMessage = "Ты полезный ассистент. Отвечай кратко, так как это ESP32.";
String userMessages[20];
String assistantMessages[20];
int messageCount = 0;

void setup() {
  Serial.begin(115200);
  delay(1000);
  
  Serial.println("\n\n=== Чат с Groq на ESP32 ===");
  
  // Подключение к WiFi
  connectToWiFi();
  
  // Добавляем системное сообщение в историю
  addMessage("system", systemMessage);
}

void loop() {
  if (Serial.available()) {
    String userInput = Serial.readStringUntil('\n');
    userInput.trim();
    
    if (userInput.length() == 0) return;
    
    // Проверка команды выхода
    if (userInput.equalsIgnoreCase("exit") || 
        userInput.equalsIgnoreCase("выход") ||
        userInput.equalsIgnoreCase("quit")) {
      Serial.println("До свидания!");
      delay(1000);
      ESP.restart();
      return;
    }
    
    // Очистка истории
    if (userInput.equalsIgnoreCase("clear")) {
      clearHistory();
      Serial.println("История очищена!");
      return;
    }
    
    Serial.print("Вы: ");
    Serial.println(userInput);
    Serial.print("Ассистент: ");
    
    // Отправляем запрос
    String response = chatWithGroq(userInput);
    Serial.println(response);
    Serial.println("\n---");
  }
}

void connectToWiFi() {
  Serial.print("Подключение к WiFi");
  WiFi.begin(ssid, password);
  
  int attempts = 0;
  while (WiFi.status() != WL_CONNECTED && attempts < 30) {
    delay(500);
    Serial.print(".");
    attempts++;
  }
  
  if (WiFi.status() == WL_CONNECTED) {
    Serial.println("\nWiFi подключен!");
    Serial.print("IP адрес: ");
    Serial.println(WiFi.localIP());
  } else {
    Serial.println("\nОшибка подключения WiFi!");
  }
}

void addMessage(String role, String content) {
  if (role == "user") {
    if (messageCount < maxHistorySize) {
      userMessages[messageCount] = content;
      assistantMessages[messageCount] = "";
      messageCount++;
    } else {
      // Сдвигаем историю
      for (int i = 1; i < maxHistorySize; i++) {
        userMessages[i-1] = userMessages[i];
        assistantMessages[i-1] = assistantMessages[i];
      }
      userMessages[maxHistorySize-1] = content;
      assistantMessages[maxHistorySize-1] = "";
    }
  } else if (role == "assistant" && messageCount > 0) {
    assistantMessages[messageCount - 1] = content;
  }
}

void clearHistory() {
  messageCount = 0;
  addMessage("system", systemMessage);
}

String chatWithGroq(String userInput) {
  if (WiFi.status() != WL_CONNECTED) {
    return "Ошибка: нет подключения к WiFi";
  }
  
  HTTPClient http;
  http.begin(url);
  http.addHeader("Content-Type", "application/json");
  http.addHeader("Authorization", "Bearer " + String(apiKey));
  
  // Создаем JSON с историей сообщений
  DynamicJsonDocument doc(4096);
  JsonArray messagesArray = doc.createNestedArray("messages");
  
  // Системное сообщение
  JsonObject sysMsg = messagesArray.createNestedObject();
  sysMsg["role"] = "system";
  sysMsg["content"] = systemMessage;
  
  // Добавляем историю диалога
  for (int i = 0; i < messageCount; i++) {
    if (userMessages[i].length() > 0) {
      JsonObject userMsg = messagesArray.createNestedObject();
      userMsg["role"] = "user";
      userMsg["content"] = userMessages[i];
      
      if (assistantMessages[i].length() > 0) {
        JsonObject assistantMsg = messagesArray.createNestedObject();
        assistantMsg["role"] = "assistant";
        assistantMsg["content"] = assistantMessages[i];
      }
    }
  }
  
  // Добавляем текущее сообщение
  JsonObject currentMsg = messagesArray.createNestedObject();
  currentMsg["role"] = "user";
  currentMsg["content"] = userInput;
  
  doc["model"] = "llama-3.3-70b-versatile";
  doc["temperature"] = 0.7;
  doc["max_tokens"] = 512;  // Ограничиваем для ESP32
  
  String jsonString;
  serializeJson(doc, jsonString);
  
  Serial.println("[DEBUG] Отправка запроса...");
  
  int httpResponseCode = http.POST(jsonString);
  
  if (httpResponseCode > 0) {
    String response = http.getString();
    
    if (httpResponseCode == 200) {
      // Парсим JSON ответ
      DynamicJsonDocument respDoc(2048);
      deserializeJson(respDoc, response);
      
      String assistantReply = respDoc["choices"][0]["message"]["content"];
      assistantReply.trim();
      
      // Сохраняем в историю
      addMessage("user", userInput);
      addMessage("assistant", assistantReply);
      
      http.end();
      return assistantReply;
    } else {
      http.end();
      return "Ошибка API: " + String(httpResponseCode) + "\n" + response;
    }
  } else {
    http.end();
    return "HTTP ошибка: " + String(httpResponseCode);
  }
}