#include <WiFi.h>
#include <esp_wifi.h>
#include <HTTPClient.h>
#include <WiFiClientSecure.h>
#include <ArduinoJson.h>
#include "secrets.h"
tm timeInfo;
String strTodayDate;
String strCookie;
String strAddressAPI;
String strBearer;
String strAuthor;
String strRequestData;
String strResponse;
int intSigningTime;
int intSigningType;
int intDayType;
StaticJsonDocument<2048> jsDocu;
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()) {
intDayType = HOLIDAY;
}
else {
if (WiFi.status() != WL_CONNECTED) {
connectWiFi();
getTime();
}
// getMAMConfig(true, true, true);
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 && intSigningType != LEAVE_ALLDAY) {
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) {
HTTPClient http;
int httpResponseCode;
bool isSucessed;
http.setFollowRedirects(HTTPC_FORCE_FOLLOW_REDIRECTS);
#ifdef DEBUG_MODE
Serial.println(headerReferer);
Serial.println(callURL);
Serial.println(strRequestData);
#endif
// if (http.begin(client, callURL)) {
if (http.begin(callURL)) {
if (headerReferer != HEADER_REFERER_NOT_MAM) {
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 :
if (headerReferer != HEADER_REFERER_NOT_MAM) {
http.addHeader("Content-Type", HTTP_HEADER_CONTENT_TYPE_JSON);
}
{
httpResponseCode = http.POST(strRequestData);
}
break;
case METHOD_PUT :
{
httpResponseCode = http.PUT(strRequestData);
}
break;
default : //METHOD_GET
{
httpResponseCode = http.GET();
}
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.println(F("[HTTP] Unable to connect"));
#endif
}
// http.end();
}
else {
isSucessed = false;
}
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) {
WiFiClientSecure *client = new WiFiClientSecure;
bool isSucessed;
int counter = 0;
isSucessed = false;
if (client) {
client->setInsecure();
while (!isSucessed) {
strResponse = "";
isSucessed = sendRequest(*client, callMethod, callURL, headerReferer);
delay(1000);
counter++;
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()) {
strRequestData = "{\"activity_text\":\"" ACT_MAIN_MENU "\",\"activity_type_id\":\"" ACT_ID_LOGIN "\"}";
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 += "\"}";
if (connectServer(METHOD_POST, API_VERIFY, HEADER_REFERER_SIGN)) { // check bearer is good
if (strResponse == "\"ok\"") {
strAuthor = HTTP_HEADER_AUTHORIZATION;
strAuthor += strBearer;
isSucessed = true;
}
else {
strRequestData = "{\"username\":\"" WIFI_USERNAME "\",\"password\":\"" WIFI_PASSWORD "\",\"device_id\":\"" MOBILE_ID "\"}";
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 "\"}";
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;
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 = "{}";
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 = "{}";
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 = "{}";
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;
}
// -----------------------------------------------------------------------------
bool checkSigned (int signingInOut, int workPeriod) {
bool isSigned = false;
bool signedInMorning;
bool signedInAfternoon;
bool signedOutNoon;
bool signedOutEvening;
strRequestData = "{}";
strAddressAPI = API_CHECK_SIGNED;
strAddressAPI += strTodayDate;
strAddressAPI += "/";
strAddressAPI += strTodayDate;
if (connectServer(METHOD_GET, strAddressAPI, HEADER_REFERER_SIGN)) { // check signed
signedInMorning = (strResponse.indexOf(SIGNED_IN_MORNING) != -1) ? true : false;
signedInAfternoon = (strResponse.indexOf(SIGNED_IN_AFTERNOON) != -1) ? true : false;
signedOutNoon = (strResponse.indexOf(SIGNED_OUT_NOON) != -1) ? true : false;
signedOutEvening = (strResponse.indexOf(SIGNED_OUT_EVENING) != -1) ? true : false;
switch (signingInOut) {
case SIGNING_IN :
isSigned = (signedInMorning || signedInAfternoon || signedOutNoon || signedOutEvening) ? true : false;
break;
case SIGNING_OUT :
switch (workPeriod) {
case WORK_ALLDAY :
isSigned = (signedInMorning && !signedInAfternoon && !signedOutNoon && !signedOutEvening) ? false : true;
break;
case WORK_MORNING :
isSigned = (signedInMorning && !signedInAfternoon && !signedOutNoon && !signedOutEvening) ? false : true;
break;
case WORK_AFTERNOON :
isSigned = (!signedInMorning && signedInAfternoon && !signedOutNoon && !signedOutEvening) ? false : true;
break;
default : //not work
isSigned = true;
break;
}
break;
default : //not in out
isSigned = true;
break;
}
}
else {
isSigned = true;
}
#ifdef DEBUG_MODE
Serial.print(F("[FREE MEM] checkSigned "));
Serial.println(esp_get_free_heap_size());
#endif
return isSigned;
}
// -----------------------------------------------------------------------------
// void getMAMConfig (bool getSigning, bool getCookie, bool getBearer) {
// bool isSucessed;
// int counter = 0;
// DeserializationError desError;
// strRequestData = "{}";
// strAddressAPI = API_GOOGLE;
// if (getSigning) {
// strAddressAPI += "&getSigning=yes";
// }
// if (getCookie) {
// strAddressAPI += "&getCookie=yes";
// }
// if (getBearer) {
// strAddressAPI += "&getBearer=yes";
// }
// isSucessed = false;
// while (!isSucessed) {
// if (connectServer(METHOD_GET, strAddressAPI, HEADER_REFERER_NOT_MAM)) {
// desError = deserializeJson(jsDocu, strResponse);
// if (desError) {
// #ifdef DEBUG_MODE
// Serial.print(F("deserializeJson() failed: "));
// Serial.println(desError.f_str());
// #endif
// isSucessed = false;
// }
// else {
// isSucessed = true;
// if (getSigning) {
// intSigningType = jsDocu["data"]["Signing"].as<signed int>();
// }
// if (getCookie) {
// strCookie = jsDocu["data"]["Cookie"].as<String>();
// }
// if (getBearer) {
// strBearer = jsDocu["data"]["Bearer"].as<String>();
// }
// }
// }
// delay(1000);
// counter++;
// if (counter >= 3) {
// ESP.restart();
// }
// }
// #ifdef DEBUG_MODE
// Serial.print(F("[FREE MEM] getMAMConifg "));
// Serial.println(esp_get_free_heap_size());
// #endif
// }
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void callMAMConfig (int optGetSetLog) {
bool isSucessed;
int counter = 0;
int returnSetBerer;
int returnSetLog;
DeserializationError desError;
strRequestData = "{}";
strAddressAPI = API_GOOGLE;
switch (optGetSetLog) {
case GET_MAM_CONFIG :
strAddressAPI += "&getSigning=yes";
strAddressAPI += "&getCookie=yes";
if (strBearer == "") strAddressAPI += "&getBearer=yes";;
break;
case SET_MAM_BEARER :
strAddressAPI += "&setBearer=";
strAddressAPI += strBearer;
break;
case SET_MAM_LOG :
strAddressAPI += "&setLogSubject=yes";
strAddressAPI += "&setLogDetail=yes";
break;
default : //not option
break;
}
isSucessed = false;
while (!isSucessed) {
if (connectServer(METHOD_GET, strAddressAPI, HEADER_REFERER_NOT_MAM)) {
desError = deserializeJson(jsDocu, strResponse);
if (desError) {
#ifdef DEBUG_MODE
Serial.print(F("deserializeJson() failed: "));
Serial.println(desError.f_str());
#endif
isSucessed = false;
}
else {
isSucessed = true;
switch (optGetSetLog) {
case GET_MAM_CONFIG :
intSigningType = jsDocu["data"]["Signing"].as<signed int>();
strCookie = jsDocu["data"]["Cookie"].as<String>();
if (strBearer == "") strBearer = jsDocu["data"]["Bearer"].as<String>();
break;
case SET_MAM_BEARER :
returnSetBerer = jsDocu["data"]["setBearer"].as<signed int>();
isSucessed = (returnSetBerer == 1) ? true : false;
break;
case SET_MAM_LOG :
returnSetLog = jsDocu["data"]["setLog"].as<signed int>();
break;
default : //not option
break;
}
}
}
delay(1000);
counter++;
if (counter >= 3) {
break;
}
}
#ifdef DEBUG_MODE
Serial.print(F("[FREE MEM] getMAMConifg "));
Serial.println(esp_get_free_heap_size());
#endif
}
// -----------------------------------------------------------------------------
void signingInOut() {
intSigningTime = timeToSign();
switch (intSigningTime) {
case MORNING_SIGNING_TIME :
strRequestData = "{\"activity_text\":\"" ACT_CLICK_SIGN_BUTTON "\",\"activity_type_id\":\"" ACT_ID_SIGN "\"}";
returnBin = connectServer(METHOD_POST, API_ACTIVITY_LOG, HEADER_REFERER_MAIN_MENU); // write log
if (intSigningType == WORK_ALLDAY && !checkSigned(SIGNING_IN)) {
strRequestData = "{\"input_method\":\"W\",\"status\":\"" STATUS_IN_MORNING "\",\"device_id\":\"" MOBILE_ID "\"}";
if (connectServer(METHOD_POST, API_CHECK_INOUT, HEADER_REFERER_MAIN_MENU)) { // signing in morning
// strResponse.replace("\"", "");
strRequestData = "{\"activity_text\":\"" ACT_SIGNED_IN_MORNING "\",\"activity_type_id\":\"" ACT_ID_SIGN "\"}";
returnBin = connectServer(METHOD_POST, API_ACTIVITY_LOG, HEADER_REFERER_MAIN_MENU); // write log
}
break;
case NOON_SIGNING_TIME :
strRequestData = "{\"activity_text\":\"" ACT_CLICK_SIGN_BUTTON "\",\"activity_type_id\":\"" ACT_ID_SIGN "\"}";
returnBin = connectServer(METHOD_POST, API_ACTIVITY_LOG, HEADER_REFERER_MAIN_MENU); // write log
if (intSigningType == WORK_MORNING && !checkSigned(SIGNING_OUT)) {
strRequestData = "{\"input_method\":\"W\",\"status\":\"" STATUS_OUT_NOON "\",\"device_id\":\"" MOBILE_ID "\"}";
if (connectServer(METHOD_POST, API_CHECK_INOUT, HEADER_REFERER_MAIN_MENU)) { // signing out noon
// strResponse.replace("\"", "");
strRequestData = "{\"activity_text\":\"" ACT_SIGNED_OUT_NOON "\",\"activity_type_id\":\"" ACT_ID_SIGN "\"}";
returnBin = connectServer(METHOD_POST, API_ACTIVITY_LOG, HEADER_REFERER_MAIN_MENU); // write log
}
}
else if (intSigningType == WORK_AFTERNOON && !checkSigned(SIGNING_IN)) {
strRequestData = "{\"activity_text\":\"" ACT_CLICK_SIGN_BUTTON "\",\"activity_type_id\":\"" ACT_ID_SIGN "\"}";
returnBin = connectServer(METHOD_POST, API_ACTIVITY_LOG, HEADER_REFERER_MAIN_MENU); // write log
strRequestData = "{\"input_method\":\"W\",\"status\":\"" STATUS_IN_AFTERNOON "\",\"device_id\":\"" MOBILE_ID "\"}";
if (connectServer(METHOD_POST, API_CHECK_INOUT, HEADER_REFERER_MAIN_MENU)) { // signing in afternoon
// strResponse.replace("\"", "");
strRequestData = "{\"activity_text\":\"" ACT_SIGNED_IN_AFTERNOON "\",\"activity_type_id\":\"" ACT_ID_SIGN "\"}";
returnBin = connectServer(METHOD_POST, API_ACTIVITY_LOG, HEADER_REFERER_MAIN_MENU); // write log
}
}
break;
case EVENING_SIGNING_TIME :
strRequestData = "{\"activity_text\":\"" ACT_CLICK_SIGN_BUTTON "\",\"activity_type_id\":\"" ACT_ID_SIGN "\"}";
returnBin = connectServer(METHOD_POST, API_ACTIVITY_LOG, HEADER_REFERER_MAIN_MENU); // write log
if ((intSigningType == WORK_ALLDAY || intSigningType == WORK_AFTERNOON) && !checkSigned(SIGNING_OUT)) {
strRequestData = "{\"input_method\":\"W\",\"status\":\"" STATUS_OUT_EVENING "\",\"device_id\":\"" MOBILE_ID "\"}";
if (connectServer(METHOD_POST, API_CHECK_INOUT, HEADER_REFERER_MAIN_MENU)) { // signing out evening
// strResponse.replace("\"", "");
strRequestData = "{\"activity_text\":\"" ACT_SIGNED_OUT_EVENING "\",\"activity_type_id\":\"" ACT_ID_SIGN "\"}";
returnBin = connectServer(METHOD_POST, API_ACTIVITY_LOG, HEADER_REFERER_MAIN_MENU); // write log
}
}
break;
default : //NOT_SIGNING_TIME
break;
}
}
}
// -----------------------------------------------------------------------------
void writeLog (const String &headerReferer, const String &activityText, const String &activityTypeId) {
bool isConnected = false;
strRequestData = "{\"activity_text\":\"";
strRequestData += activityText;
strRequestData += "\",\"activity_type_id\":\"";
strRequestData += activityTypeId;
strRequestData += "\"}";
if (connectServer(METHOD_POST, API_ACTIVITY_LOG, headerReferer)) {
// if (strResponse == "true") {
// isConnected = true;
// }
}
#ifdef DEBUG_MODE
Serial.print(F("[FREE MEM] writeLog"));
Serial.println(esp_get_free_heap_size());
#endif
return isConnected;
}
// -----------------------------------------------------------------------------