/*
#define led1Pin 15
#define led2Pin 2
#define led3Pin 4
#define led4Pin 16
#define led5Pin 17
#define led6Pin 5
#define led7Pin 18
*/
// !!!!!!!!!!!! Les librairies !!!!!!!!!!!!!!
#include <WiFi.h>
#include <WiFiUdp.h>
#include <NTPClient.h>
#include <TimeLib.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <WiFiClient.h>
#include <WebServer.h>
#include <ESPmDNS.h>
#include <Update.h>
// !!!!!!!!!!!!!!Déclarer variables PERSO!!!!!!!!!!!!!!!
// Coordonnées géographiques de votre emplacement
const float latitude = 44.889153;
const float longitude = 4.652633;
// Configuration des broches utilisées
const int ALIM_RELAY_PIN = 2; // Broche du contacteur de l'alim
const int MOTOR_RELAY_PIN = 4; // Broche du contacteur du moteur
const int END_SWITCH_PIN = 15; // Broche de l'interrupteur de fin de course
// Définissez les dates de début et de fin de l'heure d'été en France (année en cours)
const int daylightBeginDay = 28;
const int daylightBeginMonth = 3; // Mars
const int daylightEndDay = 31;
const int daylightEndMonth = 10; // Octobre
const int timeToOpen_ms = 2000; // Le temps que le moteur doit tourner pour ouvrir totalement la porte
// !!!!!!!!!!!!!!!! Variables pour le code, perso !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// Remplacez les valeurs suivantes par votre SSID et votre mot de passe WiFi
const char* ssid = "Wokwi-GUEST";
const char* password = "";
// Définissez l'adresse IP et le port du serveur NTP
const char* ntpServer = "pool.ntp.org";
// Définir l'adresse IP et le port du serveur sunrise-sunset
const char* serverIP = "api.sunrise-sunset.org";
const int serverPort = 80;
// Valeurs de temps et Offsets
int gmtOffset_sec = 3600; // Décalage horaire en secondes (UTC+1 pour la France)
int gmtOffset_hour ; // Décalage horaire en Heures (UTC+1 pour la France)
time_t yearVar = 0;
time_t monthVar = 0;
int dayVar = 0;
bool doorIsOpen = true;
bool isItDaytime ;
// Store et extrait les valeurs aux bons noms
int currentHour;
int currentMin;
int sunriseHour;
int sunsetHour;
int sunriseMin;
int sunsetMin;
int epoch;
const char* sunrise;
const char* sunset;
// Déclarez un objet NTPClient pour récupérer l'heure du serveur NTP
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, ntpServer, gmtOffset_sec);
// !!!!!!!!!!!!!!!!!!! OTA !!!!!!!!!!!!!!!!!!
WebServer server(80);
const char* host = "esp32";
/*
* Login page
*/
const char* loginIndex =
"<form name='loginForm'>"
"<table width='20%' bgcolor='A09F9F' align='center'>"
"<tr>"
"<td colspan=2>"
"<center><font size=4><b>ESP32 Login Page</b></font></center>"
"<br>"
"</td>"
"<br>"
"<br>"
"</tr>"
"<td>Username:</td>"
"<td><input type='text' size=25 name='userid'><br></td>"
"</tr>"
"<br>"
"<br>"
"<tr>"
"<td>Password:</td>"
"<td><input type='Password' size=25 name='pwd'><br></td>"
"<br>"
"<br>"
"</tr>"
"<tr>"
"<td><input type='submit' onclick='check(this.form)' value='Login'></td>"
"</tr>"
"</table>"
"</form>"
"<script>"
"function check(form)"
"{"
"if(form.userid.value=='admin' && form.pwd.value=='admin')"
"{"
"window.open('/serverIndex')"
"}"
"else"
"{"
" alert('Error Password or Username')/*displays error message*/"
"}"
"}"
"</script>";
/*
* Server Index Page
*/
const char* serverIndex =
"<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js'></script>"
"<form method='POST' action='#' enctype='multipart/form-data' id='upload_form'>"
"<input type='file' name='update'>"
"<input type='submit' value='Update'>"
"</form>"
"<div id='prg'>progress: 0%</div>"
"<script>"
"$('form').submit(function(e){"
"e.preventDefault();"
"var form = $('#upload_form')[0];"
"var data = new FormData(form);"
" $.ajax({"
"url: '/update',"
"type: 'POST',"
"data: data,"
"contentType: false,"
"processData:false,"
"xhr: function() {"
"var xhr = new window.XMLHttpRequest();"
"xhr.upload.addEventListener('progress', function(evt) {"
"if (evt.lengthComputable) {"
"var per = evt.loaded / evt.total;"
"$('#prg').html('progress: ' + Math.round(per*100) + '%');"
"}"
"}, false);"
"return xhr;"
"},"
"success:function(d, s) {"
"console.log('success!')"
"},"
"error: function (a, b, c) {"
"}"
"});"
"});"
"</script>";
void setup() {
Serial.begin(9600);
// Connexion au réseau WiFi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connexion au WiFi en cours...");
}
Serial.println("Connexion au WiFi établie");
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
// Initialisation de l'objet NTPClient
timeClient.begin();
// Initialisation des relais et de l'interrupteur de fin de course
pinMode(ALIM_RELAY_PIN, OUTPUT); // Broche du contacteur de l'alim
pinMode(MOTOR_RELAY_PIN, OUTPUT); // Broche du contacteur du moteur
pinMode(END_SWITCH_PIN, INPUT_PULLUP);
// OTA
/*use mdns for host name resolution*/
if (!MDNS.begin(host)) { //http://esp32.local
Serial.println("Error setting up MDNS responder!");
while (1) {
delay(1000);
}
}
Serial.println("mDNS responder started");
/*return index page which is stored in serverIndex */
server.on("/", HTTP_GET, []() {
server.sendHeader("Connection", "close");
server.send(200, "text/html", loginIndex);
});
server.on("/serverIndex", HTTP_GET, []() {
server.sendHeader("Connection", "close");
server.send(200, "text/html", serverIndex);
});
/*handling uploading firmware file */
server.on("/update", HTTP_POST, []() {
server.sendHeader("Connection", "close");
server.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK");
ESP.restart();
}, []() {
HTTPUpload& upload = server.upload();
if (upload.status == UPLOAD_FILE_START) {
Serial.printf("Update: %s\n", upload.filename.c_str());
if (!Update.begin(UPDATE_SIZE_UNKNOWN)) { //start with max available size
Update.printError(Serial);
}
} else if (upload.status == UPLOAD_FILE_WRITE) {
/* flashing firmware to ESP*/
if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
Update.printError(Serial);
}
} else if (upload.status == UPLOAD_FILE_END) {
if (Update.end(true)) { //true to set the size to the current progress
Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize);
} else {
Update.printError(Serial);
}
}
});
server.begin();
}
void getDate() {
// Mise à jour de l'heure depuis le serveur NTP
timeClient.update();
epoch = timeClient.getEpochTime();
dayVar = day(epoch);
monthVar = month(epoch);
yearVar = year(epoch);
}
bool isDaylightTime( int month, int day) {
if ((month > daylightBeginMonth && month < daylightEndMonth) ||
(month == daylightBeginMonth && day >= daylightBeginDay) ||
(month == daylightEndMonth && day <= daylightEndDay)) {
return true;
} else {
return false;
}
}
void isDaylightTimeCheckup_gmtOffset() {
bool isDST = isDaylightTime(monthVar, dayVar);
if (isDST) {
// Serial.println("La date d'aujourd'hui est à passer à l'heure d'été");
gmtOffset_sec = 3600;
gmtOffset_hour = 2;
}
else {
//Serial.println("La date d'aujourd'hui est à laisser en heure d'hiver");
gmtOffset_sec = 0;
gmtOffset_hour = 1;
}
}
void openDoorFunction() {
digitalWrite(MOTOR_RELAY_PIN, LOW);
delay (1000);
digitalWrite(ALIM_RELAY_PIN, HIGH);
delay (timeToOpen_ms);
digitalWrite(ALIM_RELAY_PIN, LOW);
}
void closeDoorFunction() {
digitalWrite(MOTOR_RELAY_PIN, HIGH);
delay (1000);
digitalWrite(ALIM_RELAY_PIN, HIGH);
while (END_SWITCH_PIN == HIGH) {
delay (100);
}
digitalWrite(ALIM_RELAY_PIN, LOW);
}
void loop() {
server.handleClient();
getDate();
isDaylightTimeCheckup_gmtOffset();
int epoch = 0;
epoch = timeClient.getEpochTime()+gmtOffset_sec;
// Appel de l'API sunrise-sunset pour récupérer les données
String url = "/json?lat=" + String(latitude) + "&lng=" + String(longitude) + "&formatted=0";
HTTPClient http;
http.begin(serverIP, serverPort, url);
int httpResponseCode = http.GET();
if (httpResponseCode == 200) {
String payload = http.getString();
// Parse la réponse JSON
DynamicJsonDocument doc(1024);
deserializeJson(doc, payload);
sunrise = doc["results"]["sunrise"];
sunset = doc["results"]["sunset"];
// Store et extrait les valeurs aux bons noms
currentHour = hour(epoch);
currentMin = minute(epoch);
sunriseHour = atoi(&sunrise[11]) + gmtOffset_hour;
sunsetHour = atoi(&sunset[11]) + gmtOffset_hour;
sunriseMin = atoi(&sunrise[14]);
sunsetMin = atoi(&sunset[14]);
}
else {
Serial.println("Erreur lors de l'appel de l'API sunrise-sunset");
Serial.println("_____________!!!!!!!!!!!!!!!!!!!!!!!!!!!!!___________________");
}
if ((currentHour > sunriseHour && currentHour < sunsetHour) ||
(currentHour == sunriseHour && currentMin >= sunriseMin) ||
(currentHour == sunsetHour && currentMin <= sunsetMin)) {
isItDaytime = true; // Il fait jour
Serial.println("Il fait jour ");
Serial.println("________________________________");
}
else {
isItDaytime = false; // Il fait nuit
Serial.println("Il fait nuit ");
Serial.println("________________________________");
}
if (isItDaytime != doorIsOpen) {
if (doorIsOpen) {
closeDoorFunction();
doorIsOpen = false;
Serial.println("La porte a été fermée");
Serial.println("________________________________");
}
else {
openDoorFunction();
doorIsOpen = true;
Serial.println("La porte a été ouverte");
Serial.println("________________________________");
}
}
else {
Serial.println("La porte reste dans son état précédent");
Serial.println("________________________________");
}
// DEBUGGING ON SERIAL MONITOR
Serial.print("CurrentHour : ");
Serial.println(currentHour);
Serial.print("CurrentMin : ");
Serial.println(currentMin);
Serial.println("________________________________");
Serial.print("Heure sunset : ");
Serial.println(sunsetHour);
Serial.print("Min sunset : ");
Serial.println(sunsetMin);
Serial.println("________________________________");
Serial.print("Sunset complet: ");
Serial.println(sunset);
Serial.println("________________________________");
Serial.print("Heure sunrise : ");
Serial.println(sunriseHour);
Serial.print("Min sunrise : ");
Serial.println(sunriseMin);
Serial.println("________________________________");
Serial.print("Sunrise complet: ");
Serial.println(sunrise);
Serial.println("________________________________");
Serial.print("Heure actuelle Timeclient: ");
Serial.println(timeClient.getFormattedTime());
Serial.println("________________________________");
Serial.print("Date actuelle calculée: ");
Serial.print(dayVar);
Serial.print("/");
Serial.print(monthVar);
Serial.print("/");
Serial.println(yearVar);
Serial.println("________________________________________________");
delay(1000); // Attendre 1 seconde avant la prochaine mise à jour
}
/*
void loop() {
digitalWrite(led1Pin, HIGH);
delay(1000);
digitalWrite(led2Pin, HIGH);
delay(1000);
digitalWrite(led3Pin, HIGH);
delay(1000);
digitalWrite(led4Pin, HIGH);
delay(1000);
digitalWrite(led5Pin, HIGH);
delay(1000);
digitalWrite(led6Pin, HIGH);
delay(1000);
digitalWrite(led7Pin, HIGH);
delay(2000);
digitalWrite(led1Pin, LOW);
digitalWrite(led2Pin, LOW);
digitalWrite(led3Pin, LOW);
digitalWrite(led4Pin, LOW);
digitalWrite(led5Pin, LOW);
digitalWrite(led6Pin, LOW);
digitalWrite(led7Pin, LOW);
delay(1000);
}*/