Giter Site home page Giter Site logo

Custom parameters ? about autoconnect HOT 20 CLOSED

hieromon avatar hieromon commented on August 18, 2024 4
Custom parameters ?

from autoconnect.

Comments (20)

Hieromon avatar Hieromon commented on August 18, 2024 1

That's right. I have already started designing it. It is expected to be released within a few weeks.
That release can prepare the add-on page adding input fields or buttons optionally and invoke them from the AutoConnect menu. You will be able to retrieve the inputted values in add-on page from sketches and can respond by the customized page.
However, saving/loading of user parameters will be further scheduled.

from autoconnect.

JoeyUson avatar JoeyUson commented on August 18, 2024 1

I already solve MySQL database and it is only the user grant access. Used MySQL sample database sketch and able to insert data at regular interval from ESP8266.

These 3 give type mismatch error in Serial Monitor
server.fromString(mysqlSetting.getElement("server").value);
String user = mysqlSetting.getElement("user").value;
String password = mysqlSetting.getElement("password").value;

from autoconnect.

Hieromon avatar Hieromon commented on August 18, 2024

There are many requests for the custom data entry function in part of AutoConnect 's menu transition like as your recommendation. It will be similar to the user own code as the exit routines or callback functions.
I have been thinking from time to time and have some ideas.

  1. Add custom parameters to the Configure new AP screen
  2. Add user's own screen created by PageBuilder library to menu transition

I have not decided which one to implement. Both have advantages and disadvantages.
Its enhancement will be the main title of the next update.

from autoconnect.

cruizg avatar cruizg commented on August 18, 2024

You stole the question, I was about to write the same, the idea is that with your library we can send in addition to the user and password, additional parameters and saved in the ESP8266 / ESP32 for example MQTT values or values sent from a mobile app that wants send additional to user and password parameters that register the device and then use it in the sckets.

from autoconnect.

ageurtse avatar ageurtse commented on August 18, 2024

Need this to for my project.

from autoconnect.

Hieromon avatar Hieromon commented on August 18, 2024

Now, I am staging a new version that supports this improvement on the enhance/AutoConnectAux branch, but I found a potential bug related to PROGMEM.
Also, it does not work well with LwIP v2 of ESP8266 core 2.4.2. The behavior of WiFi connection with AP_STA mode seems changed. Currently, I'm giving priority to solving it. The next version release you want will be delayed.

from autoconnect.

Naboo2604 avatar Naboo2604 commented on August 18, 2024

Hi, thank you for this very cool library. i build IoT weather sensors for family and friends and use your lib for self-configuration. it would be great if you implement custom fields, so i can use it for location data and custom name in the autoconfig process.
thanks again and merry christmas,
markus

from autoconnect.

ageurtse avatar ageurtse commented on August 18, 2024

When looking at the mqtt examples in https://github.com/Hieromon/AutoConnect/tree/enhance/AutoConnectAux there are some custom fields.

Keep in mind that this branche is the development branche, so there could be some isues.

from autoconnect.

JoeyUson avatar JoeyUson commented on August 18, 2024

Any idea how to include in the parameters the Server IP, USER and PASSWORD for use later in connection to mySQL database resides in other server or Raspi

from autoconnect.

Hieromon avatar Hieromon commented on August 18, 2024

@JoeyUson What you want to do is similar to the example mqttRSSI in the library. However, the following two conditions will be added to it.

  1. To available the MySQL settings page, ESP8266/ESP32 has already established a connection to AP with STA mode. In other words, the menu of MySQL parameters settings does not appear while processing in Captive portal.
  2. The response of the MySQL parameters setting page will return the result of the connection to MySQL.

Is it right? If so, you can control menu display dynamically using the menu function and the sketch as like this:

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <AutoConnect.h>
#include <MySQL_Connection.h>

const static char* mysqlSettingPage PROGMEM = R"(
{
  "title": "MySQL Setting",
  "uri": "/mysql_setting",
  "menu": false,
  "element": [
    {
      "name": "header",
      "type": "ACText",
      "value": "<h2>MySQL broker settings</h2>",
      "style": "text-align:center;color:#2f4f4f;padding:10px;"
    },
    {
      "name": "server",
      "type": "ACInput",
      "value": "",
      "label": "Server",
      "placeholder": "MySQL server IP address"
    },
    {
      "name": "user",
      "type": "ACInput",
      "label": "user"
    },
    {
      "name": "password",
      "type": "ACInput",
      "label": "password"
    },
    {
      "name": "connect",
      "type": "ACSubmit",
      "value": "Connect",
      "uri": "/mysql_conn"
    },
    {
      "name": "discard",
      "type": "ACSubmit",
      "value": "Discard",
      "uri": "/ac"
    }
  ]
}
)";

