From 6b702aaf4b0e43c3def98a27760efacdc7764efd Mon Sep 17 00:00:00 2001 From: Hieromon Ikasamo Date: Wed, 20 Feb 2019 17:56:16 +0900 Subject: [PATCH] Add example --- .travis.yml | 2 + examples/HelloWorld/Data/style.json | 5 + examples/HelloWorld/HelloWorld.ino | 68 +++++++ examples/mqttRSSI_NA/mqttRSSI_NA.ino | 263 +++++++++++++++++++++++++++ 4 files changed, 338 insertions(+) create mode 100644 examples/HelloWorld/Data/style.json create mode 100644 examples/HelloWorld/HelloWorld.ino create mode 100644 examples/mqttRSSI_NA/mqttRSSI_NA.ino diff --git a/.travis.yml b/.travis.yml index d2677df..3c8804c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,5 +32,7 @@ script: - buildExampleSketch HandlePortal - buildExampleSketch HandlePortalEX - buildExampleSketch Simple + - buildExampleSketch HelloWorld - buildExampleSketch mqttRSSI - buildExampleSketch mqttRSSI_FS + - buildExampleSketch mqttRSSI_NA diff --git a/examples/HelloWorld/Data/style.json b/examples/HelloWorld/Data/style.json new file mode 100644 index 0000000..6c6030c --- /dev/null +++ b/examples/HelloWorld/Data/style.json @@ -0,0 +1,5 @@ +{ + "name" : "Caption", + "type" : "ACText", + "style": "text-align:center;font-family:'Avenir','Corbel','Osaka';color:Green;" +} diff --git a/examples/HelloWorld/HelloWorld.ino b/examples/HelloWorld/HelloWorld.ino new file mode 100644 index 0000000..0ab0b81 --- /dev/null +++ b/examples/HelloWorld/HelloWorld.ino @@ -0,0 +1,68 @@ +/* + HelloWorld.ino, Example for the AutoConnect library. + Copyright (c) 2019, Hieromon Ikasamo + https://github.com/Hieromon/AutoConnect + + This software is released under the MIT License. + https://opensource.org/licenses/MIT +*/ +/* + To experience this example, upload the JSON file which is style.json + from the data folder. Its file contains the attributes for the Caption + of AutoConnectText. You can change the elements for your realization. +*/ + +#if defined(ARDUINO_ARCH_ESP8266) +#include +#include +typedef ESP8266WebServer WEBServer; +#elif defined(ARDUINO_ARCH_ESP32) +#include +#include +#include +typedef WebServer WEBServer; +#endif +#include +#include + +#define HELLO_URI "/hello" +#define PARAM_STYLE "/style.json" + +// Declare AutoConnectElements and AutoConnectAux for the custom Web page. +ACText(Caption, "Hello, world"); +AutoConnectAux helloPage(HELLO_URI, "Hello", true, { Caption }); +AutoConnect portal; + +// Redirects from root to the hello page. +void onRoot() { + WEBServer& webServer = portal.host(); + webServer.sendHeader("Location", String("http://") + webServer.client().localIP().toString() + String(HELLO_URI)); + webServer.send(302, "text/plain", ""); + webServer.client().flush(); + webServer.client().stop(); +} + +// Load the attribute of the element to modify at runtime from external. +String onHello(AutoConnectAux& aux, PageArgument& args) { + File param = SPIFFS.open(PARAM_STYLE, "r"); + aux.loadElement(param); + param.close(); + return String(); +} + +void setup() { + delay(1000); + Serial.begin(115200); + SPIFFS.begin(); // Prepare SPIFFS + + helloPage.on(onHello); // Register the attribute overwrite handler. + portal.join(helloPage); // Join the hello page. + portal.begin(); + + WEBServer& webServer = portal.host(); + webServer.on("/", onRoot); // Register the root page redirector. +} + +void loop() { + portal.handleClient(); +} diff --git a/examples/mqttRSSI_NA/mqttRSSI_NA.ino b/examples/mqttRSSI_NA/mqttRSSI_NA.ino new file mode 100644 index 0000000..e07ec57 --- /dev/null +++ b/examples/mqttRSSI_NA/mqttRSSI_NA.ino @@ -0,0 +1,263 @@ +/* +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 + +This example is based on the environment as of March 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 +#include +#define GET_CHIPID() (ESP.getChipId()) +#elif defined(ARDUINO_ARCH_ESP32) +#include +#include +#include +#define GET_CHIPID() ((uint16_t)(ESP.getEfuseMac()>>32)) +#endif +#include +#include +#include + +#define PARAM_FILE "/param.json" +#define AUX_SETTING_URI "/mqtt_setting" +#define AUX_SAVE_URI "/mqtt_save" +#define AUX_CLEAR_URI "/mqtt_clear" + +// Adjusting WebServer class with between ESP8266 and ESP32. +#if defined(ARDUINO_ARCH_ESP8266) +typedef ESP8266WebServer WiFiWebServer; +#elif defined(ARDUINO_ARCH_ESP32) +typedef WebServer WiFiWebServer; +#endif + +// This example shows a sketch that realizes the equivalent operation +// of mqttRSSI without using JSON. +// By comparing this example with the example using JSON, mqttRSSI or +// mqttRSSI_FS, you will better understand AutoConnect's custom Web page +// facility. + +// Declare AutoConnectElements for the page asf /mqtt_setting +ACText(header, "

MQTT broker settings

