From cf134c9ebb58b2a0bf2a880cb47bc48c1e94fe02 Mon Sep 17 00:00:00 2001
From: Zoe Pfister <zoe.pfister@uibk.ac.at>
Date: Mon, 16 Jan 2023 13:54:37 +0100
Subject: [PATCH] WIP: Ability to sync time via NTP, set rtc time to unix epoch
 of synced time

---
 .../ConnectionManager.cpp                     |  41 +-
 .../ConnectionManager.h                       |  20 +-
 .../RequestInformation.h                      |   6 +-
 .../lib/TimeManager/TimeManager.cpp           |  40 +-
 .../lib/TimeManager/TimeManager.h             |   7 +-
 host/host_central_mast/src/main.cpp           | 380 +++++++++---------
 6 files changed, 287 insertions(+), 207 deletions(-)

diff --git a/host/host_central_mast/lib/NetworkConnectionManager/ConnectionManager.cpp b/host/host_central_mast/lib/NetworkConnectionManager/ConnectionManager.cpp
index 73c526d..29feb8c 100644
--- a/host/host_central_mast/lib/NetworkConnectionManager/ConnectionManager.cpp
+++ b/host/host_central_mast/lib/NetworkConnectionManager/ConnectionManager.cpp
@@ -8,8 +8,8 @@
 
 #include <utility>
 