const static char* mysqlConnectPage PROGMEM = R"(
{
  "title": "MySQL Setting",
  "uri": "/mysql_conn",
  "menu": false,
  "element": [
    {
      "name": "caption",
      "type": "ACText",
      "value": "<h4>MySQL connection</h4>",
      "style": "text-align:center;color:#2f4f4f;padding:10px;"
    },
    {
      "name": "Result",
      "type": "ACText"
    },
    {
      "name": "OK",
      "type": "ACSubmit",
      "value": "OK",
      "uri": "/"
    }
  ]
}
)";

ESP8266WebServer  webServer;
AutoConnect     portal(webServer);
AutoConnectAux  mysqlSetting;
AutoConnectAux  mysqlConnect;

WiFiClient client;
MySQL_Connection conn((Client *)&client);

void handleRoot() {
  String  content =
    "<html>"
    "<head>"
    "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">"
    "</head>"
    "<body>"
    "Your sketch application there."
    "<p style=\"padding-top:5px;text-align:center\">" AUTOCONNECT_LINK(COG_24) "</p>"
    "</body>"
    "</html>";
  webServer.send(200, "text/html", content);
}

String onConnect(AutoConnectAux& aux, PageArgument& args) {
  // here, obtain parameters to connect MySQL
  IPAddress server;
  server.fromString(mysqlSetting.getElement<AutoConnectText>("server").value);
  String user = mysqlSetting.getElement<AutoConnectText>("user").value;
  String password = mysqlSetting.getElement<AutoConnectText>("password").value;

  unsigned long tm = millis();
  while (conn.connect(server, 3306, user.c_str(), password.c_str()) != true) {
    if (millis() - tm > 10000)
      break;
    delay(200);
    Serial.print('.');
  }
  AutoConnectText& result = aux.getElement<AutoConnectText>("Result");
  if (conn.connected())
    result.value = "Connected";
  else
    result.value = "Timeout";
  return String();
}

void setup() {
  delay(1000);
  Serial.begin(115200);
  Serial.println();
  mysqlSetting.load(mysqlSettingPage);
  mysqlSetting.menu(false);
  mysqlConnect.load(mysqlConnectPage);
  mysqlConnect.menu(false);
  mysqlConnect.on(onConnect);
  webServer.on("/",handleRoot);
  portal.begin();
}

void loop() {
  // MySQL setting menu control
  bool mysqlMenu = WiFi.status() == WL_CONNECTED;
  mysqlSetting.menu(mysqlMenu);

  if (conn.connected()) {
    // here, your actual sketch with using MySQL
  }

  portal.handleClient();
}

The above code has not been tested.

from autoconnect.

JoeyUson avatar JoeyUson commented on August 18, 2024

@JoeyUson What you want to do is similar to the example mqttRSSI in the library. However, the following two conditions will be added to it.

  1. To available the MySQL settings page, ESP8266/ESP32 has already established a connection to AP with STA mode. In other words, the menu of MySQL parameters settings does not appear while processing in Captive portal.
  2. The response of the MySQL parameters setting page will return the result of the connection to MySQL.

Is it right? If so, you can control menu display dynamically using the menu function and the sketch as like this:

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <AutoConnect.h>
#include <MySQL_Connection.h>

const static char* mysqlSettingPage PROGMEM = R"(
{
  "title": "MySQL Setting",
  "uri": "/mysql_setting",
  "menu": false,
  "element": [
    {
      "name": "header",
      "type": "ACText",
      "value": "<h2>MySQL broker settings</h2>",
      "style": "text-align:center;color:#2f4f4f;padding:10px;"
    },
    {
      "name": "server",
      "type": "ACInput",
      "value": "",
      "label": "Server",
      "placeholder": "MySQL server IP address"
    },
    {
      "name": "user",
      "type": "ACInput",
      "label": "user"
    },
    {
      "name": "password",
      "type": "ACInput",
      "label": "password"
    },
    {
      "name": "connect",
      "type": "ACSubmit",
      "value": "Connect",
      "uri": "/mysql_conn"
    },
    {
      "name": "discard",
      "type": "ACSubmit",
      "value": "Discard",
      "uri": "/ac"
    }
  ]
}
)";