", "text-align:center;color:#2f4f4f;padding:10px;"); +ACText(caption, "Publishing the WiFi signal strength to MQTT channel. RSSI value of ESP8266 to the channel created on ThingSpeak", "font-family:serif;color:#4682b4;"); +ACInput(mqttserver, "", "Server", "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])$", "MQTT broker server"); +ACInput(channelid, "", "Channel ID", "^[0-9]{6}$"); +ACInput(userkey, "", "User Key"); +ACInput(apikey, "", "API Key"); +ACElement(newline, "
"); +ACCheckbox(uniqueid, "unique", "Use APID unique"); +ACRadio(period, { "30 sec.", "60 sec.", "180 sec." }, "Update period", AC_Vertical, 1); +ACSubmit(save, "Start", AUX_SAVE_URI); +ACSubmit(discard, "Discard", "/"); + +// Declare the custom Web page as /mqtt_setting and contains the AutoConnectElements +AutoConnectAux mqtt_setting(AUX_SETTING_URI, "MQTT Setting", true, { + header, + caption, + mqttserver, + channelid, + userkey, + apikey, + newline, + uniqueid, + period, + newline, + save, + discard +}); + +// Declare AutoConnectElements for the page as /mqtt_save +ACText(caption2, "

Parameters available as:

", "text-align:center;color:#2f4f4f;padding:10px;"); +ACText(parameters); +ACSubmit(clear, "Clear channel", AUX_CLEAR_URI); + +// Declare the custom Web page as /mqtt_save and contains the AutoConnectElements +AutoConnectAux mqtt_save(AUX_SAVE_URI, "MQTT Setting", false, { + caption2, + parameters, + clear +}); + +AutoConnect portal; +AutoConnectConfig config; +WiFiClient wifiClient; +PubSubClient mqttClient(wifiClient); + +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 (mqttserver.value.length() <= 0) + break; + + mqttClient.setServer(mqttserver.value.c_str(), 1883); + Serial.println(String("Attempting MQTT broker:") + mqttserver.value); + + for (uint8_t i = 0; i < 8; i++) { + clientId[i] = alphanum[random(62)]; + } + clientId[8] = '\0'; + + if (mqttClient.connect(clientId, MQTT_USER_ID, userkey.value.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.value + String("/publish/") + apikey.value; + mqttClient.publish(path.c_str(), msg.c_str()); +} + +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; +} + +// Retreive the value of each element entered by '/mqtt_setting'. +String saveParams(AutoConnectAux& aux, PageArgument& args) { + // The 'where()' function returns the AutoConnectAux that caused + // the transition to this page. + mqttserver.value.trim(); + channelid.value.trim(); + userkey.value.trim(); + apikey.value.trim(); + updateInterval = period.value().substring(0, 2).toInt() * 1000; + + // Echo back saved parameters to AutoConnectAux page. + String echo = "Server: " + mqttserver.value + "
"; + echo += "Channel ID: " + channelid.value + "
"; + echo += "User Key: " + userkey.value + "
"; + echo += "API Key: " + apikey.value + "
"; + echo += "Update period: " + String(updateInterval / 1000) + " sec.
"; + echo += "Use APID unique: " + String(uniqueid.checked == true ? "true" : "false") + "
"; + parameters.value = echo; + + return String(""); +} + +void handleRoot() { + String content = + "" + "" + "" + "" + "" + "" + "

" AUTOCONNECT_LINK(COG_24) "

" + "" + ""; + + WiFiWebServer& webServer = portal.host(); + webServer.send(200, "text/html", content); +} + +// Clear channel using ThingSpeak's API. +void handleClearChannel() { + HTTPClient httpClient; + WiFiClient client; + String endpoint = mqttserver.value; + endpoint.replace("mqtt", "api"); + String delUrl = "http://" + endpoint + "/channels/" + channelid.value + "/feeds.json?api_key=" + userkey.value; + + Serial.print("DELETE " + delUrl); + if (httpClient.begin(client, delUrl)) { + Serial.print(":"); + int resCode = httpClient.sendRequest("DELETE"); + String res = httpClient.getString(); + httpClient.end(); + Serial.println(String(resCode) + "," + res); + } + else + Serial.println(" failed"); + + // Returns the redirect response. + WiFiWebServer& webServer = portal.host(); + webServer.sendHeader("Location", String("http://") + webServer.client().localIP().toString() + String("/")); + webServer.send(302, "text/plain", ""); + webServer.client().flush(); + webServer.client().stop(); +} + +void setup() { + delay(1000); + Serial.begin(115200); + Serial.println(); + SPIFFS.begin(); + + if (uniqueid.checked) { + config.apid = String("ESP") + "-" + String(GET_CHIPID(), HEX); + Serial.println("apid set to " + config.apid); + } + + config.bootUri = AC_ONBOOTURI_HOME; + config.homeUri = "/"; + portal.config(config); + + // Join the custom Web pages and register /mqtt_save handler + portal.join({ mqtt_setting, mqtt_save }); + portal.on(AUX_SAVE_URI, saveParams); + + 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(); + } + } + + WiFiWebServer& webServer = portal.host(); + webServer.on("/", handleRoot); + webServer.on(AUX_CLEAR_URI, handleClearChannel); +} + +void loop() { + portal.handleClient(); + if (updateInterval > 0) { + if (millis() - lastPub > updateInterval) { + if (!mqttClient.connected()) { + mqttConnect(); + } + String item = String("field1=") + String(getStrength(7)); + mqttPublish(item); + mqttClient.loop(); + lastPub = millis(); + } + } +}