G

Code

public
Guest Mar 19, 2024 Never 46
Clone
Plaintext paste1.txt 835 lines (692 loc) | 24.59 KB
1
#define BLYNK_TEMPLATE_ID "XXXXXXXX"
2
#define BLYNK_TEMPLATE_NAME "ota test"
3
#define BLYNK_AUTH_TOKEN "XXXXXXXXXXX"
4
5
#define BLYNK_FIRMWARE_VERSION "1.9.5"
6
7
#include <Wire.h>
8
#include <Adafruit_GFX.h>
9
#include <SH1106Wire.h>
10
#include <espnow.h>
11
#include <ESP8266WiFi.h>
12
#include <WiFiClient.h>
13
#include <WiFiClientSecure.h>
14
#include <ESP8266HTTPClient.h>
15
#include <ESP8266httpUpdate.h>
16
#include <ESP8266HTTPUpdateServer.h>
17
#include "time.h"
18
#include <Preferences.h>
19
#include "LittleFS.h"
20
#include <BlynkSimpleEsp8266.h>
21
#include "HTTPSRedirect.h"
22
//#include <ctime>
23
24
WidgetTerminal terminal(V6);
25
WidgetTerminal terminal2(V7);
26
27
// Define the watchdog timer interval in milliseconds
28
const unsigned long WATCHDOG_INTERVAL = 10000; // 10 seconds
29
30
// Initialize the previous millis value for watchdog timer
31
unsigned long previousWatchdogMillis = 0;
32
33
// Define a constant for the maximum allowed time gap in seconds (5 minutes = 300 seconds)
34
const unsigned long MAX_TIME_GAP = 300;
35
36
// Define an array to store the last received timestamps for each sensor
37
unsigned long lastReceivedTime[4] = {0}; // Initialize all elements to 0
38
39
int groundLevel=0;
40
int bgroundLevel;
41
int m1low = 3;
42
int m1high = 8;
43
int m2t =8;
44
int bm1low, bm1high, bm2t;
45
46
String initialDate="24/02/2024"; //please use exactly dd/mm/yyyy as date format
47
String binitialDate;
48
struct tm lastIrriagationDate = {0};
49
50
//wh1 = groundLevel - distance1 + bs1c
51
float s1c, s2c, s3c, s4c;
52
float bs1c, bs2c, bs3c, bs4c;
53
54
int activeSensorCount = 0;
55
String overTheAirURL = "";
56
bool pumpauth=1;
57
58
#define SDA_PIN D2
59
#define SCL_PIN D1
60
61
SH1106Wire display(0x3c, SDA_PIN, SCL_PIN);
62
63
#define BLYNK_PRINT Serial
64
65
// Enter Google Script Deployment ID:
66
const char *GScriptId = "XXXX";
67
68
// Enter command (insert_row or append_row) and your Google Sheets sheet name (default is Sheet1):
69
String payload_base = "{\"command\": \"insert_row\", \"sheet_name\": \"Sheet1\", \"values\": ";
70
String payload = "";
71
72
// Google Sheets setup (do not edit)
73
const char* host = "script.google.com";
74
const int httpsPort = 443;
75
const char* fingerprint = "";
76
String url = String("/macros/s/") + GScriptId + "/exec";
77
HTTPSRedirect* client = nullptr;
78
79
// Declare variables that will be published to Google Sheets
80
float value0 = 0;
81
float value1 = 0;
82
float value2 = 0;
83
float value3 = 0;
84
float value4 = 0;
85
bool value5 = 0;
86
bool value6 = 0;
87
float value7 = 0;
88
float value8 = 0;
89
float value9 = 0;
90
float value10 = 0;
91
float value11 = 0;
92
String value12 = initialDate;
93
float value13 = 0;
94
float value14 = 0;
95
float value15 = 0;
96
float value16 = 0;
97
float value17 = 0;
98
float value18 = 0;
99
float value19 = 0;
100
float value20 = 0;
101
102
103
BlynkTimer timer, timer2, timer3;;
104
// BlynkTimer timer2;
105
// BlynkTimer timer3;
106
107
const char* ssid = "AC/DC_P"; // Name of the Wi-Fi box
108
const char* password = "donttouchmywifi"; // MDP of the Wi-Fi box
109
110
const char* ntpServer = "pool.ntp.org";
111
const long gmtOffset_sec = 3600 * 6;
112
const int daylightOffset_sec = 3600 * 0;
113
114
struct tm initialDateTime = {0};
115
116
double seconds_diff;
117
118
int days_diff, days_diff2 ;
119
// int days_diff2;
120
121
122
123
// Relay pin
124
125
const int relayPin = D7;
126
127
// Ground level constant
128
129
130
131
float distance1, distance2, distance3, distance4, distanceAvg;
132
133
float wh1, wh2, wh3, wh4;
134
float waterHeight =0;
135
136
137
Preferences preferences, preferences1;
138
// Preferences preferences1;
139
// Structure example to receive data
140
// Must match the sender structure
141
typedef struct struct_message {
142
int id;
143
float distance;
144
} struct_message;
145
146
// Create a struct_message called myData
147
148
struct_message myData;
149
150
// Create a structure to hold the readings from each board
151
152
153
154
struct_message board1;
155
struct_message board2;
156
struct_message board3;
157
struct_message board4;
158
159
// Create an array with all the structures
160
161
struct_message boardsStruct[4] = {board1, board2, board3, board4};
162
163
// Define day and month names arrays
164
165
166
167
const char* dayNames[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
168
const char* monthNames[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
169
170
void myTimer()
171
172
{
173
Blynk.virtualWrite(V0, wh1);
174
Blynk.virtualWrite(V1, wh2);
175
Blynk.virtualWrite(V2, wh3);
176
Blynk.virtualWrite(V3, wh4);
177
Blynk.virtualWrite(V4, waterHeight);
178
Blynk.virtualWrite(V8, value6);
179
Blynk.virtualWrite(V7, "Dis1: " + String(distance1) + " Dis2: " + String(distance2) + " Dis3: " + String(distance3) + " Dis4: " + String(distance4) + " DisAVG: " + String(distanceAvg));
180
Blynk.virtualWrite(V7, "s1c: " + String(s1c) + " s2c: " + String(s2c) + " s3c: " + String(s3c) + " s4c: " + String(s4c));
181
Blynk.virtualWrite(V7, "groundLevel: " + String(groundLevel));
182
Blynk.virtualWrite(V7, "initialDate: " + String(initialDate));
183
Blynk.virtualWrite(V7, "days_diff: " + String(days_diff));
184
Blynk.virtualWrite(V7, "m1high: " + String(m1high) + " m1low: " + String(m1low) + " m2t: " + String(m2t));
185
// Blynk.virtualWrite(V7, "days_diff2: " + String(days_diff2));
186
}
187
void myTimer2()
188
{
189
value0 = wh1;
190
value1 = wh2;
191
value2 = wh3;
192
value3 = wh4;
193
value4 = waterHeight;
194
value5 = pumpauth;
195
value7 = distance1;
196
value8 = distance2;
197
value9 = distance3;
198
value10 = distance4;
199
200
value11 = distanceAvg;
201
value12 = initialDate;
202
value13 = days_diff;
203
value14 = activeSensorCount;
204
value16 = groundLevel;
205
value17 = s1c;
206
value18 = s2c;
207
value19 = s3c;
208
value20 = s4c;
209
210
211
212
static bool flag = false;
213
if (!flag){
214
client = new HTTPSRedirect(httpsPort);
215
client->setInsecure();
216
flag = true;
217
client->setPrintResponseBody(true);
218
client->setContentTypeHeader("application/json");
219
}
220
if (client != nullptr){
221
if (!client->connected()){
222
client->connect(host, httpsPort);
223
}
224
}
225
else{
226
Serial.println("Error creating client object!");
227
}
228
229
// Create json object string to send to Google Sheets
230
payload = payload_base + "\"" + \
231
value12 + "," + value13 + "," + value15 + "," + value14 + "," + value5 + "," + \
232
value6 + "," + value4 + "," + value0 + "," + value1 + "," + value2 + "," + \
233
value3 + "," + value11 + "," + value7 + "," + value8 + "," + value9 + "," + \
234
value10 + "," + value16 + "," + value17 + "," + value18 + "," + value19 + \
235
"," + value20 + "\"}";
236
237
238
// Publish data to Google Sheets
239
Serial.println("Publishing data...");
240
Serial.println(payload);
241
if(client->POST(url, host, payload)){
242
// do stuff here if publish was successful
243
}
244
else{
245
// do stuff here if publish was not successful
246
Serial.println("Error while connecting");
247
}
248
}
249
250
void myTimer3()
251
{
252
253
struct tm timeinfo;
254
if (!getLocalTime(&timeinfo)) {
255
Serial.println("Failed to obtain time");
256
}
257
258
//start
259
Serial.print("\t");
260
// Print time in the desired format
261
Serial.print("Day: ");
262
Serial.print(dayNames[timeinfo.tm_wday]);
263
Serial.print(", Month: ");
264
Serial.print(monthNames[timeinfo.tm_mon]);
265
Serial.print(" ");
266
Serial.print(timeinfo.tm_mday);
267
Serial.print(" ");
268
Serial.print(timeinfo.tm_year + 1900);
269
Serial.print(" ");
270
Serial.print(timeinfo.tm_hour);
271
Serial.print(":");
272
if (timeinfo.tm_min < 10) Serial.print("0"); // Leading zero for minutes < 10
273
Serial.print(timeinfo.tm_min);
274
Serial.print(":");
275
if (timeinfo.tm_sec < 10) Serial.print("0"); // Leading zero for seconds < 10
276
Serial.println(timeinfo.tm_sec);
277
seconds_diff = difftime(mktime(&timeinfo), mktime(&initialDateTime));
278
Serial.print("Seconds since Given date in the current timezone");
279
Serial.print("\t");
280
Serial.print(seconds_diff);
281
days_diff = seconds_diff / 86400;
282
Serial.print("\t");
283
Serial.print("Number of days");
284
Serial.print("\t");
285
Serial.print(days_diff);
286
Serial.print("\t");
287
//delay(1000);
288
// Calculate average distance from all sub-station sensors
289
distance1 = boardsStruct[0].distance;
290
distance2 = boardsStruct[1].distance;
291
distance3 = boardsStruct[2].distance;
292
distance4 = boardsStruct[3].distance;
293
294
// Assuming groundLevel, s1c, s2c, s3c, s4c are defined elsewhere in your code
295
296
if (distance1 == 0) {
297
wh1 = 0;
298
} else {
299
wh1 = groundLevel - distance1 + s1c;
300
}
301
302
if (distance2 == 0) {
303
wh2 = 0;
304
} else {
305
wh2 = groundLevel - distance2 + s2c;
306
}
307
308
if (distance3 == 0) {
309
wh3 = 0;
310
} else {
311
wh3 = groundLevel - distance3 + s3c;
312
}
313
314
if (distance4 == 0) {
315
wh4 = 0;
316
} else {
317
wh4 = groundLevel - distance4 + s4c;
318
}
319
320
321
activeSensorCount = countActiveSensors();
322
Serial.print("Active Sensors: ");
323
Serial.println(activeSensorCount);
324
if (activeSensorCount !=0 ) {
325
distanceAvg = (distance1 + distance2 + distance3 + distance4) / activeSensorCount;
326
// Calculate water height
327
waterHeight = (wh1+wh2+wh3+wh4)/activeSensorCount;
328
}
329
else {
330
distanceAvg =100;
331
waterHeight=100;
332
}
333
334
// Print water height
335
336
337
Serial.print("Water height: ");
338
Serial.print(waterHeight);
339
Serial.println(" cm");
340
341
if (days_diff >= 0 && days_diff <= 21)
342
{
343
if(waterHeight < m1low && digitalRead(relayPin) == HIGH && pumpauth == 1)
344
{
345
digitalWrite(relayPin, LOW);
346
Serial.println("Pump started");
347
}
348
349
if(waterHeight < m1low && digitalRead(relayPin) == LOW && pumpauth == 0)
350
{
351
digitalWrite(relayPin, HIGH);
352
Serial.println("Pump stopped because of pumpauth");
353
}
354
355
if(waterHeight > m1high && digitalRead(relayPin) == LOW)
356
{
357
digitalWrite(relayPin, HIGH);
358
Serial.println("Pump stopped");
359
}
360
361
value15 = 1;
362
Blynk.virtualWrite(V6, "mode 1");
363
}
364
else if (days_diff > 21 && days_diff <= 90)
365
{
366
if(waterHeight > m2t && digitalRead(relayPin) == LOW)
367
{
368
digitalWrite(relayPin, HIGH);
369
Serial.println("Pump stopped");
370
}
371
372
373
if(waterHeight <= .5)
374
{
375
preferences.begin("irrigation", true);
376
int lastIrriagationDay = preferences.getInt("lastIrriagationDay",0);
377
preferences.end();
378
if(lastIrriagationDay == 0) // means no data is stored
379
{
380
preferences.begin("irrigation", false);
381
preferences.putInt("lastIrriagationYear", timeinfo.tm_year);
382
preferences.putInt("lastIrriagationMon", timeinfo.tm_mon);
383
preferences.putInt("lastIrriagationDay", timeinfo.tm_mday);
384
preferences.putInt("lastIrriagationHr", timeinfo.tm_hour);
385
preferences.putInt("lastIrriagationMin", timeinfo.tm_min);
386
preferences.putInt("lastIrriagationSec", timeinfo.tm_sec);
387
preferences.end();
388
Blynk.virtualWrite(V6, "pref input current date");
389
}
390
}
391
392
if(waterHeight <m2t)
393
{
394
preferences.begin("irrigation", true);
395
lastIrriagationDate.tm_year = preferences.getInt("lastIrriagationYear",0);
396
lastIrriagationDate.tm_mon = preferences.getInt("lastIrriagationMon",0);
397
lastIrriagationDate.tm_mday = preferences.getInt("lastIrriagationDay",0);
398
lastIrriagationDate.tm_hour = preferences.getInt("lastIrriagationHr",0);
399
lastIrriagationDate.tm_min = preferences.getInt("lastIrriagationMin",0);
400
lastIrriagationDate.tm_sec = preferences.getInt("lastIrriagationSec",0);
401
preferences.end();
402
403
double seconds_diff2 = difftime(mktime(&timeinfo),mktime(&lastIrriagationDate));
404
days_diff2 = seconds_diff2/86400;
405
Blynk.virtualWrite(V7, "days_diff2: " + String(days_diff2));
406
407
if(days_diff2 >= 3 && digitalRead(relayPin) == HIGH && pumpauth == 1)
408
{
409
digitalWrite(relayPin, LOW);
410
Serial.println("Pump started");
411
preferences.clear();
412
}
413
if(days_diff2 >= 3 && digitalRead(relayPin) == LOW && pumpauth == 0)
414
{
415
digitalWrite(relayPin, HIGH);
416
Serial.println("Pump stopped because of pumpauth");
417
//preferences.clear();
418
}
419
}
420
value15= 2;
421
Blynk.virtualWrite(V6, "mode 2");
422
}
423
424
else
425
{
426
Serial.print("The unconditional case");
427
Blynk.virtualWrite(V6, "mode 3");
428
value15 =3;
429
}
430
431
432
if (digitalRead(relayPin) == HIGH){
433
value6 = 0;
434
}
435
else {
436
value6 = 1;
437
}
438
displayValues();
439
getlastirrigationdate();
440
}
441
442
443
void setup() {
444
Serial.begin(115200);
445
446
// Set relay pin as output
447
pinMode(relayPin, OUTPUT);
448
449
// Initialize relay to OFF
450
digitalWrite(relayPin, HIGH);
451
452
display.init();
453
display.clear();
454
455
WiFi.mode(WIFI_AP_STA);
456
// Init ESP-NOW
457
458
if (esp_now_init() != 0) {
459
Serial.println("Error initializing ESP-NOW");
460
return;
461
}
462
// Once ESPNow is successfully Init, we will register for recv CB to
463
// get recv packer info
464
esp_now_set_self_role(ESP_NOW_ROLE_SLAVE);
465
esp_now_register_recv_cb(OnDataRecv);
466
//preferences.begin("irrigation", false);
467
//preferences1.begin("values", false);
468
loadPreferences1();
469
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, password);
470
Blynk.syncAll();
471
timer.setInterval(1000L, myTimer);
472
timer2.setInterval(60000L,myTimer2);
473
timer3.setInterval(1000L,myTimer3);
474
475
// We configure the NTP server
476
477
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
478
479
480
GetDateTime(initialDate);
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 loop() {
512
513
//preferences1.end();
514
Blynk.run();
515
timer.run();
516
timer2.run();
517
timer3.run();
518
ESP.wdtFeed();
519
520
// Check if it's time to reset the watchdog timer
521
unsigned long currentMillis = millis();
522
if (currentMillis - previousWatchdogMillis >= WATCHDOG_INTERVAL) {
523
// Reset the watchdog timer
524
ESP.wdtFeed();
525
// Update the previous millis value
526
previousWatchdogMillis = currentMillis;
527
}
528
529
}
530
531
void displayValues() {
532
display.clear();
533
// Print water heights
534
display.setFont(ArialMT_Plain_10);
535
display.drawString(0, 0, "wh1:" + String(wh1));
536
display.drawString(0, 10, "wh2:" + String(wh2));
537
display.drawString(0, 20, "wh3:" + String(wh3));
538
display.drawString(0, 30, "wh4:" + String(wh4));
539
540
// Print averages and other parameters
541
display.drawString(0, 40, "DisAvg: " + String(distanceAvg));
542
display.drawString(0, 50, "whAvg: " + String(waterHeight));
543
// Add more display statements for other parameters
544
display.drawString(70, 0, "Day:" + String(days_diff));
545
display.drawString(70, 10, "Sensor:" + String(activeSensorCount));
546
display.drawString(70, 20, "Pumpauth:" + String(pumpauth));
547
display.drawString(70, 30, "Pump:" + String(value6));
548
display.drawString(70, 50, "FW:" + String( BLYNK_FIRMWARE_VERSION));
549
// Display the content
550
display.display();
551
}
552
553
BLYNK_WRITE(InternalPinOTA) {
554
Serial.println("OTA Started");
555
Blynk.virtualWrite(V6, "ota started");
556
overTheAirURL = param.asString();
557
Serial.print("overTheAirURL = ");
558
Serial.println(overTheAirURL);
559
otadisplay();
560
WiFiClient my_wifi_client;
561
HTTPClient http;
562
http.begin(my_wifi_client, overTheAirURL);
563
564
565
t_httpUpdate_return ret = ESPhttpUpdate.update(my_wifi_client, overTheAirURL);
566
switch(ret) {
567
case HTTP_UPDATE_FAILED:
568
Serial.println("[update] Update failed.");
569
otafaileddisplay();
570
break;
571
case HTTP_UPDATE_NO_UPDATES:
572
Serial.println("[update] Update no Update.");
573
otafaileddisplay();
574
break;
575
case HTTP_UPDATE_OK:
576
Serial.println("[update] Update ok."); // may not be called since we reboot the ESP
577
break;
578
}
579
}
580
581
// callback function that will be executed when data is received
582
583
void OnDataRecv(uint8_t* mac_addr, uint8_t* incomingData, uint8_t len) {
584
585
586
char macStr[18];
587
Serial.print("Packet received from: ");
588
snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
589
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
590
591
592
Serial.println(macStr);
593
memcpy(&myData, incomingData, sizeof(myData));
594
595
Serial.printf("Board ID %u: %u bytes\n", myData.id, len);
596
597
// Update the structures with the new incoming data
598
599
boardsStruct[myData.id - 1].distance = myData.distance;
600
601
Serial.printf("distance value: %f \n", boardsStruct[myData.id - 1].distance);
602
603
Serial.println();
604
// Extract sensor ID from incoming data
605
uint8_t sensorID = incomingData[0]; // Assuming the first byte contains the sensor ID
606
607
// Update the timestamp for the corresponding sensor
608
lastReceivedTime[sensorID - 1] = millis() / 1000; // Store current time in seconds
609
}
610
611
void GetDateTime(String initialDate) {
612
613
String strs[3];
614
int StringCount = 0;
615
while (initialDate.length() > 0) {
616
int index = initialDate.indexOf('/');
617
if (index == -1) // No slash found
618
{
619
strs[StringCount++] = initialDate;
620
break;
621
}
622
else {
623
strs[StringCount++] = initialDate.substring(0, index);
624
initialDate = initialDate.substring(index + 1);
625
}
626
627
628
}
629
630
631
initialDateTime.tm_hour = 0; initialDateTime.tm_min = 0; initialDateTime.tm_sec = 0;
632
initialDateTime.tm_year = (strs[2].toInt() - 1900); initialDateTime.tm_mon = (strs[1].toInt() - 1); initialDateTime.tm_mday = strs[0].toInt();
633
634
}
635
636
// This function will be called every time button Widget
637
// in Blynk app writes values to the Virtual Pin V3
638
BLYNK_WRITE(V5) {
639
int pinValue = param.asInt(); // Assigning incoming value from pin V3 to a variable
640
if (pinValue == 1) {
641
pumpauth=1;
642
} else {
643
pumpauth=0;
644
}
645
}
646
647
// Function to check if a sensor has sent data within the allowed time gap and has a non-zero timestamp
648
bool isSensorActive(int sensorID) {
649
unsigned long currentTime = millis() / 1000; // Current time in seconds
650
unsigned long lastReceived = lastReceivedTime[sensorID - 1]; // Last received time for the sensor
651
652
// Check if the time difference is within the allowed limit and the timestamp is non-zero
653
return (lastReceived != 0 && (currentTime - lastReceived) <= MAX_TIME_GAP);
654
}
655
656
// Function to count active sensors
657
int countActiveSensors() {
658
int activeCount = 0;
659
for (int i = 0; i < 4; ++i) {
660
if (isSensorActive(i + 1)) {
661
activeCount++;
662
}
663
}
664
return activeCount;
665
}
666
667
void otadisplay() {
668
display.clear();
669
// Print water heights
670
display.setFont(ArialMT_Plain_10);
671
display.drawString(0, 0, "OTA Started from:" + String(overTheAirURL));
672
display.drawString(0, 10, String(overTheAirURL));
673
display.display();
674
}
675
void otafaileddisplay(){
676
display.clear();
677
// Print water heights
678
display.setFont(ArialMT_Plain_10);
679
display.drawString(0, 0, "OTA failed");
680
display.display();
681
}
682
683
BLYNK_WRITE_DEFAULT() {
684
String command = param.asStr();
685
686
if (command.startsWith("s1c")) {
687
bs1c = command.substring(4).toFloat();
688
Blynk.virtualWrite(V6, "s1c is changed");
689
} else if (command.startsWith("s2c")) {
690
bs2c = command.substring(4).toFloat();
691
Blynk.virtualWrite(V6, "s2c is changed");
692
} else if (command.startsWith("s3c")) {
693
bs3c = command.substring(4).toFloat();
694
Blynk.virtualWrite(V6, "s3c is changed");
695
} else if (command.startsWith("s4c")) {
696
bs4c = command.substring(4).toFloat();
697
Blynk.virtualWrite(V6, "s4c is changed");
698
} else if (command.startsWith("gl")) {
699
bgroundLevel = command.substring(3).toInt();
700
Blynk.virtualWrite(V6, "groundLevel is changed");
701
} else if (command.startsWith("m1l")) {
702
bm1low = command.substring(4).toFloat();
703
Blynk.virtualWrite(V6, "mode 1 low threshold is changed");
704
} else if (command.startsWith("m1h")) {
705
bm1high = command.substring(4).toFloat();
706
Blynk.virtualWrite(V6, "mode 1 high threshold is changed");
707
} else if (command.startsWith("m2t")) {
708
bm2t = command.substring(4).toFloat();
709
Blynk.virtualWrite(V6, "mode 2 threshold is changed");
710
} else if (command.startsWith("prefc")) {
711
preferences.begin("irrigation", false);
712
preferences.clear();
713
preferences.end();
714
Blynk.virtualWrite(V6, "pref is cleared");
715
} else if (command.equals("reboot")) {
716
Blynk.virtualWrite(V6, "Restarting ESP8266...");
717
//delay(1000);
718
ESP.restart();
719
} else if (command.startsWith("idate")) {
720
String newDate = command.substring(6);
721
if (isValidDateFormat(newDate)) {
722
binitialDate = newDate;
723
GetDateTime(initialDate);
724
savePreferences1();
725
Blynk.virtualWrite(V6, "initialDate is changed");
726
} else {
727
Blynk.virtualWrite(V6, "Invalid date format. Please use dd/mm/yyyy.");
728
}
729
} else if (command.startsWith("lidate")) {
730
String newDate2 = command.substring(7);
731
if (isValidDateFormat(newDate2)) {
732
int liday = newDate2.substring(0, 2).toInt();
733
int limonth = newDate2.substring(3, 5).toInt()-1;
734
int liyear = newDate2.substring(6).toInt()-1900;
735
736
Serial.print("Last irrigation day: ");
737
Serial.println(liday);
738
Serial.print("Last irrigation month: ");
739
Serial.println(limonth);
740
Serial.print("Last irrigation year: ");
741
Serial.println(liyear);
742
743
preferences.begin("irrigation", false);
744
preferences.putInt("lastIrriagationDay", liday);
745
preferences.putInt("lastIrriagationMon", limonth);
746
preferences.putInt("lastIrriagationYear", liyear);
747
preferences.end();
748
749
Blynk.virtualWrite(V6, "last irrigation Date is changed");
750
} else {
751
Blynk.virtualWrite(V6, "Invalid date format. Please use dd/mm/yyyy.");
752
}
753
} else {
754
// Handle commands received from the Blynk Terminal widget
755
// Add your custom commands handling here
756
Blynk.virtualWrite(V6, "Not a command: " + command);
757
}
758
759
savePreferences1();
760
}
761
762
763
764
void savePreferences1() {
765
preferences1.begin("settings", false); // Open preferences with settings namespace
766
preferences1.putString("initialDate", initialDate);
767
preferences1.putFloat("s1c", bs1c);
768
preferences1.putFloat("s2c", bs2c);
769
preferences1.putFloat("s3c", bs3c);
770
preferences1.putFloat("s4c", bs4c);
771
//preferences1.putFloat("distanceAvg", distanceAvg);
772
preferences1.putInt("groundLevel", bgroundLevel);
773
774
preferences1.putFloat("m1high", bm1high);
775
preferences1.putFloat("m1low", bm1low);
776
preferences1.putFloat("m2t", bm2t);
777
preferences1.end(); // Close the preferences
778
Blynk.virtualWrite(V6, "savepref1");
779
}
780
781
void loadPreferences1() {
782
preferences1.begin("settings", true); // Open preferences with settings namespace, read-only
783
initialDate = preferences1.getString("initialDate", initialDate);
784
s1c = preferences1.getFloat("s1c", 0);
785
s2c = preferences1.getFloat("s2c", 0);
786
s3c = preferences1.getFloat("s3c", 0);
787
s4c = preferences1.getFloat("s4c", 0);
788
//distanceAvg = preferences1.getFloat("distanceAvg", 0);
789
groundLevel = preferences1.getInt("groundLevel", 0);
790
m1high = preferences1.getFloat("m1high", m1high);
791
m1low = preferences1.getFloat("m1low", m1low);
792
m2t = preferences1.getFloat("m2t", m2t);
793
preferences1.end(); // Close the preferences
794
// Blynk.virtualWrite(V6, m1high);
795
// Blynk.virtualWrite(V6, m1low);
796
// Blynk.virtualWrite(V6, m2t);
797
Blynk.virtualWrite(V6, "loadpref1");
798
}
799
800
801
bool isValidDateFormat(String date) {
802
if (date.length() != 10) {
803
return false;
804
}
805
if (date[2] != '/' || date[5] != '/') {
806
return false;
807
}
808
for (int i = 0; i < 10; i++) {
809
if (i != 2 && i != 5 && !isdigit(date[i])) {
810
return false;
811
}
812
}
813
return true;
814
}
815
816
void getlastirrigationdate()
817
{
818
preferences.begin("irrigation", true);
819
lastIrriagationDate.tm_year = preferences.getInt("lastIrriagationYear",0); // Years since 1900
820
lastIrriagationDate.tm_mon = preferences.getInt("lastIrriagationMon",0); // Months since January
821
lastIrriagationDate.tm_mday = preferences.getInt("lastIrriagationDay",0);
822
lastIrriagationDate.tm_hour = preferences.getInt("lastIrriagationHr",0);
823
lastIrriagationDate.tm_min = preferences.getInt("lastIrriagationMin",0);
824
lastIrriagationDate.tm_sec = preferences.getInt("lastIrriagationSec",0);
825
826
char date_str[20]; // Assuming 20 characters are sufficient
827
// Set the values for lastIrriagationDate as you have done
828
// Convert the date to a string
829
strftime(date_str, sizeof(date_str), "%d/%m/%Y", &lastIrriagationDate);
830
// Print the formatted date string
831
Serial.print("Last irrigation date: ");
832
Serial.println(date_str);
833
Blynk.virtualWrite(V7, "Last irrigation date: " + String(date_str));
834
preferences.end();
835
}