const static char* mysqlConnectPage PROGMEM = R"(
{
  "title": "MySQL Setting",
  "uri": "/mysql_conn",
  "menu": false,
  "element": [
    {
      "name": "caption",
      "type": "ACText",
      "value": "<h4>MySQL connection</h4>",
      "style": "text-align:center;color:#2f4f4f;padding:10px;"
    },
    {
      "name": "Result",
      "type": "ACText"
    },
    {
      "name": "OK",
      "type": "ACSubmit",
      "value": "OK",
      "uri": "/"
    }
  ]
}
)";

ESP8266WebServer  webServer;
AutoConnect     portal(webServer);
AutoConnectAux  mysqlSetting;
AutoConnectAux  mysqlConnect;

WiFiClient client;
MySQL_Connection conn((Client *)&client);

void handleRoot() {
  String  content =
    "<html>"
    "<head>"
    "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">"
    "</head>"
    "<body>"
    "Your sketch application there."
    "<p style=\"padding-top:5px;text-align:center\">" AUTOCONNECT_LINK(COG_24) "</p>"
    "</body>"
    "</html>";
  webServer.send(200, "text/html", content);
}

String onConnect(AutoConnectAux& aux, PageArgument& args) {
  // here, obtain parameters to connect MySQL
  IPAddress server;
  server.fromString(mysqlSetting.getElement<AutoConnectText>("server").value);
  String user = mysqlSetting.getElement<AutoConnectText>("user").value;
  String password = mysqlSetting.getElement<AutoConnectText>("password").value;

  unsigned long tm = millis();
  while (conn.connect(server, 3306, user.c_str(), password.c_str()) != true) {
    if (millis() - tm > 10000)
      break;
    delay(200);
    Serial.print('.');
  }
  AutoConnectText& result = aux.getElement<AutoConnectText>("Result");
  if (conn.connected())
    result.value = "Connected";
  else
    result.value = "Timeout";
  return String();
}

void setup() {
  delay(1000);
  Serial.begin(115200);
  Serial.println();
  mysqlSetting.load(mysqlSettingPage);
  mysqlSetting.menu(false);
  mysqlConnect.load(mysqlConnectPage);
  mysqlConnect.menu(false);
  mysqlConnect.on(onConnect);
  webServer.on("/",handleRoot);
  portal.begin();
}

void loop() {
  // MySQL setting menu control
  bool mysqlMenu = WiFi.status() == WL_CONNECTED;
  mysqlSetting.menu(mysqlMenu);

  if (conn.connected()) {
    // here, your actual sketch with using MySQL
  }

  portal.handleClient();
}

The above code has not been tested.

Just new in using AutoConnect with MySQL, however I add "portal.join({ mysqlSetting });" just after mysqlConnect.on(onConnect); and the setting menu appear in the menu selection but after filling the form it give 403 error code

from autoconnect.

Hieromon avatar Hieromon commented on August 18, 2024

At first, can you determine the state of LAN transparency with a sniffer tool such as Wireshark? 403 response has nothing to do with AutoConnect.

from autoconnect.

Hieromon avatar Hieromon commented on August 18, 2024

@JoeyUson I reviewed the code I presented. Your point is partially correct. The above code does not have a custom web page joined to the portal. The code to add is below.

portal.join({ mysqlSetting, mysqlConnect });

However, the cause of the 403 response is unknown.

from autoconnect.

JoeyUson avatar JoeyUson commented on August 18, 2024

from autoconnect.

Hieromon avatar Hieromon commented on August 18, 2024

@JoeyUson
Sorry, I took a mistake. The correct code is:

  server.fromString(mysqlSetting.getElement<AutoConnectInput>("server").value);
  String user = mysqlSetting.getElement<AutoConnectInput>("user").value;
  String password = mysqlSetting.getElement<AutoConnectInput>("password").value;

from autoconnect.

JoeyUson avatar JoeyUson commented on August 18, 2024

//Here the complete code for the test I did for AutoConnect and MySQL connection after the changes
// It is working now , Thanks a lot for the assistance

