#include <WiFi.h>
#include <esp_wifi.h>
#include <HTTPClient.h>
#include <WiFiClientSecure.h>
#include "secrets.h"
tm timeInfo;
String strTodayDate;
String strCookie;
String strAddressAPI;
String strBearer;
String strAuthor;
String strRequestData;
String strResponse;
int intSigningTime;
int intDayType;
void setup() {
#ifdef DEBUG_MODE
Serial.begin(9600);
delay(5000);
#endif
strCookie.reserve(20);
strAddressAPI.reserve(200);
strBearer.reserve(1500);
strAuthor.reserve(1500);
strRequestData.reserve(1500);
strResponse.reserve(10000);
configTime(GMT_OFFSET_SEC, DAY_LIGHT_OFFSET_SEC, NTP_SERVER);
connectWiFi();
getTime();
#ifdef DEBUG_MODE
Serial.print(F("[FREE MEM] Exit Setup "));
Serial.println(esp_get_free_heap_size());
#endif
}
// -----------------------------------------------------------------------------
void loop() {
getTime();
intDayType = WORKDAY;
// if (isWeekEnd()) {
if (!isWeekEnd()) {
intDayType = HOLIDAY;
}
else {
if (WiFi.status() != WL_CONNECTED) {
connectWiFi();
getTime();
}
// getsheetdata();
intSigningTime = timeToSign();
// switch (intSigningTime) {
// case MORNING_SIGNING_TIME :
// // break;
// case NOON_SIGNING_TIME :
// // break;
// case EVENING_SIGNING_TIME :
// break;
// default : //NOT_SIGNING_TIME
// break;
// }
// if (intSigningTime != NOT_SIGNING_TIME) {
// if (intSigningTime == NOT_SIGNING_TIME) {
processSigning();
// processSigning();
// processSigning();
// processSigning();
// processSigning();
// processSigning();
// processSigning();
// processSigning();
// }
// mamLogin();
// isHoliday();
// checkSignedInOut();
// signInOut();
// WiFi.disconnect(true);
// delay(delayMilliSec(WEEKDAY));
}
#ifdef DEBUG_MODE
Serial.print(F("[FREE MEM] Before Delay "));
Serial.println(esp_get_free_heap_size());
#endif
delay(delayMilliSec(intDayType));
}
// -----------------------------------------------------------------------------
void connectWiFi() {
int counter = 0;
uint8_t newMACAddress[] = {MAC_ADDR_1, MAC_ADDR_2, MAC_ADDR_3, MAC_ADDR_4, MAC_ADDR_5, MAC_ADDR_6};
#ifdef DEBUG_MODE
Serial.print(F("Connecting to network: "));
Serial.println(SSID);
#endif
WiFi.disconnect(true);
WiFi.mode(WIFI_STA);
WiFi.setHostname(MOBILE_NAME);
esp_wifi_set_mac(WIFI_IF_STA, newMACAddress);
//WiFi.begin(SSID, WPA2_AUTH_PEAP, WIFI_IDENTITY, WIFI_USERNAME, WIFI_PASSWORD);
WiFi.begin(SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
counter++;
if (counter >= 60) {
ESP.restart();
}
}
#ifdef DEBUG_MODE
Serial.print(F("WiFi connected IP address : "));
Serial.println(WiFi.localIP());
Serial.println(WiFi.getHostname());
Serial.println(WiFi.macAddress());
#endif
}
// -----------------------------------------------------------------------------
void getTime() {
int counter = 0;
while (!getLocalTime(&timeInfo)) {
delay(500);
counter++;
if (counter >= 60) {
ESP.restart();
}
}
strTodayDate = String(timeInfo.tm_year + 1900);
strTodayDate += "-";
strTodayDate += String(timeInfo.tm_mon + 1);
strTodayDate += "-";
strTodayDate += String(timeInfo.tm_mday);
#ifdef DEBUG_MODE
Serial.println(&timeInfo, "%A, %d %B %Y %H:%M:%S");
#endif
}
// -----------------------------------------------------------------------------
bool isWeekEnd () {
if (timeInfo.tm_wday == 0 || timeInfo.tm_wday == 6) {
return true;
}
else {
return false;
}
}
// -----------------------------------------------------------------------------
long delayMilliSec (int intDayType) {
int minFromMidNight;
int minToMidNight;
int minToDelay;
minFromMidNight = (timeInfo.tm_hour * 60) + timeInfo.tm_min;
minToMidNight = (MIN_ALLDAY - minFromMidNight);
switch (intDayType) {
case HOLIDAY :
if (timeInfo.tm_wday == 6) { // saturday
minToDelay = (minToMidNight + MIN_ALLDAY + MIN_MIDNIGHT_TO_MORNING); // next monday morning
}
else { // sunday or holiday
minToDelay = (minToMidNight + MIN_MIDNIGHT_TO_MORNING); // next morning
}
break;
default : // WORKDAY
if (minFromMidNight < MIN_MIDNIGHT_TO_MORNING) {
minToDelay = (MIN_MIDNIGHT_TO_MORNING - minFromMidNight); // till morning
}
else if ((minFromMidNight < MIN_MIDNIGHT_TO_NOON)) {
minToDelay = (MIN_MIDNIGHT_TO_NOON - minFromMidNight); // till noon
}
else if ((minFromMidNight < MIN_MIDNIGHT_TO_EVENING)) {
minToDelay = (MIN_MIDNIGHT_TO_EVENING - minFromMidNight); // till evening
}
else {
if (timeInfo.tm_wday == 5) { // friday
minToDelay = (minToMidNight + (MIN_ALLDAY * 2) + MIN_MIDNIGHT_TO_MORNING); // next monday morning
}
else {
minToDelay = (minToMidNight + MIN_MIDNIGHT_TO_MORNING); // next morning
}
}
break;
}
#ifdef DEBUG_MODE
Serial.print(F("delay min :"));
Serial.println(minToDelay);
#endif
return ((minToDelay + random(5)) * 60 * 1000); // add random minitue (0 - 5 min) and convert to millisec
}
// -----------------------------------------------------------------------------
int timeToSign () {
int minFromMidNight;
minFromMidNight = (timeInfo.tm_hour * 60) + timeInfo.tm_min;
if (minFromMidNight >= MIN_MIDNIGHT_TO_MORNING && minFromMidNight <= MIN_MIDNIGHT_TO_MORNING_END) {
return MORNING_SIGNING_TIME;
}
else if (minFromMidNight >= MIN_MIDNIGHT_TO_NOON && minFromMidNight <= MIN_MIDNIGHT_TO_NOON_END) {
return NOON_SIGNING_TIME;
}
else if (minFromMidNight >= MIN_MIDNIGHT_TO_EVENING && minFromMidNight <= MIN_MIDNIGHT_TO_EVENING_END) {
return EVENING_SIGNING_TIME;
}
else {
return NOT_SIGNING_TIME;
}
}
// -----------------------------------------------------------------------------
bool sendRequest(WiFiClientSecure &client, int callMethod, const String &callURL, const String &headerReferer) {
#ifdef DEBUG_MODE
Serial.print(F("[FREE MEM] before sendRequest "));
Serial.println(esp_get_free_heap_size());
#endif
HTTPClient http;
int httpResponseCode;
bool isSucessed;
// if (http.begin(client, callURL)) {
if (http.begin(callURL)) {
http.setUserAgent(HTTP_HEADER_USER_AGENT);
http.addHeader("Host", HTTP_HEADER_HOST);
http.addHeader("Cookie", strCookie);
http.addHeader("Accept", HTTP_HEADER_ACCEPT);
http.addHeader("Authorization", strAuthor);
http.addHeader("Origin", HTTP_HEADER_ORIGIN);
http.addHeader("X-Requested-With", HTTP_HEADER_X_REQUESTED_WITH);
http.addHeader("Sec-Fetch-Site", HTTP_HEADER_SEC_FETCH_SITE);
http.addHeader("Sec-Fetch-Mode", HTTP_HEADER_SEC_FETCH_MODE);
http.addHeader("Sec-Fetch-Dest", HTTP_HEADER_SEC_FETCH_DEST);
http.addHeader("Referer", headerReferer);
// http.addHeader("Accept-Encoding", HTTP_HEADER_ACCEPT_ENCODEING);
http.addHeader("Accept-Language", HTTP_HEADER_ACCEPT_LANGUAGE);
http.addHeader("Connection", HTTP_HEADER_CONNECTION);
switch (callMethod) {
case METHOD_POST :
http.addHeader("Content-Type", HTTP_HEADER_CONTENT_TYPE_JSON);
{
#ifdef DEBUG_MODE
Serial.print(F("[FREE MEM] before post "));
Serial.println(esp_get_free_heap_size());
#endif
httpResponseCode = http.POST(strRequestData);
#ifdef DEBUG_MODE
Serial.print(F("[FREE MEM] after post "));
Serial.println(esp_get_free_heap_size());
#endif
}
break;
case METHOD_PUT :
{
#ifdef DEBUG_MODE
Serial.print(F("[FREE MEM] before put "));
Serial.println(esp_get_free_heap_size());
#endif
httpResponseCode = http.PUT(strRequestData);
#ifdef DEBUG_MODE
Serial.print(F("[FREE MEM] after put "));
Serial.println(esp_get_free_heap_size());
#endif
}
break;
default : //METHOD_GET
{
#ifdef DEBUG_MODE
Serial.print(F("[FREE MEM] before get "));
Serial.println(esp_get_free_heap_size());
#endif
httpResponseCode = http.GET();
#ifdef DEBUG_MODE
Serial.print(F("[FREE MEM] after get "));
Serial.println(esp_get_free_heap_size());
#endif
}
break;
}
if (httpResponseCode > 0) {
strResponse = http.getString();
isSucessed = true;
#ifdef DEBUG_MODE
Serial.print(F("HTTP :"));
Serial.println(httpResponseCode);
Serial.println(strResponse);
#endif
}
else {
isSucessed = false;
#ifdef DEBUG_MODE
Serial.print(F("Error code: "));
Serial.println(httpResponseCode);
#endif
}
// http.end();
}
else {
isSucessed = false;
#ifdef DEBUG_MODE
Serial.println(F("[HTTP] Unable to connect"));
#endif
}
http.end();
#ifdef DEBUG_MODE
Serial.print(F("[FREE MEM] after sendRequest "));
Serial.println(esp_get_free_heap_size());
#endif
return isSucessed;
}
// -----------------------------------------------------------------------------
bool connectServer(int callMethod, const String &callURL, const String &headerReferer) {
#ifdef DEBUG_MODE
Serial.print(F("[FREE MEM] before connectServer "));
Serial.println(esp_get_free_heap_size());
#endif
WiFiClientSecure *client = new WiFiClientSecure;
bool isSucessed;
int counter = 0;
isSucessed = false;
if (client) {
client->setInsecure();
while (!isSucessed) {
isSucessed = sendRequest(*client, callMethod, callURL, headerReferer);
delay(1000);
counter++;
strResponse = "";
if (counter >= 3) {
break;
}
}
}
delete client;
#ifdef DEBUG_MODE
Serial.print(F("[FREE MEM] after connectServer "));
Serial.println(esp_get_free_heap_size());
#endif
return isSucessed;
}
// -----------------------------------------------------------------------------
void processSigning () {
// if (mamLogin() && notHoliday() && isOnWiFi()) {
if (mamLogin() && !notHoliday() && !isOnWiFi()) {
strRequestData = "{\"activity_text\":\"" ACT_MAIN_MENU "\",\"activity_type_id\":\"" ACT_ID_LOGIN "\"}";
strResponse = "";
connectServer(METHOD_POST, API_ACTIVITY_LOG, HEADER_REFERER_MAIN_MENU); // write log
deviceSeen();
wifiLocation();
// signingInOut();
}
else {
}
}
// -----------------------------------------------------------------------------
bool mamLogin () {
bool isSucessed = false;
bool returnBin;
strRequestData = "{\"token\":\"";
strRequestData += strBearer;
strRequestData += "\"}";
strResponse = "";
if (connectServer(METHOD_POST, API_VERIFY, HEADER_REFERER_SIGN)) { // check bearer is good
if (strResponse == "\"ok\"") {
isSucessed = true;
}
else {
strRequestData = "{\"username\":\"" WIFI_USERNAME "\",\"password\":\"" WIFI_PASSWORD "\",\"device_id\":\"" MOBILE_ID "\"}";
strResponse = "";
if (connectServer(METHOD_POST, API_LOGIN, HEADER_REFERER_SIGN)) { // log in
strResponse.replace("\"", "");
// strBearer = strResponse;
// strAuthor = HTTP_HEADER_AUTHORIZATION;
// strAuthor += strBearer;
strRequestData = "{\"activity_text\":\"" ACT_LOGIN "\",\"activity_type_id\":\"" ACT_ID_LOGIN "\"}";
strResponse = "";
returnBin = connectServer(METHOD_POST, API_ACTIVITY_LOG, HEADER_REFERER_LOGIN); // write log
isSucessed = true;
}
}
}
#ifdef DEBUG_MODE
Serial.print(F("[FREE MEM] mamLogin "));
Serial.println(esp_get_free_heap_size());
#endif
return isSucessed;
}
// -----------------------------------------------------------------------------
bool notHoliday () {
bool isWorkDay = false;
strRequestData = "{}";
strAddressAPI = API_HOLIDAY;
strAddressAPI += strTodayDate;
strAddressAPI += "/";
strAddressAPI += strTodayDate;
strResponse = "";
if (connectServer(METHOD_GET, strAddressAPI, HEADER_REFERER_SIGN)) { // check holiday
if (strResponse == "[]") {
isWorkDay = true;
}
else {
intDayType = HOLIDAY;
isWorkDay = false;
}
}
#ifdef DEBUG_MODE
Serial.print(F("[FREE MEM] notHoliday "));
Serial.println(esp_get_free_heap_size());
#endif
return isWorkDay;
}
// -----------------------------------------------------------------------------
bool isOnWiFi () {
bool isConnected = false;
strRequestData = "{}";
strResponse = "";
if (connectServer(METHOD_GET, API_CHECK_WIFI, HEADER_REFERER_MAIN_MENU)) {
if (strResponse == "true") {
isConnected = true;
}
}
#ifdef DEBUG_MODE
Serial.print(F("[FREE MEM] isOnWiFi "));
Serial.println(esp_get_free_heap_size());
#endif
return isConnected;
}
// -----------------------------------------------------------------------------
bool deviceSeen () {
bool isSucessed;
strRequestData = "{}";
strResponse = "";
isSucessed = connectServer(METHOD_PUT, API_DEVICE_SEEN, HEADER_REFERER_MAIN_MENU);
#ifdef DEBUG_MODE
Serial.print(F("[FREE MEM] deviceSeen "));
Serial.println(esp_get_free_heap_size());
#endif
return isSucessed;
}
// -----------------------------------------------------------------------------
bool wifiLocation () {
bool isSucessed;
strRequestData = "{}";
strResponse = "";
isSucessed = connectServer(METHOD_GET, API_CHECK_WIFI_LOCATION, HEADER_REFERER_MAIN_MENU);
#ifdef DEBUG_MODE
Serial.print(F("[FREE MEM] wifiLocation "));
Serial.println(esp_get_free_heap_size());
#endif
return isSucessed;
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------Loading
wemos-s2-mini
wemos-s2-mini