the programed timing doesnt seem to work i tried everything including AI...
if i controll the relays manualy by the webui everything works. the preprogramed hour/minute only works first time (turn on) the "ramp-up" "ramp-down" and "turn off" doesnt work what am i missing?
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
const char* ssid = "Gxxxx";
const char* password = "Gxxxxx";
const char* hostName = "t5";
IPAddress ip(192, 168, 1, 100); // Static IP address for Wemos Mini
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
ESP8266WebServer server(80);
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "194.58.203.148", 0, 60000); // Set timezone to UTC (0 seconds offset from UTC)
unsigned long relayStartTime[] = {0, 0, 0, 0, 0, 0, 0, 0}; // Array to store start time for each relay
bool relayAlreadyActivated[8] = {false, false, false, false, false, false, false, false};
String morningMessages[] = {
"good morning actinic channel",
"actinic 10%",
"actinic 30%",
"good morning blue+ channel",
"blue+ 10%",
"blue+ 30%",
"good morning coral+ channel",
"coral+ 10%",
"coral+ 30%",
"good morning other channel",
"other 10%",
"other 30%"
};
String eveningMessages[] = {
"actinic 100%",
"actinic 30%",
"actinic 10%",
"good night actinic channel",
"blue+ 100%",
"blue+ 30%",
"blue+ 10%",
"good night blue+ channel",
"coral+ 100%",
"coral+ 30%",
"coral+ 10%",
"good night coral+ channel",
"other 100%",
"other 30%",
"other 10%",
"good night other channel"
};
String serialData = ""; // Variable to store serial data
const unsigned long relayDurations[] = {
500, // Turn on relay 1 (500 ms)
500, // Turn on relay 2 (500 ms)
500, // Turn on relay 3 (500 ms)
500, // Turn on relay 4 (500 ms)
3000, // Ramp up relay 1 (3000 ms)
3000, // Ramp up relay 2 (3000 ms)
3000, // Ramp up relay 3 (3000 ms)
3000, // Ramp up relay 4 (3000 ms)
3000, // Ramp down relay 1 (3000 ms)
3000, // Ramp down relay 2 (3000 ms)
3000, // Ramp down relay 3 (3000 ms)
3000, // Ramp down relay 4 (3000 ms)
500, // Turn off relay 1 (500 ms)
500, // Turn off relay 2 (500 ms)
500, // Turn off relay 3 (500 ms)
500 // Turn off relay 4 (500 ms)
};
void setup() {
Serial.begin(115200); // Initialize serial communication
pinMode(D5, OUTPUT);
pinMode(D6, OUTPUT);
pinMode(D7, OUTPUT);
pinMode(D8, OUTPUT);
digitalWrite(D5, LOW);
digitalWrite(D6, LOW);
digitalWrite(D7, LOW);
digitalWrite(D8, LOW);
WiFi.hostname(hostName); // Set the local domain
WiFi.config(ip, gateway, subnet); // Set the static IP address
WiFi.begin(ssid, password);
Serial.println("Connecting to WiFi...");
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("");
Serial.println("Connected to WiFi");
Serial.println(WiFi.localIP());
Serial.println("Updating time from NTP server...");
timeClient.begin(); // Start NTP client
timeClient.setTimeOffset(3600); // Set timezone (1 hour in seconds for Europe, use -3600 for daylight saving time)
server.on("/", handleRoot);
server.on("/relay1", handleRelay1);
server.on("/relay2", handleRelay2);
server.on("/relay3", handleRelay3);
server.on("/relay4", handleRelay4); // Endpoint for serial data
server.on("/relay5", handleRelay5);
server.on("/relay6", handleRelay6);
server.on("/relay7", handleRelay7);
server.on("/relay8", handleRelay8);
server.begin();
}
void loop() {
timeClient.update(); // Update current time
server.handleClient();
unsigned long currentTime = timeClient.getEpochTime(); // Get current time in seconds
// Turn On
activateRelayAt(1, 21, 20, morningMessages[0], currentTime); // Adjust timings according to your desired timezone
activateRelayAt(2, 21, 21, morningMessages[3], currentTime);
activateRelayAt(3, 21, 22, morningMessages[6], currentTime);
activateRelayAt(4, 21, 23, morningMessages[9], currentTime);
// Ramp-up
activateRelayAt(5, 21, 24, morningMessages[2], currentTime); // Adjust timings according to your desired timezone
activateRelayAt(6, 21, 25, morningMessages[5], currentTime);
activateRelayAt(7, 21, 26, morningMessages[8], currentTime);
activateRelayAt(8, 21, 27, morningMessages[11], currentTime);
// Ramp-down
activateRelayAt(9, 21, 28, eveningMessages[2], currentTime); // Adjust timings according to your desired timezone
activateRelayAt(10, 21, 29, eveningMessages[6], currentTime);
activateRelayAt(11, 21, 30, eveningMessages[10], currentTime);
activateRelayAt(12, 21, 31, eveningMessages[14], currentTime);
// Turn Off
activateRelayAt(13, 21, 32, eveningMessages[3], currentTime); // Adjust timings according to your desired timezone
activateRelayAt(14, 21, 33, eveningMessages[7], currentTime);
activateRelayAt(15, 21, 34, eveningMessages[11], currentTime);
activateRelayAt(16, 21, 35, eveningMessages[15], currentTime);
delay(1000);
}
void handleRoot() {
String content = "<h1 style=\"text-align:center;font-size:48px;\">Glenn's reef 5.0 T5 control</h1>";
content += "<div style=\"text-align:center;font-size:32px;margin-bottom:20px;\">";
// Display current time with larger digits
content += "Current Time: <span id=\"current-time\"></span>";
content += "</div>";
content += "<div style=\"margin-bottom: 10px;text-align:center;\">";
// Buttons to activate relays with improved appearance
content += "<button class=\"relayButton\" onclick=\"activateRelay('/relay1', 'Actinic On/Off')\">Actinic On/Off</button>";
content += "<button class=\"relayButton\" onclick=\"activateRelay('/relay2', 'Blue+ On/Off')\">Blue+ On/Off</button>";
content += "<button class=\"relayButton\" onclick=\"activateRelay('/relay3', 'Coral+ On/Off')\">Coral+ On/Off</button>";
content += "<button class=\"relayButton\" onclick=\"activateRelay('/relay4', 'Other On/Off')\">Other On/Off</button>";
content += "<button class=\"relayButton\" onclick=\"activateRelay('/relay5', 'Actinic +/-')\">Actinic +/-</button>";
content += "<button class=\"relayButton\" onclick=\"activateRelay('/relay6', 'Blue+ +/-')\">Blue+ +/-</button>";
content += "<button class=\"relayButton\" onclick=\"activateRelay('/relay7', 'Coral+ +/-')\">Coral+ +/-</button>";
content += "<button class=\"relayButton\" onclick=\"activateRelay('/relay8', 'Other +/-')\">Other +/-</button>";
content += "</div>";
// Add a div for the serial log
content += "<div id=\"serialLog\" style=\"margin: 0 auto; width: 50%; height: 10em; overflow-y: scroll; border: 1px solid #ccc; padding: 10px;\"></div>";
// CSS styles for buttons
content += "<style>";
content += ".relayButton {";
content += "background-color: #4CAF50;"; /* Green color */
content += "border: none;";
content += "color: white;";
content += "padding: 15px 32px;";
content += "text-align: center;";
content += "text-decoration: none;";
content += "display: inline-block;";
content += "font-size: 16px;";
content += "margin: 4px 2px;";
content += "cursor: pointer;";
content += "}";
content += "</style>";
// JavaScript to handle button clicks and serial output, and update time every second
content += "<script>";
content += "function activateRelay(url, message) {";
content += "var xhr = new XMLHttpRequest();";
content += "xhr.open('GET', url, true);";
content += "xhr.onload = function() {";
content += "if(xhr.status == 200) { updateSerialOutput(new Date().toLocaleTimeString() + ' - ' + message); }";
content += "};";
content += "xhr.send();";
content += "}";
content += "function updateSerialOutput(data) {";
content += "var serialLog = document.getElementById('serialLog');"; // Get the div element for the serial log
content += "serialLog.innerHTML += '<pre>' + data + '</pre>';"; // Append the new data to the existing log with a line break
content += "scrollToBottom(serialLog);"; // Scroll to the bottom of the serial log
content += "}";
content += "function updateCurrentTime() {";
content += "var currentTimeElement = document.getElementById('current-time');";
content += "currentTimeElement.innerText = new Date().toLocaleTimeString();"; // Update current time every second
content += "}";
content += "function scrollToBottom(element) {";
content += "element.scrollTop = element.scrollHeight;"; // Scroll to the bottom of the element
content += "}";
content += "setInterval(updateCurrentTime, 1000);"; // Update current time every second
content += "</script>";
server.send(200, "text/html", content);
}
void handleRelay1() {
digitalWrite(D5, HIGH);
delay(relayDurations[0]);
digitalWrite(D5, LOW);
server.send(200, "text/plain", "Channel 1 activated");
}
void handleRelay2() {
digitalWrite(D6, HIGH);
delay(relayDurations[1]);
digitalWrite(D6, LOW);
server.send(200, "text/plain", "Channel 2 activated");
}
void handleRelay3() {
digitalWrite(D7, HIGH);
delay(relayDurations[2]);
digitalWrite(D7, LOW);
server.send(200, "text/plain", "Channel 3 activated");
}
void handleRelay4() {
digitalWrite(D8, HIGH);
delay(relayDurations[3]);
digitalWrite(D8, LOW);
server.send(200, "text/plain", "Channel 4 activated");
}
void handleRelay5() {
digitalWrite(D5, HIGH);
delay(relayDurations[4]);
digitalWrite(D5, LOW);
server.send(200, "text/plain", "Channel 1 dimmed activated");
}
void handleRelay6() {
digitalWrite(D6, HIGH);
delay(relayDurations[5]);
digitalWrite(D6, LOW);
server.send(200, "text/plain", "Channel 2 dimmed activated");
}
void handleRelay7() {
digitalWrite(D7, HIGH);
delay(relayDurations[6]);
digitalWrite(D7, LOW);
server.send(200, "text/plain", "Channel 3 dimmed activated");
}
void handleRelay8() {
digitalWrite(D8, HIGH);
delay(relayDurations[7]);
digitalWrite(D8, LOW);
server.send(200, "text/plain", "Channel 4 dimmed activated");
}
void activateRelayAt(int relayNumber, int targetHour, int targetMinute, String message, unsigned long currentTime) {
// Check if it's the specified hour and minute and if the relay has not already been activated
if (timeClient.getHours() == targetHour && timeClient.getMinutes() == targetMinute && !relayAlreadyActivated[relayNumber - 1]) {
Serial.println("Activating relay " + String(relayNumber));
digitalWrite(relayPinFromNumber(relayNumber), HIGH);
delay(relayDurations[relayNumber - 1]); // Use relay duration to determine how long the relay should be active
digitalWrite(relayPinFromNumber(relayNumber), LOW);
Serial.println(message); // Print the message to the serial log for debugging
server.send(200, "text/plain", message); // Send the message to the web interface
// Mark the relay as activated for the current time
relayAlreadyActivated[relayNumber - 1] = true;
}
}
void updateSerialOutput(String data) {
Serial.println(data);
// Save the serial data
serialData += data + "\n";
// Send the serial data to the web interface
server.send(200, "text/plain", data);
}
int relayPinFromNumber(int relayNumber) {
switch(relayNumber) {
case 1:
return D5;
case 2:
return D6;
case 3:
return D7;
case 4:
return D8;
default:
return -1; // Invalid relay number
}
}