`#if defined(ARDUINO_ARCH_ESP8266)
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#elif defined(ARDUINO_ARCH_ESP32)
#include <WiFi.h>
#include <WebServer.h>
#endif

#include <AutoConnect.h>
#include <MySQL_Connection.h>
#include <MySQL_Cursor.h>

const static char* mysqlSettingPage PROGMEM = R"(
{
"title": "MySQL Setting",
"uri": "/mysql_setting",
"menu": false,
"element": [
{
"name": "header",
"type": "ACText",
"value": "

MySQL broker settings

",
"style": "text-align:center;color:#2f4f4f;padding:10px;"
},
{
"name": "server",
"type": "ACInput",
"value": "",
"label": "Server",
"placeholder": "MySQL server IP address"
},
{
"name": "user",
"type": "ACInput",
"label": "user"
},
{
"name": "password",
"type": "ACInput",
"label": "password"
},
{
"name": "connect",
"type": "ACSubmit",
"value": "Connect",
"uri": "/mysql_conn"
},
{
"name": "discard",
"type": "ACSubmit",
"value": "Discard",
"uri": "/_ac"
}
]
}
)";

const static char* mysqlConnectPage PROGMEM = R"(
{
"title": "MySQL Setting",
"uri": "/mysql_conn",
"menu": false,
"element": [
{
"name": "caption",
"type": "ACText",
"value": "

MySQL connection

",
"style": "text-align:center;color:#2f4f4f;padding:10px;"
},
{
"name": "Result",
"type": "ACText"
},
{
"name": "OK",
"type": "ACSubmit",
"value": "OK",
"uri": "/"
}
]
}
)";

#if defined(ARDUINO_ARCH_ESP8266)
ESP8266WebServer webServer;
#elif defined(ARDUINO_ARCH_ESP32)
WebServer webServer;
#endif

AutoConnect portal(webServer);
AutoConnectAux mysqlSetting;
AutoConnectAux mysqlConnect;

WiFiClient client;

// database related
MySQL_Connection conn((Client )&client);
MySQL_Cursor
cursor;
// Sample query
const char INSERT_SQL[] = "INSERT INTO test_arduino.hello_arduino (message) VALUES ('Hello, Arduino!')";

void handleRoot() { // this is the content of the root page to be display as default
String content =
""
""
"<meta name="viewport" content="width=device-width, initial-scale=1">"
""
""
"Your sketch application there."
"<p style="padding-top:5px;text-align:center">" AUTOCONNECT_LINK(COG_24) "

"
""
"";
webServer.send(200, "text/html", content);
}

String onConnect(AutoConnectAux& aux, PageArgument& args) {
// here, obtain parameters to connect MySQL
IPAddress server;

server.fromString(mysqlSetting.getElement<AutoConnectInput>("server").value);
String user = mysqlSetting.getElement<AutoConnectInput>("user").value;
String password = mysqlSetting.getElement<AutoConnectInput>("password").value;

unsigned long tm = millis();

while (conn.connect(server, 3306, user.c_str(), password.c_str()) != true) {
	if (millis() - tm > 500)
		break;
	delay(200);
	Serial.print('.');
}

AutoConnectText& result = aux.getElement<AutoConnectText>("Result");
if (conn.connected()) {
	result.value = "Connected";
	// create MySQL cursor object if connected
	cursor = new MySQL_Cursor(&conn);
}
else
	result.value = "Timeout";
return String();

}

void setup() {
delay(1000);
Serial.begin(115200);
Serial.println();
mysqlSetting.load(mysqlSettingPage);
mysqlSetting.menu(false); // hide the myssqlSetting from menu initially
mysqlConnect.load(mysqlConnectPage);
mysqlConnect.menu(false); // should always be hidden and call by mysqlsetting only
mysqlConnect.on(onConnect); // to be executed for database connection

portal.join({ mysqlSetting,mysqlConnect});	// added in the standard menu items
webServer.on("/", handleRoot);
portal.begin();

}

void loop() {
// MySQL setting menu control
bool mysqlMenu = WiFi.status() == WL_CONNECTED;
mysqlSetting.menu(mysqlMenu); // will display the mysqlSetting once connected to WiFi

static unsigned long tm = millis();

if (conn.connected()) 					// if still connected to database
	if (millis() - tm > 5000) {
		cursor->execute(INSERT_SQL);		// Insert Hello Message
		tm = millis();
	}

portal.handleClient();

}`

With the above sketch I noticed that if you reset the board the WiFi connection is restore but for MySQL connection you need to feed in again the server,user and password for database access in order to reconnect. Is it possible to save the 3 data and during reboot will be use to reconnect to database and of course if unsuccessful will give timeout ?

from autoconnect.

Hieromon avatar Hieromon commented on August 18, 2024

You can save the inputted parameter as server IP, user, and password for MySQL connection, to SPIFFS on the ESP module. The AutoConnectAux::saveElement function outputs the specified elements to the stream along with the elements value.
For example, to save the server IP address, user, password after conn.connect is successful, you can use the following code:

#include <FS.h>
#define PARAM_FILE      "/param.json"