-ConnectionManager::ConnectionManager(TinyGsm &modem, GPRSCredentials credentials)
-    : modem(modem), credentials(std::move(credentials)) {}
+ConnectionManager::ConnectionManager(TinyGsm &modem, GPRSCredentials credentials, ModemPins modemPins)
+    : modem(modem), credentials(std::move(credentials)), modemPins(modemPins) {}
 
 void ConnectionManager::restartModem() {
     // Restart takes quite some time
@@ -101,7 +101,7 @@ bool ConnectionManager::isNetworkConnected() {
     return modem.isNetworkConnected();
 }
 std::string ConnectionManager::connect(int port, RequestInformation requestInformation) {
-    TinyGsmClient client{modem};
+    TinyGsmClient client{modem, 0};
     if (!client.connect(requestInformation.host.c_str(), port)) {
         throw LTEConnectionException("Failed to connect to host");
     }
@@ -122,3 +122,38 @@ std::string ConnectionManager::connect(int port, RequestInformation requestInfor
     client.stop();
     return line.c_str();
 }
+
+void ConnectionManager::modemPowerOn() {
+    pinMode(modemPins.pwr, OUTPUT);
+    digitalWrite(modemPins.pwr, LOW);
+    delay(1000);
+    digitalWrite(modemPins.pwr, HIGH);
+}
+
+void ConnectionManager::modemPowerOff() {
+    modem.sendAT("+CPOWD=1");
+    if (modem.waitResponse(10000L) != 1) {
+        esp_log_write(ESP_LOG_WARN, TAG_GSM.c_str(), "Failed to power off modem\n");
+    }
+    modem.poweroff();
+    pinMode(modemPins.pwr, OUTPUT);
+    digitalWrite(modemPins.pwr, LOW);
+    delay(1500);
+    digitalWrite(modemPins.pwr, HIGH);
+}
+void ConnectionManager::unlockSimCard() {
+    // Unlock your SIM card with a PIN if needed
+    if (modem.getSimStatus() != 3) {
+        modem.simUnlock(credentials.password.c_str());
+    }
+}
+bool ConnectionManager::waitForNetwork() {
+    if (!modem.waitForNetwork(600000L, true)) {
+        delay(10000);
+        return false;
+    }
+    return true;
+}
+bool ConnectionManager::gprsDisconnect() {
+    return modem.gprsDisconnect();
+}
diff --git a/host/host_central_mast/lib/NetworkConnectionManager/ConnectionManager.h b/host/host_central_mast/lib/NetworkConnectionManager/ConnectionManager.h
index 7d1b8c0..4f774d0 100644
--- a/host/host_central_mast/lib/NetworkConnectionManager/ConnectionManager.h
+++ b/host/host_central_mast/lib/NetworkConnectionManager/ConnectionManager.h
@@ -18,12 +18,22 @@
 static const std::string TAG_GSM = "GSM";
 
 class ConnectionManager {
+
+  public:
+    struct ModemPins {
+        int dtr;
+        int tx;
+        int rx;
+        int pwr;
+    };
+
   private:
     TinyGsm &modem;
     const GPRSCredentials credentials;
+    ModemPins modemPins;
 
   public:
-    ConnectionManager(TinyGsm &modem, GPRSCredentials credentials);
+    ConnectionManager(TinyGsm &modem, GPRSCredentials credentials, ModemPins modemPins);
 
     std::string connect(int port, RequestInformation requestInformation);
 
@@ -46,8 +56,16 @@ class ConnectionManager {
     void setBand(BandMode bandMode, int band);
 
     bool gprsConnect();
+    bool gprsDisconnect();
 
     bool isNetworkConnected();
+
+    void modemPowerOn();
+
+    void modemPowerOff();
+
+    void unlockSimCard();
+    bool waitForNetwork();
 };
 
 #endif // HOST_CENTRAL_MAST_CONNECTIONMANAGER_H
diff --git a/host/host_central_mast/lib/NetworkConnectionManager/RequestInformation.h b/host/host_central_mast/lib/NetworkConnectionManager/RequestInformation.h
index a6d0bdd..84843cf 100644
--- a/host/host_central_mast/lib/NetworkConnectionManager/RequestInformation.h
+++ b/host/host_central_mast/lib/NetworkConnectionManager/RequestInformation.h
@@ -32,8 +32,10 @@ struct RequestInformation {
         request += "User-Agent: ESP32\r\n";
         request += "Content-Type: text/plain\r\n";
         request += "Content-Length: " + String(body.length()) + "\r\n";
-        request += "\r\n";
-        request += body;
+        if (body.length() > 0) {
+            request += "\r\n";
+            request += body;
+        }
         return request;
     }
 };
diff --git a/host/host_central_mast/lib/TimeManager/TimeManager.cpp b/host/host_central_mast/lib/TimeManager/TimeManager.cpp
index 2ece1ba..dce0ddd 100644
--- a/host/host_central_mast/lib/TimeManager/TimeManager.cpp
+++ b/host/host_central_mast/lib/TimeManager/TimeManager.cpp
@@ -4,16 +4,13 @@
 
 #include "TimeManager.h"
 
-
-TimeManager::TimeManager(TinyGsmSim7000 &modem) : modem(modem) {
-
-}
+TimeManager::TimeManager(TinyGsmSim7000 &modem) : modem(modem) {}
 
 void TimeManager::syncNTP(const std::string &ntpServer) {
     esp_log_write(ESP_LOG_DEBUG, TAG, "NTP Server Syncing...\n");
 
-    auto error = modem.NTPServerSync(ntpServer.c_str(), timeZone);
-
+    long error = modem.NTPServerSync(ntpServer.c_str(), timeZone);
+    esp_log_write(ESP_LOG_DEBUG, TAG, "error code: %ld\n", error);
     /**
       According to TinGsmNTP.tpp, the error codes are:
       case 1: "Network time synchronization is successful";
@@ -24,10 +21,11 @@ void TimeManager::syncNTP(const std::string &ntpServer) {
       case 65: "Service response timeout";
       default: "Unknown error: " + String(error);
      */
-    if (error != 1) {
+    // 255 is ok in our case (https://github.com/vshymanskyy/TinyGSM/pull/652)
+    if (error != 1 && error != 255) {
         throw NTPException(modem.ShowNTPError(error).c_str());
     } else {
-        esp_log_write(ESP_LOG_DEBUG, TAG, "NTP: %s", modem.ShowNTPError(error).c_str());
+        esp_log_write(ESP_LOG_DEBUG, TAG, "NTP: Network time synchronization is successful\n");
     }
 }
 
@@ -36,14 +34,25 @@ time_t TimeManager::timeToUnixEpochSeconds(const std::string &time, const std::s
     struct tm tm {};
     time_t dateInEpoch = 0;
 
-    std::stringstream stringStream(time);
+    // For some unknown reason, we have to use the C functions here instead of the std:: ones.
+    if (strptime(time.c_str(), format.c_str(), &tm)) {
+        time_t curTime;
+        struct tm *timeinfo;
 
-    try {
-        stringStream >> std::get_time(&tm, format.c_str());
-    } catch (std::exception &e) {
-        throw StringToTimeConversionException(("Error converting time to epoch %s", e.what()));
-    }
+        timeinfo = localtime(&curTime);
+
+        timeinfo->tm_year = tm.tm_year;
+        timeinfo->tm_mon = tm.tm_mon;
+        timeinfo->tm_mday = tm.tm_mday;
+        timeinfo->tm_hour = tm.tm_hour;
+        timeinfo->tm_min = tm.tm_min;
+        timeinfo->tm_sec = tm.tm_sec;
+        timeinfo->tm_isdst = -1;
 
+        dateInEpoch = mktime(timeinfo);
+    } else {
+        throw StringToTimeConversionException("Failed to parse date");
+    }
     return dateInEpoch;
 }
 
@@ -53,6 +62,5 @@ void TimeManager::writeModemTimeToRTC() {
     time_t time = timeToUnixEpochSeconds(gsmDateTimeString.c_str());
 
     rtc.setTime(time);
-    esp_log_write(ESP_LOG_INFO, TAG, "Time set to EPOCH: %s\n",
-                  String(rtc.getEpoch()).c_str());
+    esp_log_write(ESP_LOG_INFO, TAG, "Time set to EPOCH: %s\n", String(rtc.getEpoch()).c_str());
 }
diff --git a/host/host_central_mast/lib/TimeManager/TimeManager.h b/host/host_central_mast/lib/TimeManager/TimeManager.h
index 3de9998..967cc13 100644
--- a/host/host_central_mast/lib/TimeManager/TimeManager.h
+++ b/host/host_central_mast/lib/TimeManager/TimeManager.h
@@ -26,12 +26,13 @@ class TimeManager {
     // I would like this to be a const reference but the functions used by the modem are not const
     TinyGsmSim7000 &modem;
 
+    // convert time to unix epoch seconds
+    static time_t timeToUnixEpochSeconds(const std::string &time, const std::string &format = "%y/%m/%d,%T+00");
+
+  public:
     // sync ntp
     void syncNTP(const std::string &ntpServer = "time1.uibk.ac.at");
 
-    // convert time to unix epoch seconds
-    static time_t timeToUnixEpochSeconds(const std::string &time, const std::string &format = "%y/%m/%d,%H:%M:%S%z");
-
     // write modem time to rtc
     void writeModemTimeToRTC();
 };
diff --git a/host/host_central_mast/src/main.cpp b/host/host_central_mast/src/main.cpp
index ecb1003..4c24347 100644
--- a/host/host_central_mast/src/main.cpp
+++ b/host/host_central_mast/src/main.cpp
@@ -1,6 +1,6 @@
 #define TINY_GSM_MODEM_SIM7000
 
-
+#include "ConnectionManager.h"
 #include "FS.h"
 #include "SD.h"
 #include "SPI.h"
@@ -16,7 +16,7 @@
 
 static const std::string TAG = "MAIN";
 static const std::string TAG_ESPNOW = "ESPNOW";
-static const std::string TAG_GSM = "GSM";
+// static const std::string TAG_GSM = "GSM";
 
 /*
   FILE: AllFunctions.ino
@@ -38,18 +38,6 @@ const char apn[] = "m2m.public.at"; // SET TO YOUR APN
 const char gprsUser[] = "";
 const char gprsPass[] = "";
 
-#include <TinyGsmClient.h>
-
-#ifdef DUMP_AT_COMMANDS // if enabled it requires the streamDebugger lib
-
-#include <StreamDebugger.h>
-
-StreamDebugger debugger(SerialAT, Serial);
-TinyGsm modem(debugger);
-#else
-TinyGsm modem(SerialAT);
-#endif
-
 #define uS_TO_S_FACTOR 1000000ULL // Conversion factor for micro seconds to seconds
 #define TIME_TO_SLEEP 5           // Time ESP32 will go to sleep (in seconds)
 
@@ -65,10 +53,24 @@ TinyGsm modem(SerialAT);
 #define SD_CS 13
 #define LED_PIN 12
 
-enum MessageType {
-    dataAck,
-    hostChange
-};
+const GPRSCredentials gprsCredentials = GPRSCredentials("m2m.public.at", "", "");
+
+#include <TinyGsmClient.h>
+
+#ifdef DUMP_AT_COMMANDS // if enabled it requires the streamDebugger lib
+
+#include <StreamDebugger.h>
+
+StreamDebugger debugger(SerialAT, Serial);
+TinyGsm modem(debugger);
+ConnectionManager connectionManager{modem, gprsCredentials,
+                                    ConnectionManager::ModemPins{PIN_DTR, PIN_TX, PIN_RX, PWR_PIN}};
+
+#else
+TinyGsm modem(SerialAT);
+#endif
+
+enum MessageType { dataAck, hostChange };
 typedef struct response {
     MessageType type;
     uint8_t mac[6];
@@ -77,6 +79,8 @@ typedef struct response {
 
 #include <TimeManager.h>
 
+TimeManager timeManager{modem};
+
 uint8_t BROADCAST_MAC[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
 esp_now_peer_info_t broadcast = {};
 response announce = {};
@@ -118,7 +122,7 @@ int vprintf_into_sd(const char *szFormat, va_list args) {
 
         // debug output
         vprintf(logstring.c_str(), args);
-        logFile.write((uint8_t *) log_print_buffer, (size_t) ret);
+        logFile.write((uint8_t *)log_print_buffer, (size_t)ret);
         // to be safe in case of crashes: flush the output
         logFile.flush();
         logFile.close();
@@ -185,9 +189,8 @@ void on_data_recv(const uint8_t *mac, const uint8_t *incomingData, int len) {
     response.type = dataAck;
     esp_read_mac(response.mac, ESP_MAC_WIFI_STA);
     response.time = rtc.getEpoch();
-    esp_err_t success = esp_now_send(mac, (uint8_t *) &response, sizeof(response));
-    esp_log_write(ESP_LOG_DEBUG, TAG_ESPNOW.c_str(),
-                  (success == ESP_OK) ? "Response sent\n" : "Failed to respond\n");
+    esp_err_t success = esp_now_send(mac, (uint8_t *)&response, sizeof(response));
+    esp_log_write(ESP_LOG_DEBUG, TAG_ESPNOW.c_str(), (success == ESP_OK) ? "Response sent\n" : "Failed to respond\n");
 }
 
 String documentToLineProtocolString(const DynamicJsonDocument &doc) {
@@ -199,10 +202,8 @@ String documentToLineProtocolString(const DynamicJsonDocument &doc) {
     String channel = doc["channel"].as<String>();
     String clientMac = doc["clientMac"].as<String>();
 
-    String lineData =
-            sensorName + ",clientMac=" + clientMac + ",protocol=" + protocol + ",channel=" +
-            channel + " "
-            + measurementType + "=" + value + " " + timestamp;
+    String lineData = sensorName + ",clientMac=" + clientMac + ",protocol=" + protocol + ",channel=" + channel + " "
+                      + measurementType + "=" + value + " " + timestamp;
     return lineData;
 }
 
@@ -216,7 +217,7 @@ void saveStringToSDCard(const std::string &dataString) {
         }
         dataFile.close();
     }
-        // if the file isn't open, pop up an error:
+    // if the file isn't open, pop up an error:
     else {
         esp_log_write(ESP_LOG_ERROR, TAG.c_str(), "error opening datalog.txt\n");
         // TODO: Error handling
@@ -227,8 +228,7 @@ DynamicJsonDocument parseReceivedJsonData(char *data) {
     DynamicJsonDocument doc(250);
     auto error = deserializeJson(doc, data);
     if (error) {
-        esp_log_write(ESP_LOG_ERROR, TAG_ESPNOW.c_str(), "Error while parsing json: %s\n",
-                      error.f_str());
+        esp_log_write(ESP_LOG_ERROR, TAG_ESPNOW.c_str(), "Error while parsing json: %s\n", error.f_str());
         // TODO error handling
     }
     return doc;
@@ -244,8 +244,7 @@ String getMacAddressAsString(const uint8_t *mac) {
 }
 
 [[noreturn]] void ESPNOWReceiveTask(void *parameter) {
-    esp_log_write(ESP_LOG_DEBUG, TAG_ESPNOW.c_str(), "ESPNOWReceiveTask started on core %d\n",
-                  xPortGetCoreID());
+    esp_log_write(ESP_LOG_DEBUG, TAG_ESPNOW.c_str(), "ESPNOWReceiveTask started on core %d\n", xPortGetCoreID());
 
     WiFi.mode(WIFI_STA);
 
@@ -261,13 +260,29 @@ String getMacAddressAsString(const uint8_t *mac) {
 
     esp_now_register_recv_cb(on_data_recv);
 
+    broadcast.channel = 0;
+    broadcast.encrypt = false;
+    memcpy(&broadcast.peer_addr, &BROADCAST_MAC, sizeof(BROADCAST_MAC));
+    if (esp_now_add_peer(&broadcast) != ESP_OK) {
+        esp_log_write(ESP_LOG_WARN, TAG_ESPNOW.c_str(), "Failed to add Broadcast Host");
+    }
+
+    announce.type = hostChange;
+    esp_read_mac(announce.mac, ESP_MAC_WIFI_STA);
+    announce.time = rtc.getEpoch();
+    if (esp_now_send(BROADCAST_MAC, (uint8_t *)&announce, sizeof(announce)) != ESP_OK) {
+        esp_log_write(ESP_LOG_WARN, TAG_ESPNOW.c_str(), "Failed to announce mac");
+    } else {
+        esp_log_write(ESP_LOG_DEBUG, TAG_ESPNOW.c_str(), "Mac announced!");
+    }
+
     while (true) {
     }
 }
 
 time_t timeToUnixEpochSeconds(const std::string &time) {
     //	22/10/27,10:16:20+00
-    struct tm tm{};
+    struct tm tm {};
     time_t dateInEpoch = 0;
 
     if (strptime(time.c_str(), "%y/%m/%d,%T+00", &tm)) {
@@ -296,7 +311,7 @@ void setup() {
     setupSDCard();
 
     //	https://stackoverflow.com/questions/60442350/arduinos-esp-log-set-vprintf-does-not-work-on-esp32
-    esp_log_set_vprintf(&vprintf_into_sd);
+    //    esp_log_set_vprintf(&vprintf_into_sd);
     esp_log_level_set("*", ESP_LOG_VERBOSE);
     esp_log_write(ESP_LOG_DEBUG, TAG.c_str(), "%s", WiFi.macAddress().c_str());
 
@@ -320,29 +335,6 @@ void setup() {
 
     // Restart takes quite some time
     // To skip it, call init() instead of restart()
-    esp_log_write(ESP_LOG_DEBUG, TAG_GSM.c_str(), "Initializing modem...\n");
-    if (!modem.restart()) {
-        esp_log_write(ESP_LOG_WARN, TAG_GSM.c_str(),
-                      "Failed to restart modem, attempting to continue without restarting\n");
-    }
-
-    syncUTCTimeToRTC();
-
-    broadcast.channel = 0;
-    broadcast.encrypt = false;
-    memcpy(&broadcast.peer_addr, &BROADCAST_MAC, sizeof(BROADCAST_MAC));
-    if (esp_now_add_peer(&broadcast) != ESP_OK) {
-        esp_log_write(ESP_LOG_WARN, TAG_ESPNOW.c_str(), "Failed to add Broadcast Host");
-    }
-
-    announce.type = hostChange;
-    esp_read_mac(announce.mac, ESP_MAC_WIFI_STA);
-    announce.time = rtc.getEpoch();
-    if (esp_now_send(BROADCAST_MAC, (uint8_t *) &announce, sizeof(announce)) != ESP_OK) {
-        esp_log_write(ESP_LOG_WARN, TAG_ESPNOW.c_str(), "Failed to announce mac");
-    } else {
-        esp_log_write(ESP_LOG_DEBUG, TAG_ESPNOW.c_str(), "Mac announced!");
-    }
 }
 
 // waitResponse default is 1000ms
@@ -357,8 +349,7 @@ void syncUTCTimeToRTC() {
     time_t time = timeToUnixEpochSeconds(gsmDateTimeString.c_str());
 
     rtc.setTime(time);
-    esp_log_write(ESP_LOG_INFO, TAG_GSM.c_str(), "Time set to EPOCH: %s\n",
-                  String(rtc.getEpoch()).c_str());
+    esp_log_write(ESP_LOG_INFO, TAG_GSM.c_str(), "Time set to EPOCH: %s\n", String(rtc.getEpoch()).c_str());
 }
 
 void setupSDCard() {
@@ -385,14 +376,7 @@ void turnOffLEDs() { // Set LED OFF
 }
 
 const String INFLUXDB_TOKEN =
-        "dUh2gbVLv7e3egqocxriDsJQNUacA9qZ5YXsYtdnVAglnHgy4nx-jDVO7nGlSF34BosfnuwnUDaviC7dQeC5RQ==";
-
-struct RequestInformation {
-    String method;
-    String host;
-    String path;
-    String body;
-};
+    "dUh2gbVLv7e3egqocxriDsJQNUacA9qZ5YXsYtdnVAglnHgy4nx-jDVO7nGlSF34BosfnuwnUDaviC7dQeC5RQ==";
 
 String buildRequest(const RequestInformation &requestInformation) {
     String request = "";
@@ -409,150 +393,182 @@ String buildRequest(const RequestInformation &requestInformation) {
 
 void loop() {
 
+    connectionManager.modemPowerOn();
+    delay(5000L);
+
     // Restart takes quite some time
     // To skip it, call init() instead of restart()
-    esp_log_write(ESP_LOG_DEBUG, TAG.c_str(), "Initializing modem...\n");
-    if (!modem.init()) {
-        esp_log_write(ESP_LOG_DEBUG, TAG.c_str(),
-                      "Failed to restart modem, attempting to continue without restarting\n");
-    }
+    connectionManager.restartModem();
 
     announce.time = rtc.getEpoch();
-    if (esp_now_send(BROADCAST_MAC, (uint8_t *) &announce, sizeof(announce)) != ESP_OK) {
+    if (esp_now_send(BROADCAST_MAC, (uint8_t *)&announce, sizeof(announce)) != ESP_OK) {
         esp_log_write(ESP_LOG_WARN, TAG_ESPNOW.c_str(), "Failed to announce mac\n");
     } else {
         esp_log_write(ESP_LOG_DEBUG, TAG_ESPNOW.c_str(), "Mac announced!\n");
     }
 
+    connectionManager.disableGPS();
+
+    try {
+        connectionManager.setNetworkMode(LTE_ONLY);
+        connectionManager.setPreferredMode(CAT_M);
+    } catch (const std::exception &e) {
+        esp_log_write(ESP_LOG_ERROR, TAG_GSM.c_str(), "Error setting network mode: %s\n", e.what());
+    }
+
     String name = modem.getModemName();
-    delay(500);
-    esp_log_write(ESP_LOG_DEBUG, TAG.c_str(), "Modem Name %s\n", name.c_str());
+    esp_log_write(ESP_LOG_DEBUG, TAG_GSM.c_str(), "Modem Name: %s\n", name.c_str());
 
     String modemInfo = modem.getModemInfo();
-    delay(500);
-    esp_log_write(ESP_LOG_DEBUG, TAG.c_str(), "Modem Info: %s\n", modemInfo.c_str());
-
-    // Set SIM7000G GPIO4 LOW ,turn off GPS power
-    // CMD:AT+SGPIO=0,4,1,0
-    // Only in version 20200415 is there a function to control GPS power
-    modem.sendAT("+SGPIO=0,4,1,0");
-    if (modem.waitResponse(10000L) != 1) {
-        DBG(" SGPIO=0,4,1,0 false ");
+    esp_log_write(ESP_LOG_DEBUG, TAG_GSM.c_str(), "Modem Info: %s\n", modemInfo.c_str());
+
+    connectionManager.unlockSimCard();
+
+    if (!connectionManager.waitForNetwork()) {
+        esp_log_write(ESP_LOG_ERROR, TAG_GSM.c_str(), "Network not available\n");
+        return;
     }
 
-    modem.sendAT("+CFUN=0 ");
-    if (modem.waitResponse(10000L) != 1) {
-        DBG(" +CFUN=0  false ");
+    if (connectionManager.isNetworkConnected()) {
+        esp_log_write(ESP_LOG_DEBUG, TAG_GSM.c_str(), "Network connected\n");
     }
+
     delay(200);
 
-    /*
-      2 Automatic
-      13 GSM only
-      38 LTE only
-      51 GSM and LTE only
-    * * * */
-    String res;
-    res = modem.setNetworkMode(38);
-    if (res != "1") {
-        DBG("setNetworkMode  false ");
+    esp_log_write(ESP_LOG_DEBUG, TAG_GSM.c_str(), "Connecting to %s\n", gprsCredentials.apn.c_str());
+    if (!connectionManager.gprsConnect()) {
+        esp_log_write(ESP_LOG_ERROR, TAG_GSM.c_str(), "GPRS not connected\n");
         return;
     }
-    delay(200);
 
-    /*
-      1 CAT-M
-      2 NB-Iot
-      3 CAT-M and NB-IoT
-    * * */
-    //	res = modem.setPreferredMode(1);
-    //	if (res != "1") {
-    //
-    //		DBG("setPreferredMode  false ");
-    //		return;
-    //	}
-    delay(200);
+    bool res = modem.isGprsConnected();
+    esp_log_write(ESP_LOG_DEBUG, TAG_GSM.c_str(), "GPRS connected: %s\n", res ? "true" : "false");
+
+    String ccid = modem.getSimCCID();
+    esp_log_write(ESP_LOG_DEBUG, TAG_GSM.c_str(), "CCID: %s\n", ccid.c_str());
+
+    String imei = modem.getIMEI();
+    esp_log_write(ESP_LOG_DEBUG, TAG_GSM.c_str(), "IMEI: %s\n", imei.c_str());
+
+    String imsi = modem.getIMSI();
+    esp_log_write(ESP_LOG_DEBUG, TAG_GSM.c_str(), "IMSI: %s\n", imsi.c_str());
+
+    String cop = modem.getOperator();
+    esp_log_write(ESP_LOG_DEBUG, TAG_GSM.c_str(), "Operator: %s\n", cop.c_str());
+
+    IPAddress local = modem.localIP();
+    esp_log_write(ESP_LOG_DEBUG, TAG_GSM.c_str(), "Local IP: %s\n", local.toString().c_str());
+
+    int csq = modem.getSignalQuality();
+    esp_log_write(ESP_LOG_DEBUG, TAG_GSM.c_str(), "Signal quality: %d\n", csq);
 
-    /*AT+CBANDCFG=<mode>,<band>[,<band>…]
-     * <mode> "CAT-M"   "NB-IOT"
-     * <band>  The value of <band> must is in the band list of getting from  AT+CBANDCFG=?
-     * For example, my SIM card carrier "NB-iot" supports B8.  I will configure +CBANDCFG= "Nb-iot ",8
-     */
-    modem.sendAT("+CBANDCFG=\"CAT-M\",8 ");
-    if (modem.waitResponse(10000L) != 1) {
-        DBG(" +CBANDCFG=\"NB-IOT\" ");
+    try {
+        timeManager.syncNTP("at.pool.ntp.org");
+    } catch (const std::exception &e) {
+        esp_log_write(ESP_LOG_ERROR, TAG_GSM.c_str(), "Error syncing time: %s\n", e.what());
     }
-    delay(200);
 
-    modem.sendAT("+CFUN=1 ");
-    if (modem.waitResponse(10000L) != 1) {
-        DBG(" +CFUN=1  false ");
+    try {
+        timeManager.writeModemTimeToRTC();
+    } catch (const std::exception &e) {
+        esp_log_write(ESP_LOG_ERROR, TAG_GSM.c_str(), "Error writing time to rtc: %s\n", e.what());
     }
-    delay(200);
 
-    //	modem.disableGPS();
-    delay(200);
-    esp_log_write(ESP_LOG_DEBUG, TAG.c_str(), "%s\n", String(modem.getSignalQuality()).c_str());
-    delay(200);
-    esp_log_write(ESP_LOG_DEBUG, TAG.c_str(), "Trying to connect to network\n");
-    modem.gprsConnect(apn, gprsUser, gprsPass);
-    delay(200);
-    syncUTCTimeToRTC();
+    //    RequestInformation requestInformation("GET", "vsh.pp.ua", "/TinyGSM/logo.txt", "");
+    //    auto s = connectionManager.connect(80, requestInformation);
+    //    esp_log_write(ESP_LOG_DEBUG, TAG_GSM.c_str(), "Response: %s\n", s.c_str());
 
-    esp_log_write(ESP_LOG_DEBUG, TAG.c_str(), "Waiting for network...\n");
-    if (!modem.isNetworkConnected()) {
-        esp_log_write(ESP_LOG_DEBUG, TAG.c_str(), "Network not connected\n");
-        return;
+    connectionManager.gprsDisconnect();
+    delay(5000L);
+
+    if (!modem.isGprsConnected()) {
+        esp_log_write(ESP_LOG_DEBUG, TAG_GSM.c_str(), "GPRS disconnected\n");
     } else {
-        esp_log_write(ESP_LOG_DEBUG, TAG.c_str(), "Network connected\n");
-        delay(200);
-
-        // quality
-        esp_log_write(ESP_LOG_DEBUG, TAG.c_str(), "%s\n", String(modem.getSignalQuality()).c_str());
-        // make a http post request
-        String url = "influxdb.qe-forte.uibk.ac.at";
-        String path = "/api/v2/write?org=QE&bucket=esp32test&precision=s";
-        Serial.print("Connecting to ");
-        esp_log_write(ESP_LOG_DEBUG, TAG.c_str(), "%s\n", url.c_str());
-        // Use WiFiClient class to create TCP connections
-
-        while (!queue.empty()) {
-
-            xSemaphoreTake(xMutex, portMAX_DELAY);
-            String lineData = queue.front();
-            queue.pop();
-            xSemaphoreGive(xMutex);
-
-            RequestInformation requestInformation{.method = "POST", .host = url, .path = path, .body = lineData};
-
-            //"sensorName":"DRS26","timestamp":1666872216,"protocol":"I2C","value":0,"channel":0,"measurementType":"CIRCUMFERENCE_INCREMENT"
-
-            String request = buildRequest(requestInformation);
-            esp_log_write(ESP_LOG_VERBOSE, TAG.c_str(), "request: %s\n", request.c_str());
-
-            TinyGsmClient client{modem};
-            const int httpPort = 80;
-            if (!client.connect(url.c_str(), httpPort)) {
-                esp_log_write(ESP_LOG_DEBUG, TAG.c_str(), "connection failed\n");
-                return;
-            }
-
-            client.print(request);
-
-            // print response
-            while (client.connected()) {
-                String line = client.readStringUntil('\n');
-                if (line == "\r") {
-                    esp_log_write(ESP_LOG_DEBUG, TAG.c_str(), "headers received\n");
-                    break;
-                }
-            }
-            client.stop();
-            delay(1000);
-        }
-        DBG("Network connected");
+        esp_log_write(ESP_LOG_ERROR, TAG_GSM.c_str(), "GPRS not disconnected\n");
     }
 
+    connectionManager.modemPowerOff();
+
+    //
+    //    connectionManager.setBand(ConnectionManager::BAND_CAT_M, 20);
+    //
+    //    delay(200);
+    //
+    //    connectionManager.setModemFunctionalityLevel(ModemFunctionalityLevel::FULL);
+    //    delay(200);
+
+    //	modem.disableGPS();
+    //    delay(200);
+    //    esp_log_write(ESP_LOG_DEBUG, TAG.c_str(), "%s\n", String(modem.getSignalQuality()).c_str());
+    //
+    //    esp_log_write(ESP_LOG_DEBUG, TAG.c_str(), "Trying to connect to network\n");
+    //
+    //    Serial.println("\n\n\nWaiting for network...");
+    //    if (!modem.waitForNetwork()) {
+    //        delay(10000);
+    //        return;
+    //    }
+
+    //    esp_log_write(ESP_LOG_DEBUG, TAG.c_str(), "Waiting for network...\n");
+    //    if (!connectionManager.isNetworkConnected()) {
+    //        esp_log_write(ESP_LOG_DEBUG, TAG.c_str(), "Network not connected\n");
+    //        return;
+    //    } else {
+    //        esp_log_write(ESP_LOG_DEBUG, TAG.c_str(), "Network connected\n");
+    //        delay(200);
+    //        connectionManager.gprsConnect();
+    //        delay(200);
+    //        delay(200);
+    //        syncUTCTimeToRTC();
+    //
+    //        // quality
+    //        esp_log_write(ESP_LOG_DEBUG, TAG.c_str(), "%s\n", String(modem.getSignalQuality()).c_str());
+    //        // make a http post request
+    //        String url = "influxdb.qe-forte.uibk.ac.at";
+    //        String path = "/api/v2/write?org=QE&bucket=esp32test&precision=s";
+    //        Serial.print("Connecting to ");
+    //        esp_log_write(ESP_LOG_DEBUG, TAG.c_str(), "%s\n", url.c_str());
+    //        // Use WiFiClient class to create TCP connections
+    //
+    //        while (!queue.empty()) {
+    //
+    //            xSemaphoreTake(xMutex, portMAX_DELAY);
+    //            String lineData = queue.front();
+    //            queue.pop();
+    //            xSemaphoreGive(xMutex);
+    //            String method = "POST";
+    //
+    //            RequestInformation requestInformation = RequestInformation(method, url, path, lineData);
+    //
+    //            //"sensorName":"DRS26","timestamp":1666872216,"protocol":"I2C","value":0,"channel":0,"measurementType":"CIRCUMFERENCE_INCREMENT"
+    //
+    //            String request = buildRequest(requestInformation);
+    //            esp_log_write(ESP_LOG_VERBOSE, TAG.c_str(), "request: %s\n", request.c_str());
+    //
+    //            connectionManager.connect(80, requestInformation);
+    //            //            TinyGsmClient client{modem};
+    //            //            const int httpPort = 80;
+    //            //            if (!client.connect(url.c_str(), httpPort)) {
+    //            //                esp_log_write(ESP_LOG_DEBUG, TAG.c_str(), "connection failed\n");
+    //            //                return;
+    //            //            }
+    //            //
+    //            //            client.print(request);
+    //            //
+    //            //            // print response
+    //            //            while (client.connected()) {
+    //            //                String line = client.readStringUntil('\n');
+    //            //                if (line == "\r") {
+    //            //                    esp_log_write(ESP_LOG_DEBUG, TAG.c_str(), "headers received\n");
+    //            //                    break;
+    //            //                }
+    //            //            }
+    //            //            client.stop();
+    //            delay(1000);
+    //        }
+    //        DBG("Network connected");
+    //    }
+
 #if TINY_GSM_POWERDOWN
     // Try to power-off (modem may decide to restart automatically)
     // To turn off modem completely, please use Reset/Enable pins
@@ -564,5 +580,5 @@ void loop() {
     esp_log_write(ESP_LOG_DEBUG, TAG.c_str(), "Poweroff.");
 #endif
 
-    delay(1000);
+    delay(5000);
 }
-- 
GitLab