#include <ESP8266WiFi.h>
#include "HTTPSRedirect.h"
// #include <credentials.h>
/*
The credentials.h file at least has to contain:
char mySSID[]="your SSID";
char myPASSWORD[]="your Password";
const char *GScriptIdRead = "............"; //replace with you gscript id for reading the calendar
const char *GScriptIdWrite = "..........."; //replace with you gscript id for writing the calendar
It has to be placed in the libraries folder
If you do not want a credentials file. delete the line: #include <credentials.h>
*/
//Connection Settings
const char* host = "script.google.com";
const char* googleRedirHost = "script.googleusercontent.com";
const int httpsPort = 443;
unsigned long entryCalender, entryPrintStatus, entryInterrupt, heartBeatEntry, heartBeatLedEntry;
String url;
#define UPDATETIME 10000
#ifdef CREDENTIALS
const char* ssid = mySSID;
const char* password = myPASSWORD;
const char *GScriptIdRead = GoogleScriptIdRead;
const char *GScriptIdWrite = GoogleScriptIdWrite;
#else
//Network credentials
const char* ssid = "............";
const char* password = "............"; //replace with your password
//Google Script ID
const char *GScriptIdRead = "............"; //replace with you gscript id for reading the calendar
const char *GScriptIdWrite = "..........."; //replace with you gscript id for writing the calendar
#endif
#define NBR_EVENTS 4
String possibleEvents[NBR_EVENTS] = {"Laundry", "Meal", "Telephone", "Shop"};
byte LEDpins[NBR_EVENTS] = {D2, D7, D4, D8}; // connect LEDs to these pins or change pin number here
byte switchPins[NBR_EVENTS] = {D1, D3, D5, D6}; // connect switches to these pins or change pin number here
bool switchPressed[NBR_EVENTS];
boolean beat = false;
int beatLED = 0;
enum taskStatus {
none,
due,
done
};
taskStatus taskStatus[NBR_EVENTS];
HTTPSRedirect* client = nullptr;
String calendarData = "";
bool calenderUpToDate;
//Connect to wifi
void connectToWifi() {
Serial.println();
Serial.print("Connecting to wifi: ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("WiFi connected ");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
// Use HTTPSRedirect class to create a new TLS connection
client = new HTTPSRedirect(httpsPort);
client->setInsecure();
client->setPrintResponseBody(true);
client->setContentTypeHeader("application/json");
Serial.print("Connecting to ");
Serial.println(host);
// Try to connect for a maximum of 5 times
bool flag = false;
for (int i = 0; i < 5; i++) {
int retval = client->connect(host, httpsPort);
if (retval == 1) {
flag = true;
break;
}
else
Serial.println("Connection failed. Retrying...");
}
if (!flag) {
Serial.print("Could not connect to server: ");
Serial.println(host);
Serial.println("Exiting...");
ESP.reset();
}
Serial.println("Connected to Google");
}
void printStatus() {
for (int i = 0; i < NBR_EVENTS; i++) {
Serial.print("Task ");
Serial.print(i);
Serial.print(" Status ");
Serial.println(taskStatus[i]);
}
Serial.println("----------");
}
void getCalendar() {
// Serial.println("Start Request");
// HTTPSRedirect client(httpsPort);
unsigned long getCalenderEntry = millis();
// Try to connect for a maximum of 5 times
bool flag = false;
for (int i = 0; i < 5; i++) {
int retval = client->connect(host, httpsPort);
if (retval == 1) {
flag = true;
break;
}
else
Serial.println("Connection failed. Retrying...");
}
if (!flag) {
Serial.print("Could not connect to server: ");
Serial.println(host);
Serial.println("Exiting...");
ESP.reset();
}
//Fetch Google Calendar events
String url = String("/macros/s/") + GScriptIdRead + "/exec";
client->GET(url, host);
calendarData = client->getResponseBody();
Serial.print("Calendar Data---> ");
Serial.println(calendarData);
calenderUpToDate = true;
yield();
}
void createEvent(String title) {
// Serial.println("Start Write Request");
// Try to connect for a maximum of 5 times
bool flag = false;
for (int i = 0; i < 5; i++) {
int retval = client->connect(host, httpsPort);
if (retval == 1) {
flag = true;
break;
}
else
Serial.println("Connection failed. Retrying...");
}
if (!flag) {
Serial.print("Could not connect to server: ");
Serial.println(host);
Serial.println("Exiting...");
ESP.reset();
}
// Create event on Google Calendar
String url = String("/macros/s/") + GScriptIdWrite + "/exec" + "?title=" + title;
client->GET(url, host);
// Serial.println(url);
Serial.println("Write Event created ");
calenderUpToDate = false;
}
void manageStatus() {
for (int i = 0; i < NBR_EVENTS; i++) {
switch (taskStatus[i]) {
case none:
if (switchPressed[i]) {
digitalWrite(LEDpins[i], HIGH);
while (!calenderUpToDate) getCalendar();
if (!eventHere(i)) createEvent(possibleEvents[i]);
Serial.print(i);
Serial.println(" 0 -->1");
//getCalendar();
taskStatus[i] = due;
} else {
if (eventHere(i)) {
digitalWrite(LEDpins[i], HIGH);
Serial.print(i);
Serial.println(" 0 -->1");
taskStatus[i] = due;
}
}
break;
case due:
if (switchPressed[i]) {
digitalWrite(LEDpins[i], LOW);
Serial.print(i);
Serial.println(" 1 -->2");
taskStatus[i] = done;
}
break;
case done:
if (calenderUpToDate && !eventHere(i)) {
digitalWrite(LEDpins[i], LOW);
Serial.print(i);
Serial.println(" 2 -->0");
taskStatus[i] = none;
}
break;
default:
break;
}
switchPressed[i] = false;
}
yield();
}
bool eventHere(int task) {
if (calendarData.indexOf(possibleEvents[task], 0) >= 0 ) {
// Serial.print("Task found ");
// Serial.println(task);
return true;
} else {
// Serial.print("Task not found ");
// Serial.println(task);
return false;
}
}
ICACHE_RAM_ATTR void handleInterrupt() {
if (millis() > entryInterrupt + 100) {
entryInterrupt = millis();
for (int i = 0; i < NBR_EVENTS; i++) {
if (digitalRead(switchPins[i]) == LOW) {
switchPressed[i] = true;
}
}
}
}
void setup() {
Serial.begin(115200);
Serial.println("Reminder_V2");
for (int i = 0; i < NBR_EVENTS; i++) {
pinMode(LEDpins[i], OUTPUT);
taskStatus[i] = none; // Reset all LEDs
pinMode(switchPins[i], INPUT_PULLUP);
switchPressed[i] = false;
attachInterrupt(digitalPinToInterrupt(switchPins[i]), handleInterrupt, FALLING);
}
connectToWifi();
getCalendar();
entryCalender = millis();
}
void loop() {
if (millis() > entryCalender + UPDATETIME) {
getCalendar();
entryCalender = millis();
}
manageStatus();
if (millis() > entryPrintStatus + 5000) {
printStatus();
entryPrintStatus = millis();
}
if (millis() > heartBeatEntry + 30000) {
beat = true;
heartBeatEntry = millis();
}
heartBeat();
}
void heartBeat() {
if (beat) {
if ( millis() > heartBeatLedEntry + 100) {
heartBeatLedEntry = millis();
if (beatLED < NBR_EVENTS) {
if (beatLED > 0) digitalWrite(LEDpins[beatLED - 1], LOW);
digitalWrite(LEDpins[beatLED], HIGH);
beatLED++;
}
else {
for (int i = 0; i < NBR_EVENTS; i++) {
if (taskStatus[i] == due) digitalWrite(LEDpins[i], HIGH);
else digitalWrite(LEDpins[i], LOW);
}
beatLED = 0;
beat = false;
}
}
}
}