// In onConnect function

  if (conn.connected()) {
    saveParams(PARAM_FILE);    // Insert this line
    result.value = "Connected";
    // create MySQL cursor object if connected
    cursor = new MySQL_Cursor(&conn);
  }

// Add new function to save parameter as the below:
void saveParams(const char* paramFile) {
  SPIFFS.begin();
  File param = SPIFFS.open(paramFile, "w");
  mysqlSetting.saveElement(param, { "server", "user", "password" });
  param.close();
  SPIFFS.end();
}

And, load this parameter file in advance after resetting.

void setup() {
  delay(1000);
  Serial.begin(115200);
  Serial.println();
  mysqlSetting.load(mysqlSettingPage);

  loadParams(PARAM_FILE);       // Load the parameters in advance

  mysqlSetting.menu(false);	// hide the myssqlSetting from menu initially
  mysqlConnect.load(mysqlConnectPage);
...
}

// Add new function to load the stored parameter as the below:
void loadParams(const char* paramFile) {
  SPIFFS.begin();
  File param = SPIFFS.open(paramFile, "r");
  if (param) {
    bool rc = mysqlSetting.loadElement(param);    // Load the elements with parameters
    if (rc)
      Serial.println(String(paramFile) + " loaded");
    else
      Serial.println(String(paramFile) + " failed to load");
    param.close();
  }
  SPIFFS.end();
}

But this is still not enough. It's smart that the menu is available when you time out with parameters loaded after reset as you said. Therefore we can take the further measures.

  1. Make server IP, user, password to global variables. It is accessible at any time.
  2. The loaded parameters are stored in their global variables and retrieved as needed.
  3. The MySQL connection is executed by another function. This function takes parameters from the above global variables.
  4. In the loop function, we do the sketch application. Activate the menu if the MySQL connection lost.

Here, the final code looks like this

#if defined(ARDUINO_ARCH_ESP8266)
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#elif defined(ARDUINO_ARCH_ESP32)
#include <WiFi.h>
#include <WebServer.h>
#include <SPIFFS.h>
#endif

#include <FS.h>
#include <AutoConnect.h>
#include <MySQL_Connection.h>
#include <MySQL_Cursor.h>

const static char* mysqlSettingPage PROGMEM = R"(
{
  "title": "MySQL Setting",
  "uri": "/mysql_setting",
  "menu": false,
  "element": [
    {
      "name": "header",
      "type": "ACText",
      "value": "MySQL broker settings",
      "style": "text-align:center;color:#2f4f4f;padding:10px;"
    },
    {
      "name": "server",
      "type": "ACInput",
      "value": "",
      "label": "Server",
      "placeholder": "MySQL server IP address"
    },
    {
      "name": "user",
      "type": "ACInput",
      "label": "user"
    },
    {
      "name": "password",
      "type": "ACInput",
      "label": "password"
    },
    {
      "name": "connect",
      "type": "ACSubmit",
      "value": "Connect",
      "uri": "/mysql_conn"
    },
    {
      "name": "discard",
      "type": "ACSubmit",
      "value": "Discard",
      "uri": "/_ac"
    }
  ]
}
)";
const static char* mysqlConnectPage PROGMEM = R"(
{
  "title": "MySQL Setting",
  "uri": "/mysql_conn",
  "menu": false,
  "element": [
    {
      "name": "caption",
      "type": "ACText",
      "value": "MySQL connection",
      "style": "text-align:center;color:#2f4f4f;padding:10px;"
    },
    {
      "name": "Result",
      "type": "ACText"
    },
    {
      "name": "OK",
      "type": "ACSubmit",
      "value": "OK",
      "uri": "/"
    }
  ]
}
)";
#if defined(ARDUINO_ARCH_ESP8266)
ESP8266WebServer webServer;
#elif defined(ARDUINO_ARCH_ESP32)
WebServer webServer;
#endif

AutoConnect	portal(webServer);
AutoConnectAux	mysqlSetting;
AutoConnectAux	mysqlConnect;
WiFiClient client;

// database related
MySQL_Connection conn((Client )&client);
MySQL_Cursor cursor;
IPAddress server;
String user;
String password;
bool invokeConnect = false;

// Parameter file
#define PARAM_FILE  "/param.json"

// Sample query
const char INSERT_SQL[] = "INSERT INTO test_arduino.hello_arduino (message) VALUES ('Hello, Arduino!')";

void handleRoot() {
  String  content =
    "<html>"
    "<head>"
    "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">"
    "</head>"
    "<body>"
    "Your sketch application there."
    "<p style=\"padding-top:5px;text-align:center\">" AUTOCONNECT_LINK(COG_24) "</p>"
    "</body>"
    "</html>";
  webServer.send(200, "text/html", content);
}

