Files
Arduino/ESP8266_VELUX/ESP8266_VELUX.ino
Jérôme Delacotte 7b30d6e298 first commit
2025-03-06 11:15:32 +01:00

629 lines
18 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//#include <ArduinoJson.h>
#include <EEPROM.h>
#include <Ticker.h>
#include <ArduinoJson.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
void tick();
Ticker timer(tick, 1000); ;
Ticker timer2(tick, 1000); ;
// Adresse de départ dans l'EEPROM pour stocker la variable
#define EEPROM_ADDRESS 0
#define MAX_TIME 30
struct To_Store {
int max_time[2];
int theorique_position[2];
};
To_Store to_store;
// Time to sleep (in seconds):
const int sleepTimeS = 10;
// =======================
// WIFI
// =======================
#include <ESP8266WebServer.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
// Your WiFi credentials.
// Set password to "" for open networks.
const char* ssid = "Livebox-37cc";
const char* pass = "8A6060920A8A86896F770F2C47";
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 0, 0);
IPAddress DNS(192, 168, 1, 1);
ESP8266WebServer server(80);
const char* host = "192.168.1.3";
const int port = 81;
const char* apiEndpoint = "/json.htm?type=command&param=getSunRiseSet";
unsigned long lastUpdateTime = 0;
const unsigned long updateInterval = 5 * 60 * 1000; // 5 minutes en millisecondes
String currentTime = "";
String sunriseTime = "";
String sunsetTime = "";
// =======================
// MOTOR
// =======================
bool motor_is_running[2] = {false, false};
String sens[2] = {"", ""};
int mmin = 0;
String error = "";
String date = "";
String heure = "";
#define PIN_1 0 //=D6 was D3
#define PIN_2 2 //=D7 was D4
#define PIN_3 4
#define PIN_4 5
//#define PIN_1 17 //=D6 was D3
//#define PIN_2 18 //=D7 was D4
//#define PIN_3 19
//#define PIN_4 20
int getValueFromParam(String param_key);
void setup() {
// initialize digital pin LED_BUILTIN as an output.
Serial.begin(115200);
pinMode(PIN_1, OUTPUT);
pinMode(PIN_2, OUTPUT);
pinMode(PIN_3, OUTPUT);
pinMode(PIN_4, OUTPUT);
stop(1);
stop(2);
Serial.println("Motors initialized.");
delay(10);
// Connectez-vous au réseau WiFi
WiFi.begin(ssid, pass);
Serial.println("Connexion au WiFi en cours.");
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("");
Serial.println("Connecté au réseau WiFi");
Serial.println(WiFi.localIP());
// Définissez les gestionnaires pour les différentes URL
server.on("/", HTTP_GET, handleRoot);
server.on("/forward", HTTP_GET, handleForward);
server.on("/backward", HTTP_GET, handleBackward);
server.on("/stop", HTTP_GET, handleStop);
server.on("/reset", HTTP_GET, handleReset);
server.on("/setFinCourse", HTTP_GET, handleFinCourse);
server.on("/add", HTTP_GET, handleAdd);
server.on("/sub", HTTP_GET, handleSub);
server.on("/data", HTTP_GET, handleData);
// Démarrer le serveur
server.begin();
Serial.println("Serveur Web démarré");
// Initialisation de l'EEPROM
EEPROM.begin(sizeof(To_Store));
// Lire la valeur stockée dans l'EEPROM
EEPROM.get(EEPROM_ADDRESS, to_store);
if (to_store.max_time[0] == 0) {
to_store.max_time[0] = MAX_TIME;
}
if (to_store.theorique_position[0] == 0) {
to_store.theorique_position[0] = 0;
}
if (to_store.max_time[1] == 0) {
to_store.max_time[1] = MAX_TIME;
}
if (to_store.theorique_position[1] == 0) {
to_store.theorique_position[1] = 0;
}
///////////////////////////////////
// UPDATE OTA
///////////////////////////////////
// Port defaults to 8266
ArduinoOTA.setPort(8266);
// Hostname defaults to esp8266-[ChipID]
//ArduinoOTA.setHostname("ESP8266_VELUX_NORD_1");
// No authentication by default
// ArduinoOTA.setPassword("admin");
// Password can be set with it's md5 value as well
// MD5(admin) = 21232f297a57a5a743894a0e4a801fc3
// ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");
ArduinoOTA.onStart([]() {
Serial.println("Start");
});
ArduinoOTA.onEnd([]() {
Serial.println("\nEnd");
});
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
});
ArduinoOTA.onError([](ota_error_t error) {
Serial.printf("Error[%u]: ", error);
if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
else if (error == OTA_END_ERROR) Serial.println("End Failed");
});
ArduinoOTA.begin();
getSunRiseSet();
}
void tick() {
for (int button = 0; button < 2; button ++) {
if (motor_is_running[button]) {
Serial.print(button);
Serial.print(" ");
Serial.println("La méthode est appelée toutes les 1 seconde !");
if (sens[button] == "backward") {
to_store.theorique_position[button] --;
Serial.println("Backward is running " + String(to_store.theorique_position[button]));
}
else {
to_store.theorique_position[button] ++;
Serial.println("Forward is running " + String(to_store.theorique_position[button]));
}
EEPROM.put(EEPROM_ADDRESS, to_store);
EEPROM.commit();
if (to_store.theorique_position[button] < 0 || to_store.theorique_position[button] > to_store.max_time[button]) {
Serial.println("Stop running " + String(to_store.theorique_position[button]) + " / " + String(to_store.max_time[button]));
stop(button);
}
}
}
}
void loop() {
// getJson();
ArduinoOTA.handle();
// Gérez les requêtes du serveur
server.handleClient();
if (millis() - lastUpdateTime >= updateInterval) {
// Appeler la méthode getSunRiseSet
getSunRiseSet();
// Mettre à jour le temps de la dernière mise à jour
lastUpdateTime = millis();
}
timer.update();
timer2.update();
}
void getJson()
{
// // Host
// const char* host = "192.168.1.3";
// const int port = 81;
// Logging data to cloud
Serial.print("Connecting to ");
Serial.println(host);
// Use WiFiClient class to create TCP connections
WiFiClient client;
if (!client.connect(host, port)) {
Serial.println("connection failed");
return;
}
// This will send the request to the server
client.print(String("GET /json.htm?type=command&param=getSunRiseSet") + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n\r\n");
delay(10);
// Read all the lines of the reply from server and print them to Serial
String json = "";
while(client.available()){
String line = client.readStringUntil('\r');
//Serial.print(line);
json += line;
}
Serial.println(json);
delay(1000);
}
void handleRoot() {
// Générer la page HTML avec CSS
String html = "<html><head>";
html += "<meta charset='UTF-8'>";
html += "<meta name='viewport' content='width=device-width, initial-scale=1.0'>";
html += "<link type='text/css' rel='stylesheet' href='http://192.168.1.3:81/velux/velux.css'>";
html += "<script src='http://192.168.1.3:81/velux/jquery.min.js'></script>";
html += "<script src='http://192.168.1.3:81/velux/velux.js'></script>";
// html += "<style>";
// html += "body { font-family: Arial, sans-serif; text-align: center; }";
// html += "h1 { color: #333; }";
// html += "form { margin: 10% auto; max-width: 100%; }";
// html += "input { padding: 1em; margin: 1em; }";
// html += "#buttons {list-style: none;}";
// html += "#button { display: inline-block; list-style-type: none;}";
// html += "@media (max-width: 600px) {li {display: block; margin: 5px 0;list-style-type: none;}}";
// html += "</style>";
html += "</head><body>";
html += "<h1>Controle du velux 1 " + String(to_store.theorique_position[0]) + "/" + String(to_store.max_time[0]) + "</h1>";
html += "<h1>Controle du velux 2 " + String(to_store.theorique_position[1]) + "/" + String(to_store.max_time[1]) + "</h1>";
html += "<h2>" + String(WiFi.localIP().toString()) + "</h2>";
html += "<h2>" + String(sunriseTime) + " " + String(sunsetTime) + "</h2>";
for (int button=0; button < 2;button ++) {
html += "<ul class='buttons'>";
html += "<li class='button' onclick='showNotification()'><form action='/reset?button=" + String(button) + "' method='get'>";
html += "<input type='input' hidden name='button' value='" + String(button) + "'>";
html += "<input type='submit' value='Reset'>";
html += "</form></li>";
html += "<li class='button' onclick='showNotification()'><form action='/setFinCourse?button=" + String(button) + "' method='get'>";
html += "<input type='input' hidden name='button' value='" + String(button) + "'>";
html += "<input type='submit' value='Set Bas'>";
html += "</form></li>";
html += "<li class='button' onclick='showNotification()'><form action='/forward?button=" + String(button) + "' method='get'>";
// html += "<input type='hidden' id='time' name='time' value='" + String(to_store.max_time - to_store.theorique_position) + "'>";
html += "<input type='input' hidden name='button' value='" + String(button) + "'>";
html += "<input type='submit' value='Descendre'>";
html += "</form></li>";
html += "<li class='button' onclick='showNotification()'><form action='/backward?button=" + String(button) + "' method='get'>";
html += "<input type='input' hidden name='button' value='" + String(button) + "'>";
html += "<input type='submit' value='Monter'>";
html += "</form></li>";
html += "<li class='button' onclick='showNotification()'><form action='/stop?button=" + String(button) + "' method='get'>";
html += "<input type='input' hidden name='button' value='" + String(button) + "'>";
html += "<input type='submit' value='Arr&eacute;ter'>";
html += "</form></li>";
html += "<li class='button' onclick='showNotification()'><form action='/add?button=" + String(button) + "' method='get'>";
html += "<input type='input' hidden name='button' value='" + String(button) + "'>";
html += "<input type='submit' value=' temps'>";
html += "</form></li>";
html += "<li class='button' onclick='showNotification()'><form action='/sub?button=" + String(button) + "' method='get'>";
html += "<input type='input' hidden name='button' value='" + String(button) + "'>";
html += "<input type='submit' value='Diminuer temps'>";
html += "</form></li>";
html += "</ul>";
}
if (error != "") {
html += "<p>" + error + "</p>";
}
html += "<div id='notification' class='notification'></div>";
html += "</body></html>";
// Envoyer la page HTML au client
server.send(200, "text/html", html);
}
void handleReset() {
mmin = 0;
int button = getValueFromParam("button");
to_store.theorique_position[button] = 0;
to_store.max_time[button] = MAX_TIME;
EEPROM.put(EEPROM_ADDRESS, to_store);
EEPROM.commit();
// Vous pouvez ajouter ici le code pour traiter la vitesse comme vous le souhaitez
// Rediriger vers la page principale après le traitement
server.sendHeader("Location", "/");
server.send(302, "text/plain", "Redirection vers la page principale");
}
void handleFinCourse() {
int button = getValueFromParam("button");
to_store.max_time[button] = to_store.theorique_position[button];
EEPROM.put(EEPROM_ADDRESS, to_store);
EEPROM.commit();
// Vous pouvez ajouter ici le code pour traiter la vitesse comme vous le souhaitez
// Rediriger vers la page principale après le traitement
server.sendHeader("Location", "/");
server.send(302, "text/plain", "Redirection vers la page principale");
}
void handleForward() {
int button = getValueFromParam("button");
stop(button);
error = "";
if (to_store.theorique_position[button] >= to_store.max_time[button]) {
error = "La position actuelle est maximale";
server.sendHeader("Location", "/");
server.send(302, "text/plain", "Redirection vers la page principale");
return;
}
motor_is_running[button] = true;
sens[button] = "forward";
Serial.println("avance");
if (button == 1) {
digitalWrite(PIN_4, HIGH);
digitalWrite(PIN_3, LOW);
timer.start();
}
if (button == 0) {
digitalWrite(PIN_2, HIGH);
digitalWrite(PIN_1, LOW);
timer2.start();
}
delay(200);
Serial.println(readVcc());
Serial.println("avance fin");
// Vous pouvez ajouter ici le code pour traiter la vitesse comme vous le souhaitez
// Rediriger vers la page principale après le traitement
server.sendHeader("Location", "/");
server.send(302, "text/plain", "Redirection vers la page principale");
}
void handleBackward() {
int button = getValueFromParam("button");
stop(button);
error = "";
if (to_store.theorique_position[button] <= mmin) {
error = "La position actuelle est minimale";
server.sendHeader("Location", "/");
server.send(302, "text/plain", "Redirection vers la page principale");
return;
}
motor_is_running[button] = true;
sens[button] = "backward";
Serial.println("recule");
if (button == 1) {
digitalWrite(PIN_4, LOW);
digitalWrite(PIN_3, HIGH);
timer.start();
}
if (button == 0) {
digitalWrite(PIN_2, LOW);
digitalWrite(PIN_1, HIGH); // turn the LED on (HIGH is the voltage level)
timer2.start();
}
delay(200);
Serial.println(readVcc());
Serial.println("recule fin");
// Vous pouvez ajouter ici le code pour traiter la vitesse comme vous le souhaitez
// Rediriger vers la page principale après le traitement
server.sendHeader("Location", "/");
server.send(302, "text/plain", "Redirection vers la page principale");
}
void handleStop() {
Serial.println("Arrêt");
int button = getValueFromParam("button");
stop(button);
// Vous pouvez ajouter ici le code pour gérer l'arrêt comme vous le souhaitez
// Rediriger vers la page principale après le traitement
server.sendHeader("Location", "/");
server.send(302, "text/plain", "Redirection vers la page principale");
}
void handleAdd() {
int button = getValueFromParam("button");
Serial.println("Arrêt");
stop(button);
to_store.max_time[button] ++;
EEPROM.put(EEPROM_ADDRESS, to_store);
EEPROM.commit();
// Vous pouvez ajouter ici le code pour gérer l'arrêt comme vous le souhaitez
// Rediriger vers la page principale après le traitement
server.sendHeader("Location", "/");
server.send(302, "text/plain", "Redirection vers la page principale");
}
void handleData() {
// Création d'un objet JSON
StaticJsonDocument<200> jsonDoc;
jsonDoc["sensor"] = "temperature";
jsonDoc["value"] = 25.5;
// Conversion de l'objet JSON en chaîne JSON
String jsonString;
serializeJson(jsonDoc, jsonString);
// Configuration de la réponse HTTP
server.sendHeader("Content-Type", "application/json");
server.send(200, "application/json", jsonString);
}
void handleSub() {
int button = getValueFromParam("button");
Serial.println("Arrêt");
stop(button);
to_store.max_time[button] --;
EEPROM.put(EEPROM_ADDRESS, to_store);
EEPROM.commit();
// Vous pouvez ajouter ici le code pour gérer l'arrêt comme vous le souhaitez
// Rediriger vers la page principale après le traitement
server.sendHeader("Location", "/");
server.send(302, "text/plain", "Redirection vers la page principale");
}
void stop(int button)
{
motor_is_running[button] = false;
sens[button] = "";
if (to_store.theorique_position[button] < 0) {
to_store.theorique_position[button] = 0;
}
if (to_store.theorique_position[button] > to_store.max_time[button]) {
to_store.theorique_position[button] = to_store.max_time[button];
}
if (button == 0) {
Serial.println("stop 0 ");
digitalWrite(PIN_1, HIGH);
digitalWrite(PIN_2, HIGH);
timer.stop();
}
if (button == 1) {
Serial.println("stop 1");
digitalWrite(PIN_3, HIGH);
digitalWrite(PIN_4, HIGH);
timer2.stop();
}
delay(200);
Serial.println("stop fin");
}
//--------------------------------------------------------------------------------------------------
// Read current supply voltage
//--------------------------------------------------------------------------------------------------
String readVcc() {
// most exact output
uint16_t v = ESP.getVcc();
float_t v_cal = ((float) v / 1024.0f);
char v_str[10];
dtostrf(v_cal, 5, 3, v_str);
sprintf(v_str, "%s", v_str);
Serial.print("Tension lue ");
Serial.println(String(v_str));
return String(v_str); //ESP.getVcc() / 1024.0f; // Vcc in millivolts
}
void getSunRiseSet() {
// Connecter à votre réseau WiFi
WiFiClient client;
if (client.connect(host, port)) {
// Effectuer la requête HTTP
client.print(String("GET ") + apiEndpoint + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n\r\n");
// Attendre la réponse
while (!client.available()) {
delay(10);
}
// Lire la réponse
String response;
while (client.available()) {
char c = client.read();
response = c;
// Vérifier si le JSON commence par '{' ou '['
if (c == '{' || c == '[') {
break;
}
}
// Lire le reste de la réponse JSON
while (client.available()) {
char c = client.read();
response += c;
}
Serial.println(response);
// Fermer la connexion
client.stop();
// Analyser la réponse JSON
DynamicJsonDocument doc(1024); // ajustez la taille du document en fonction de votre réponse JSON
deserializeJson(doc, response);
// Extraire les valeurs d'heure actuelle, lever du soleil et coucher du soleil
currentTime = String(doc["ServerTime"]);
sunriseTime = String(doc["Sunrise"]);
sunsetTime = String(doc["Sunset"]);
// Stocker les valeurs dans des variables ou faire autre chose avec elles
Serial.println("Heure actuelle : " + String(currentTime));
Serial.println("Lever du soleil : " + String(sunriseTime));
Serial.println("Coucher du soleil : " + String(sunsetTime));
} else {
Serial.println("Échec de la connexion au serveur");
}
}
int getValueFromParam(String param_key)
{
String message = "Number of args received:";
message += server.args();
for (int i = 0; i < server.args(); i++) {
message = message + ("Arg nº" + String(i) + " > ");
message = message + (server.argName(i) + ": ");
message = message + (server.arg(i) + "\n");
if (param_key.equals(server.argName(i))) {
Serial.println(message);
return String(server.arg(i)).toInt();
}
}
Serial.println(message);
return 0;
}