Files
Arduino/ESP8266_DIMMER/ESP8266_DIMMER.ino
2025-07-01 18:25:48 +02:00

541 lines
13 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.
/////////////////////
// Domoticz Classe
/////////////////////
#include "ESP8266_DIMMER.h"
#include <ESP8266WebServer.h>
void handleRoot(void);
int getValueFromParam();
void setPwm(int pwm);
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);
// DIMMER
ESP8266WebServer server(80);
void ICACHE_RAM_ATTR handleInterrupt();
#define HOSTNAME "ESP8266_RADIATEUR"
// Dimmer
#include <RBDdimmer.h>//
#define LEDn 15
#define outputPin 13 // D7
#define zerocross 12 // D6 for boards with CHANGEBLE input pins
#define pas 5
bool led;
int pwm;
int pwmCount;
dimmerLamp dimmer(outputPin, zerocross); //initialase port for dimmer for ESP8266, ESP32, Arduino due boards
//dimmerLamp dimmer(outputPin); //initialase port for dimmer for MEGA, Leonardo, UNO, Arduino M0, Arduino Zero
String webpage = R"=(
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LED Control</title>
<link type='text/css' rel='stylesheet' href='http://192.168.1.3:81/velux/style.css'>
<script>
var xmlHttp01=createXmlHttpObject();
var previous_value = 10;
function createXmlHttpObject(){
if(window.XMLHttpRequest){
xmlHttp=new XMLHttpRequest();
}else{
xmlHttp=new ActiveXObject('Microsoft.XMLHTTP');
}
return xmlHttp;
}
function process(){
if(xmlHttp01.readyState==0 || xmlHttp01.readyState==4){
xmlHttp01.open('GET','getData',true);
xmlHttp01.onreadystatechange=handleServerResponse;
xmlHttp01.send(null);
}
setTimeout('process()', 30000);
}
function handleServerResponse(){
var field = document.getElementById('current_value');
if(field && xmlHttp01.readyState == 4 && xmlHttp01.status == 200){
const json_obj = JSON.parse(xmlHttp01.response);
// console.log(xmlHttp01.response);
const values = Object.values(json_obj);
var value = values[1]
if (value != previous_value) {
let button = document.querySelector('.arcade-button');
button.classList.add('gradient'); // Ajoute l'effet
setTimeout(() => button.classList.remove('gradient'), 3000);
previous_value = value;
}
field.textContent = value
}
}
</script>
<style>
body {
align-content: center;
background-color: #3498db;
color: white;
display: flex;
font-family: 'Arial', sans-serif;
margin: 0;
padding: 0;
flex-wrap: wrap;
justify-content: space-around;
align-items: center;
width: 300px;
}
.control-container {
background: #66cc66;
width: 256px;
height: 64px;
margin: 10px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
transition: background-color 0.3s ease-in-out; /* Ajout de la transition */
}
h2,button {
margin: 0;
font-size: 1rem;
}
p {
font-size: 1.2rem;
margin-top: 20px;
}
/* Ajout des styles au survol ou au clic */
.control-container:hover,
.control-container:active {
background-color: #a0a0a0;
}
.arcade-button {
display: inline-block;
position: relative;
width: 150px;
height: 150px;
background-color: #005599;
border: 10px solid #2c3e50;
border-radius: 50%;
overflow: hidden;
cursor: pointer;
transition: background-color 0.3s ease-in-out;
}
.arcade-button:hover {
background-color: #2980b9;
}
.container {
display: flex;
flex-direction: column;
width: 100%;
align-content: center;
align-items: center;
}
header {
background-color: #003366;
padding: 1rem;
text-align: center;
}
.header_info {
display: flex;
}
.header_info h2 {
margin: 0 10px;
}
h1, h2 {
color: white;
margin: 0;
}
.button-content {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: #ecf0f1;
font-size: 1.5rem;
text-align: center;
}
/* Effet Flash */
.arcade-button.flash {
animation: flash 0.3s;
}
@keyframes flash {
0% { background-color: #005599; }
50% { background-color: red; }
100% { background-color: #005599; }
}
/* Animation fluide entre rouge et orange */
@keyframes smoothGradient {
0% { background-color: #005599; }
50% { background-color: orange; }
100% { background-color: #005599; }
}
.arcade-button.gradient {
animation: smoothGradient 3s ease-in-out; /* Durée ajustable */
}
</style>
</head>
<body onload='process()'>
<div class="container">
<header>
<h1>Surplux solaire</h1>
<div class="header_info">
<h2>@@IP@@</h2>
</div>
</header>
<div class="control-container" id="LEDn">
<button onclick="alert('on');">ON</button>
</div>
<div class="control-container" id="pwmplus">
<a href="/plus?value=10">Plus</a>
</div>
<div class="control-container" id="pwmminus">
<a href="/minus?value=10">Minus</a>
</div>
<div class="control-container" id="pwmstop">
<a href="/stop">Stop</a>
</div>
<div class="arcade-button">
<div class="button-content" id='current_value'>@@pwmCount@@</div>
</div>
</div>
</body>
</html>
)=";
void ledON(){
led=1;
digitalWrite(LEDn, led);
handleRoot();
}
void ledOFF(){
led=0;
digitalWrite(LEDn, led);
handleRoot();
}
//pwm functions - if pwm is set to 1/-1 it will in-/decrease pwmCounter in loop()
void exact(){
int value_to_set = getValueFromParam();
pwm=value_to_set;
pwmCount = pwm;
if (pwmCount>100) pwmCount = 100;
if (pwmCount < 0) {
pwmCount = 0;
}
Serial.println(pwmCount);
//dimmer.setPower(pwmCount);
setPwm(pwmCount);
handleRoot();
}
void plus(){
int value_to_set = getValueFromParam();
if (value_to_set <= 0) {
value_to_set = 5;
}
pwm+=value_to_set;
setPwm(pwm);
handleRoot();
}
void minus(){
int value_to_set = getValueFromParam();
if (value_to_set <= 0) {
value_to_set = 5;
}
pwm+=-value_to_set;
setPwm(pwm);
handleRoot();
}
void stopPWM(){
pwm=0; //-pwmCount;
setPwm(pwm);
handleRoot();
}
void setPwm(int pwm)
{
pwmCount = pwm;
if (pwmCount>100) pwmCount = 100;
if (pwmCount <= 1) {
pwmCount = 0;
}
Serial.println(pwmCount);
if (pwmCount <= 0) {
dimmer.setState(ON_OFF_typedef::OFF);
}
else {
dimmer.setState(ON_OFF_typedef::ON);
}
dimmer.setPower(pwmCount);
}
//----------------------------------------------------------------------------------
void handleRoot(void){
String page = webpage;
page.replace("@@pwmCount@@", String(pwmCount));
page.replace("@@IP@@", String(WiFi.localIP().toString()));
//Serial.println(page);
server.send(200, "text/html", page);
}
int getValueFromParam()
{
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 (server.argName(i) == "value") {
return String(server.arg(i)).toInt();
}
}
Serial.println(message);
return pas;
}
void initWifi()
{
WiFi.mode(WIFI_AP);
WiFi.begin(_ssid, _pass); //Connect to local Wifi
Serial.println();
Serial.print("Connecting to WiFi");
while (WiFi.status() != WL_CONNECTED)
{
Serial.print(".");
delay(500);
}
Serial.println("WiFi Connected!");
Serial.print("Connexion au reseau ");
Serial.println(WiFi.localIP());
}
void initWifiStatic(
IPAddress ip,
IPAddress gateway,
IPAddress subnet,
IPAddress DNS)
{
WiFi.config(ip, gateway, subnet, DNS);
delay(100);
WiFi.mode(WIFI_STA);
WiFi.begin(_ssid, _pass);
Serial.print("Connecting");
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(200);
}
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.println();
Serial.println("Fail connecting");
delay(5000);
ESP.restart();
}
Serial.print(" static OK ");
Serial.print("Module IP: ");
Serial.println(WiFi.localIP());
}
String generateKey()
{
// WiFi.mode(WIFI_AP);
// Do a little work to get a unique-ish name. Append the
// last two bytes of the MAC (HEX'd) to "Thing-":
uint8_t mac[WL_MAC_ADDR_LENGTH];
WiFi.softAPmacAddress(mac);
String macID = String(mac[WL_MAC_ADDR_LENGTH - 2], HEX) + String(mac[WL_MAC_ADDR_LENGTH - 1], HEX);
macID.toUpperCase();
String AP_NameString = "ESP8266 Thing " + macID;
char AP_NameChar[AP_NameString.length() + 1];
memset(AP_NameChar, 0, AP_NameString.length() + 1);
for (int i = 0; i < AP_NameString.length(); i++)
{
AP_NameChar[i] = AP_NameString.charAt(i);
}
// WiFi.softAP(AP_NameChar, WiFiAPPSK);
Serial.println("macID=" + macID);
return macID;
}
IPAddress getIP(String macId)
{
// IPAddress ip (192, 168, 1, 222);
//
// String fst = macId.substring(0, 2);
// String sec = macId.substring(2);
//
// char fstc[fst.length() + 1];
// fst.toCharArray(fstc, fst.length() + 1);
//
// char secc[sec.length() + 1];
// sec.toCharArray(secc, fst.length() + 1);
return IPAddress (192, 168, 1, 222); //IPAddress(192, 168, strtol(fstc, 0, 16), strtol(secc, 0, 16));
}
void handleData()
{
String JSON = F("");
JSON += "{\"id\":\"current\", \"value\":" + String(pwmCount) + "}";
JSON += "";
server.send(200, "application/json", JSON);
}
void setup()
{
Serial.begin(115200);
//delay(200);
String macId = generateKey();
IPAddress ip = getIP(macId);
// Conversion d'objet en pointeur
initWifiStatic(ip, gateway, subnet, DNS);
//Server________________________________
server.begin();
server.on("/", handleRoot);
// server.on("/LEDon", ledON);
// server.on("/LEDoff", ledOFF);
server.on("/minus", minus);
server.on("/plus", plus);
server.on("/exact", exact);
server.on("/stop", stopPWM);
server.on("/getData", handleData);
//initialize variables__________________
pwm = 0;
pwmCount= 0;
led = 0;
Serial.print("Module IP: ");
Serial.println(WiFi.softAPIP());
// Dimmer
Serial.println("Dimmer Program is starting...");
delay(1000);
dimmer.begin(NORMAL_MODE, ON); //dimmer initialisation: name.begin(MODE, STATE)
Serial.println("Set value");
dimmer.setState(ON_OFF_typedef::OFF);
dimmer.setPower(pwmCount); // setPower(0-100%);
// send temperature every 30s
// flipper.attach(30, flip);
// Port defaults to 8266
ArduinoOTA.setPort(8266);
// Hostname defaults to esp8266-[ChipID]
ArduinoOTA.setHostname(HOSTNAME);
// 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([]() {
String type;
if (ArduinoOTA.getCommand() == U_FLASH) {
type = "sketch";
} else { // U_FS
type = "filesystem";
}
// NOTE: if updating FS this would be the place to unmount FS using FS.end()
Serial.println("Start updating " + type);
});
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();
Serial.println("Ready");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
}
long temps = 0;
void loop()
{
server.handleClient();
ArduinoOTA.handle();
}