// Get parameters from AutoConnectElement
void getParams() {
  // here, obtain parameters to connect MySQL
  server.fromString(mysqlSetting.getElement<AutoConnectInput>("server").value);
  user = mysqlSetting.getElement<AutoConnectInput>("user").value;
  user.trim();
  password = mysqlSetting.getElement<AutoConnectInput>("password").value;
  password.trim();
  invokeConnect = true;
}

// Load parameter
void loadParams(const char* paramFile) {
  SPIFFS.begin();
  File param = SPIFFS.open(paramFile, "r");
  if (param) {
    // Load the elements with parameters
    bool rc = mysqlSetting.loadElement(param);
    if (rc) {
      // here, obtain parameters to connect MySQL
      getParams();
      Serial.println(String(paramFile) + " loaded");
    }
    else
      Serial.println(String(paramFile) + " failed to load");
    param.close();
  }
  SPIFFS.end();
}

// Save parameter
void saveParams(const char* paramFile) {
  SPIFFS.begin();
  File param = SPIFFS.open(paramFile, "w");
  mysqlSetting.saveElement(param, { "server", "user", "password" });
  param.close();
  SPIFFS.end();
}

// Custom Web page onConnect handler
String onConnect(AutoConnectAux& aux, PageArgument& args) {
  getParams();
  connectMySQL(3000);
  AutoConnectText& result = aux.getElement<AutoConnectText>("Result");
  if (conn.connected()) {
    saveParams(PARAM_FILE);
    result.value = "Connected";
    // create MySQL cursor object if connected
    cursor = new MySQL_Cursor(&conn);
  }
  else
    result.value = "Timeout";
  return String();
}

// Makes MySQL connection
bool connectMySQL(unsigned long timeout) {
  if (invokeConnect)
    return false;

  unsigned long tm = millis();
  Serial.print("MySQL connection start ");
  Serial.print(server + " ");
  Serial.print(user + " ");
  Serial.println(password);

  bool rc;
  while ((rc = conn.connect(server, 3306, user.c_str(), password.c_str())) != true) {
    if (millis() - tm > timeout) {
      // Once it times out, it does not try to connect
      // with the same parameters.
      invokeConnect = false;
      Serial.println("timeout");
      break;
    }
    delay(300);
    Serial.print('.');
  }
  return rc;
}

void setup() {
  delay(1000);
  Serial.begin(115200);
  Serial.println();
  mysqlSetting.load(mysqlSettingPage);
  loadParams(PARAM_FILE);     // Load the parameters in advance
  mysqlSetting.menu(false);   // hide the myssqlSetting from menu initially
  mysqlConnect.load(mysqlConnectPage);
  mysqlConnect.menu(false);   // should always be hidden and call by mysqlsetting only
  mysqlConnect.on(onConnect);	// to be executed for database connection

  portal.join({ mysqlSetting,mysqlConnect});	// added in the standard menu items
  webServer.on("/", handleRoot);
  portal.begin();
}

void loop() {
  // MySQL setting menu control
  bool mysqlMenu = WiFi.status() == WL_CONNECTED;
  // will display the mysqlSetting once connected to WiFi
  mysqlSetting.menu(mysqlMenu);

  static unsigned long tm = millis();
  if (conn.connected()) { 					// if still connected to database
    if (millis() - tm > 5000) {
      cursor->execute(INSERT_SQL);  // Insert Hello Message
      tm = millis();
    }
  }
  else if (mysqlMenu) {
    // WiFi connection has been established, but MySQL connection lost
    // Try to reconnect
    connectMySQL(3000);
  }

  portal.handleClient();
}

from autoconnect.

JoeyUson avatar JoeyUson commented on August 18, 2024

I remove the delay(300) inside the loop of conn.connect.. to reduce the delay in connecting the WiFi. It seems the mySQLconnect is racing with WiFI connection and now it takes longer time to connect the WiFi. It works and the save server,user and password are retain even restart of esp8266.

