#include <WiFi.h>
const unsigned int dayTS = 86400 ; //86400 Sec = 1 Day
const unsigned int hourTS = 3600 ;
const unsigned int minuteTS = 60 ;
#define NTP_SERVER "pool.ntp.org"
#define UTC_OFFSET 28800
#define UTC_OFFSET_DST 0
bool hibernate_mode = true;
uint8_t wakeup_period = 2; //in hour every ? hour wakeup
uint8_t division_delay = 30; //in minute delay ? minutes for work time division
uint8_t valve_on_timer = 10; //in minute turn on valve time
String hibernate_start = "1400"; //in hour
String hibernate_stop = "2400"; //in hour
void printLocalTime() {
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
Serial.println("Connection Err");
return;
}
Serial.println(&timeinfo, "%d/%m/%Y %H:%M:%S");
}
void setup() {
Serial.begin(115200);
Serial.print("Connecting to ");
Serial.print("WiFi ");
WiFi.begin("Wokwi-GUEST", "", 6);
while (WiFi.status() != WL_CONNECTED) {
delay(250);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
Serial.println("Online");
Serial.println("Updating time...");
configTime(UTC_OFFSET, UTC_OFFSET_DST, NTP_SERVER);
}
void loop() {
printLocalTime();
unsigned int current_ts = espUnixtime() % dayTS ;
unsigned int sleep_ts = calcSleepTS(current_ts);
Serial.println();
//boot
//wakeup and close valve
//setup next boot open value = true
//calc next boot timer
//sleep
//wakeup and open valve
//setup next boot open value = false
//sleep for ? min
//wakeup and close valve
//setup next boot open value = true
//calc next boot timer
//sleep
//wakeup and open valve
//setup next boot open value = false
//sleep for ? min
delay(2000);
}
unsigned int calcSleepTS(unsigned int now_ts) {
bool operation_mode = false;
bool corss_day = false;
int h_start_ts = 0;
int h_stop_ts = 0;
if (hibernate_mode) {
Serial.println("Checking operation mode");
ts2time(now_ts, "Time now" );
h_start_ts = time2ts(hibernate_start, "Hibernate Start");
h_stop_ts = time2ts(hibernate_stop, "Hibernate Stop");
bool valid_setting = ( h_start_ts >= 0 ) && (h_stop_ts >= 0);
Serial.println( valid_setting ? "Valid hibernate time" : "Invalid hibernate time");
if (valid_setting) {
corss_day = h_start_ts > h_stop_ts;
Serial.println( corss_day ? "Cross day : true" : "Cross day : false");
if (corss_day) {
if (( now_ts >= h_stop_ts ) && ( now_ts < h_start_ts )) operation_mode = true;
} else {
if (( now_ts < h_start_ts ) || ( now_ts >= h_stop_ts )) operation_mode = true;
}
} else operation_mode = true;
} else operation_mode = true;
Serial.println(operation_mode ? "Current mode : operation" : "Current mode : hibernate");
Serial.println("Calculate sleep time");
unsigned int rest_ts = 0;
unsigned int next_wakeup_ts = 0;
if (operation_mode) {
uint8_t currentHour = now_ts / 3600;
Serial.printf("Next wakeup hour : %02d ", currentHour);
if ((currentHour % 2) == 0 ) {
Serial.printf("+ 2 = %02d ", currentHour + 2 );
next_wakeup_ts = (currentHour + 2) * hourTS;
} else {
Serial.printf("+ 1 = %02d ", currentHour + 1 );
next_wakeup_ts = (currentHour + 1) * hourTS;
}
Serial.printf("( %d ) ", next_wakeup_ts );
next_wakeup_ts = next_wakeup_ts + division_delay * minuteTS;
Serial.printf("with %d mins division delay ( %d ) \n", division_delay, next_wakeup_ts );
rest_ts = next_wakeup_ts - now_ts ;
} else {
if (corss_day) {
next_wakeup_ts = dayTS + h_stop_ts + division_delay * minuteTS;
rest_ts = next_wakeup_ts - now_ts;
} else {
next_wakeup_ts = h_stop_ts + division_delay * minuteTS ;
rest_ts = next_wakeup_ts - now_ts ;
}
}
ts2time(rest_ts, "Time to sleep");
ts2time(next_wakeup_ts, "Next wakeup time");
return rest_ts;
}
/*****************************************************************************
Return ESP32 Timestamp ! to UTC Time //eg: "1649913928"
*****************************************************************************/
unsigned long espUnixtime() {
time_t now;
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
//Serial.println("Failed to obtain time");
return (0);
}
time(&now);
return now + 28800 ; //return to UTC Timestamp
}
void ts2time(unsigned int ts, String desc) {
ts = ts % dayTS;
uint8_t hh = ts / hourTS ;
uint8_t mm = (ts % hourTS) / minuteTS ;
Serial.printf("%s : %02d:%02d (%d) \n", desc.c_str(), hh, mm, ts );
}
int time2ts(String timestr, String desc) {
uint16_t time = timestr.toInt();
if (time > 2400) return -1;
uint32_t ts = 0;
uint8_t hh = time / 100;
uint8_t mm = time % 100;
if (mm > 60) return -1;
ts = hh * hourTS + mm * minuteTS ;
Serial.printf("%s at %02d:%02d to ts : %d \n", desc.c_str(), hh, mm, ts);
return ts;
}