G

RTC clock and timers fixed

public
Guest Mar 19, 2024 Never 30
Clone
Plaintext paste1.txt 758 lines (654 loc) | 22.96 KB
1
/* Comment this out to disable prints and save space */
2
#define BLYNK_PRINT Serial
3
4
/* Fill in information from Blynk Device Info here */
5
#define BLYNK_TEMPLATE_ID "XXXXXX"
6
#define BLYNK_TEMPLATE_NAME "ota test"
7
#define BLYNK_AUTH_TOKEN "XXXXXX"
8
9
#define BLYNK_FIRMWARE_VERSION "1.9.5"
10
11
#include <SPI.h>
12
#include <ESP8266WiFi.h>
13
#include <BlynkSimpleEsp8266.h>
14
#include <TimeLib.h>
15
#include <WidgetRTC.h>
16
#include <Wire.h>
17
#include <Adafruit_GFX.h>
18
#include <SH1106Wire.h>
19
#include <espnow.h>
20
#include <WiFiClient.h>
21
#include <WiFiClientSecure.h>
22
#include <ESP8266HTTPClient.h>
23
#include <ESP8266httpUpdate.h>
24
#include <ESP8266HTTPUpdateServer.h>
25
#include <Preferences.h>
26
#include "HTTPSRedirect.h"
27
28
BlynkTimer timer;
29
30
WidgetRTC rtc;
31
32
const char* ssid = "AC/DC_P"; // Name of the Wi-Fi box
33
const char* password = "donttouchmywifi"; // MDP of the Wi-Fi box
34
35
// Declare the target date in dd/mm/yyyy format
36
String initialDate = "01/03/2024";
37
struct tm lastIrriagationDate = {0};
38
39
// Define a constant for the maximum allowed time gap in seconds (5 minutes = 300 seconds)
40
const unsigned long MAX_TIME_GAP = 300;
41
42
// Define an array to store the last received timestamps for each sensor
43
unsigned long lastReceivedTime[4] = {0}; // Initialize all elements to 0
44
45
int groundLevel=0;
46
int bgroundLevel;
47
int m1low = 3;
48
int m1high = 8;
49
int m2t =8;
50
int bm1low, bm1high, bm2t;
51
52
float s1c, s2c, s3c, s4c;
53
float bs1c, bs2c, bs3c, bs4c;
54
55
int activeSensorCount = 0;
56
String overTheAirURL = "";
57
bool pumpauth=1;
58
59
#define SDA_PIN D2
60
#define SCL_PIN D1
61
62
SH1106Wire display(0x3c, SDA_PIN, SCL_PIN);
63
64
// Enter Google Script Deployment ID:
65
const char *GScriptId = "XXXXXX";
66
67
// Enter command (insert_row or append_row) and your Google Sheets sheet name (default is Sheet1):
68
String payload_base = "{\"command\": \"insert_row\", \"sheet_name\": \"Sheet1\", \"values\": ";
69
String payload = "";
70
71
// Google Sheets setup (do not edit)
72
const char* host = "script.google.com";
73
const int httpsPort = 443;
74
const char* fingerprint = "";
75
String url = String("/macros/s/") + GScriptId + "/exec";
76
HTTPSRedirect* client = nullptr;
77
78
// Declare variables that will be published to Google Sheets
79
float value0 = 0;
80
float value1 = 0;
81
float value2 = 0;
82
float value3 = 0;
83
float value4 = 0;
84
bool value5 = 0;
85
bool value6 = 0;
86
float value7 = 0;
87
float value8 = 0;
88
float value9 = 0;
89
float value10 = 0;
90
float value11 = 0;
91
String value12 = initialDate;
92
float value13 = 0;
93
float value14 = 0;
94
float value15 = 0;
95
float value16 = 0;
96
float value17 = 0;
97
float value18 = 0;
98
float value19 = 0;
99
float value20 = 0;
100
101
double seconds_diff;
102
int days_diff, days_diff2 ;
103
104
// Relay pin
105
const int relayPin = D7;
106
107
float distance1, distance2, distance3, distance4, distanceAvg;
108
float wh1, wh2, wh3, wh4;
109
float waterHeight =0;
110
111
Preferences preferences;
112
113
typedef struct struct_message {
114
int id;
115
float distance;
116
} struct_message;
117
118
// Create a struct_message called myData
119
struct_message myData;
120
121
// Create a structure to hold the readings from each board
122
struct_message board1;
123
struct_message board2;
124
struct_message board3;
125
struct_message board4;
126
127
// Create an array with all the structures
128
struct_message boardsStruct[4] = {board1, board2, board3, board4};
129
130
131
// Digital clock display of the time
132
void clockDisplay()
133
{
134
// You can call hour(), minute(), ... at any time
135
// Please see Time library examples for details
136
137
int hour_12h = hourFormat12();
138
String am_pm = (hour() < 12) ? "AM" : "PM";
139
140
String currentTime = String(hour_12h) + ":" + minute() + ":" + second() + " " + am_pm;
141
String currentDate = String(day()) + " " + month() + " " + year();
142
Serial.print("Current time: ");
143
Serial.print(currentTime);
144
Serial.print(" ");
145
Serial.print(currentDate);
146
Serial.println();
147
148
// Calculate the difference in days
149
int days_diff = calculatedays_difference(initialDate);
150
Serial.print("Days difference: ");
151
Serial.println(days_diff);
152
}
153
154
// Function to calculate the difference in days between target date and current date
155
int calculatedays_difference(String initialDate)
156
{
157
// Parse target date
158
int targetDay, targetMonth, targetYear;
159
const char* initialDateChar = initialDate.c_str();
160
sscanf(initialDateChar, "%d/%d/%d", &targetDay, &targetMonth, &targetYear);
161
162
// Create tmElements_t structure
163
tmElements_t tm;
164
tm.Year = targetYear - 1970; // Years since 1970
165
tm.Month = targetMonth;
166
tm.Day = targetDay;
167
tm.Hour = 0;
168
tm.Minute = 0;
169
tm.Second = 0;
170
171
// Convert tmElements_t structure to time_t
172
time_t targetTime = makeTime(tm);
173
// Calculate current time
174
time_t currentTime = now();
175
// Calculate difference in seconds
176
int secondsDiff = difftime(currentTime, targetTime);
177
// Convert seconds to days
178
int days_diff = secondsDiff / 86400;
179
return days_diff;
180
}
181
182
BLYNK_CONNECTED() {
183
// Synchronize time on connection
184
rtc.begin();
185
}
186
187
void setup()
188
{
189
// Debug console
190
Serial.begin(9600);
191
loadpreferences();
192
WiFi.mode(WIFI_AP_STA);
193
// Init ESP-NOW
194
if (esp_now_init() != 0) {
195
Serial.println("Error initializing ESP-NOW");
196
return;
197
}
198
// Once ESPNow is successfully Init, we will register for recv CB to
199
// get recv packer info
200
esp_now_set_self_role(ESP_NOW_ROLE_SLAVE);
201
esp_now_register_recv_cb(OnDataRecv);
202
203
204
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, password);
205
Blynk.syncAll();
206
// Set relay pin as output
207
pinMode(relayPin, OUTPUT);
208
// Initialize relay to OFF
209
digitalWrite(relayPin, HIGH);
210
display.init();
211
display.clear();
212
gsheetsetup();
213
setSyncInterval(10 * 60); // Sync interval in seconds (10 minutes)
214
// Display digital clock every 10 seconds
215
//timer.setInterval(10000L, clockDisplay);
216
timer.setInterval(1000L, mainloop); // call the take_sensor_reading() function every 5 seconds
217
timer.setInterval(10000L, gsheets); // call the take_sensor_reading() function every 5 seconds
218
timer.setInterval(1000L, blynkdash);
219
220
}
221
222
void loop()
223
{
224
Blynk.run();
225
timer.run();
226
}
227
228
void mainloop(){
229
clockDisplay();
230
// Calculate average distance from all sub-station sensors
231
distance1 = boardsStruct[0].distance;
232
distance2 = boardsStruct[1].distance;
233
distance3 = boardsStruct[2].distance;
234
distance4 = boardsStruct[3].distance;
235
236
// Assuming groundLevel, s1c, s2c, s3c, s4c are defined elsewhere in your code
237
238
if (distance1 == 0) {
239
wh1 = 0;
240
} else {
241
wh1 = groundLevel - distance1 + s1c;
242
}
243
if (distance2 == 0) {
244
wh2 = 0;
245
} else {
246
wh2 = groundLevel - distance2 + s2c;
247
}
248
if (distance3 == 0) {
249
wh3 = 0;
250
} else {
251
wh3 = groundLevel - distance3 + s3c;
252
}
253
if (distance4 == 0) {
254
wh4 = 0;
255
} else {
256
wh4 = groundLevel - distance4 + s4c;
257
}
258
activeSensorCount = countActiveSensors();
259
Serial.print("Active Sensors: ");
260
Serial.println(activeSensorCount);
261
if (activeSensorCount !=0 ) {
262
distanceAvg = (distance1 + distance2 + distance3 + distance4) / activeSensorCount;
263
// Calculate water height
264
waterHeight = (wh1+wh2+wh3+wh4)/activeSensorCount;
265
}
266
else {
267
distanceAvg =100;
268
waterHeight=100;
269
}
270
Serial.print("Water height: ");
271
Serial.print(waterHeight);
272
Serial.println(" cm");
273
274
if (days_diff >= 0 && days_diff <= 21)
275
{
276
if(waterHeight < m1low && digitalRead(relayPin) == HIGH && pumpauth == 1)
277
{
278
digitalWrite(relayPin, LOW);
279
Serial.println("Pump started");
280
}
281
282
if(waterHeight < m1low && digitalRead(relayPin) == LOW && pumpauth == 0)
283
{
284
digitalWrite(relayPin, HIGH);
285
Serial.println("Pump stopped because of pumpauth");
286
}
287
288
if(waterHeight > m1high && digitalRead(relayPin) == LOW)
289
{
290
digitalWrite(relayPin, HIGH);
291
Serial.println("Pump stopped");
292
}
293
294
value15 = 1;
295
Blynk.virtualWrite(V6, "mode 1");
296
}
297
298
else if (days_diff > 21 && days_diff <= 90)
299
{
300
if(waterHeight > m2t && digitalRead(relayPin) == LOW)
301
{
302
digitalWrite(relayPin, HIGH);
303
Serial.println("Pump stopped");
304
}
305
306
307
if(waterHeight <= .5)
308
{
309
preferences.begin("irrigation", true);
310
int lastIrriagationDay = preferences.getInt("lastIrriagationDay",0);
311
preferences.end();
312
if(lastIrriagationDay == 0) // means no data is stored
313
{
314
preferences.begin("irrigation", false);
315
preferences.putInt("lastIrriagationYear", year());
316
preferences.putInt("lastIrriagationMon", month());
317
preferences.putInt("lastIrriagationDay", day());
318
preferences.putInt("lastIrriagationHr", hour());
319
preferences.putInt("lastIrriagationMin", minute());
320
preferences.putInt("lastIrriagationSec", second());
321
preferences.end();
322
Blynk.virtualWrite(V6, "pref input current date");
323
}
324
}
325
326
if(waterHeight <m2t)
327
{
328
preferences.begin("irrigation", true);
329
// Load last irrigation time from preference memory
330
int lastYear = preferences.getInt("lastIrriagationYear", 0);
331
int lastMonth = preferences.getInt("lastIrriagationMon", 0);
332
int lastDay = preferences.getInt("lastIrriagationDay", 0);
333
int lastHour = preferences.getInt("lastIrriagationHr", 0);
334
int lastMinute = preferences.getInt("lastIrriagationMin", 0);
335
int lastSecond = preferences.getInt("lastIrriagationSec", 0);
336
preferences.end(); // Close the preferences
337
338
Serial.printf("Last irrigation time: %02d/%02d/%04d %02d:%02d:%02d\n", lastDay, lastMonth, lastYear, lastHour, lastMinute, lastSecond);
339
340
// Create tmElements_t structure for last irrigation time
341
tmElements_t lastIrrigationTime;
342
lastIrrigationTime.Year = lastYear - 1970; // Years since 1970
343
lastIrrigationTime.Month = lastMonth-1;
344
lastIrrigationTime.Day = lastDay;
345
lastIrrigationTime.Hour = lastHour;
346
lastIrrigationTime.Minute = lastMinute;
347
lastIrrigationTime.Second = lastSecond;
348
349
// Convert tmElements_t structure to time_t for last irrigation time
350
time_t lastIrrigationTime_t = makeTime(lastIrrigationTime);
351
352
// Calculate current time
353
time_t currentTime = now();
354
355
// Calculate difference in seconds
356
int secondsDiff = difftime(currentTime, lastIrrigationTime_t);
357
358
// Convert seconds to days
359
int daysDiff2 = secondsDiff / 86400;
360
Blynk.virtualWrite(V7, "days_diff2: " + String(days_diff2));
361
}
362
363
if(days_diff2 >= 3 && digitalRead(relayPin) == HIGH && pumpauth == 1)
364
{
365
digitalWrite(relayPin, LOW);
366
Serial.println("Pump started");
367
368
preferences.begin("irrigation", false);
369
preferences.remove("lastIrriagationYear");
370
preferences.remove("lastIrriagationMon");
371
preferences.remove("lastIrriagationDay");
372
preferences.remove("lastIrriagationHr");
373
preferences.remove("lastIrriagationMin");
374
preferences.remove("lastIrriagationSec");
375
preferences.end();
376
}
377
if(days_diff2 >= 3 && digitalRead(relayPin) == LOW && pumpauth == 0)
378
{
379
digitalWrite(relayPin, HIGH);
380
Serial.println("Pump stopped because of pumpauth");
381
}
382
value15= 2;
383
Blynk.virtualWrite(V6, "mode 2");
384
}
385
else
386
{
387
Serial.print("The unconditional case");
388
Blynk.virtualWrite(V6, "mode 3");
389
value15 =3;
390
}
391
if (digitalRead(relayPin) == HIGH){
392
value6 = 0;
393
}
394
else {
395
value6 = 1;
396
}
397
displayValues();
398
}
399
400
void blynkdash()
401
402
{
403
Blynk.virtualWrite(V0, wh1);
404
Blynk.virtualWrite(V1, wh2);
405
Blynk.virtualWrite(V2, wh3);
406
Blynk.virtualWrite(V3, wh4);
407
Blynk.virtualWrite(V4, waterHeight);
408
Blynk.virtualWrite(V8, value6);
409
Blynk.virtualWrite(V7, "Dis1: " + String(distance1) + " Dis2: " + String(distance2) + " Dis3: " + String(distance3) + " Dis4: " + String(distance4) + " DisAVG: " + String(distanceAvg));
410
Blynk.virtualWrite(V7, "s1c: " + String(s1c) + " s2c: " + String(s2c) + " s3c: " + String(s3c) + " s4c: " + String(s4c));
411
Blynk.virtualWrite(V7, "groundLevel: " + String(groundLevel));
412
Blynk.virtualWrite(V7, "initialDate: " + String(initialDate));
413
Blynk.virtualWrite(V7, "days_diff: " + String(days_diff));
414
Blynk.virtualWrite(V7, "m1high: " + String(m1high) + " m1low: " + String(m1low) + " m2t: " + String(m2t));
415
// Blynk.virtualWrite(V7, "days_diff2: " + String(days_diff2));
416
}
417
void gsheets()
418
{
419
value0 = wh1;
420
value1 = wh2;
421
value2 = wh3;
422
value3 = wh4;
423
value4 = waterHeight;
424
value5 = pumpauth;
425
value7 = distance1;
426
value8 = distance2;
427
value9 = distance3;
428
value10 = distance4;
429
430
value11 = distanceAvg;
431
value12 = initialDate;
432
value13 = days_diff;
433
value14 = activeSensorCount;
434
value16 = groundLevel;
435
value17 = s1c;
436
value18 = s2c;
437
value19 = s3c;
438
value20 = s4c;
439
440
441
442
static bool flag = false;
443
if (!flag){
444
client = new HTTPSRedirect(httpsPort);
445
client->setInsecure();
446
flag = true;
447
client->setPrintResponseBody(true);
448
client->setContentTypeHeader("application/json");
449
}
450
if (client != nullptr){
451
if (!client->connected()){
452
client->connect(host, httpsPort);
453
}
454
}
455
else{
456
Serial.println("Error creating client object!");
457
}
458
459
// Create json object string to send to Google Sheets
460
payload = payload_base + "\"" + \
461
value12 + "," + value13 + "," + value15 + "," + value14 + "," + value5 + "," + \
462
value6 + "," + value4 + "," + value0 + "," + value1 + "," + value2 + "," + \
463
value3 + "," + value11 + "," + value7 + "," + value8 + "," + value9 + "," + \
464
value10 + "," + value16 + "," + value17 + "," + value18 + "," + value19 + \
465
"," + value20 + "\"}";
466
467
468
// Publish data to Google Sheets
469
Serial.println("Publishing data...");
470
//Serial.println(payload);
471
if(client->POST(url, host, payload)){
472
// do stuff here if publish was successful
473
}
474
else{
475
// do stuff here if publish was not successful
476
Serial.println("Error while connecting");
477
}
478
}
479
480
void gsheetsetup(){
481
// Use HTTPSRedirect class to create a new TLS connection
482
client = new HTTPSRedirect(httpsPort);
483
client->setInsecure();
484
client->setPrintResponseBody(true);
485
client->setContentTypeHeader("application/json");
486
487
Serial.print("Connecting to ");
488
Serial.println(host);
489
490
// Try to connect for a maximum of 5 times
491
bool flag = false;
492
for (int i=0; i<5; i++){
493
int retval = client->connect(host, httpsPort);
494
if (retval == 1){
495
flag = true;
496
Serial.println("Connected");
497
break;
498
}
499
else
500
Serial.println("Connection failed. Retrying...");
501
}
502
if (!flag){
503
Serial.print("Could not connect to server: ");
504
Serial.println(host);
505
return;
506
}
507
delete client; // delete HTTPSRedirect object
508
client = nullptr; // delete HTTPSRedirect object
509
}
510
511
void displayValues() {
512
display.clear();
513
// Print water heights
514
display.setFont(ArialMT_Plain_10);
515
display.drawString(0, 0, "wh1:" + String(wh1));
516
display.drawString(0, 10, "wh2:" + String(wh2));
517
display.drawString(0, 20, "wh3:" + String(wh3));
518
display.drawString(0, 30, "wh4:" + String(wh4));
519
520
// Print averages and other parameters
521
display.drawString(0, 40, "DisAvg: " + String(distanceAvg));
522
display.drawString(0, 50, "whAvg: " + String(waterHeight));
523
// Add more display statements for other parameters
524
display.drawString(70, 0, "Day:" + String(days_diff));
525
display.drawString(70, 10, "Sensor:" + String(activeSensorCount));
526
display.drawString(70, 20, "Pumpauth:" + String(pumpauth));
527
display.drawString(70, 30, "Pump:" + String(value6));
528
display.drawString(70, 50, "FW:" + String( BLYNK_FIRMWARE_VERSION));
529
// Display the content
530
display.display();
531
}
532
533
BLYNK_WRITE(InternalPinOTA) {
534
Serial.println("OTA Started");
535
Blynk.virtualWrite(V6, "ota started");
536
overTheAirURL = param.asString();
537
Serial.print("overTheAirURL = ");
538
Serial.println(overTheAirURL);
539
otadisplay();
540
WiFiClient my_wifi_client;
541
HTTPClient http;
542
http.begin(my_wifi_client, overTheAirURL);
543
544
545
t_httpUpdate_return ret = ESPhttpUpdate.update(my_wifi_client, overTheAirURL);
546
switch(ret) {
547
case HTTP_UPDATE_FAILED:
548
Serial.println("[update] Update failed.");
549
otafaileddisplay();
550
break;
551
case HTTP_UPDATE_NO_UPDATES:
552
Serial.println("[update] Update no Update.");
553
otafaileddisplay();
554
break;
555
case HTTP_UPDATE_OK:
556
Serial.println("[update] Update ok."); // may not be called since we reboot the ESP
557
break;
558
}
559
}
560
561
void OnDataRecv(uint8_t* mac_addr, uint8_t* incomingData, uint8_t len) {
562
563
564
char macStr[18];
565
Serial.print("Packet received from: ");
566
snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
567
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
568
569
570
Serial.println(macStr);
571
memcpy(&myData, incomingData, sizeof(myData));
572
573
Serial.printf("Board ID %u: %u bytes\n", myData.id, len);
574
575
// Update the structures with the new incoming data
576
577
boardsStruct[myData.id - 1].distance = myData.distance;
578
579
Serial.printf("distance value: %f \n", boardsStruct[myData.id - 1].distance);
580
581
Serial.println();
582
// Extract sensor ID from incoming data
583
uint8_t sensorID = incomingData[0]; // Assuming the first byte contains the sensor ID
584
585
// Update the timestamp for the corresponding sensor
586
lastReceivedTime[sensorID - 1] = millis() / 1000; // Store current time in seconds
587
}
588
589
BLYNK_WRITE(V5) {
590
int pinValue = param.asInt(); // Assigning incoming value from pin V3 to a variable
591
if (pinValue == 1) {
592
pumpauth=1;
593
} else {
594
pumpauth=0;
595
}
596
}
597
598
bool isSensorActive(int sensorID) {
599
unsigned long currentTime = millis() / 1000; // Current time in seconds
600
unsigned long lastReceived = lastReceivedTime[sensorID - 1]; // Last received time for the sensor
601
602
// Check if the time difference is within the allowed limit and the timestamp is non-zero
603
return (lastReceived != 0 && (currentTime - lastReceived) <= MAX_TIME_GAP);
604
}
605
606
// Function to count active sensors
607
int countActiveSensors() {
608
int activeCount = 0;
609
for (int i = 0; i < 4; ++i) {
610
if (isSensorActive(i + 1)) {
611
activeCount++;
612
}
613
}
614
return activeCount;
615
}
616
617
void otadisplay() {
618
display.clear();
619
// Print water heights
620
display.setFont(ArialMT_Plain_10);
621
display.drawString(0, 0, "OTA Started from:" + String(overTheAirURL));
622
display.drawString(0, 10, String(overTheAirURL));
623
display.display();
624
}
625
626
void otafaileddisplay(){
627
display.clear();
628
// Print water heights
629
display.setFont(ArialMT_Plain_10);
630
display.drawString(0, 0, "OTA failed");
631
display.display();
632
}
633
634
BLYNK_WRITE(V6) {
635
String command = param.asStr();
636
637
if (command.startsWith("s1c")) {
638
bs1c = command.substring(4).toFloat();
639
Blynk.virtualWrite(V6, "s1c is changed");
640
} else if (command.startsWith("s2c")) {
641
bs2c = command.substring(4).toFloat();
642
Blynk.virtualWrite(V6, "s2c is changed");
643
} else if (command.startsWith("s3c")) {
644
bs3c = command.substring(4).toFloat();
645
Blynk.virtualWrite(V6, "s3c is changed");
646
} else if (command.startsWith("s4c")) {
647
bs4c = command.substring(4).toFloat();
648
Blynk.virtualWrite(V6, "s4c is changed");
649
} else if (command.startsWith("gl")) {
650
bgroundLevel = command.substring(3).toInt();
651
Blynk.virtualWrite(V6, "groundLevel is changed");
652
} else if (command.startsWith("m1l")) {
653
bm1low = command.substring(4).toFloat();
654
Blynk.virtualWrite(V6, "mode 1 low threshold is changed");
655
} else if (command.startsWith("m1h")) {
656
bm1high = command.substring(4).toFloat();
657
Blynk.virtualWrite(V6, "mode 1 high threshold is changed");
658
} else if (command.startsWith("m2t")) {
659
bm2t = command.substring(4).toFloat();
660
Blynk.virtualWrite(V6, "mode 2 threshold is changed");
661
} else if (command.startsWith("prefc")) {
662
preferences.begin("irrigation", false);
663
preferences.clear();
664
preferences.end();
665
Blynk.virtualWrite(V6, "pref is cleared");
666
} else if (command.equals("reboot")) {
667
Blynk.virtualWrite(V6, "Restarting ESP8266...");
668
//delay(1000);
669
ESP.restart();
670
} else if (command.startsWith("idate")) {
671
String newDate = command.substring(6);
672
if (isValidDateFormat(newDate)) {
673
initialDate = newDate;
674
savepreferences();
675
Blynk.virtualWrite(V6, "initialDate is changed");
676
} else {
677
Blynk.virtualWrite(V6, "Invalid date format. Please use dd/mm/yyyy.");
678
}
679
} else if (command.startsWith("lidate")) {
680
String newDate2 = command.substring(7);
681
if (isValidDateFormat(newDate2)) {
682
int liday = newDate2.substring(0, 2).toInt();
683
int limonth = newDate2.substring(3, 5).toInt()-1;
684
int liyear = newDate2.substring(6).toInt()-1900;
685
686
Serial.print("Last irrigation day: ");
687
Serial.println(liday);
688
Serial.print("Last irrigation month: ");
689
Serial.println(limonth);
690
Serial.print("Last irrigation year: ");
691
Serial.println(liyear);
692
693
preferences.begin("irrigation", false);
694
preferences.putInt("lastIrriagationDay", liday);
695
preferences.putInt("lastIrriagationMon", limonth);
696
preferences.putInt("lastIrriagationYear", liyear);
697
preferences.end();
698
699
Blynk.virtualWrite(V6, "last irrigation Date is changed");
700
} else {
701
Blynk.virtualWrite(V6, "Invalid date format. Please use dd/mm/yyyy.");
702
}
703
} else {
704
// Handle commands received from the Blynk Terminal widget
705
// Add your custom commands handling here
706
Blynk.virtualWrite(V6, "Not a command: " + command);
707
}
708
709
savepreferences();
710
}
711
712
void savepreferences() {
713
preferences.begin("settings", false); // Open preferences with settings namespace
714
preferences.putString("initialDate", initialDate);
715
preferences.putFloat("s1c", s1c);
716
preferences.putFloat("s2c", s2c);
717
preferences.putFloat("s3c", s3c);
718
preferences.putFloat("s4c", s4c);
719
//preferences.putFloat("distanceAvg", distanceAvg);
720
preferences.putInt("groundLevel", bgroundLevel);
721
722
preferences.putFloat("m1high", m1high);
723
preferences.putFloat("m1low", m1low);
724
preferences.putFloat("m2t", m2t);
725
preferences.end(); // Close the preferences
726
Blynk.virtualWrite(V6, "savepref1");
727
}
728
729
void loadpreferences() {
730
preferences.begin("settings", true); // Open preferences with settings namespace, read-only
731
initialDate = preferences.getString("initialDate", initialDate);
732
s1c = preferences.getFloat("s1c", 0);
733
s2c = preferences.getFloat("s2c", 0);
734
s3c = preferences.getFloat("s3c", 0);
735
s4c = preferences.getFloat("s4c", 0);
736
groundLevel = preferences.getInt("groundLevel", 0);
737
m1high = preferences.getFloat("m1high", m1high);
738
m1low = preferences.getFloat("m1low", m1low);
739
m2t = preferences.getFloat("m2t", m2t);
740
preferences.end(); // Close the preferences
741
Blynk.virtualWrite(V6, "loadpref1");
742
}
743
744
745
bool isValidDateFormat(String date) {
746
if (date.length() != 10) {
747
return false;
748
}
749
if (date[2] != '/' || date[5] != '/') {
750
return false;
751
}
752
for (int i = 0; i < 10; i++) {
753
if (i != 2 && i != 5 && !isdigit(date[i])) {
754
return false;
755
}
756
}
757
return true;
758
}