diff --git a/.travis.yml b/.travis.yml
index 7d8bbbb..1967126 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -33,3 +33,4 @@ script:
- buildExampleSketch HandlePortalEX
- buildExampleSketch Simple
- buildExampleSketch mqttRSSI
+ - buildExampleSketch mqttRSSI_FS
diff --git a/examples/mqttRSSI_FS/data/mqtt_save.json b/examples/mqttRSSI_FS/data/mqtt_save.json
new file mode 100644
index 0000000..35954ed
--- /dev/null
+++ b/examples/mqttRSSI_FS/data/mqtt_save.json
@@ -0,0 +1,19 @@
+{
+ "title": "MQTT Setting",
+ "uri": "/mqtt_save",
+ "name": "mqttsave",
+ "menu": false,
+ "element": [
+ {
+ "name": "caption",
+ "type": "ACText",
+ "value": "
Parameter saved as:
",
+ "style": "text-align:center;color:#2f4f4f;padding:10px;"
+ },
+ {
+ "name": "validation",
+ "type": "ACText",
+ "value": ""
+ }
+ ]
+}
diff --git a/examples/mqttRSSI_FS/data/mqtt_setting.json b/examples/mqttRSSI_FS/data/mqtt_setting.json
new file mode 100644
index 0000000..319335d
--- /dev/null
+++ b/examples/mqttRSSI_FS/data/mqtt_setting.json
@@ -0,0 +1,85 @@
+{
+ "title": "MQTT Setting",
+ "uri": "/mqtt_setting",
+ "menu": true,
+ "element": [
+ {
+ "name": "header",
+ "type": "ACText",
+ "value": "MQTT broker settings
",
+ "style": "text-align:center;color:#2f4f4f;padding:10px;"
+ },
+ {
+ "name": "caption",
+ "type": "ACText",
+ "value": "Publishing the WiFi signal strength to MQTT channel. RSSI value of ESP8266 to the channel created on ThingSpeak",
+ "style": "font-family:serif;color:#4682b4;"
+ },
+ {
+ "name": "mqttserver",
+ "type": "ACInput",
+ "value": "",
+ "placeholder": "MQTT broker server",
+ "label": "Server"
+ },
+ {
+ "name": "channelid",
+ "type": "ACInput",
+ "value": "",
+ "label": "Channel ID"
+ },
+ {
+ "name": "userkey",
+ "type": "ACInput",
+ "value": "",
+ "label": "User Key"
+ },
+ {
+ "name": "apikey",
+ "type": "ACInput",
+ "value": "",
+ "label": "API Key"
+ },
+ {
+ "name": "period",
+ "type": "ACRadio",
+ "label": "Update period",
+ "value": [
+ "30 sec.",
+ "60 sec.",
+ "180 sec."
+ ],
+ "arrange": "vertical",
+ "checked": 1
+ },
+ {
+ "name": "newline",
+ "type": "ACElement",
+ "value": "
"
+ },
+ {
+ "name": "apid",
+ "type": "ACCheckbox",
+ "label": "Use APID unique",
+ "checked": true
+ },
+ {
+ "name": "hostname",
+ "type": "ACInput",
+ "label": "ESP host name",
+ "value": ""
+ },
+ {
+ "name": "save",
+ "type": "ACSubmit",
+ "value": "SAVE",
+ "uri": "/mqtt_save"
+ },
+ {
+ "name": "discard",
+ "type": "ACSubmit",
+ "value": "Discard",
+ "uri": "/"
+ }
+ ]
+}
diff --git a/examples/mqttRSSI_FS/mqttRSSI_FS.ino b/examples/mqttRSSI_FS/mqttRSSI_FS.ino
new file mode 100644
index 0000000..7900e2a
--- /dev/null
+++ b/examples/mqttRSSI_FS/mqttRSSI_FS.ino
@@ -0,0 +1,252 @@
+/*
+ ESP8266/ESP32 publish the RSSI as the WiFi signal strength to ThingSpeak channel.
+ This example is for explaining how to use the AutoConnect library.
+
+ In order to execute this example, the ThingSpeak account is needed. Sing up
+ for New User Account and create a New Channel via My Channels.
+ For details, please refer to the project page.
+ https://hieromon.github.io/AutoConnect/examples/index.html#used-with-mqtt-as-a-client-application
+
+ Also, this example uses AutoConnectAux menu customization which stored in SPIFFS.
+ To evaluate this example, you upload the contents as mqtt_setting.json of
+ the data folder with MkSPIFFS Tool ("ESP8266 Sketch Data Upload" in Tools menu
+ in Arduino IDE).
+
+ This example is based on the thinkspeak.com environment as of Dec. 20, 2018.
+ Copyright (c) 2018 Hieromon Ikasamo.
+ This software is released under the MIT License.
+ https://opensource.org/licenses/MIT
+*/
+
+#if defined(ARDUINO_ARCH_ESP8266)
+#include
+#elif defined(ARDUINO_ARCH_ESP32)
+#include
+#include
+#endif
+#include
+#include
+#include
+
+#define PARAM_FILE "/param.json"
+#define AUX_MQTTSETTING "/mqtt_setting"
+#define AUX_MQTTSAVE "/mqtt_save"
+
+AutoConnect portal;
+AutoConnectConfig config;
+WiFiClient wifiClient;
+PubSubClient mqttClient(wifiClient);
+String serverName;
+String channelId;
+String userKey;
+String apiKey;
+String apid;
+String hostName;
+unsigned int updateInterval = 0;
+unsigned long lastPub = 0;
+
+#define MQTT_USER_ID "anyone"
+
+bool mqttConnect() {
+ static const char alphanum[] = "0123456789"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"; // For random generation of client ID.
+ char clientId[9];
+
+ uint8_t retry = 10;
+ while (!mqttClient.connected()) {
+ if (serverName.length() <= 0)
+ break;
+
+ mqttClient.setServer(serverName.c_str(), 1883);
+ Serial.println(String("Attempting MQTT broker:") + serverName);
+
+ for (uint8_t i = 0; i < 8; i++) {
+ clientId[i] = alphanum[random(62)];
+ }
+ clientId[8] = '\0';
+
+ if (mqttClient.connect(clientId, MQTT_USER_ID, userKey.c_str())) {
+ Serial.println("Established:" + String(clientId));
+ return true;
+ } else {
+ Serial.println("Connection failed:" + String(mqttClient.state()));
+ if (!--retry)
+ break;
+ }
+ delay(3000);
+ }
+ return false;
+}
+
+void mqttPublish(String msg) {
+ String path = String("channels/") + channelId + String("/publish/") + apiKey;
+ int tLen = path.length();
+ char topic[tLen];
+ path.toCharArray(topic, tLen + 1);
+
+ int mLen = msg.length();
+ char payload[mLen];
+ msg.toCharArray(payload, mLen + 1);
+
+ mqttClient.publish(topic, payload);
+}
+
+int getStrength(uint8_t points) {
+ uint8_t sc = points;
+ long rssi = 0;
+
+ while (sc--) {
+ rssi += WiFi.RSSI();
+ delay(20);
+ }
+ return points ? static_cast(rssi / points) : 0;
+}
+
+String loadParams(AutoConnectAux& aux, PageArgument& args) {
+ (void)(args);
+ SPIFFS.begin();
+ File param = SPIFFS.open(PARAM_FILE, "r");
+ if (param) {
+ aux.loadElement(param);
+ param.close();
+ }
+ else
+ Serial.println(PARAM_FILE " open failed");
+ SPIFFS.end();
+ return "";
+}
+
+String saveParams(AutoConnectAux& aux, PageArgument& args) {
+ String echo;
+
+ serverName = args.arg("mqttserver");
+ serverName.trim();
+ echo = "mqttserver: " + serverName + "
";
+
+ channelId = args.arg("channelid");
+ channelId.trim();
+ echo += "channelid: " + channelId + "
";
+
+ userKey = args.arg("userkey");
+ userKey.trim();
+ echo += "userkey: " + userKey + "
";
+
+ apiKey = args.arg("apikey");
+ apiKey.trim();
+ echo += "apikey: " + apiKey + "
";
+
+ String upd = args.arg("period");
+ updateInterval = upd.substring(0, 2).toInt() * 1000;
+ echo += "period: " + String(updateInterval) + "
";
+
+ String uniqueid = args.arg("uniqueid");
+ echo += "uniqueid: " + uniqueid + "
";
+
+ hostName = args.arg("hostname");
+ hostName.trim();
+ echo += "hostname: " + hostName + "
";
+
+ SPIFFS.begin();
+ File param = SPIFFS.open(PARAM_FILE, "w");
+ portal.aux("/mqtt_setting")->saveElement(param, { "mqttserver", "channelid", "userkey", "apikey", "period", "uniqueid", "hostname" });
+ param.close();
+ SPIFFS.end();
+ return echo;
+}
+
+void handleRoot() {
+ String content =
+ ""
+ ""
+ ""
+ ""
+ ""
+ ""
+ "" AUTOCONNECT_LINK(COG_24) "
"
+ ""
+ "";
+
+#if defined(ARDUINO_ARCH_ESP8266)
+ ESP8266WebServer& server = portal.host();
+#elif defined(ARDUINO_ARCH_ESP32)
+ WebServer& server = portal.host();
+#endif
+ server.send(200, "text/html", content);
+}
+
+bool loadAux(const String auxName) {
+ bool rc = false;
+ String fn = auxName + ".json";
+ File fs = SPIFFS.open(fn.c_str(), "r");
+ if (fs) {
+ rc = portal.load(fs);
+ fs.close();
+ }
+ else
+ Serial.println("SPIFFS open failed: " + fn);
+ return rc;
+}
+
+void setup() {
+ delay(1000);
+ Serial.begin(115200);
+ Serial.println();
+
+ SPIFFS.begin();
+ loadAux(AUX_MQTTSETTING);
+ loadAux(AUX_MQTTSAVE);
+ SPIFFS.end();
+
+ AutoConnectAux* setting = portal.aux(AUX_MQTTSETTING);
+ if (setting) {
+ AutoConnectCheckbox& uniqueidElm = setting->getElement("uniqueid");
+ AutoConnectInput& hostnameElm = setting->getElement("hostname");
+ if (uniqueidElm.checked) {
+ config.apid = String("ESP") + "_" + String(ESP.getChipId(), HEX);
+ }
+ if (hostnameElm.value.length()) {
+ config.hostName = hostnameElm.value;
+ }
+
+ portal.on(AUX_MQTTSETTING, loadParams);
+ portal.on(AUX_MQTTSAVE, saveParams, AC_EXIT_LATER);
+ portal.config(config);
+ }
+ else
+ Serial.println("aux. load error");
+
+ Serial.print("WiFi ");
+ if (portal.begin()) {
+ Serial.println("connected:" + WiFi.SSID());
+ Serial.println("IP:" + WiFi.localIP().toString());
+ } else {
+ Serial.println("connection failed:" + String(WiFi.status()));
+ while (1) {
+ delay(100);
+ yield();
+ }
+ }
+
+#if defined(ARDUINO_ARCH_ESP8266)
+ ESP8266WebServer& server = portal.host();
+#elif defined(ARDUINO_ARCH_ESP32)
+ WebServer& server = portal.host();
+#endif
+ server.on("/", handleRoot);
+}
+
+void loop() {
+ if (updateInterval > 0) {
+ if (millis() - lastPub > updateInterval) {
+ if (!mqttClient.connected()) {
+ mqttConnect();
+ }
+ String item = String("field1=") + String(getStrength(7));
+ mqttPublish(item);
+ mqttClient.loop();
+ lastPub = millis();
+ }
+ }
+ portal.handleClient();
+}