Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • informatik/qe/forte/sensor-system
1 result
Show changes
Commits on Source (2)
Showing
with 634 additions and 799 deletions
...@@ -9,6 +9,7 @@ AllowShortFunctionsOnASingleLine: Inline ...@@ -9,6 +9,7 @@ AllowShortFunctionsOnASingleLine: Inline
AlwaysBreakTemplateDeclarations: Yes AlwaysBreakTemplateDeclarations: Yes
BreakBeforeBinaryOperators: NonAssignment BreakBeforeBinaryOperators: NonAssignment
BreakBeforeBraces: Custom BreakBeforeBraces: Custom
NamespaceIndentation: All
BraceWrapping: BraceWrapping:
AfterFunction: false AfterFunction: false
... ...
//
// Created by zoe on 1/24/23.
//
#ifndef HOST_CENTRAL_MAST_MESSAGETYPE_H
#define HOST_CENTRAL_MAST_MESSAGETYPE_H
enum MessageType { dataAck, hostChange };
typedef struct response {
MessageType type;
uint8_t mac[6];
long time; // Clang-Tidy: Narrowing conversion from 'unsigned long' to signed type 'long' is implementation-defined
// (see rtc in main.cpp)
} response;
#endif // HOST_CENTRAL_MAST_MESSAGETYPE_H
...@@ -2,18 +2,18 @@ ...@@ -2,18 +2,18 @@
// Created by zoe on 12/19/22. // Created by zoe on 12/19/22.
// //
#include "TimeManager.h" #include "NTPManager.h"
TimeManager::TimeManager(TinyGsmSim7000 &modem) : modem(modem) {} NTPManager::NTPManager(TinyGsmSim7000 &modem) : modem(modem) {}
void TimeManager::syncNTP(const std::string &ntpServer, const std::string &backupNtpServer) { void NTPManager::syncNTP(const std::string &ntpServer, const std::string &backupNtpServer) {
// create list of ntp servers // create list of ntp servers
std::vector<std::string> ntpServers; std::vector<std::string> ntpServers;
ntpServers.push_back(ntpServer); ntpServers.push_back(ntpServer);
ntpServers.push_back(backupNtpServer); ntpServers.push_back(backupNtpServer);
tryNtpServerSync(backupNtpServer, ntpServers); tryNtpServerSync(backupNtpServer, ntpServers);
} }
void TimeManager::tryNtpServerSync(const std::string &backupNtpServer, void NTPManager::tryNtpServerSync(const std::string &backupNtpServer,
std::vector<std::string> &ntpServers) { // try to sync ntp with each server std::vector<std::string> &ntpServers) { // try to sync ntp with each server
for (const auto &server : ntpServers) { for (const auto &server : ntpServers) {
try { try {
...@@ -21,15 +21,16 @@ void TimeManager::tryNtpServerSync(const std::string &backupNtpServer, ...@@ -21,15 +21,16 @@ void TimeManager::tryNtpServerSync(const std::string &backupNtpServer,
return; return;
} catch (NTPException &e) { } catch (NTPException &e) {
if (server == backupNtpServer) { if (server == backupNtpServer) {
esp_log_write(ESP_LOG_ERROR, TAG, "Failed to sync NTP with %s (%s)\n", server.c_str(), e.what()); esp_log_write(ESP_LOG_ERROR, TAG_TIMEMANAGER, "Failed to sync NTP with %s (%s)\n", server.c_str(),
e.what());
} }
esp_log_write(ESP_LOG_ERROR, TAG, "Failed to sync NTP with %s (%s). Retrying with backup...\n", esp_log_write(ESP_LOG_ERROR, TAG_TIMEMANAGER, "Failed to sync NTP with %s (%s). Retrying with backup...\n",
server.c_str(), e.what()); server.c_str(), e.what());
} }
} }
} }
void TimeManager::synchronizeNTPWithModem(const std::string &ntpServer) { void NTPManager::synchronizeNTPWithModem(const std::string &ntpServer) {
esp_log_write(ESP_LOG_DEBUG, TAG, "NTP Server Syncing...\n"); esp_log_write(ESP_LOG_DEBUG, TAG_TIMEMANAGER, "NTP Server Syncing...\n");
long error = modem.NTPServerSync(ntpServer.c_str(), timeZone); long error = modem.NTPServerSync(ntpServer.c_str(), timeZone);
/** /**
...@@ -46,11 +47,11 @@ void TimeManager::synchronizeNTPWithModem(const std::string &ntpServer) { ...@@ -46,11 +47,11 @@ void TimeManager::synchronizeNTPWithModem(const std::string &ntpServer) {
if (error != 1 && error != 255) { if (error != 1 && error != 255) {
throw NTPException(modem.ShowNTPError(error).c_str()); throw NTPException(modem.ShowNTPError(error).c_str());
} else { } else {
esp_log_write(ESP_LOG_DEBUG, TAG, "NTP: Network time synchronization is successful\n"); esp_log_write(ESP_LOG_DEBUG, TAG_TIMEMANAGER, "NTP: Network time synchronization is successful\n");
} }
} }
time_t TimeManager::timeToUnixEpochSeconds(const std::string &time, const std::string &format) { time_t NTPManager::timeToUnixEpochSeconds(const std::string &time, const std::string &format) {
// 22/10/27,10:16:20+00 // 22/10/27,10:16:20+00
struct tm tm {}; struct tm tm {};
time_t dateInEpoch = 0; time_t dateInEpoch = 0;
...@@ -77,11 +78,11 @@ time_t TimeManager::timeToUnixEpochSeconds(const std::string &time, const std::s ...@@ -77,11 +78,11 @@ time_t TimeManager::timeToUnixEpochSeconds(const std::string &time, const std::s
return dateInEpoch; return dateInEpoch;
} }
void TimeManager::writeModemTimeToRTC() { void NTPManager::writeModemTimeToRTC() {
auto gsmDateTimeString = modem.getGSMDateTime(DATE_FULL); auto gsmDateTimeString = modem.getGSMDateTime(DATE_FULL);
esp_log_write(ESP_LOG_DEBUG, TAG, "GSM DateTime: %s\n", gsmDateTimeString.c_str()); esp_log_write(ESP_LOG_DEBUG, TAG_TIMEMANAGER, "GSM DateTime: %s\n", gsmDateTimeString.c_str());
time_t time = timeToUnixEpochSeconds(gsmDateTimeString.c_str()); time_t time = timeToUnixEpochSeconds(gsmDateTimeString.c_str());
rtc.setTime(time); 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_TIMEMANAGER, "Time set to EPOCH: %s\n", String(rtc.getEpoch()).c_str());
} }
...@@ -2,11 +2,12 @@ ...@@ -2,11 +2,12 @@
// Created by zoe on 12/19/22. // Created by zoe on 12/19/22.
// //
#ifndef HOST_CENTRAL_MAST_TIMEMANAGER_H #ifndef HOST_CENTRAL_MAST_NTPMANAGER_H
#define HOST_CENTRAL_MAST_TIMEMANAGER_H #define HOST_CENTRAL_MAST_NTPMANAGER_H
#define TINY_GSM_MODEM_SIM7000 #define TINY_GSM_MODEM_SIM7000
#include "Definitions.h"
#include "ESP32Time.h" #include "ESP32Time.h"
#include "NTPException.hpp" #include "NTPException.hpp"
#include "StringToTimeConversionException.hpp" #include "StringToTimeConversionException.hpp"
...@@ -14,13 +15,11 @@ ...@@ -14,13 +15,11 @@
#include <iomanip> #include <iomanip>
#include <string> #include <string>
class TimeManager { class NTPManager {
public: public:
explicit TimeManager(TinyGsmSim7000 &modem); explicit NTPManager(TinyGsmSim7000 &modem);
private: private:
constexpr static char *TAG = "TimeManager";
ESP32Time rtc;
int timeZone = 0; int timeZone = 0;
// I would like this to be a const reference but the functions used by the modem are not const // I would like this to be a const reference but the functions used by the modem are not const
...@@ -40,4 +39,4 @@ class TimeManager { ...@@ -40,4 +39,4 @@ class TimeManager {
void writeModemTimeToRTC(); void writeModemTimeToRTC();
}; };
#endif // HOST_CENTRAL_MAST_TIMEMANAGER_H #endif // HOST_CENTRAL_MAST_NTPMANAGER_H
\ No newline at end of file \ No newline at end of file
...@@ -5,16 +5,16 @@ ...@@ -5,16 +5,16 @@
#ifndef HOST_CENTRAL_MAST_STRINGTOTIMECONVERSIONEXCEPTION_HPP #ifndef HOST_CENTRAL_MAST_STRINGTOTIMECONVERSIONEXCEPTION_HPP
#define HOST_CENTRAL_MAST_STRINGTOTIMECONVERSIONEXCEPTION_HPP #define HOST_CENTRAL_MAST_STRINGTOTIMECONVERSIONEXCEPTION_HPP
#include "NTPManager.h"
#include <exception> #include <exception>
#include <string> #include <string>
#include "TimeManager.h"
class StringToTimeConversionException : public std::exception { class StringToTimeConversionException : public std::exception {
public: public:
explicit StringToTimeConversionException(const std::string &message) : message(message) {} explicit StringToTimeConversionException(const std::string &message) : message(message) {}
const char *what() const noexcept override { const char *what() const noexcept override {
esp_log_write(ESP_LOG_ERROR, "TimeManager", "Error converting time to epoch: %s", esp_log_write(ESP_LOG_ERROR, "NTPManager", "Error converting time to epoch: %s",
message.c_str()); message.c_str());
return message.c_str(); return message.c_str();
} }
......
...@@ -3,10 +3,6 @@ ...@@ -3,10 +3,6 @@
// //
#include "ConnectionManager.h" #include "ConnectionManager.h"
#include "LTEConnectionException.hpp"
#include "ModemFunctionalityLevel.h"
#include <utility>
ConnectionManager::ConnectionManager(TinyGsm &modem, GPRSCredentials credentials, ModemPins modemPins) ConnectionManager::ConnectionManager(TinyGsm &modem, GPRSCredentials credentials, ModemPins modemPins)
: modem(modem), credentials(std::move(credentials)), modemPins(modemPins) {} : modem(modem), credentials(std::move(credentials)), modemPins(modemPins) {}
...@@ -14,17 +10,16 @@ ConnectionManager::ConnectionManager(TinyGsm &modem, GPRSCredentials credentials ...@@ -14,17 +10,16 @@ ConnectionManager::ConnectionManager(TinyGsm &modem, GPRSCredentials credentials
void ConnectionManager::restartModem() { void ConnectionManager::restartModem() {
// Restart takes quite some time // Restart takes quite some time
// To skip it, call init() instead of restart() // To skip it, call init() instead of restart()
esp_log_write(ESP_LOG_DEBUG, TAG_GSM.c_str(), "Restarting modem...\n"); esp_log_write(ESP_LOG_DEBUG, TAG_GSM, "Restarting modem...\n");
if (!modem.restart()) { if (!modem.restart()) {
esp_log_write(ESP_LOG_WARN, TAG_GSM.c_str(), esp_log_write(ESP_LOG_WARN, TAG_GSM, "Failed to restart modem, attempting to continue without restarting\n");
"Failed to restart modem, attempting to continue without restarting\n");
} }
} }
void ConnectionManager::initModem() { void ConnectionManager::initModem() {
esp_log_write(ESP_LOG_DEBUG, TAG_GSM.c_str(), "Initializing modem...\n"); esp_log_write(ESP_LOG_DEBUG, TAG_GSM, "Initializing modem...\n");
if (!modem.init()) { if (!modem.init()) {
esp_log_write(ESP_LOG_WARN, TAG_GSM.c_str(), "Failed to initialize modem, attempting to continue...\n"); esp_log_write(ESP_LOG_WARN, TAG_GSM, "Failed to initialize modem, attempting to continue...\n");
} }
setModemFunctionalityLevel(MINIMAL); setModemFunctionalityLevel(MINIMAL);
} }
...@@ -100,9 +95,9 @@ bool ConnectionManager::gprsConnect() { ...@@ -100,9 +95,9 @@ bool ConnectionManager::gprsConnect() {
bool ConnectionManager::isNetworkConnected() { bool ConnectionManager::isNetworkConnected() {
return modem.isNetworkConnected(); return modem.isNetworkConnected();
} }
std::string ConnectionManager::connect(int port, RequestInformation requestInformation) { std::string ConnectionManager::connect(RequestInformation requestInformation) {
TinyGsmClient client{modem, 0}; TinyGsmClient client{modem, 0};
if (!client.connect(requestInformation.host.c_str(), port)) { if (!client.connect(requestInformation.host.c_str(), requestInformation.port)) {
throw LTEConnectionException("Failed to connect to host"); throw LTEConnectionException("Failed to connect to host");
} }
...@@ -115,7 +110,7 @@ std::string ConnectionManager::connect(int port, RequestInformation requestInfor ...@@ -115,7 +110,7 @@ std::string ConnectionManager::connect(int port, RequestInformation requestInfor
while (client.connected()) { while (client.connected()) {
line += client.readStringUntil('\n'); line += client.readStringUntil('\n');
if (line == "\r") { if (line == "\r") {
esp_log_write(ESP_LOG_DEBUG, TAG_GSM.c_str(), "headers received\n"); esp_log_write(ESP_LOG_DEBUG, TAG_GSM, "headers received\n");
break; break;
} }
} }
...@@ -131,9 +126,11 @@ void ConnectionManager::modemPowerOn() { ...@@ -131,9 +126,11 @@ void ConnectionManager::modemPowerOn() {
} }
void ConnectionManager::modemPowerOff() { void ConnectionManager::modemPowerOff() {
// Try to power-off (modem may decide to restart automatically)
// To turn off modem completely, please use Reset/Enable pins
modem.sendAT("+CPOWD=1"); modem.sendAT("+CPOWD=1");
if (modem.waitResponse(10000L) != 1) { if (modem.waitResponse(10000L) != 1) {
esp_log_write(ESP_LOG_WARN, TAG_GSM.c_str(), "Failed to power off modem\n"); esp_log_write(ESP_LOG_WARN, TAG_GSM, "Failed to power off modem\n");
} }
modem.poweroff(); modem.poweroff();
pinMode(modemPins.pwr, OUTPUT); pinMode(modemPins.pwr, OUTPUT);
...@@ -157,3 +154,28 @@ bool ConnectionManager::waitForNetwork() { ...@@ -157,3 +154,28 @@ bool ConnectionManager::waitForNetwork() {
bool ConnectionManager::gprsDisconnect() { bool ConnectionManager::gprsDisconnect() {
return modem.gprsDisconnect(); return modem.gprsDisconnect();
} }
void ConnectionManager::logModemInformation() {
bool res = modem.isGprsConnected();
esp_log_write(ESP_LOG_DEBUG, TAG_GSM, "GPRS connected: %s\n", res ? "true" : "false");
String ccid = modem.getSimCCID();
esp_log_write(ESP_LOG_DEBUG, TAG_GSM, "CCID: %s\n", ccid.c_str());
String imei = modem.getIMEI();
esp_log_write(ESP_LOG_DEBUG, TAG_GSM, "IMEI: %s\n", imei.c_str());
String imsi = modem.getIMSI();
esp_log_write(ESP_LOG_DEBUG, TAG_GSM, "IMSI: %s\n", imsi.c_str());
String cop = modem.getOperator();
esp_log_write(ESP_LOG_DEBUG, TAG_GSM, "Operator: %s\n", cop.c_str());
IPAddress local = modem.localIP();
esp_log_write(ESP_LOG_DEBUG, TAG_GSM, "Local IP: %s\n", local.toString().c_str());
int csq = modem.getSignalQuality();
esp_log_write(ESP_LOG_DEBUG, TAG_GSM, "Signal quality: %d\n", csq);
}
bool ConnectionManager::isGprsConnected() {
return modem.isGprsConnected();
}
...@@ -7,15 +7,16 @@ ...@@ -7,15 +7,16 @@
#define TINY_GSM_MODEM_SIM7000 #define TINY_GSM_MODEM_SIM7000
#include "Definitions.h"
#include "GPRSCredentials.h" #include "GPRSCredentials.h"
#include "LTEConnectionException.hpp"
#include "Mode.h" #include "Mode.h"
#include "ModemFunctionalityLevel.h" #include "ModemFunctionalityLevel.h"
#include "NetworkMode.h" #include "NetworkMode.h"
#include "RequestInformation.h" #include "RequestInformation.h"
#include "StreamDebugger.h" #include "StreamDebugger.h"
#include <TinyGsmClient.h> #include <TinyGsmClient.h>
#include <utility>
static const std::string TAG_GSM = "GSM";
class ConnectionManager { class ConnectionManager {
...@@ -35,7 +36,7 @@ class ConnectionManager { ...@@ -35,7 +36,7 @@ class ConnectionManager {
public: public:
ConnectionManager(TinyGsm &modem, GPRSCredentials credentials, ModemPins modemPins); ConnectionManager(TinyGsm &modem, GPRSCredentials credentials, ModemPins modemPins);
std::string connect(int port, RequestInformation requestInformation); std::string connect(RequestInformation requestInformation);
void enableGPS(); void enableGPS();
...@@ -66,6 +67,9 @@ class ConnectionManager { ...@@ -66,6 +67,9 @@ class ConnectionManager {
void unlockSimCard(); void unlockSimCard();
bool waitForNetwork(); bool waitForNetwork();
void logModemInformation();
bool isGprsConnected();
}; };
#endif // HOST_CENTRAL_MAST_CONNECTIONMANAGER_H #endif // HOST_CENTRAL_MAST_CONNECTIONMANAGER_H
...@@ -6,31 +6,42 @@ ...@@ -6,31 +6,42 @@
#define HOST_CENTRAL_MAST_REQUESTINFORMATION_H #define HOST_CENTRAL_MAST_REQUESTINFORMATION_H
#include <Arduino.h> #include <Arduino.h>
#include <Definitions.h>
#include <map>
enum RequestMethod {
GET,
POST,
};
struct RequestInformation { struct RequestInformation {
String method; RequestMethod method;
std::map<String, String> headers;
int port;
String host; String host;
String path; String path;
String body; String body;
RequestInformation(String method, String host, String path, String body) { RequestInformation(const RequestMethod &method, const String &host, const int &port, const String &path,
const String &body, const std::map<String, String> &headers) {
this->method = method; this->method = method;
this->port = port;
this->headers = headers;
this->host = host; this->host = host;
this->path = path; this->path = path;
this->body = body; this->body = body;
} }
// TODO: Move to configuration file
const String INFLUXDB_TOKEN =
"dUh2gbVLv7e3egqocxriDsJQNUacA9qZ5YXsYtdnVAglnHgy4nx-jDVO7nGlSF34BosfnuwnUDaviC7dQeC5RQ==";
String buildRequest() { String buildRequest() {
String methodString = method == RequestMethod::GET ? "GET" : "POST";
String request = ""; String request = "";
request += method + " " + path + " HTTP/1.1\r\n"; request += methodString + " " + path + " HTTP/1.1\r\n";
request += "Host: " + host + "\r\n"; request += "Host: " + host + "\r\n";
request += "Authorization: Token " + INFLUXDB_TOKEN + "\r\n"; request += "User-Agent: ESP32-Host\r\n";
request += "User-Agent: ESP32\r\n"; for (auto &header : headers) {
request += "Content-Type: text/plain\r\n"; request += header.first + ": " + header.second + "\r\n";
}
// request += "Authorization: Token " + INFLUXDB_TOKEN + "\r\n";
request += "Content-Length: " + String(body.length()) + "\r\n"; request += "Content-Length: " + String(body.length()) + "\r\n";
if (body.length() > 0) { if (body.length() > 0) {
request += "\r\n"; request += "\r\n";
......
...@@ -14,7 +14,7 @@ void ResendManager::init() { ...@@ -14,7 +14,7 @@ void ResendManager::init() {
} }
uint ResendManager::getLastResendFileId() const { // get the next file id to be resend uint ResendManager::getLastResendFileId() const { // get the next file id to be resend
auto filesInDirectory = getFilesInDirectory(resendDirectoryPath); auto filesInDirectory = SDUtilities::getFilesInDirectory(resendDirectoryPath);
// convert the file names to uint // convert the file names to uint
std::list<uint> fileUintIDs; std::list<uint> fileUintIDs;
...@@ -38,24 +38,24 @@ uint ResendManager::getLastResendFileId() const { // get the next file id to be ...@@ -38,24 +38,24 @@ uint ResendManager::getLastResendFileId() const { // get the next file id to be
} }
void ResendManager::createResendDirectory() const { // create directory if it doesn't exist void ResendManager::createResendDirectory() const { // create directory if it doesn't exist
createDirectory("/resend"); SDUtilities::createDirectory("/resend");
} }
void ResendManager::storeForResend(const String &messageToBeSend) { void ResendManager::storeForResend(const String &messageToBeSend) {
// create file // create file
String filename = String(nextResendFileId); String filename = String(nextResendFileId);
writeFile(messageToBeSend, resendDirectoryPath + "/" + filename); SDUtilities::writeFile(messageToBeSend, resendDirectoryPath + "/" + filename);
ResendManager::incrementCount(); ResendManager::incrementCount();
} }
std::optional<ResendPointType> ResendManager::loadNextToBeResendMessage() { std::optional<ResendPointType> ResendManager::loadNextToBeResendMessage() {
// get first file in resend directory // get first file in resend directory
auto filename = getFirstFileNameInDirectory(resendDirectoryPath.c_str()); auto filename = SDUtilities::getFirstFileNameInDirectory(resendDirectoryPath.c_str());
if (filename.has_value()) { if (filename.has_value()) {
// read file // read file
auto message = readFile(resendDirectoryPath + "/" + filename.value().c_str()); auto message = SDUtilities::readFile(resendDirectoryPath + "/" + filename.value().c_str());
return ResendPointType{message, filename.value()}; return ResendPointType{message, filename.value()};
} }
return std::nullopt; return std::nullopt;
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define HOST_CENTRAL_MAST_DEFINITIONS_H #define HOST_CENTRAL_MAST_DEFINITIONS_H
#include "Arduino.h" #include "Arduino.h"
#include "ESP32Time.h"
#define uS_TO_S_FACTOR 1000000ULL // Conversion factor for micro seconds to seconds #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) #define TIME_TO_SLEEP 5 // Time ESP32 will go to sleep (in seconds)
...@@ -22,6 +23,23 @@ ...@@ -22,6 +23,23 @@
#define SD_CS 13 #define SD_CS 13
#define LED_PIN 12 #define LED_PIN 12
// See all AT commands, if wanted
// #define DUMP_AT_COMMANDS
#define TAG_ESPNOW "ESPNOW"
#define TAG_MAIN "MAIN"
#define TAG_SD "SD"
#define TAG_GSM "GSM"
#define TAG_TIMEMANAGER "TIMEMANAGER"
#define TAG_SDUTILITIES "SDUTILITIES"
#define SD_CARD_FAIL_COUNTER 100
constexpr bool PRINT_TO_SERIAL = true;
// global definition of RTC. Initialised in main
extern ESP32Time rtc;
const String INFLUXDB_TOKEN = const String INFLUXDB_TOKEN =
"dUh2gbVLv7e3egqocxriDsJQNUacA9qZ5YXsYtdnVAglnHgy4nx-jDVO7nGlSF34BosfnuwnUDaviC7dQeC5RQ=="; "dUh2gbVLv7e3egqocxriDsJQNUacA9qZ5YXsYtdnVAglnHgy4nx-jDVO7nGlSF34BosfnuwnUDaviC7dQeC5RQ==";
......
//
// Created by zoe on 1/24/23.
//
#include "SDCardLogger.h"
namespace SDCardLogger {
char log_print_buffer[512];
bool printToSerial = false;
void printDebugToSerial(bool printToSerialAsWell) {
printToSerial = printToSerialAsWell;
}
int vprintf_into_sd(const char *szFormat, va_list args) {
String logstring = "[" + rtc.getDateTime() + "] ";
logstring += szFormat;
if (!SDUtilities::isSDAvailable()) {
if (printToSerial) {
logstring += " (SD card not available)\n";
vprintf(logstring.c_str(), args);
}
return 1;
}
// write evaluated format string into buffer
int ret = vsnprintf(log_print_buffer, sizeof(log_print_buffer), logstring.c_str(), args);
String date = rtc.getDate();
String filename = "/log_" + date + ".txt";
// output is now in buffer. write to file.
if (ret >= 0) {
if (!SD.exists(filename)) {
File writeLog = SD.open(filename, FILE_WRITE);
if (!writeLog) {
Serial.println("Couldn't open " + filename + " for writing");
SDUtilities::setSDAvailable(false);
return 1;
}
delay(50);
writeLog.close();
}
File logFile = SD.open(filename, FILE_APPEND);
// debug output
if (printToSerial) {
vprintf(logstring.c_str(), args);
}
logFile.write((uint8_t *)log_print_buffer, (size_t)ret);
// to be safe in case of crashes: flush the output
logFile.flush();
logFile.close();
}
return ret;
}
} // namespace SDCardLogger
//
// Created by zoe on 1/24/23.
//
#ifndef HOST_CENTRAL_MAST_SDCARDLOGGER_H
#define HOST_CENTRAL_MAST_SDCARDLOGGER_H
#include "Definitions.h"
#include "SD.h"
#include "Utilities.h"
namespace SDCardLogger {
void printDebugToSerial(bool printToSerialAsWell);
int vprintf_into_sd(const char *szFormat, va_list args);
}; // namespace SDCardLogger
#endif // HOST_CENTRAL_MAST_SDCARDLOGGER_H
...@@ -4,148 +4,302 @@ ...@@ -4,148 +4,302 @@
#include "Utilities.h" #include "Utilities.h"
void setupSDCard(); namespace SDUtilities {
void saveStringToSDCard(const std::string &dataString);
std::list<String> getFilesInDirectory(const String &dirname) { bool SDAvailable = true;
std::list<String> files;
File dir = openDirectory(dirname);
while (true) {
File nextFile = dir.openNextFile();
if (!nextFile) {
break;
}
if (!nextFile.isDirectory()) {
files.emplace_back(nextFile.name());
}
nextFile.close();
}
return files;
}
std::optional<String> getLastFileInDirectory(const String &dirname) { void setSDAvailable(bool sdAvailable) {
SDAvailable = sdAvailable;
}
File root = openDirectory(dirname); // Used to try to remount SD card if it fails more than x times (100)
root.rewindDirectory(); int sdFailCounter = 0;
bool isSDAvailable() {
return SDAvailable;
}
File file = root.openNextFile(); void tryRemountingSD() {
while (file) { try {
File nextFile = root.openNextFile(); setupSDCard(SD_MISO, SD_MOSI, SD_SCLK, SD_CS);
if (!nextFile) { setSDAvailable(true);
break; } catch (SDSetupException &e) {
esp_log_write(ESP_LOG_ERROR, TAG_SDUTILITIES, "Couldn't remount SD card: %s\n", e.what());
} }
file = nextFile; sdFailCounter = 0;
} }
// log
if (file) { bool checkSDAvailability(const String &errorMessage) {
esp_log_write(ESP_LOG_INFO, "getLastFileInDirectory", "Last file name: %s\n", file.name()); if (!isSDAvailable()) {
return file.name(); sdFailCounter++;
} else { if (sdFailCounter % SD_CARD_FAIL_COUNTER == 0) {
esp_log_write(ESP_LOG_INFO, "getLastFileInDirectory", "No file found\n"); esp_log_write(ESP_LOG_ERROR, TAG_SDUTILITIES, "SD card not available. Trying to remount...\n");
return std::nullopt; tryRemountingSD();
}
String message = errorMessage + " (SD card not available, failed " + sdFailCounter + " times)\n";
esp_log_write(ESP_LOG_ERROR, TAG_SDUTILITIES, "%s", message.c_str());
// if re-mount was successful, this will be true
return isSDAvailable();
}
return true;
};
std::list<String> getFilesInDirectory(const String &dirname) {
if (!checkSDAvailability("Couldn't get files in directory " + dirname)) {
return {};
}
std::list<String> files;
File dir = openDirectory(dirname);
while (true) {
File nextFile = dir.openNextFile();
if (!nextFile) {
break;
}
if (!nextFile.isDirectory()) {
files.emplace_back(nextFile.name());
}
nextFile.close();
}
return files;
} }
}
File openDirectory(const String &dirname) { std::optional<String> getLastFileInDirectory(const String &dirname) {
File root = SD.open(dirname);
if (!root) { if (!checkSDAvailability("Couldn't get last file in directory " + dirname)) {
esp_log_write(ESP_LOG_ERROR, "openDirectory", "Failed to open directory\n"); return std::nullopt;
throw; }
File root = openDirectory(dirname);
root.rewindDirectory();
File file = root.openNextFile();
while (file) {
File nextFile = root.openNextFile();
if (!nextFile) {
break;
}
file = nextFile;
}
// log
if (file) {
esp_log_write(ESP_LOG_INFO, TAG_SDUTILITIES, "Last file name: %s\n", file.name());
return file.name();
} else {
esp_log_write(ESP_LOG_INFO, TAG_SDUTILITIES, "No file found\n");
return std::nullopt;
}
} }
if (!root.isDirectory()) { File openDirectory(const String &dirname) {
esp_log_write(ESP_LOG_ERROR, "openDirectory", "Not a directory\n");
throw; if (!checkSDAvailability("Couldn't open directory " + dirname)) {
throw;
}
File root = SD.open(dirname);
if (!root) {
esp_log_write(ESP_LOG_ERROR, TAG_SDUTILITIES, "Failed to open directory\n");
throw;
}
if (!root.isDirectory()) {
esp_log_write(ESP_LOG_ERROR, TAG_SDUTILITIES, "Not a directory\n");
throw;
}
return root;
} }
return root;
}
std::optional<String> getFirstFileNameInDirectory(const String &dirname) {
File root = openDirectory(dirname); std::optional<String> getFirstFileNameInDirectory(const String &dirname) {
root.rewindDirectory();
File file = root.openNextFile(); if (!checkSDAvailability("Couldn't get first file in directory " + dirname)) {
if (file) { return std::nullopt;
esp_log_write(ESP_LOG_INFO, "getFirstFileNameInDirectory", "file found: %s\n", file.name()); }
return file.name();
} else { File root = openDirectory(dirname);
esp_log_write(ESP_LOG_INFO, "getFirstFileNameInDirectory", "no file found\n"); root.rewindDirectory();
return std::nullopt;
File file = root.openNextFile();
if (file) {
esp_log_write(ESP_LOG_INFO, TAG_SDUTILITIES, "file found: %s\n", file.name());
return file.name();
} else {
esp_log_write(ESP_LOG_INFO, TAG_SDUTILITIES, "no file found\n");
return std::nullopt;
}
} }
}
File openForWrite(const String &filePath) { File openForWrite(const String &filePath) {
File file = SD.open(filePath, FILE_WRITE);
if (!file) { if (!checkSDAvailability("Couldn't open file " + filePath + " for writing")) {
esp_log_write(ESP_LOG_ERROR, "SD", "Failed to open file for writing\n"); throw;
throw; }
File file = SD.open(filePath, FILE_WRITE);
if (!file) {
esp_log_write(ESP_LOG_ERROR, TAG_SDUTILITIES, "Failed to open file for writing\n");
throw;
}
return file;
} }
return file;
}
File openForRead(const String &filePath) { File openForRead(const String &filePath) {
File file = SD.open(filePath, FILE_READ);
if (!file) { if (!checkSDAvailability("Couldn't open file " + filePath + " for reading")) {
esp_log_write(ESP_LOG_ERROR, "SD", "Failed to open file for reading\n"); throw;
throw; }
File file = SD.open(filePath, FILE_READ);
if (!file) {
esp_log_write(ESP_LOG_ERROR, TAG_SDUTILITIES, "Failed to open file for reading\n");
throw;
}
return file;
} }
return file;
}
void writeFile(const String &messageToBeSend, const String &filePath) { void writeFile(const String &messageToBeSend, const String &filePath) {
File file = openForWrite(filePath);
if (file.print(messageToBeSend)) { if (!checkSDAvailability("Couldn't write to file " + filePath)) {
esp_log_write(ESP_LOG_INFO, "SD", "File written %s\n", filePath.c_str()); throw;
} else { }
esp_log_write(ESP_LOG_ERROR, "SD", "Write failed %s\n", filePath.c_str());
throw; File file = openForWrite(filePath);
if (file.print(messageToBeSend)) {
esp_log_write(ESP_LOG_INFO, TAG_SDUTILITIES, "File written %s\n", filePath.c_str());
} else {
esp_log_write(ESP_LOG_ERROR, TAG_SDUTILITIES, "Write failed %s\n", filePath.c_str());
throw;
}
file.close();
} }
file.close();
}
String readFile(const String &filePath) {
File file = openForRead(filePath);
String ret; String readFile(const String &filePath) {
if (!checkSDAvailability("Couldn't read file " + filePath)) {
throw;
}
File file = openForRead(filePath);
while (file.available()) { String ret;
ret += (char)file.read();
while (file.available()) {
ret += (char)file.read();
}
file.close();
return ret;
} }
file.close(); void createDirectory(const String &dirname) {
return ret;
}
void createDirectory(const String &dirname) { if (!checkSDAvailability("Couldn't create directory " + dirname)) {
if (!SD.exists(dirname)) { throw;
SD.mkdir(dirname); }
esp_log_write(ESP_LOG_INFO, "createDirectory", "Created directory: %s\n", dirname.c_str());
} else { if (!SD.exists(dirname)) {
esp_log_write(ESP_LOG_WARN, "createDirectory", "Directory already exists\n"); SD.mkdir(dirname);
esp_log_write(ESP_LOG_INFO, TAG_SDUTILITIES, "Created directory: %s\n", dirname.c_str());
} else {
esp_log_write(ESP_LOG_WARN, TAG_SDUTILITIES, "Directory already exists\n");
}
} }
}
void setupSDCard(int MISO, int MOSI, int SCLK, int CS) { void setupSDCard(int MISO, int MOSI, int SCLK, int CS) {
SPI.begin(SCLK, MISO, MOSI, CS); SPI.begin(SCLK, MISO, MOSI, CS);
if (!SD.begin(CS)) { if (!SD.begin(CS)) {
esp_log_write(ESP_LOG_ERROR, "Utilities", "Card MOUNT FAIL\n"); esp_log_write(ESP_LOG_ERROR, TAG_SDUTILITIES, "Card MOUNT FAIL\n");
throw SDSetupException("Card MOUNT FAIL"); throw SDSetupException("Card MOUNT FAIL");
} else { } else {
uint32_t cardSize = SD.cardSize() / (1024 * 1024); uint32_t cardSize = SD.cardSize() / (1024 * 1024);
String sdcardSizeString = "SDCard Size: " + String(cardSize) + "MB"; String sdcardSizeString = "SDCard Size: " + String(cardSize) + "MB";
esp_log_write(ESP_LOG_DEBUG, "Utilities", "%s\n", sdcardSizeString.c_str()); esp_log_write(ESP_LOG_DEBUG, TAG_SDUTILITIES, "%s\n", sdcardSizeString.c_str());
}
} }
}
void saveStringToSDCard(const std::string &dataString) { void saveStringToSDCard(const std::string &dataString) {
File dataFile = SD.open("/datalog.txt", FILE_APPEND);
if (!checkSDAvailability("Couldn't save string to SD card")) {
throw SDCardException("Couldn't save string to SD card");
}
// if the file is available, write to it: File dataFile = SD.open("/datalog.txt", FILE_APPEND);
if (dataFile) {
if (dataString.length() > 0) { // if the file is available, write to it:
dataFile.println(dataString.c_str()); if (dataFile) {
if (dataString.length() > 0) {
dataFile.println(dataString.c_str());
}
dataFile.close();
}
// if the file isn't open, pop up an error:
else {
esp_log_write(ESP_LOG_ERROR, TAG_SDUTILITIES, "error opening datalog.txt\n");
throw SDCardException("error opening datalog.txt");
} }
dataFile.close();
} }
// if the file isn't open, pop up an error: } // namespace SDUtilities
else {
esp_log_write(ESP_LOG_ERROR, "Utilities", "error opening datalog.txt\n"); // I don't think this does anything. Copied from the example
throw SDCardException("error opening datalog.txt"); void turnOffLEDs() { // Set LED OFF
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, HIGH);
pinMode(PWR_PIN, OUTPUT);
digitalWrite(PWR_PIN, HIGH);
delay(300);
digitalWrite(PWR_PIN, LOW);
}
String getMacAddressAsString(const uint8_t *mac) {
String macAddress;
for (int i = 0; i < 6; i++) {
macAddress += String(mac[i], HEX);
}
esp_log_write(ESP_LOG_DEBUG, TAG_ESPNOW, "MAC: %s\n", macAddress.c_str());
return macAddress;
}
String documentToLineProtocolString(const DynamicJsonDocument &doc) {
String measurementType = doc["measurementType"].as<String>();
String sensorName = doc["sensorName"].as<String>();
String timestamp = doc["timestamp"].as<String>();
String protocol = doc["protocol"].as<String>();
String value = doc["value"].as<String>();
String channel = doc["channel"].as<String>();
String clientMac = doc["clientMac"].as<String>();
String lineData = sensorName + ",clientMac=" + clientMac + ",protocol=" + protocol + ",channel=" + channel + " "
+ measurementType + "=" + value + " " + timestamp;
return lineData;
}
DynamicJsonDocument parseReceivedJsonData(char *data) {
DynamicJsonDocument doc(250);
auto error = deserializeJson(doc, data);
if (error) {
esp_log_write(ESP_LOG_ERROR, TAG_ESPNOW, "Error while parsing json: %s\n", error.c_str());
// TODO error handling
} }
return doc;
}
String documentToServerReadableString(const DynamicJsonDocument &doc) {
StaticJsonDocument<1024> serverDoc;
String hostMacAddressString = WiFi.macAddress();
hostMacAddressString.replace(":", "");
hostMacAddressString.toLowerCase();
serverDoc["host"] = hostMacAddressString;
serverDoc["client"] = doc["clientMac"].as<String>();
serverDoc["sensorProtocol"] = doc["protocol"].as<String>();
serverDoc["protocolAddress"] = doc["channel"].as<String>();
serverDoc["hardwareName"] = doc["sensorName"].as<String>();
// each value is a element in the readigs array
JsonArray readings = serverDoc.createNestedArray("readings");
JsonObject reading = readings.createNestedObject();
reading["name"] = doc["measurementType"].as<String>();
reading["value"] = doc["value"].as<float>();
serverDoc["time"] = doc["timestamp"].as<uint32_t>();
String serverString;
serializeJson(serverDoc, serverString);
esp_log_write(ESP_LOG_DEBUG, TAG_ESPNOW, "Server readable data: %s\n", serverString.c_str());
return serverString;
} }
\ No newline at end of file
...@@ -5,21 +5,34 @@ ...@@ -5,21 +5,34 @@
#ifndef HOST_CENTRAL_MAST_UTILITIES_H #ifndef HOST_CENTRAL_MAST_UTILITIES_H
#define HOST_CENTRAL_MAST_UTILITIES_H #define HOST_CENTRAL_MAST_UTILITIES_H
#include "ArduinoJson.h"
#include "SD.h" #include "SD.h"
#include "SDCardException.h" #include "SDCardException.h"
#include "SDSetupException.h" #include "SDSetupException.h"
#include "WiFi.h"
#include <Arduino.h> #include <Arduino.h>
#include <Definitions.h> #include <Definitions.h>
#include <WString.h> #include <WString.h>
#include <list> #include <list>
File openDirectory(const String &dirname); namespace SDUtilities {
std::list<String> getFilesInDirectory(const String &dirname); File openDirectory(const String &dirname);
std::optional<String> getFirstFileNameInDirectory(const String &dirname); std::list<String> getFilesInDirectory(const String &dirname);
std::optional<String> getLastFileInDirectory(const String &dirname); std::optional<String> getFirstFileNameInDirectory(const String &dirname);
void writeFile(const String &messageToBeSend, const String &filePath); std::optional<String> getLastFileInDirectory(const String &dirname);
String readFile(const String &filePath); void writeFile(const String &messageToBeSend, const String &filePath);
void createDirectory(const String &dirname); String readFile(const String &filePath);
void setupSDCard(int MISO, int MOSI, int SCLK, int CS); void createDirectory(const String &dirname);
void saveStringToSDCard(const std::string &dataString); void setupSDCard(int MISO, int MOSI, int SCLK, int CS);
void saveStringToSDCard(const std::string &dataString);
void setSDAvailable(bool sdAvailable);
bool isSDAvailable();
} // namespace SDUtilities
void turnOffLEDs();
String getMacAddressAsString(const uint8_t *mac);
String documentToLineProtocolString(const DynamicJsonDocument &doc);
DynamicJsonDocument parseReceivedJsonData(char *data);
String documentToServerReadableString(const DynamicJsonDocument &doc);
#endif // HOST_CENTRAL_MAST_UTILITIES_H #endif // HOST_CENTRAL_MAST_UTILITIES_H
This diff is collapsed.
///**************************************************************
// *
// * This sketch connects to a website and downloads a page.
// * It can be used to perform HTTP/RESTful API calls.
// *
// * TinyGSM Getting Started guide:
// * https://tiny.cc/tinygsm-readme
// *
// **************************************************************/
//
//// Select your modem:
//// #define TINY_GSM_MODEM_SIM800
//// #define TINY_GSM_MODEM_SIM808
//// #define TINY_GSM_MODEM_SIM868
//// #define TINY_GSM_MODEM_SIM900
//#define TINY_GSM_MODEM_SIM7000
//// #define TINY_GSM_MODEM_SIM7000SSL
//// #define TINY_GSM_MODEM_SIM7080
//// #define TINY_GSM_MODEM_SIM5360
//// #define TINY_GSM_MODEM_SIM7600
//// #define TINY_GSM_MODEM_UBLOX
//// #define TINY_GSM_MODEM_SARAR4
//// #define TINY_GSM_MODEM_M95
//// #define TINY_GSM_MODEM_BG96
//// #define TINY_GSM_MODEM_A6
//// #define TINY_GSM_MODEM_A7
//// #define TINY_GSM_MODEM_M590
//// #define TINY_GSM_MODEM_MC60
//// #define TINY_GSM_MODEM_MC60E
//// #define TINY_GSM_MODEM_ESP8266
//// #define TINY_GSM_MODEM_XBEE
//// #define TINY_GSM_MODEM_SEQUANS_MONARCH
//
//// Set serial for debug console (to the Serial Monitor, default speed 115200)
//#define SerialMon Serial
//
//// Set serial for AT commands (to the module)
//// Use Hardware Serial on Mega, Leonardo, Micro
//#ifndef __AVR_ATmega328P__
//#define SerialAT Serial1
//
//// or Software Serial on Uno, Nano
//#else
//#include <SoftwareSerial.h>
//SoftwareSerial SerialAT(2, 3); // RX, TX
//#endif
//
//// Increase RX buffer to capture the entire response
//// Chips without internal buffering (A6/A7, ESP8266, M590)
//// need enough space in the buffer for the entire response
//// else data will be lost (and the http library will fail).
//#if !defined(TINY_GSM_RX_BUFFER)
//#define TINY_GSM_RX_BUFFER 650
//#endif
//
//// See all AT commands, if wanted
//#define DUMP_AT_COMMANDS
//
//// Define the serial console for debug prints, if needed
//#define TINY_GSM_DEBUG SerialMon
//
//// Range to attempt to autobaud
//// NOTE: DO NOT AUTOBAUD in production code. Once you've established
//// communication, set a fixed baud rate using modem.setBaud(#).
//#define GSM_AUTOBAUD_MIN 9600
//#define GSM_AUTOBAUD_MAX 115200
//
//// Add a reception delay, if needed.
//// This may be needed for a fast processor at a slow baud rate.
//// #define TINY_GSM_YIELD() { delay(2); }
//
//// Uncomment this if you want to use SSL
//// #define USE_SSL
//
//// Define how you're planning to connect to the internet.
//// This is only needed for this example, not in other code.
//#define TINY_GSM_USE_GPRS true
//#define TINY_GSM_USE_WIFI false
//
//// set GSM PIN, if any
//#define GSM_PIN ""
//
//// Your GPRS credentials, if any
//const char apn[] = "m2m.public.at";
//const char gprsUser[] = "";
//const char gprsPass[] = "";
//
//// Your WiFi connection credentials, if applicable
//const char wifiSSID[] = "YourSSID";
//const char wifiPass[] = "YourWiFiPass";
//
//// Server details
//const char server[] = "vsh.pp.ua";
//const char resource[] = "/TinyGSM/logo.txt";
//
//#include <TinyGsmClient.h>
//#include <WiFi.h>
//#include <esp_now.h>
//
//// Just in case someone defined the wrong thing..
//#if TINY_GSM_USE_GPRS && not defined TINY_GSM_MODEM_HAS_GPRS
//#undef TINY_GSM_USE_GPRS
//#undef TINY_GSM_USE_WIFI
//#define TINY_GSM_USE_GPRS false
//#define TINY_GSM_USE_WIFI true
//#endif
//#if TINY_GSM_USE_WIFI && not defined TINY_GSM_MODEM_HAS_WIFI
//#undef TINY_GSM_USE_GPRS
//#undef TINY_GSM_USE_WIFI
//#define TINY_GSM_USE_GPRS true
//#define TINY_GSM_USE_WIFI false
//#endif
//
//#ifdef DUMP_AT_COMMANDS
//#include <StreamDebugger.h>
//StreamDebugger debugger(SerialAT, SerialMon);
//TinyGsm modem(debugger);
//#else
//TinyGsm modem(SerialAT);
//#endif
//
//#ifdef USE_SSL
//TinyGsmClientSecure client_satellite(modem);
//const int port = 443;
//#else
//TinyGsmClient client_satellite(modem);
//const int port = 80;
//#endif
//
//TaskHandle_t Task1;
//
//void on_data_sent(const uint8_t *mac_addr, esp_now_send_status_t status)
//{
// // go to sleep
//}
//
//void on_data_recv(const uint8_t *mac, const uint8_t *incomingData, int len)
//{
// // print mac
// Serial.print("Message recieved: Core ");
// Serial.println(xPortGetCoreID());
// for (int i = 0; i < 6; i++) {
// Serial.print(mac[i], HEX);
// Serial.print(":");
// }
// Serial.println();
// char data[len];
// memcpy(data, incomingData, len);
// Serial.println(data);
//}
//
//[[noreturn]] void Task1code(void *parameter)
//{
// Serial.println(xPortGetCoreID());
// WiFi.mode(WIFI_STA);
// Serial.println("ESPNow init");
// if (esp_now_init() != ESP_OK) {
// // initialization failed
// Serial.println("ESPNow init failed");
// // not sure about this
// }
// Serial.println("ESPNow init success");
// esp_now_register_recv_cb(on_data_recv);
//
// while (true) {
// }
//}
//
//void setup2()
//{
// // Set console baud rate
// SerialMon.begin(115200);
// delay(10);
//
// // !!!!!!!!!!!
// // Set your reset, enable, power pins here
// // !!!!!!!!!!!
//
// SerialMon.println("Wait...");
//
// xTaskCreatePinnedToCore(Task1code, /* Function to implement the task */
// "Task1", /* Name of the task */
// 10000, /* Stack size in words */
// nullptr, /* Task input parameter */
// 0, /* Priority of the task */
// &Task1, /* Task handle. */
// 0); /* Core where the task should run */
//
// // Set GSM module baud rate
// // TinyGsmAutoBaud(SerialAT, GSM_AUTOBAUD_MIN, GSM_AUTOBAUD_MAX);
// modem.setBaud(9600);
// // SerialAT.begin(9600);
// delay(6000);
//
// // Restart takes quite some time
// // To skip it, call init() instead of restart()
// SerialMon.println("Initializing modem...");
// modem.restart();
// // modem.init();
//
// String modemInfo = modem.getModemInfo();
// SerialMon.print("Modem Info: ");
// SerialMon.println(modemInfo);
//
//#if TINY_GSM_USE_GPRS
// // Unlock your SIM card with a PIN if needed
// if (GSM_PIN && modem.getSimStatus() != 3) {
// modem.simUnlock(GSM_PIN);
// }
//#endif
//}
//
//void loop2()
//{
//#if TINY_GSM_USE_WIFI
// // Wifi connection parameters must be set before waiting for the network
// SerialMon.print(F("Setting SSID/password..."));
// if (!modem.networkConnect(wifiSSID, wifiPass)) {
// SerialMon.println(" fail");
// delay(10000);
// return;
// }
// SerialMon.println(" success");
//#endif
//
//#if TINY_GSM_USE_GPRS && defined TINY_GSM_MODEM_XBEE
// // The XBee must run the gprsConnect function BEFORE waiting for network!
// modem.gprsConnect(apn, gprsUser, gprsPass);
//#endif
//
// SerialMon.print("Waiting for network...");
// if (!modem.waitForNetwork()) {
// SerialMon.println(" fail");
// delay(10000);
// return;
// }
// SerialMon.println(" success");
//
// if (modem.isNetworkConnected()) {
// SerialMon.println("Network connected");
// }
//
//#if TINY_GSM_USE_GPRS
// // GPRS connection parameters are usually set after network registration
// SerialMon.print(F("Connecting to "));
// SerialMon.print(apn);
// if (!modem.gprsConnect(apn, gprsUser, gprsPass)) {
// SerialMon.println(" fail");
// delay(10000);
// return;
// }
// SerialMon.println(" success");
//
// if (modem.isGprsConnected()) {
// SerialMon.println("GPRS connected");
// }
//#endif
//
// SerialMon.print("Connecting to ");
// SerialMon.println(server);
// if (!client_satellite.connect(server, port)) {
// SerialMon.println(" fail");
// delay(10000);
// return;
// }
// SerialMon.println(" success");
//
// // Make a HTTP GET request:
// SerialMon.println("Performing HTTP GET request...");
// client_satellite.print(String("GET ") + resource + " HTTP/1.1\r\n");
// client_satellite.print(String("Host: ") + server + "\r\n");
// client_satellite.print("Connection: close\r\n\r\n");
// client_satellite.println();
//
// uint32_t timeout = millis();
// while (client_satellite.connected() && millis() - timeout < 10000L) {
// // Print available data
// while (client_satellite.available()) {
// char c = client_satellite.read();
// SerialMon.print(c);
// timeout = millis();
// }
// }
// SerialMon.println();
//
// // Shutdown
//
// client_satellite.stop();
// SerialMon.println(F("Server disconnected"));
//
//#if TINY_GSM_USE_WIFI
// modem.networkDisconnect();
// SerialMon.println(F("WiFi disconnected"));
//#endif
//#if TINY_GSM_USE_GPRS
// modem.gprsDisconnect();
// SerialMon.println(F("GPRS disconnected"));
//#endif
//
// // Do nothing forevermore
// while (true) {
// delay(1000);
// }
//}