#include <WiFi.h>
#include <HTTPClient.h>
#include <WiFiClientSecure.h> // Maktaba Jdida dyal s-sécurité
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <DHT.h>
#include <SPI.h>
#include <SD.h>
#include "config.h"
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
#define DHTPIN 15
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
#define LED_FRIGO 13
#define LED_CHAUFFAGE 26
#define LED_EXTRACTION 27
#define LED_SOS 14
#define BUZZER_PIN 4
#define POT_PIN 34
#define BTN_CRASH 12
#define SD_CS_PIN 5
bool sosActif = false;
unsigned long lastTime = 0;
float temp = 0;
float hum = 0;
bool reseauActif = false;
String idToken = "";
String nomVilles[5] = {"Chtouka", "Biougra", "Inezgane", "Agadir", "Port Agadir"};
float routeGPS[5][2] = { {30.1234, -9.4567}, {30.2000, -9.5000}, {30.3150, -9.5400}, {30.3800, -9.5800}, {30.4200, -9.6200} };
int indexGPS = 0;
unsigned long lastGPSTime = 0;
// --- FONCTION DE SÉCURITÉ (LOGIN FIREBASE - M-SSE77A) ---
void authentifierFirebase() {
if (WiFi.status() == WL_CONNECTED) {
Serial.println("🔐 Authentification securisee en cours...");
// L'ASTUCE HIYA HADI: K-n-goulou lih t-t-connecta wakha ma-kaynch certificat SSL
WiFiClientSecure client;
client.setInsecure();
HTTPClient httpAuth;
String authUrl = "https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=" + API_KEY;
httpAuth.begin(client, authUrl); // Zdna 'client' hna
httpAuth.addHeader("Content-Type", "application/json");
String authPayload = "{\"email\":\"" + USER_EMAIL + "\",\"password\":\"" + USER_PASSWORD + "\",\"returnSecureToken\":true}";
int httpCode = httpAuth.POST(authPayload);
if (httpCode == 200) {
String response = httpAuth.getString();
int startIndex = response.indexOf("\"idToken\": \"") + 12;
int endIndex = response.indexOf("\"", startIndex);
idToken = response.substring(startIndex, endIndex);
Serial.println("✅ LOGIN REUSSI ! ESP32 est connecte.");
} else {
Serial.print("❌ ERREUR LOGIN: "); Serial.println(httpCode);
}
httpAuth.end();
}
}
void setup() {
Serial.begin(115200);
pinMode(BTN_CRASH, INPUT_PULLUP);
pinMode(LED_SOS, OUTPUT);
pinMode(LED_FRIGO, OUTPUT);
pinMode(LED_CHAUFFAGE, OUTPUT);
pinMode(LED_EXTRACTION, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
dht.begin();
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
SD.begin(SD_CS_PIN);
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
display.setTextSize(1);
display.setCursor(15, 20); display.println("SMART-SOUSS OS");
display.setCursor(10, 40); display.println("Connexion WiFi...");
display.display();
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.print("Connexion au WiFi");
while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); }
Serial.println("\nWiFi Connecte !");
authentifierFirebase();
delay(1000);
}
void loop() {
if (digitalRead(BTN_CRASH) == LOW) { sosActif = true; }
if (millis() - lastGPSTime > 8000 && !sosActif) {
indexGPS++; if(indexGPS >= 5) indexGPS = 0;
lastGPSTime = millis();
}
if (millis() - lastTime > 4000) {
temp = dht.readTemperature();
hum = dht.readHumidity();
int potValue = analogRead(POT_PIN);
int qualite = map(potValue, 0, 4095, 100, 0);
reseauActif = (random(0, 4) != 0) && (WiFi.status() == WL_CONNECTED);
float tempMin, tempMax;
String nomProduit = (TYPE_PRODUIT == 1) ? "T. CERISE" : "FRAMBOISE";
if (TYPE_PRODUIT == 1) { tempMin = 10.0; tempMax = 12.0; } else { tempMin = 0.0; tempMax = 2.0; }
bool coolingActive = false, heatingActive = false, extractActive = false;
if (temp > tempMax) { digitalWrite(LED_FRIGO, HIGH); digitalWrite(LED_CHAUFFAGE, LOW); coolingActive = true; }
else if (temp < tempMin) { digitalWrite(LED_FRIGO, LOW); digitalWrite(LED_CHAUFFAGE, HIGH); heatingActive = true; }
else { digitalWrite(LED_FRIGO, LOW); digitalWrite(LED_CHAUFFAGE, LOW); }
if (qualite < 60) { digitalWrite(LED_EXTRACTION, HIGH); extractActive = true; } else { digitalWrite(LED_EXTRACTION, LOW); }
if (sosActif) { digitalWrite(LED_SOS, HIGH); tone(BUZZER_PIN, 1000); }
display.clearDisplay();
display.fillRect(0, 0, 128, 12, SSD1306_WHITE);
display.setTextColor(SSD1306_BLACK);
display.setCursor(3, 2); display.print(" CHAUFFEUR: HASSAN ");
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 15); display.print("PRODUIT: "); display.print(nomProduit);
display.setCursor(0, 27); display.print("Tmp:"); display.print(temp, 1); display.print("C | Qlt:"); display.print(qualite); display.print("%");
display.setCursor(0, 39); display.print("Lieu: "); display.print(nomVilles[indexGPS]);
display.drawLine(0, 48, 128, 48, SSD1306_WHITE);
display.setCursor(0, 52);
if (sosActif) { display.print("!!! URGENCE CRASH !!!"); }
else {
if (coolingActive) display.println("> ALERTE: FRIGO ON");
else if (heatingActive) display.println("> ALERTE: CHAUFFAGE ON");
else if (extractActive) display.println("> ALERTE: FILTRE ON");
else display.println("> ETAT: NORMAL");
}
display.display();
String jsonPayload = "{\"chauffeur\":\"Hassan\", \"produit\":\"" + nomProduit + "\", \"temperature\":" + String(temp) + ", \"qualite_air\":" + String(qualite) + ", \"latitude\":" + String(routeGPS[indexGPS][0], 4) + ", \"longitude\":" + String(routeGPS[indexGPS][1], 4) + ", \"ville_actuelle\":\"" + nomVilles[indexGPS] + "\", \"alerte_urgence\":" + String(sosActif) + "}";
if (reseauActif && idToken != "") {
Serial.println("\n[INTERNET OK] - Envoi Protege par Token...");
// K-n-khdmo b client securisé hta f l'envoi dyal l'Data
WiFiClientSecure clientData;
clientData.setInsecure();
HTTPClient http;
String urlAvecSecurite = FIREBASE_URL + "?auth=" + idToken;
http.begin(clientData, urlAvecSecurite); // Zdna 'clientData' hna
http.addHeader("Content-Type", "application/json");
int httpResponseCode = http.PUT(jsonPayload);
if (httpResponseCode == 200) {
Serial.print("✅ SUCCES 200 ! Donnees acceptees par Firebase.");
if (sosActif) Serial.println(" 🚨 [URGENCE] Localisation envoyee a l'hopital !");
} else {
Serial.print("❌ Erreur HTTP: "); Serial.println(httpResponseCode);
}
http.end();
} else {
Serial.println("\n[HORS LIGNE] - Perte de signal WiFi awla Login Faux !");
File logFile = SD.open("/log.txt", FILE_APPEND);
if (logFile) { logFile.println(jsonPayload); logFile.close(); }
}
lastTime = millis();
}
}