diff --git a/src/drivers/SPIStorage/SPIStorage.h b/src/drivers/SPIStorage/SPIStorage.h new file mode 100644 index 0000000..3a3ad35 --- /dev/null +++ b/src/drivers/SPIStorage/SPIStorage.h @@ -0,0 +1,129 @@ +#ifndef _SPISTORAGE_H_ +#define _SPISTORAGE_H_ + +#define ESP_DRD_USE_SPIFFS true + +#include +#include +#include + +#include + +#include "..\drivers.h" +#include "..\storage.h" + +// JSON configuration file +#define JSON_CONFIG_FILE "/config.json" + +class SPIStorage +{ +private: + bool SPIFFSInitialized_; +public: + SPIStorage() + { + SPIFFSInitialized_ = init(); + } + + ~SPIStorage() + { + SPIFFS.end(); + }; + + void saveConfigFile(TSettings*Settings) + { + // Save Config in JSON format + Serial.println(F("Saving configuration...")); + + // Create a JSON document + StaticJsonDocument<512> json; + json["poolString"] = Settings->PoolAddress; + json["portNumber"] = Settings->PoolPort; + json["btcString"] = Settings->BtcWallet; + json["gmtZone"] = Settings->Timezone; + + // Open config file + File configFile = SPIFFS.open(JSON_CONFIG_FILE, "w"); + if (!configFile) + { + // Error, file did not open + Serial.println("failed to open config file for writing"); + } + + // Serialize JSON data to write to file + serializeJsonPretty(json, Serial); + if (serializeJson(json, configFile) == 0) + { + // Error writing file + Serial.println(F("Failed to write to file")); + } + // Close file + configFile.close(); + } + + bool init() + { + if (SPIFFSInitialized_) + return SPIFFSInitialized_; + return SPIFFS.begin(false) || SPIFFS.begin(true); + }; + + TSettings loadConfigFile() + { + // Load existing configuration file + // Uncomment if we need to format filesystem + // SPIFFS.format(); + + // Read configuration from FS json + Serial.println("Mounting File System..."); + TSettings Settings; + // May need to make it begin(true) first time you are using SPIFFS + if ((SPIFFSInitialized_)||(init())) + { + Serial.println("mounted file system"); + if (SPIFFS.exists(JSON_CONFIG_FILE)) + { + // The file exists, reading and loading + Serial.println("reading config file"); + File configFile = SPIFFS.open(JSON_CONFIG_FILE, "r"); + if (configFile) + { + Serial.println("Opened configuration file"); + StaticJsonDocument<512> json; + DeserializationError error = deserializeJson(json, configFile); + configFile.close(); + serializeJsonPretty(json, Serial); + if (!error) + { + Serial.println("Parsing JSON"); + + strcpy(Settings.PoolAddress, json["poolString"]); + strcpy(Settings.BtcWallet, json["btcString"]); + Settings.PoolPort = json["portNumber"].as(); + Settings.Timezone = json["gmtZone"].as(); + Settings.holdsData = true; + } + else + { + // Error loading JSON data + Serial.println("Failed to load json config"); + } + } + } + } + else + { + // Error mounting file system + Serial.println("Failed to mount FS"); + } + return Settings; + } + + void deleteConfigFile() + { + Serial.println("Erasing config file.."); + SPIFFS.remove(JSON_CONFIG_FILE); //Borramos fichero + } +}; + +#endif // _SPISTORAGE_H_ diff --git a/src/drivers/storage.h b/src/drivers/storage.h new file mode 100644 index 0000000..5fbd4b7 --- /dev/null +++ b/src/drivers/storage.h @@ -0,0 +1,16 @@ +#ifndef _STORAGE_H_ +#define _STORAGE_H_ + +class TSettings +{ +public: + char WifiSSID[80]{ "sA51" }; + char WifiPW[80]{ "0000" }; + char PoolAddress[80]{ "public-pool.io" }; + char BtcWallet[80]{ "yourBtcAddress" }; + uint32_t PoolPort{ 21496 }; + uint32_t Timezone{ 2 }; + bool holdsData{ false }; +}; + +#endif // _STORAGE_H_ \ No newline at end of file diff --git a/src/mining.cpp b/src/mining.cpp index 3d9d74b..454b4cf 100644 --- a/src/mining.cpp +++ b/src/mining.cpp @@ -9,6 +9,7 @@ #include "utils.h" #include "monitor.h" #include "drivers/display.h" +#include "drivers/storage.h" unsigned long templates = 0; unsigned long hashes= 0; @@ -23,9 +24,8 @@ unsigned int valids; // increased if blockhash <= target double best_diff = 0.0; // Variables to hold data from custom textboxes -extern char poolString[80]; -extern int portNumber; -extern char btcString[80]; +extern TSettings Settings; + IPAddress serverIP(1, 1, 1, 1); //Temporally save poolIPaddres //Global work data @@ -49,14 +49,14 @@ bool checkPoolConnection(void) { //Resolve first time pool DNS and save IP if(serverIP == IPAddress(1,1,1,1)) { - WiFi.hostByName(poolString, serverIP); + WiFi.hostByName(Settings.PoolAddress, serverIP); Serial.printf("Resolved DNS and save ip (first time) got: %s\n", serverIP.toString()); } //Try connecting pool IP - if (!client.connect(serverIP, portNumber)) { - Serial.println("Imposible to connect to : " + String(poolString)); - WiFi.hostByName(poolString, serverIP); + if (!client.connect(serverIP, Settings.PoolPort)) { + Serial.println("Imposible to connect to : " + String(Settings.PoolAddress)); + WiFi.hostByName(Settings.PoolAddress, serverIP); Serial.printf("Resolved DNS got: %s\n", serverIP.toString()); vTaskDelay(1000 / portTICK_PERIOD_MS); return false; @@ -156,7 +156,7 @@ void runStratumWorker(void *name) { continue; } - strcpy(mWorker.wName, btcString); + strcpy(mWorker.wName, Settings.BtcWallet); strcpy(mWorker.wPass, "x"); // STEP 2: Pool authorize work (Block Info) tx_mining_auth(client, mWorker.wName, mWorker.wPass); //Don't verifies authoritzation, TODO diff --git a/src/monitor.cpp b/src/monitor.cpp index a5c652e..c5bd398 100644 --- a/src/monitor.cpp +++ b/src/monitor.cpp @@ -7,8 +7,8 @@ #include "mining.h" #include "utils.h" #include "monitor.h" +#include "drivers/storage.h" -extern char poolString[80]; extern unsigned long templates; extern unsigned long hashes; extern unsigned long Mhashes; @@ -22,7 +22,7 @@ extern double best_diff; // track best diff extern monitor_data mMonitor; -extern int GMTzone; //Gotten from saved config +extern TSettings Settings; //Gotten from saved config WiFiUDP ntpUDP; NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 3600, 60000); @@ -37,7 +37,7 @@ void setup_monitor(void){ // Adjust offset depending on your zone // GMT +2 in seconds (zona horaria de Europa Central) - timeClient.setTimeOffset(3600 * GMTzone); + timeClient.setTimeOffset(3600 * Settings.Timezone); Serial.println("TimeClient setup done"); } diff --git a/src/wManager.cpp b/src/wManager.cpp index 4248f05..3151e58 100644 --- a/src/wManager.cpp +++ b/src/wManager.cpp @@ -1,138 +1,68 @@ -#define ESP_DRD_USE_SPIFFS true // Include Libraries //#include ".h" #include -#include -#include #include -#include + #include "wManager.h" #include "monitor.h" #include "drivers/display.h" -// JSON configuration file -#define JSON_CONFIG_FILE "/config.json" +#include "drivers/SPIStorage/SPIStorage.h" +#include "drivers/storage.h" // Flag for saving data bool shouldSaveConfig = false; -// Variables to hold data from custom textboxes -char poolString[80] = "public-pool.io"; -int portNumber = 21496;//3333; -char btcString[80] = "yourBtcAddress"; -int GMTzone = 2; //Currently selected in spain - +DisplayDriver dongleDisplayDriver = {}; +TSettings Settings; +/* { + .BtcWallet = "", + .holdsData = false, + .PoolAddress = "", + .PoolPort = 0, + .Timezone = 0, + .WifiPW = "", + .WifiSSID = "" +} +*/ // Define WiFiManager Object WiFiManager wm; extern monitor_data mMonitor; -void saveConfigFile() -// Save Config in JSON format -{ - Serial.println(F("Saving configuration...")); - - // Create a JSON document - StaticJsonDocument<512> json; - json["poolString"] = poolString; - json["portNumber"] = portNumber; - json["btcString"] = btcString; - json["gmtZone"] = GMTzone; - - // Open config file - File configFile = SPIFFS.open(JSON_CONFIG_FILE, "w"); - if (!configFile) - { - // Error, file did not open - Serial.println("failed to open config file for writing"); - } - - // Serialize JSON data to write to file - serializeJsonPretty(json, Serial); - if (serializeJson(json, configFile) == 0) - { - // Error writing file - Serial.println(F("Failed to write to file")); - } - // Close file - configFile.close(); -} - -bool loadConfigFile() -// Load existing configuration file -{ - // Uncomment if we need to format filesystem - // SPIFFS.format(); - - // Read configuration from FS json - Serial.println("Mounting File System..."); - - // May need to make it begin(true) first time you are using SPIFFS - if (SPIFFS.begin(false) || SPIFFS.begin(true)) - { - Serial.println("mounted file system"); - if (SPIFFS.exists(JSON_CONFIG_FILE)) - { - // The file exists, reading and loading - Serial.println("reading config file"); - File configFile = SPIFFS.open(JSON_CONFIG_FILE, "r"); - if (configFile) - { - Serial.println("Opened configuration file"); - StaticJsonDocument<512> json; - DeserializationError error = deserializeJson(json, configFile); - configFile.close(); - serializeJsonPretty(json, Serial); - if (!error) - { - Serial.println("Parsing JSON"); - - strcpy(poolString, json["poolString"]); - strcpy(btcString, json["btcString"]); - portNumber = json["portNumber"].as(); - GMTzone = json["gmtZone"].as(); - return true; - } - else - { - // Error loading JSON data - Serial.println("Failed to load json config"); - } - } - } - } - else - { - // Error mounting file system - Serial.println("Failed to mount FS"); - } - - return false; -} - +SPIStorage SPIFS; void saveConfigCallback() // Callback notifying us of the need to save configuration { - Serial.println("Should save config"); - shouldSaveConfig = true; - //wm.setConfigPortalBlocking(false); + Serial.println("Should save config"); + shouldSaveConfig = true; + //wm.setConfigPortalBlocking(false); } -void configModeCallback(WiFiManager *myWiFiManager) +void configModeCallback(WiFiManager* myWiFiManager) // Called when config mode launched { - Serial.println("Entered Configuration Mode"); + Serial.println("Entered Configuration Mode"); - Serial.print("Config SSID: "); - Serial.println(myWiFiManager->getConfigPortalSSID()); + Serial.print("Config SSID: "); + Serial.println(myWiFiManager->getConfigPortalSSID()); - Serial.print("Config IP Address: "); - Serial.println(WiFi.softAPIP()); + Serial.print("Config IP Address: "); + Serial.println(WiFi.softAPIP()); } +void reset_configurations() +{ + Serial.println("Erasing Config, restarting"); + SPIFS.deleteConfigFile(); + wm.resetSettings(); + ESP.restart(); +} + + void init_WifiManager() { #ifdef MONITOR_SPEED @@ -140,186 +70,178 @@ void init_WifiManager() #else Serial.begin(115200); #endif //MONITOR_SPEED - //Serial.setTxTimeoutMs(10); + //Serial.setTxTimeoutMs(10); - //Init pin 15 to eneble 5V external power (LilyGo bug) - #ifdef PIN_ENABLE5V + //Init pin 15 to eneble 5V external power (LilyGo bug) +#ifdef PIN_ENABLE5V pinMode(PIN_ENABLE5V, OUTPUT); digitalWrite(PIN_ENABLE5V, HIGH); - #endif +#endif - // Change to true when testing to force configuration every time we run - bool forceConfig = false; + // Change to true when testing to force configuration every time we run + bool forceConfig = false; - #if defined(PIN_BUTTON_2) +#if defined(PIN_BUTTON_2) // Check if button2 is pressed to enter configMode with actual configuration - if(!digitalRead(PIN_BUTTON_2)){ - Serial.println(F("Button pressed to force start config mode")); - forceConfig = true; - wm.setBreakAfterConfig(true); //Set to detect config edition and save + if (!digitalRead(PIN_BUTTON_2)) { + Serial.println(F("Button pressed to force start config mode")); + resetConfig(); + forceConfig = true; + wm.setBreakAfterConfig(true); //Set to detect config edition and save } - #endif - - bool spiffsSetup = loadConfigFile(); - if (!spiffsSetup) - { - Serial.println(F("Forcing config mode as there is no saved config")); - forceConfig = true; - - } +#endif + // Explicitly set WiFi mode + WiFi.mode(WIFI_STA); - // Explicitly set WiFi mode - WiFi.mode(WIFI_STA); - - // Reset settings (only for development) - //wm.resetSettings(); - - //Set dark theme - //wm.setClass("invert"); // dark theme - - // Set config save notify callback - wm.setSaveConfigCallback(saveConfigCallback); - - // Set callback that gets called when connecting to previous WiFi fails, and enters Access Point mode - wm.setAPCallback(configModeCallback); - - //Advanced settings - wm.setConfigPortalBlocking(false); //Hacemos que el portal no bloquee el firmware - wm.setConnectTimeout(50); // how long to try to connect for before continuing - //wm.setConfigPortalTimeout(30); // auto close configportal after n seconds - // wm.setCaptivePortalEnable(false); // disable captive portal redirection - // wm.setAPClientCheck(true); // avoid timeout if client connected to softap - //wm.setTimeout(120); - //wm.setConfigPortalTimeout(120); //seconds - - // Custom elements - - // Text box (String) - 80 characters maximum - WiFiManagerParameter pool_text_box("Poolurl", "Pool url", poolString, 80); - - // Need to convert numerical input to string to display the default value. - char convertedValue[6]; - sprintf(convertedValue, "%d", portNumber); - - // Text box (Number) - 7 characters maximum - WiFiManagerParameter port_text_box_num("Poolport", "Pool port", convertedValue, 7); - - // Text box (String) - 80 characters maximum - WiFiManagerParameter addr_text_box("btcAddress", "Your BTC address", btcString, 80); - - // Text box (Number) - 2 characters maximum - char charZone[6]; - sprintf(charZone, "%d", GMTzone); - WiFiManagerParameter time_text_box_num("TimeZone", "TimeZone fromUTC (-12/+12)", charZone, 3); - - // Add all defined parameters - wm.addParameter(&pool_text_box); - wm.addParameter(&port_text_box_num); - wm.addParameter(&addr_text_box); - wm.addParameter(&time_text_box_num); - - Serial.println("AllDone: "); - if (forceConfig) - // Run if we need a configuration - { - //No configuramos timeout al modulo - wm.setConfigPortalBlocking(true); //Hacemos que el portal SI bloquee el firmware - drawSetupScreen(); - if (!wm.startConfigPortal("NerdMinerAP","MineYourCoins")) + Settings = SPIFS.loadConfigFile(); + if (!Settings.holdsData) { - Serial.println("failed to connect and hit timeout"); - //Could be break forced after edditing, so save new config - strncpy(poolString, pool_text_box.getValue(), sizeof(poolString)); - portNumber = atoi(port_text_box_num.getValue()); - strncpy(btcString, addr_text_box.getValue(), sizeof(btcString)); - GMTzone = atoi(time_text_box_num.getValue()); - saveConfigFile(); - delay(3000); - //reset and try again, or maybe put it to deep sleep - ESP.restart(); - delay(5000); + Serial.println(F("Forcing config mode as there is no saved config")); + forceConfig = true; + }; + + // Reset settings (only for development) + //wm.resetSettings(); + + //Set dark theme + //wm.setClass("invert"); // dark theme + + // Set config save notify callback + wm.setSaveConfigCallback(saveConfigCallback); + + // Set callback that gets called when connecting to previous WiFi fails, and enters Access Point mode + wm.setAPCallback(configModeCallback); + + //Advanced settings + wm.setConfigPortalBlocking(false); //Hacemos que el portal no bloquee el firmware + wm.setConnectTimeout(50); // how long to try to connect for before continuing + //wm.setConfigPortalTimeout(30); // auto close configportal after n seconds + // wm.setCaptivePortalEnable(false); // disable captive portal redirection + // wm.setAPClientCheck(true); // avoid timeout if client connected to softap + //wm.setTimeout(120); + //wm.setConfigPortalTimeout(120); //seconds + + // Custom elements + + // Text box (String) - 80 characters maximum + WiFiManagerParameter pool_text_box("Poolurl", "Pool url", Settings.PoolAddress, 80); + + // Need to convert numerical input to string to display the default value. + char convertedValue[6]; + sprintf(convertedValue, "%d", Settings.PoolPort); + + // Text box (Number) - 7 characters maximum + WiFiManagerParameter port_text_box_num("Poolport", "Pool port", convertedValue, 7); + + // Text box (String) - 80 characters maximum + WiFiManagerParameter addr_text_box("btcAddress", "Your BTC address", Settings.BtcWallet, 80); + + // Text box (Number) - 2 characters maximum + char charZone[6]; + sprintf(charZone, "%d", Settings.Timezone); + WiFiManagerParameter time_text_box_num("TimeZone", "TimeZone fromUTC (-12/+12)", charZone, 3); + + // Add all defined parameters + wm.addParameter(&pool_text_box); + wm.addParameter(&port_text_box_num); + wm.addParameter(&addr_text_box); + wm.addParameter(&time_text_box_num); + + Serial.println("AllDone: "); + if (forceConfig) + // Run if we need a configuration + { + //No configuramos timeout al modulo + wm.setConfigPortalBlocking(true); //Hacemos que el portal SI bloquee el firmware + drawSetupScreen(); + Settings = TSettings(); + if (!wm.startConfigPortal(Settings.WifiSSID, Settings.WifiPW)) + { + Serial.println("failed to connect and hit timeout"); + //Could be break forced after edditing, so save new config + strncpy(Settings.PoolAddress, pool_text_box.getValue(), sizeof(Settings.PoolAddress)); + Settings.PoolPort = atoi(port_text_box_num.getValue()); + strncpy(Settings.BtcWallet, addr_text_box.getValue(), sizeof(Settings.BtcWallet)); + Settings.Timezone = atoi(time_text_box_num.getValue()); + SPIFS.saveConfigFile(&Settings); + delay(3000); + //reset and try again, or maybe put it to deep sleep + ESP.restart(); + delay(5000); + } } - } - else - { - //Tratamos de conectar con la configuraciĆ³n inicial ya almacenada + else + { + //Tratamos de conectar con la configuraciĆ³n inicial ya almacenada + mMonitor.NerdStatus = NM_Connecting; + wm.setCaptivePortalEnable(false); // disable captive portal redirection + if (!wm.autoConnect(Settings.WifiSSID, Settings.WifiPW)) + { + Serial.println("Failed to connect and hit timeout"); + //delay(3000); + // if we still have not connected restart and try all over again + //ESP.restart(); + //delay(5000); + } + } + mMonitor.NerdStatus = NM_Connecting; - wm.setCaptivePortalEnable(false); // disable captive portal redirection - if (!wm.autoConnect("NerdMinerAP","MineYourCoins")) - { - Serial.println("Failed to connect and hit timeout"); - //delay(3000); - // if we still have not connected restart and try all over again - //ESP.restart(); - //delay(5000); + + //Conectado a la red Wifi + if (WiFi.status() == WL_CONNECTED) { + //tft.pushImage(0, 0, MinerWidth, MinerHeight, MinerScreen); + Serial.println(""); + Serial.println("WiFi connected"); + Serial.print("IP address: "); + Serial.println(WiFi.localIP()); + + // Lets deal with the user config values + + // Copy the string value + strncpy(Settings.PoolAddress, pool_text_box.getValue(), sizeof(Settings.PoolAddress)); + Serial.print("PoolString: "); + Serial.println(Settings.PoolAddress); + + //Convert the number value + Settings.PoolPort = atoi(port_text_box_num.getValue()); + Serial.print("portNumber: "); + Serial.println(Settings.PoolPort); + + // Copy the string value + strncpy(Settings.BtcWallet, addr_text_box.getValue(), sizeof(Settings.BtcWallet)); + Serial.print("btcString: "); + Serial.println(Settings.BtcWallet); + + //Convert the number value + Settings.Timezone = atoi(time_text_box_num.getValue()); + Serial.print("TimeZone fromUTC: "); + Serial.println(Settings.Timezone); } - } - mMonitor.NerdStatus = NM_Connecting; - - //Conectado a la red Wifi - if(WiFi.status() == WL_CONNECTED){ - //tft.pushImage(0, 0, MinerWidth, MinerHeight, MinerScreen); - Serial.println(""); - Serial.println("WiFi connected"); - Serial.print("IP address: "); - Serial.println(WiFi.localIP()); - - // Lets deal with the user config values - - // Copy the string value - strncpy(poolString, pool_text_box.getValue(), sizeof(poolString)); - Serial.print("PoolString: "); - Serial.println(poolString); - - //Convert the number value - portNumber = atoi(port_text_box_num.getValue()); - Serial.print("portNumber: "); - Serial.println(portNumber); - - // Copy the string value - strncpy(btcString, addr_text_box.getValue(), sizeof(btcString)); - Serial.print("btcString: "); - Serial.println(btcString); - - //Convert the number value - GMTzone = atoi(time_text_box_num.getValue()); - Serial.print("TimeZone fromUTC: "); - Serial.println(GMTzone); - } - - // Save the custom parameters to FS - if (shouldSaveConfig) - { - saveConfigFile(); - } + // Save the custom parameters to FS + if (shouldSaveConfig) + { + SPIFS.saveConfigFile(&Settings); + } } -void reset_configurations() { - Serial.println("Erasing Config, restarting"); - wm.resetSettings(); - SPIFFS.remove(JSON_CONFIG_FILE); //Borramos fichero - ESP.restart(); -} - - //----------------- MAIN PROCESS WIFI MANAGER -------------- int oldStatus = 0; void wifiManagerProcess() { - - wm.process(); // avoid delays() in loop when non-blocking and other long running code - - int newStatus = WiFi.status(); - if (newStatus != oldStatus) { - if (newStatus == WL_CONNECTED) { - Serial.println("CONNECTED - Current ip: " + WiFi.localIP().toString()); - } else { - Serial.print("[Error] - current status: "); - Serial.println(newStatus); + + wm.process(); // avoid delays() in loop when non-blocking and other long running code + + int newStatus = WiFi.status(); + if (newStatus != oldStatus) { + if (newStatus == WL_CONNECTED) { + Serial.println("CONNECTED - Current ip: " + WiFi.localIP().toString()); + } else { + Serial.print("[Error] - current status: "); + Serial.println(newStatus); + } + oldStatus = newStatus; } - oldStatus = newStatus; - } }