Latest sketch
`// AutoConnect with MySQL database connection that work for ESP8266 and ESP32

#if defined(ARDUINO_ARCH_ESP8266)
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h> // for using esp.local
#include <FS.h>
#elif defined(ARDUINO_ARCH_ESP32)
#include <WiFi.h>
#include <WebServer.h>
#include <MDNS.h>
#include <SPIFFS.h>
#endif

								// in order to save the MySQL connection parameter to JSON

#include <AutoConnect.h>
#include <MySQL_Connection.h>
#include <MySQL_Cursor.h>

//************************************************ Access Point default password ************************************
#define AP_PASSWORD "12345678" // default password for Access Point
#define DEVICE_TITLE "WiFi_Camera" // Header title to appear in webpage

const static char* mysqlSettingPage PROGMEM = R"(
{
"title": "MySQL Setting",
"uri": "/mysql_setting",
"menu": false,
"element": [
{
"name": "header",
"type": "ACText",
"value": "

MySQL broker settings

",
"style": "text-align:center;color:#2f4f4f;padding:10px;"
},
{
"name": "mysqlserver",
"type": "ACInput",
"value": "",
"label": "MySQLServer",
"placeholder": "MySQL server IP address"
},
{
"name": "user",
"type": "ACInput",
"label": "User",
"placeholder": "MySQL user"
},
{
"name": "password",
"type": "ACInput",
"label": "Password",
"placeholder": "MySQL password"
},
{
"name": "connect",
"type": "ACSubmit",
"value": "Connect",
"uri": "/mysql_conn"
},
{
"name": "discard",
"type": "ACSubmit",
"value": "Discard",
"uri": "/_ac"
}
]
}
)";

const static char* mysqlConnectPage PROGMEM = R"(
{
"title": "MySQL Setting",
"uri": "/mysql_conn",
"menu": false,
"element": [
{
"name": "caption",
"type": "ACText",
"value": "

MySQL connection

",
"style": "text-align:center;color:#2f4f4f;padding:10px;"
},
{
"name": "Result",
"type": "ACText"
},
{
"name": "OK",
"type": "ACSubmit",
"value": "OK",
"uri": "/"
}
]
}
)";

// Select the correct Webserver base in processor
#if defined(ARDUINO_ARCH_ESP8266)
ESP8266WebServer webServer;
#elif defined(ARDUINO_ARCH_ESP32)
WebServer webServer;
#endif

// AutoConnect declaration for menu handling with Aux page
AutoConnect portal(webServer);
AutoConnectConfig config; // for customization of various parameters for Autoconnect
AutoConnectAux mysqlSetting;
AutoConnectAux mysqlConnect;

WiFiClient client;

// database related connection declaration
MySQL_Connection conn((Client *)&client);
IPAddress mysqlserver;
String user;
String password;

// Sample query
const char INSERT_SQL[] = "INSERT INTO test_arduino.hello_arduino (message) VALUES ('Hello, Arduino!')";

bool invokeConnect = false;
// Parameter file
#define PARAM_FILE "/param.json"

/* Set Customized parameters for AutoConnect

  • Can be use to uniquely identified each chip

  • Can have a known IP for Access point
    /
    void setAP() {
    // define a unique SSID based on the chip ID as alternative
    /

    #if defined(ARDUINO_ARCH_ESP8266)
    config.apid = "ESP-" + String(ESP.getChipId(), HEX);
    #elif defined(ARDUINO_ARCH_ESP32)
    config.apid = "ESP-" + String((uint32_t)(ESP.getEfuseMac() >> 32), HEX);
    #endif
    */

    // define unique access point base on device title without space
    config.apid = DEVICE_TITLE;
    config.psk = AP_PASSWORD;

    // Access point Definition
    config.apip = IPAddress(192, 168, 240, 1); // Sets SoftAP IP address
    config.gateway = IPAddress(192, 168, 240, 1); // Sets WLAN router IP address same since no actual gateway
    config.netmask = IPAddress(255, 255, 255, 0); // Sets WLAN scope

/* If needed to have static IP address
config.staip = IPAddress(192, 168, 10, 10); // Sets static IP
config.staGateway = IPAddress(192, 168, 10, 1); // Sets WiFi router address
config.staNetmask = IPAddress(255, 255, 255, 0); // Sets WLAN scope
*/
config.title = DEVICE_TITLE; // Customize the menu title

portal.config(config);				     			 // Update the configuration

}

void handleRoot() { // this is the content of the root page to be display as default
String content =
""
""
"<meta name="viewport" content="width=device-width, initial-scale=1">"
""
""
"Your sketch application there."
"<p style="padding-top:5px;text-align:center">" AUTOCONNECT_LINK(COG_24) "

"
""
"";
webServer.send(200, "text/html", content);
}

// Get parameters from AutoConnectElement
void getParams() {
// here, obtain parameters to connect MySQL
mysqlserver.fromString(mysqlSetting.getElement("mysqlserver").value);
user = mysqlSetting.getElement("user").value;
user.trim();
password = mysqlSetting.getElement("password").value;
password.trim();
invokeConnect = true;
}

// Load parameter of MySQL from JSON file
bool loadParams(const char* paramFile) {
bool loadedParameter = false;
SPIFFS.begin();
File param = SPIFFS.open(paramFile, "r");
if (param) {
// Load the elements with parameters
bool rc = mysqlSetting.loadElement(param);
if (rc) {
// here, obtain parameters to connect MySQL
// getParams(); load only parameters to Element so no need
Serial.println(String(paramFile) + " loaded");
loadedParameter = true;
}
else
Serial.println(String(paramFile) + " failed to load");
param.close(); //since able to open then close now here
}
SPIFFS.end();
return loadedParameter;
}

// Save parameter to /param.json file
void saveParams(const char* paramFile) {
SPIFFS.begin();
File param = SPIFFS.open(paramFile, "w");
mysqlSetting.saveElement(param, { "mysqlserver", "user", "password" });
param.close();
SPIFFS.end();
}

// Makes MySQL connection
bool connectMySQL(unsigned long timeout) {

bool rc = false;		// if connected to MySQl database

if (WiFi.status() == WL_CONNECTED) { // if connected only to WiFi will start the MySQL connecting process
	getParams(); // get the parameters from the elements of AutoConnect ,if loaded then has the value from JSON file
	Serial.println("***MySQL connection start***");
	Serial.print("MySQLServer:"); Serial.println(mysqlserver);
	Serial.println("User:" + user + " ");
	Serial.println("Password:" + password);

	unsigned long tm = millis();

	while ((rc = conn.connect(mysqlserver, 3306, user.c_str(), password.c_str())) != true) {
		if (millis() - tm > timeout) {
			// Once it times out, it does not try to connect
			// with the same parameters.
			invokeConnect = false;
			Serial.println("timeout");
			break;
		}

// delay(100);
// Serial.print('.');
}

}
return rc;	// will return true if connected during the while loop else false

}

// new version
// Custom Web page onConnect handler
String onConnect(AutoConnectAux& aux, PageArgument& args) {
connectMySQL(3000); // get MySQL credential for connection and try to connect with delay
AutoConnectText& result = aux.getElement("Result");
if (conn.connected()) { // success connection to database
saveParams(PARAM_FILE); // write JSON file
result.value = "Connected";
}
else
result.value = "Timeout";
return String();
}

void setup() {
delay(1000);
Serial.begin(115200);
Serial.println();
setAP(); // set the WiFi parameters for AutoConnect

mysqlSetting.load(mysqlSettingPage);// define the setting page
mysqlSetting.menu(false);			// hide the myssqlSetting from menu initially
loadParams(PARAM_FILE);				// Load the parameters in advance even not connected to WiFi
mysqlConnect.load(mysqlConnectPage);// define the connectpage
mysqlConnect.menu(false);			// should always be hidden and call by mysqlsetting only
mysqlConnect.on(onConnect);			// to be executed for database connection

portal.join({ mysqlSetting,mysqlConnect});	// added in the standard menu items
webServer.on("/", handleRoot);
// portal.begin();
if (portal.begin())
	if (MDNS.begin(DEVICE_TITLE)) {		// Using the device title as device.local
		MDNS.addService("http", "tcp", 80);
	}

}

void loop() {
// MySQL setting menu control
bool mysqlMenu = WiFi.status() == WL_CONNECTED;
mysqlSetting.menu(mysqlMenu); // will display the mysqlSetting once connected to WiFi

static unsigned long tm = millis();

if (conn.connected()) {										// if still connected to database
	// normal process to execute while connected to MySQL
	if (millis() - tm > 5000) {
		MySQL_Cursor* cur_mem = new MySQL_Cursor(&conn);	// create MySQL cursor object if connected
		cur_mem->execute(INSERT_SQL);						// Insert Hello Message to dbase
		delete cur_mem;										// Deleting the cursor also frees up memory used   

		tm = millis();										// get new timer as start up
	}
}
else 
	connectMySQL(3000);					// Try to reconnect

portal.handleClient();					// handle the interaction to WiFi

}`

from autoconnect.

Hieromon avatar Hieromon commented on August 18, 2024

@JoeyUson I can not evaluate it because your adjustment depends on the MySQL library but I think you understand AutoConnect's parameter loading and saving mechanism.
May I close this topic?

from autoconnect.

JoeyUson avatar JoeyUson commented on August 18, 2024

Yeh you can, its more in fine tuning..

from autoconnect.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.