Supports AutoConnectAux

pull/41/head
Hieromon Ikasamo 6 years ago
parent ad07e1b448
commit d281bb33e7
  1. 10
      README.md
  2. 2
      src/AutoConnect.cpp
  3. 79
      src/AutoConnect.h
  4. 375
      src/AutoConnectAux.cpp
  5. 168
      src/AutoConnectAux.h
  6. 103
      src/AutoConnectDefs.h
  7. 49
      src/AutoConnectElement.h
  8. 170
      src/AutoConnectElementBasis.h
  9. 107
      src/AutoConnectElementBasisImpl.h
  10. 173
      src/AutoConnectElementJson.h
  11. 140
      src/AutoConnectElementJsonImpl.h

@ -32,10 +32,14 @@ AutoConnect can be embedded easily into your sketch, just "**begin**" and "**han
The sketches which provide the web page using ESP8266WebServer/WebServer there is, AutoConnect will not disturb it. AutoConnect can use an already instantiated ESP8266WebServer object(ESP8266) or WebServer object(ESP32), or itself can assign it.
### Adding the user-owned web screen can easily
### Adding the user-owned web screen can easily <sup><sub>ENHANCED w/ v0.9.7</sub></sup>
You can easily add your own web screen with sketch. It can be called from the AutoConnect menu and parameters can be passed.
### Adding the extended menu with a simple code can easily <sup><sub>ENHANCED w/ v0.9.7</sub></sup>
Just loading the elements of portal screen extension written with JSON allows you to incorporate your owned portal screen into the AutoConnect menu.
## Supported hardware
Apply the [Arduino core](https://github.com/esp8266/Arduino) of the ESP8266 Community.
@ -86,8 +90,10 @@ Full documentation is available on https://Hieromon.github.io/AutoConnect, some
## Change log
### [0.9.7] Nov. 11, 2018
- Supports addition of AutoConnect menu with user sketch by AutoConnectAux implementation.
- Supports AutoConnect menu extention by user sketch with **AutoConnectAux** implementation that attached **AutoConnectElement**.
- Supports loading and saving of user-defined parameters with JSON format.
- Supports AutoConnectConfig::immediateStart option, to start the portal immediately without first trying WiFi.begin.
- Improved source code placement of predefined macros. Defined macros have been moved to ```AutoConnectDefs.h```.
### [0.9.6] Sept. 27, 2018
- Improvement of RSSI detection for saved SSIDs.

@ -700,4 +700,4 @@ void AutoConnect::_disconnectWiFi(bool wifiOff) {
#endif
while (WiFi.status() == WL_CONNECTED)
delay(100);
}
}

@ -28,85 +28,11 @@ using WebServerClass = WebServer;
#endif
#include <EEPROM.h>
#include <PageBuilder.h>
#include "AutoConnectDefs.h"
#include "AutoConnectPage.h"
#include "AutoConnectCredential.h"
#include "AutoConnectAux.h"
// Uncomment the following AC_DEBUG to enable debug output.
#define AC_DEBUG
// Debug output destination can be defined externally with AC_DEBUG_PORT
#ifndef AC_DEBUG_PORT
#define AC_DEBUG_PORT Serial
#endif
#ifdef AC_DEBUG
#define AC_DBG(...) do {AC_DEBUG_PORT.print("[AC] "); AC_DEBUG_PORT.printf( __VA_ARGS__ );} while (0)
#else
#define AC_DBG(...)
#endif
#ifndef AUTOCONNECT_APID
#if defined(ARDUINO_ARCH_ESP8266)
#define AUTOCONNECT_APID "esp8266ap"
#elif defined(ARDUINO_ARCH_ESP32)
#define AUTOCONNECT_APID "esp32ap"
#endif
#endif
#ifndef AUTOCONNECT_PSK
#define AUTOCONNECT_PSK "12345678"
#endif
#ifndef AUTOCONNECT_AP_IP
#define AUTOCONNECT_AP_IP 0x01F4A8C0 //*< 192.168.244.1 */
#endif // !AUTOCONNECT_AP_IP
#ifndef AUTOCONNECT_AP_GW
#define AUTOCONNECT_AP_GW 0x01F4A8C0 //*< 192.168.244.1 */
#endif // !AUTOCONNECT_AP_GW
#ifndef AUTOCONNECT_AP_NM
#define AUTOCONNECT_AP_NM 0x00FFFFFF //*< 255.255.255.0 */
#endif // !AUTOCONNECT_AP_NM
#ifndef AUTOCONNECT_URI
#define AUTOCONNECT_URI "/_ac"
#endif
#ifndef AUTOCONNECT_HOMEURI
#define AUTOCONNECT_HOMEURI "/"
#endif
#ifndef AUTOCONNECT_MENU_TITLE
#define AUTOCONNECT_MENU_TITLE "AutoConnect"
#endif
#define AUTOCONNECT_MENU_TITLE_CONNETED "Connected"
#define AUTOCONNECT_URI_CONFIG AUTOCONNECT_URI "/config"
#define AUTOCONNECT_URI_CONNECT AUTOCONNECT_URI "/connect"
#define AUTOCONNECT_URI_RESULT AUTOCONNECT_URI "/result"
#define AUTOCONNECT_URI_OPEN AUTOCONNECT_URI "/open"
#define AUTOCONNECT_URI_DISCON AUTOCONNECT_URI "/disc"
#define AUTOCONNECT_URI_RESET AUTOCONNECT_URI "/reset"
#define AUTOCONNECT_URI_SUCCESS AUTOCONNECT_URI "/success"
#define AUTOCONNECT_URI_FAIL AUTOCONNECT_URI "/fail"
#ifndef AUTOCONNECT_TIMEOUT
#define AUTOCONNECT_TIMEOUT 30000
#endif
#ifndef AUTOCONNECT_STARTUPTIME
#define AUTOCONNECT_STARTUPTIME 10
#endif
#ifndef AUTOCONNECT_HTTPPORT
#define AUTOCONNECT_HTTPPORT 80
#endif
#ifndef AUTOCONNECT_DNSPORT
#define AUTOCONNECT_DNSPORT 53
#endif
#define AC_UNUSED(expr) do { (void)(expr); } while (0)
/**< A type to save established credential at WiFi.begin automatically. */
typedef enum AC_SAVECREDENTIAL {
AC_SAVECREDENTIAL_NEVER,
@ -286,7 +212,7 @@ class AutoConnect {
/** Extended pages made up with AutoConnectAux */
std::unique_ptr<AutoConnectAux> _aux;
/** Saved configurations */
AutoConnectConfig _apConfig;
struct station_config _credential;
@ -363,6 +289,7 @@ class AutoConnect {
#elif defined(ARDUINO_ARCH_ESP32)
friend class WebServer;
#endif
friend class AutoConnectAux;
};

@ -1,18 +1,22 @@
/**
* Implementation of AutoConnectAux class and subordinated AutoConnectElement class.
* @file AutoConnectAux.cpp
* @author hieromon@gmail.com
* @version 0.9.7
* @date 2018-11-17
* @copyright MIT license.
* Implementation of AutoConnectAux class.
* @file AutoConnectAuxBasisImpl.h
* @author hieromon@gmail.com
* @version 0.9.7
* @date 2018-11-17
* @copyright MIT license.
*/
#include "AutoConnect.h"
#include "AutoConnectAux.h"
#include "AutoConnectElement.h"
#include "AutoConnectElementBasisImpl.h"
#ifdef AUTOCONNECT_USE_JSON
#include "AutoConnectElementJsonImpl.h"
#endif
/**
* Template for auxiliary page composed with AutoConnectAux of user sketch.
*
* The structure of the auxiliary page depends on this template for
* the purpose to be incorporated into the AutoConnect Menu.
* The page element implemented by AutoConnectElement is placed at the
@ -57,100 +61,8 @@ const char AutoConnectAux::_PAGE_AUX[] PROGMEM = {
};
/**
* Generate an HTML <button> element. The onclick behavior depends on
* the code held in <EFBFBD>faction<EFBFBD>f member.
* @return String an HTML string.
*/
const String AutoConnectButton::toHTML(void) const {
return String(FPSTR("<button type=\"button\" name=\"")) + name + String(FPSTR("\" value=\"")) + value + String(FPSTR("\" onclick=\"")) + action + String("\">") + value + String(FPSTR("</button>"));
}
/**
* Generate an HTML <input type=checkbox> element.
* A "value" is associated with the input tag and sent by the form
* action as the value of "name". If the label member is contained, it
* is placed to the right side of the checkbox to be labeled.
* If the label member is empty, only the checkbox is placed.
* @return String an HTML string.
*/
const String AutoConnectCheckbox::toHTML(void) const {
String html;
html = String(FPSTR("<input type=\"checkbox\" name=\"")) + name + String(FPSTR("\" value=\"")) + value + String("\"");
if (checked)
html += String(FPSTR(" checked"));
if (label.length())
html += String(" id=\"") + name + String("\"><label for=\"") + name + String("\">") + label + String(FPSTR("</label"));
html += String(FPSTR("><br>"));
return html;
}
/**
* Generate an HTML <input type=text> element.
* If the value member is contained, it is reflected in the placeholder
* attribute. The entered value can be obtained using the user callback
* function registered by AutoConnectAux::on after the form is sent in
* combination with AutoConnectSubmit.
* @return String an HTML string.
*/
const String AutoConnectInput::toHTML(void) const {
String html = String();
if (label.length())
html = String(FPSTR("<label for=\"")) + name + String("\">") + label + String(FPSTR("</label>"));
html += String(FPSTR("<input type=\"text\" id=\"")) + name + String(FPSTR("\" name=\"")) + name;
if (value.length())
html += String(FPSTR("\" placeholder=\"")) + value;
html += String(FPSTR("\"><br>"));
return html;
}
/**
* Generate an HTML <select> element with an <option> element.
* The attribute value of the <option> element is given to the
* AutoConnectSelect class as a string array, which would be stored
* in the 'options' member. If a label member is contained, the <label>
* element would be generated the preface of <select>.
* @return String an HTML string.
*/
const String AutoConnectSelect::toHTML(void) const {
String html = String();
if (label.length())
html = String(FPSTR("<label>")) + label + String(FPSTR("</label>"));
html += String(FPSTR("<select name=\"")) + name + String("\">");
std::size_t n = _options.size();
if (n) {
for (std::size_t n = 0; n < _options.size(); n++)
html += String(FPSTR("<option value=\"")) + _options[n] + "\">" + _options[n] + String(FPSTR("</option>"));
}
html += String(FPSTR("</select><br>"));
return html;
}
/**
* Generate an HTML <input type=button> element. This element is used
* for form submission. An 'onclick' attribute calls fixed JavaScript
* code as 'sa' named and it's included in the template.
* @return String an HTML string.
*/
const String AutoConnectSubmit::toHTML(void) const {
return String(FPSTR("<input type=\"button\" name=\"")) + name + String(FPSTR("\" value=\"")) + value + String(FPSTR("\" onclick=\"_sa('")) + uri + String("')\">");
}
/**
* Generate an HTML text element from a string of the value member. If a style
* exists, it gives a style attribute.
* @return String an HTML string.
*/
const String AutoConnectText::toHTML(void) const {
return String(FPSTR("<div style=\"")) + style + String("\">") + value + String(FPSTR("</div>"));
}
/**
* Destructs container of AutoConnectElement and release a unique
* pointer of AutoConnect instance.
* Destructs container of AutoConnectElement and release a unique
* pointer of AutoConnect instance.
*/
AutoConnectAux::~AutoConnectAux() {
_addonElm.clear();
@ -160,17 +72,17 @@ AutoConnectAux::~AutoConnectAux() {
}
/**
* Add an AutoConnectElement
* @param addon A reference of AutoConnectElement.
* Add an AutoConnectElement
* @param addon A reference of AutoConnectElement.
*/
void AutoConnectAux::add(AutoConnectElement& addon) {
_addonElm.push_back(addon);
AC_DBG("%s placed on %s\n", addon.name.c_str(), uri());
AC_DBG("%s placed on %s\n", addon.name.length() ? addon.name.c_str() : "*nonamed*", uri());
}
/**
* Add an AutoConnectElement vector container to the AutoConnectAux page.
* @param addons AutoConnectElementVT collection.
* Add an AutoConnectElement vector container to the AutoConnectAux page.
* @param addons AutoConnectElementVT collection.
*/
void AutoConnectAux::add(AutoConnectElementVT addons) {
for (std::size_t n = 0; n < addons.size(); n++)
@ -178,12 +90,12 @@ void AutoConnectAux::add(AutoConnectElementVT addons) {
}
/**
* Releases the AutoConnectElements with the specified name from
* the AutoConnectAux page. Releases all AutoConnectElements with
* the same name in AutoConnectAux.
* @param name
* @return true The specified AutoConnectElements have been released.
* @return false The specified AutoConnectElement not found in AutoConnectAux.
* Releases the AutoConnectElements with the specified name from
* the AutoConnectAux page. Releases all AutoConnectElements with
* the same name in AutoConnectAux.
* @param name
* @return true The specified AutoConnectElements have been released.
* @return false The specified AutoConnectElement not found in AutoConnectAux.
*/
bool AutoConnectAux::release(const String name) {
bool rc = false;
@ -199,13 +111,13 @@ bool AutoConnectAux::release(const String name) {
}
/**
* Concatenates subsequent AutoConnectAux pages starting from oneself
* to the chain list.
* AutoConnectAux is collected in the chain list and each object is
* chained by the "_next". AutoConnect follows the "_next" to manage
* auxiliary pages. The _concat function concatenates subsequent
* AutoConnectAuxs.
* @param aux A reference of AutoConnectAux.
* Concatenates subsequent AutoConnectAux pages starting from oneself
* to the chain list.
* AutoConnectAux is collected in the chain list and each object is
* chained by the "_next". AutoConnect follows the "_next" to manage
* auxiliary pages. The _concat function concatenates subsequent
* AutoConnectAuxs.
* @param aux A reference of AutoConnectAux.
*/
void AutoConnectAux::_concat(AutoConnectAux& aux) {
if (_next)
@ -215,11 +127,11 @@ void AutoConnectAux::_concat(AutoConnectAux& aux) {
}
/**
* Register the AutoConnect that owns itself.
* AutoConenctAux needs to access the AutoConnect member. Also
* AutoConnectAux is cataloged by chain list. The _join function
* registers AutoConnect in the following AutoConnectAux chain list.
* @param ac A reference of AutoConnect.
* Register the AutoConnect that owns itself.
* AutoConenctAux needs to access the AutoConnect member. Also
* AutoConnectAux is cataloged by chain list. The _join function
* registers AutoConnect in the following AutoConnectAux chain list.
* @param ac A reference of AutoConnect.
*/
void AutoConnectAux::_join(AutoConnect& ac) {
_ac.reset(&ac);
@ -230,10 +142,10 @@ void AutoConnectAux::_join(AutoConnect& ac) {
}
/**
* Insert the token handler of PageBuilder. This handler inserts HTML
* elements generated by the whole AutoConnectElements to the auxiliary page.
* @param args A reference of PageArgument but unused.
* @return HTML string that should be inserted.
* Insert the token handler of PageBuilder. This handler inserts HTML
* elements generated by the whole AutoConnectElements to the auxiliary page.
* @param args A reference of PageArgument but unused.
* @return HTML string that should be inserted.
*/
const String AutoConnectAux::_insertElement(PageArgument& args) {
AC_UNUSED(args);
@ -260,13 +172,13 @@ const String AutoConnectAux::_insertElement(PageArgument& args) {
}
/**
* Generate an auxiliary page assembled with the AutoConnectElement.
* This function is the core procedure of AutoConnectAux, and uses
* PageBuilder from the _PAGE_AUX template to build an AutoConnect
* menu and insert HTML elements. A template of an auxiliary page is
* fixed and its structure inherits from the AutoConnect.
* @param uri An uri of the auxiliary page.
* @return A PageElement of auxiliary page.
* Generate an auxiliary page assembled with the AutoConnectElement.
* This function is the core procedure of AutoConnectAux, and uses
* PageBuilder from the _PAGE_AUX template to build an AutoConnect
* menu and insert HTML elements. A template of an auxiliary page is
* fixed and its structure inherits from the AutoConnect.
* @param uri An uri of the auxiliary page.
* @return A PageElement of auxiliary page.
*/
PageElement* AutoConnectAux::_setupPage(String uri) {
PageElement* elm = nullptr;
@ -302,12 +214,12 @@ PageElement* AutoConnectAux::_setupPage(String uri) {
}
/**
* Inject the <li> element depending on the "luxbar-item" attribute
* for implementing the AutoConnect menu.
* @param args A reference of PageArgument but it's only used for
* interface alignment and is not actually used.
* @return A concatenated string of <li> elements for the menu item of
* AutoConnect.
* Inject the <li> element depending on the "luxbar-item" attribute
* for implementing the AutoConnect menu.
* @param args A reference of PageArgument but it's only used for
* interface alignment and is not actually used.
* @return A concatenated string of <li> elements for the menu item of
* AutoConnect.
*/
const String AutoConnectAux::_injectMenu(PageArgument& args) {
String menuItem;
@ -318,3 +230,184 @@ const String AutoConnectAux::_injectMenu(PageArgument& args) {
menuItem += _next->_injectMenu(args);
return menuItem;
}
#ifdef AUTOCONNECT_USE_JSON
/**
* Create an instance from the AutoConnectElement of the JSON object.
* @param json A reference of JSON
* @return A pointer of created AutoConnectElement instance.
*/
AutoConnectElement* AutoConnectAux::_createElement(const JsonObject& json) {
AutoConnectElement* elm = nullptr;
String type = json.get<String>(F(AUTOCONNECT_JSON_KEY_TYPE));
switch (_asElementType(type)) {
case AC_Element:
elm = new AutoConnectElement;
break;
case AC_Button: {
AutoConnectButton* cert_elm = new AutoConnectButton;
return reinterpret_cast<AutoConnectElement*>(cert_elm);
}
case AC_Checkbox: {
AutoConnectCheckbox* cert_elm = new AutoConnectCheckbox;
return reinterpret_cast<AutoConnectElement*>(cert_elm);
}
case AC_Input: {
AutoConnectInput* cert_elm = new AutoConnectInput;
return reinterpret_cast<AutoConnectElement*>(cert_elm);
}
case AC_Select: {
AutoConnectSelect* cert_elm = new AutoConnectSelect;
return reinterpret_cast<AutoConnectElement*>(cert_elm);
}
case AC_Submit: {
AutoConnectSubmit* cert_elm = new AutoConnectSubmit;
return reinterpret_cast<AutoConnectElement*>(cert_elm);
}
case AC_Text: {
AutoConnectText* cert_elm = new AutoConnectText;
return reinterpret_cast<AutoConnectElement*>(cert_elm);
}
}
return elm;
}
/**
* Load element specified by the name parameter from the stream
* described by JSON. Usually, the Stream is specified a storm file of
* SD or SPIFFS. The Stream must be opened before invoking the function.
* @param in Reference of the Stream which contains the parameter
* file described by JSON.
* @param name The element name to be loaded.
* @return A reference of loaded AutoConnectElement instance.
*/
AutoConnectElement& AutoConnectAux::loadElement(Stream& in, const String name) {
DynamicJsonBuffer jsonBuffer;
JsonObject& jb = jsonBuffer.parseObject(in);
if (!jb.success())
return _nullElement();
JsonArray& aux = jb[AUTOCONNECT_JSON_KEY_AUX];
if (!aux.success())
return _nullElement();
for (JsonObject& page : aux) {
if (page["uri"].as<String>() == String(uri())) {
JsonArray& element = page[AUTOCONNECT_JSON_KEY_ELEMENT];
for (JsonObject& elm : element) {
if (name.equalsIgnoreCase(elm.get<String>(F(AUTOCONNECT_JSON_KEY_NAME)))) {
// The specified element is defined in the JSON stream.
// Loads from JSON object.
const String inType = elm[AUTOCONNECT_JSON_KEY_TYPE].as<String>();
AutoConnectElement* auxElm = _getElement(name);
// The element is not created yet, create new one.
if (!auxElm) {
if ((auxElm = _createElement(elm))) {
AC_DBG("%s<%d> of %s created\n", name.c_str(), (int)(auxElm->typeOf()), uri());
add(*auxElm); // Insert to AutoConnect
}
else {
AC_DBG("%s unknown element type\n", name.c_str());
return _nullElement();
}
}
if (auxElm->loadElement(elm)) {
AC_DBG("%s<%d> of %s loaded\n", name.c_str(), (int)auxElm->typeOf(), uri());
}
else {
// Element type mismatch
AC_DBG("Type of %s element mismatched\n", name.c_str());
return _nullElement();
}
}
}
}
}
return _nullElement();
}
/**
* Serialize the element to JSON and write it to the stream.
* @param out An output stream
* @param element A reference of the element to be output.
* @return Number of byte output
*/
size_t AutoConnectAux::saveElement(Stream& out, const AutoConnectElement& element) {
DynamicJsonBuffer jsonBuffer;
JsonObject& jb = jsonBuffer.parseObject(out);
if (!jb.success())
return 0;
JsonArray& aux = jb[AUTOCONNECT_JSON_KEY_AUX];
if (!aux.success())
return 0;
for (JsonObject& page : aux) {
if (page["uri"].as<String>() == String(uri())) {
JsonArray& element_j = page[AUTOCONNECT_JSON_KEY_ELEMENT];
for (JsonObject& elm : element_j) {
if (elm[AUTOCONNECT_JSON_KEY_NAME].as<String>() == element.name) {
elm.set(F(AUTOCONNECT_JSON_KEY_VALUE), element.value);
return jb.prettyPrintTo(out);
}
}
}
}
return 0;
}
/**
* Get already registered AutoConnectElement.
* @param name Element name
* @return A pointer to the registered AutoConnectElement.
*/
AutoConnectElement* AutoConnectAux::_getElement(const String name) {
for (std::size_t n = 0; n < _addonElm.size(); n++)
if (_addonElm[n].get().name == name)
return &(_addonElm[n].get());
return nullptr;
}
/**
* Convert element type from type as String.
* @param type An element type as String
* @return A type of ACElement_t
*/
const ACElement_t AutoConnectAux::_asElementType(const String type) {
typedef struct {
const char* tName;
ACElement_t tEnum;
} ACElementType_t;
static const ACElementType_t types[] PROGMEM = {
{ AUTOCONNECT_JSON_TYPE_ACBUTTON, AC_Button },
{ AUTOCONNECT_JSON_TYPE_ACCHECKBOX, AC_Checkbox },
{ AUTOCONNECT_JSON_TYPE_ACELEMENT, AC_Element },
{ AUTOCONNECT_JSON_TYPE_ACINPUT, AC_Input },
{ AUTOCONNECT_JSON_TYPE_ACSELECT, AC_Select },
{ AUTOCONNECT_JSON_TYPE_ACSUBMIT, AC_Submit },
{ AUTOCONNECT_JSON_TYPE_ACTEXT, AC_Text }
};
ACElement_t t = AC_Unknown;
for (size_t n = 0; n < (sizeof(types) / sizeof(ACElementType_t)); n++) {
if (type.equalsIgnoreCase(String(types[n].tName)))
return types[n].tEnum;
}
return t;
}
/**
* Returns a null element as static storage.
* This static element is referred by invalid JSON data.
* @return A reference of a static element defined by name as null.
*/
AutoConnectElement& AutoConnectAux::_nullElement() {
static AutoConnectElement nullElement("","");
return nullElement;
}
#endif

@ -1,10 +1,10 @@
/**
* Declaration of AutoConnectAux class and subordinated AutoConnectElement class.
* @file AutoConnectAux.h
* @author hieromon@gmail.com
* @version 0.9.7
* @date 2018-11-17
* @copyright MIT license.
* Declaration of AutoConnectAux basic class.
* @file AutoConnectAuxBasis.h
* @author hieromon@gmail.com
* @version 0.9.7
* @date 2018-11-17
* @copyright MIT license.
*/
#ifndef _AUTOCONNECTAUX_H_
@ -14,144 +14,10 @@
#include <memory>
#include <functional>
#include <PageBuilder.h>
#include "AutoConnectDefs.h"
#include "AutoConnectElement.h"
class AutoConnect; // Reference to avoid circular
/**
* AutoConnectAux element base.
* Placed a labeled button that can be added by user sketch.
* @param name Button name string.
* @param value Button value string.
*/
class AutoConnectElement {
public:
explicit AutoConnectElement(const char* name, const char* value) : name(String(name)), value(String(value)) {}
virtual ~AutoConnectElement() {}
virtual const String toHTML(void) const { return value; } /**< HTML code to be generated */
String name; /**< Element name */
String value; /**< Element value */
};
/**
* Button arrangement class, a part of AutoConnectAux element.
* Placed a labeled button that can be added by user sketch.
* @param name Button name string.
* @param value Button value string.
* @param action A sting of action code, it contains a simple JavaScript code.
*/
class AutoConnectButton : public AutoConnectElement {
public:
explicit AutoConnectButton(const char* name = "", const char* value = "", const String action = String()) : AutoConnectElement(name, value), action(action) {}
const String toHTML(void) const;
String action; /**< A script for an onclick */
};
/**
* Checkbox arrangement class, a part of AutoConnectAux element.
* Place a optionally labeled input-box that can be added by user sketch.
* @param name Checkbox name string.
* @param value A string value associated with the input.
* @param label A label string that follows checkbox, optionally.
* The label is placed on the right side of the checkbox.
*/
class AutoConnectCheckbox : public AutoConnectElement {
public:
explicit AutoConnectCheckbox(const char* name = "", const char* value = "", const char* label = "", const bool checked = false) : AutoConnectElement(name, value), label(String(label)), checked(checked) {}
~AutoConnectCheckbox() {}
const String toHTML(void) const;
String label; /**< A label for a subsequent input box */
bool checked; /**< The element should be pre-selected */
};
/**
* Input-box arrangement class, a part of AutoConnectAux element.
* Place a optionally labeled input-box that can be added by user sketch.
* @param name Input-box name string.
* @param value Default value string. This string display as a placeholder by the default.
* @param label A label string that follows Input-box, optionally.
* The label is placed in front of Input-box.
*/
class AutoConnectInput : public AutoConnectElement {
public:
explicit AutoConnectInput(const char* name = "", const char* value = "", const char* label = "") : AutoConnectElement(name, value), label(String(label)) {}
~AutoConnectInput() {}
const String toHTML(void) const;
String label; /**< A label for a subsequent input box */
};
/**
* Selection-box arrangement class, A part of AutoConnectAux element.
* Place a optionally labeled Selection-box that can be added by user sketch.
* @param name Input-box name string.
* @param options String array display in a selection list.
* @param label A label string that follows Input-box, optionally.
* The label is placed in front of Input-box.
*/
class AutoConnectSelect : public AutoConnectElement {
public:
explicit AutoConnectSelect(const char* name = "", std::vector<String> options = {}, const char* label = "") : AutoConnectElement(name, ""), label(String(label)), _options(options) {}
~AutoConnectSelect() {}
const String toHTML(void) const;
void option(const String value) { _options.push_back(value); }
void empty(void) { _options.clear(); }
String label; /**< A label for a subsequent input box */
protected:
std::vector<String> _options; /**< List options array */
};
/**
* Submit button arrangement class, a part of AutoConnectAux element.
* Place a submit button with a label that can be added by user sketch.
* With the button behavior, the values of the elements contained in
* the form would be sent using the post method.
* @param name Button name string.
* @param value Sending value string.
* @param uri Sending uri string.
*/
class AutoConnectSubmit : public AutoConnectElement {
public:
explicit AutoConnectSubmit(const char* name = "", const char* value = "", const char* uri = "") : AutoConnectElement(name, value), uri(String(uri)) {}
const String toHTML(void) const;
String uri; /**< An url of submitting to */
};
/**
* Text arrangement class, a part of AutoConnectAux element.
* @param
* @param name Text name string.
* @param value Text value string.
* @param style A string of style-code for decoration, optionally.
* An arrangement text would be placed with <div> contains. A string
* of style-codes are given for '<div style=>'.
*/
class AutoConnectText : public AutoConnectElement {
public:
explicit AutoConnectText(const char* name = "", const char* value = "", const char* style = "") : AutoConnectElement(name, value), style(String(style)) {}
~AutoConnectText() {}
const String toHTML(void) const;
String style; /**< CSS style modifier native code */
};
/**
* Support declare the AutoConnectElement variable with reducing the
* arguments. These macros declare the AutoConnectElement variable
* with the same name as a "name" argument.
*/
#define ACElement(n, v) AutoConnectElements n(#n, v)
#define ACButton(n, ...) AutoConnectButton n(#n, ## __VA_ARGS__)
#define ACCheckbox(n, ...) AutoConnectCheckbox n(#n, ## __VA_ARGS__)
#define ACInput(n, ...) AutoConnectInput n(#n, ## __VA_ARGS__)
#define ACSelect(n, ...) AutoConnectSelect n(#n, ## __VA_ARGS__)
#define ACSubmit(n, ...) AutoConnectSubmit n(#n, ## __VA_ARGS__)
#define ACText(n, ...) AutoConnectText n(#n, ## __VA_ARGS__)
class AutoConnect;
// Manage placed AutoConnectElement with a vector
typedef std::vector<std::reference_wrapper<AutoConnectElement>> AutoConnectElementVT;
@ -167,6 +33,8 @@ typedef enum {
AC_EXIT_BOTH = 3
} AutoConnectExitOrder_t;
//class AutoConnect; // Reference to avoid circular
/**
* A class that handles an auxiliary page with AutoConnectElement
* that placed on it by binding it to the AutoConnect menu.
@ -188,6 +56,11 @@ class AutoConnectAux : public PageBuilder {
void menu(const bool post) { _menu = post; } /**< Set or reset the display as menu item for this aux. */
void on(const AuxHandlerFunctionT handler, const AutoConnectExitOrder_t order = AC_EXIT_AHEAD) { _handler = handler; _order = order; } /**< Set user handler */
#ifdef AUTOCONNECT_USE_JSON
AutoConnectElement& loadElement(Stream& in, const String name);
size_t saveElement(Stream& out, const AutoConnectElement& element);
#endif
protected:
void _concat(AutoConnectAux& aux);
void _join(AutoConnect& ac);
@ -196,6 +69,13 @@ class AutoConnectAux : public PageBuilder {
const String _injectTitle(PageArgument& args) { return _title; }
const String _injectMenu(PageArgument& args);
#ifdef AUTOCONNECT_USE_JSON
AutoConnectElement* _createElement(const JsonObject& json);
AutoConnectElement* _getElement(const String name);
static const ACElement_t _asElementType(const String type);
static AutoConnectElement& _nullElement(void);
#endif
String _title; /**< A title of the page */
bool _menu; /**< Switch for menu displaying */
AutoConnectElementVT _addonElm; /**< A vector set of AutoConnectElements placed on this auxiliary page */
@ -210,4 +90,4 @@ class AutoConnectAux : public PageBuilder {
friend class AutoConnect;
};
#endif // _AUTOCONNECTAUX_H_
#endif // _AUTOCONNECTAUX_H_

@ -0,0 +1,103 @@
/**
* Predefined AutoConnect configuration parameters.
* @file AutoConnectDefs.h
* @author hieromon@gmail.com
* @version 0.9.7
* @date 2018-11-17
* @copyright MIT license.
*/
#ifndef _AUTOCONNECTDEFS_H_
#define _AUTOCONNECTDEFS_H_
// Uncomment the following AC_DEBUG to enable debug output.
#define AC_DEBUG
// Debug output destination can be defined externally with AC_DEBUG_PORT
#ifndef AC_DEBUG_PORT
#define AC_DEBUG_PORT Serial
#endif // !AC_DEBUG_PORT
#ifdef AC_DEBUG
#define AC_DBG(...) do {AC_DEBUG_PORT.print("[AC] "); AC_DEBUG_PORT.printf( __VA_ARGS__ );} while (0)
#else
#define AC_DBG(...)
#endif // !AC_DEBUG
// Indicator to specify that AutoConnectAux handles elements with JSON.
#define AUTOCONNECT_USE_JSON
// Predefined parameters
// SSID that Captive portal started.
#ifndef AUTOCONNECT_APID
#if defined(ARDUINO_ARCH_ESP8266)
#define AUTOCONNECT_APID "esp8266ap"
#elif defined(ARDUINO_ARCH_ESP32)
#define AUTOCONNECT_APID "esp32ap"
#endif // !ARDUINO_ARCH_ESP8266
#endif // !AUTOCONNECT_APID
// Password that Captive portal started.
#ifndef AUTOCONNECT_PSK
#define AUTOCONNECT_PSK "12345678"
#endif // !AUTOCONNECT_PSK
#ifndef AUTOCONNECT_AP_IP
#define AUTOCONNECT_AP_IP 0x01F4A8C0 //*< 192.168.244.1 */
#endif // !AUTOCONNECT_AP_IP
#ifndef AUTOCONNECT_AP_GW
#define AUTOCONNECT_AP_GW 0x01F4A8C0 //*< 192.168.244.1 */
#endif // !AUTOCONNECT_AP_GW
#ifndef AUTOCONNECT_AP_NM
#define AUTOCONNECT_AP_NM 0x00FFFFFF //*< 255.255.255.0 */
#endif // !AUTOCONNECT_AP_NM
// AutoConnect menu root path
#ifndef AUTOCONNECT_URI
#define AUTOCONNECT_URI "/_ac"
#endif // !AUTOCONNECT_URI
// Root URI of home path prepared by user sketch
#ifndef AUTOCONNECT_HOMEURI
#define AUTOCONNECT_HOMEURI "/"
#endif // !AUTOCONNECT_HOMEURI
// AutoConnect menu title
#ifndef AUTOCONNECT_MENU_TITLE
#define AUTOCONNECT_MENU_TITLE "AutoConnect"
#endif // !AUTOCONNECT_MENU_TITLE
#define AUTOCONNECT_MENU_TITLE_CONNETED "Connected"
// URIs of AutoConnect menu collection
#define AUTOCONNECT_URI_CONFIG AUTOCONNECT_URI "/config"
#define AUTOCONNECT_URI_CONNECT AUTOCONNECT_URI "/connect"
#define AUTOCONNECT_URI_RESULT AUTOCONNECT_URI "/result"
#define AUTOCONNECT_URI_OPEN AUTOCONNECT_URI "/open"
#define AUTOCONNECT_URI_DISCON AUTOCONNECT_URI "/disc"
#define AUTOCONNECT_URI_RESET AUTOCONNECT_URI "/reset"
#define AUTOCONNECT_URI_SUCCESS AUTOCONNECT_URI "/success"
#define AUTOCONNECT_URI_FAIL AUTOCONNECT_URI "/fail"
// Time-out limitation when AutoConnect::begin
#ifndef AUTOCONNECT_TIMEOUT
#define AUTOCONNECT_TIMEOUT 30000
#endif // !AUTOCONNECT_TIMEOUT
// Advance wait time
#ifndef AUTOCONNECT_STARTUPTIME
#define AUTOCONNECT_STARTUPTIME 10
#endif // !AUTOCONNECT_STARTUPTIME
// Default HTTP port
#ifndef AUTOCONNECT_HTTPPORT
#define AUTOCONNECT_HTTPPORT 80
#endif // !AUTOCONNECT_HTTPPORT
// DNS port
#ifndef AUTOCONNECT_DNSPORT
#define AUTOCONNECT_DNSPORT 53
#endif // !AUTOCONNECT_DNSPORT
// Explicitly avoiding unused warning with token handler of PageBuilder
#define AC_UNUSED(expr) do { (void)(expr); } while (0)
#endif // _AUTOCONNECTDEFS_H_

@ -0,0 +1,49 @@
/**
* Alias declarations for an accessible the AutoConnectElement class.
* @file AutoConnectAux.h
* @author hieromon@gmail.com
* @version 0.9.7
* @date 2018-11-17
* @copyright MIT license.
*/
#ifndef _AUTOCONNECTELEMENT_H_
#define _AUTOCONENCTELEMENT_H_
#include "AutoConnectElementBasis.h"
//#include "AutoConnectElementBasisImpl.h"
#ifdef AUTOCONNECT_USE_JSON
#include <ArduinoJson.h>
#include "AutoConnectElementJson.h"
//#include "AutoConnectElementJsonImpl.h"
using AutoConnectElement = AutoConnectElementJson;
using AutoConnectButton = AutoConnectButtonJson;
using AutoConnectCheckbox = AutoConnectCheckboxJson;
using AutoConnectInput = AutoConnectInputJson;
using AutoConnectSelect = AutoConnectSelectJson;
using AutoConnectSubmit = AutoConnectSubmitJson;
using AutoConnectText = AutoConnectTextJson;
#else
using AutoConnectElement = AutoConnectElementBasis;
using AutoConnectButton = AutoConnectButtonBasis;
using AutoConnectCheckbox = AutoConnectCheckboxBasis;
using AutoConnectInput = AutoConnectInputBasis;
using AutoConnectSelect = AutoConnectSelectBasis;
using AutoConnectSubmit = AutoConnectSubmitBasis;
using AutoConnectText = AutoConnectTextBasis;
#endif
/**
* Support declare the AutoConnectElement variable with reducing the
* arguments. These macros declare the AutoConnectElement variable
* with the same name as a "name" argument.
*/
#define ACElement(n, v) AutoConnectElement n(#n, v)
#define ACButton(n, ...) AutoConnectButton n(#n, ##__VA_ARGS__)
#define ACCheckbox(n, ...) AutoConnectCheckbox n(#n, ##__VA_ARGS__)
#define ACInput(n, ...) AutoConnectInput n(#n, ##__VA_ARGS__)
#define ACSelect(n, ...) AutoConnectSelect n(#n, ##__VA_ARGS__)
#define ACSubmit(n, ...) AutoConnectSubmit n(#n, ##__VA_ARGS__)
#define ACText(n, ...) AutoConnectText n(#n, ##__VA_ARGS__)
#endif // _AUTOCONNECTELEMENT_H_

@ -0,0 +1,170 @@
/**
* Declaration of AutoConnectElement basic class.
* @file AutoConnectElementBasis.h
* @author hieromon@gmail.com
* @version 0.9.7
* @date 2018-11-17
* @copyright MIT license.
*/
#ifndef _AUTOCONNECTELEMENTBASIS_H_
#define _AUTOCONNECTELEMENTBASIS_H_
#include <vector>
#include <memory>
typedef enum {
AC_Button,
AC_Checkbox,
AC_Element,
AC_Input,
AC_Select,
AC_Submit,
AC_Text,
AC_Unknown
} ACElement_t; /**< AutoConnectElement class type */
/**
* AutoConnectAux element base.
* Placed a raw text that can be added by user sketch.
* @param name A name string for the element.
* @param value A raw text to be placed in HTML.
*/
class AutoConnectElementBasis {
public:
explicit AutoConnectElementBasis(const char* name = "", const char* value = "") : name(String(name)), value(String(value)) {
_type = AC_Element;
}
virtual ~AutoConnectElementBasis() {}
virtual const String toHTML(void) const { return value; }
const ACElement_t typeOf(void) const { return _type; }
String name; /**< Element name */
String value; /**< Element value */
protected:
ACElement_t _type; /**< Element type identifier */
};
/**
* Button arrangement class, a part of AutoConnectAux element.
* Place a labeled button that can be added by user sketch.
* @param name Button element name string.
* @param value Value string with the placed button.
* @param action Script code to execute with the button pushed.
*/
class AutoConnectButtonBasis : virtual public AutoConnectElementBasis {
public:
explicit AutoConnectButtonBasis(const char* name = "", const char* value = "", const String action = String()) : AutoConnectElementBasis(name, value), action(action) {
_type = AC_Button;
}
~AutoConnectButtonBasis() {}
const String toHTML(void) const;
String action;
};
/**
* Checkbox arrangement class, a part of AutoConnectAux element.
* Place a optionally labeled input-box that can be added by user sketch.
* @param name Checkbox name string.
* @param value A string value associated with the input.
* @param label A label string that follows checkbox, optionally.
* The label is placed on the right side of the checkbox.
*/
class AutoConnectCheckboxBasis : virtual public AutoConnectElementBasis {
public:
explicit AutoConnectCheckboxBasis(const char* name = "", const char* value = "", const char* label = "", const bool checked = false) : AutoConnectElementBasis(name, value), label(String(label)), checked(checked) {
_type = AC_Checkbox;
}
virtual ~AutoConnectCheckboxBasis() {}
const String toHTML(void) const;
String label; /**< A label for a subsequent input box */
bool checked; /**< The element should be pre-selected */
};
/**
* Input-box arrangement class, a part of AutoConnectAux element.
* Place a optionally labeled input-box that can be added by user sketch.
* @param name Input-box name string.
* @param value Default value string. This string display as a placeholder by the default.
* @param label A label string that follows Input-box, optionally.
* The label is placed in front of Input-box.
*/
class AutoConnectInputBasis : virtual public AutoConnectElementBasis {
public:
explicit AutoConnectInputBasis(const char* name = "", const char* value = "", const char* label = "") : AutoConnectElementBasis(name, value), label(String(label)) {
_type = AC_Input;
}
virtual ~AutoConnectInputBasis() {}
const String toHTML(void) const;
String label; /**< A label for a subsequent input box */
};
/**
* Selection-box arrangement class, A part of AutoConnectAux element.
* Place a optionally labeled Selection-box that can be added by user sketch.
* @param name Input-box name string.
* @param options String array display in a selection list.
* @param label A label string that follows Input-box, optionally.
* The label is placed in front of Input-box.
*/
class AutoConnectSelectBasis : virtual public AutoConnectElementBasis {
public:
explicit AutoConnectSelectBasis(const char* name = "", std::vector<String> options = {}, const char* label = "") : AutoConnectElementBasis(name, ""), label(String(label)), _options(options) {
_type = AC_Select;
}
virtual ~AutoConnectSelectBasis() {}
const String toHTML(void) const;
void option(const String value) { _options.push_back(value); }
void empty(void) { _options.clear(); }
String label; /**< A label for a subsequent input box */
protected:
std::vector<String> _options; /**< List options array */
};
/**
* Submit button arrangement class, a part of AutoConnectAux element.
* Place a submit button with a label that can be added by user sketch.
* With the button behavior, the values of the elements contained in
* the form would be sent using the post method.
* @param name Button name string.
* @param value Sending value string.
* @param uri Sending uri string.
*/
class AutoConnectSubmitBasis : virtual public AutoConnectElementBasis {
public:
explicit AutoConnectSubmitBasis(const char* name = "", const char* value = "", const char* uri = "") : AutoConnectElementBasis(name, value), uri(String(uri)) {
_type = AC_Submit;
}
virtual ~AutoConnectSubmitBasis() {}
const String toHTML(void) const;
String uri; /**< An url of submitting to */
};
/**
* Text arrangement class, a part of AutoConnectAux element.
* @param
* @param name Text name string.
* @param value Text value string.
* @param style A string of style-code for decoration, optionally.
* An arrangement text would be placed with <div> contains. A string
* of style-codes are given for '<div style=>'.
*/
class AutoConnectTextBasis : virtual public AutoConnectElementBasis {
public:
explicit AutoConnectTextBasis(const char* name = "", const char* value = "", const char* style = "") : AutoConnectElementBasis(name, value), style(String(style)) {
_type = AC_Text;
}
virtual ~AutoConnectTextBasis() {}
const String toHTML(void) const;
String style; /**< CSS style modifier native code */
};
#endif // _AUTOCONNECTELEMENTBASIS_H_

@ -0,0 +1,107 @@
/**
* Implementation of AutoConnectElementBasis classes.
* @file AutoConnectElementImpl.h
* @author hieromon@gmail.com
* @version 0.9.7
* @date 2018-11-17
* @copyright MIT license.
*/
#ifndef _AUTOCONNECTELEMENTBASISIMPL_H_
#define _AUTOCONNECTELEMENTBASISIMPL_H_
#include "AutoConnectElementBasis.h"
/**
* Generate an HTML <button> element. The onclick behavior depends on
* the code held in factionf member.
* @return An HTML string.
*/
const String AutoConnectButtonBasis::toHTML(void) const {
return String(FPSTR("<button type=\"button\" name=\"")) + name + String(FPSTR("\" value=\"")) + value + String(FPSTR("\" onclick=\"")) + action + String("\">") + value + String(FPSTR("</button>"));
}
/**
* Generate an HTML <input type=checkbox> element.
* A "value" is associated with the input tag and sent by the form
* action as the value of "name". If the label member is contained, it
* is placed to the right side of the checkbox to be labeled.
* f the label member is empty, only the checkbox is placed.
* @return An HTML string.
*/
const String AutoConnectCheckboxBasis::toHTML(void) const {
String html;
html = String(FPSTR("<input type=\"checkbox\" name=\"")) + name + String(FPSTR("\" value=\"")) + value + String("\"");
if (checked)
html += String(FPSTR(" checked"));
if (label.length())
html += String(" id=\"") + name + String("\"><label for=\"") + name + String("\">") + label + String(FPSTR("</label"));
html += String(FPSTR("><br>"));
return html;
}
/**
* Generate an HTML <input type=text> element.
* If the value member is contained, it is reflected in the placeholder
* attribute. The entered value can be obtained using the user callback
* function registered by AutoConnectAux::on after the form is sent in
* combination with AutoConnectSubmit.
* @return String an HTML string.
*/
const String AutoConnectInputBasis::toHTML(void) const {
String html = String();
if (label.length())
html = String(FPSTR("<label for=\"")) + name + String("\">") + label + String(FPSTR("</label>"));
html += String(FPSTR("<input type=\"text\" id=\"")) + name + String(FPSTR("\" name=\"")) + name;
if (value.length())
html += String(FPSTR("\" placeholder=\"")) + value;
html += String(FPSTR("\"><br>"));
return html;
}
/**
* Generate an HTML <select> element with an <option> element.
* The attribute value of the <option> element is given to the
* AutoConnectSelect class as a string array, which would be stored
* in the 'options' member. If a label member is contained, the <label>
* element would be generated the preface of <select>.
* @return String an HTML string.
*/
const String AutoConnectSelectBasis::toHTML(void) const {
String html = String();
if (label.length())
html = String(FPSTR("<label>")) + label + String(FPSTR("</label>"));
html += String(FPSTR("<select name=\"")) + name + String("\">");
std::size_t n = _options.size();
if (n) {
for (std::size_t n = 0; n < _options.size(); n++)
html += String(FPSTR("<option value=\"")) + _options[n] + "\">" + _options[n] + String(FPSTR("</option>"));
}
html += String(FPSTR("</select><br>"));
return html;
}
/**
* Generate an HTML <input type=button> element. This element is used
* for form submission. An 'onclick' attribute calls fixed JavaScript
* code as 'sa' named and it's included in the template.
* @return String an HTML string.
*/
const String AutoConnectSubmitBasis::toHTML(void) const {
return String(FPSTR("<input type=\"button\" name=\"")) + name + String(FPSTR("\" value=\"")) + value + String(FPSTR("\" onclick=\"_sa('")) + uri + String("')\">");
}
/**
* Generate an HTML text element from a string of the value member. If a style
* exists, it gives a style attribute.
* @return String an HTML string.
*/
const String AutoConnectTextBasis::toHTML(void) const {
return String(FPSTR("<div style=\"")) + style + String("\">") + value + String(FPSTR("</div>"));
}
#endif // _AUTOCONNECTELEMENTBASISIMPL_H_

@ -0,0 +1,173 @@
/**
* Declaration of AutoConnectElement extended classes using JSON.
* @file AutoConnectElementJson.h
* @author hieromon@gmail.com
* @version 0.9.7
* @date 2018-11-17
* @copyright MIT license.
*/
#ifndef _AUTOCONNECTELEMENTJSON_H_
#define _AUTOCONNECTELEMENTJSON_H_
#include "AutoConnectElementBasis.h"
#include <ArduinoJson.h>
#define AUTOCONNECT_JSON_KEY_AUX "aux"
#define AUTOCONNECT_JSON_KEY_ELEMENT "element"
#define AUTOCONNECT_JSON_KEY_ACTION "action"
#define AUTOCONNECT_JSON_KEY_CHECKED "checked"
#define AUTOCONNECT_JSON_KEY_LABEL "label"
#define AUTOCONNECT_JSON_KEY_NAME "name"
#define AUTOCONNECT_JSON_KEY_OPTIONS "options"
#define AUTOCONNECT_JSON_KEY_STYLE "style"
#define AUTOCONNECT_JSON_KEY_TYPE "type"
#define AUTOCONNECT_JSON_KEY_URI "uri"
#define AUTOCONNECT_JSON_KEY_VALUE "value"
#define AUTOCONNECT_JSON_TYPE_ACBUTTON "ACButton"
#define AUTOCONNECT_JSON_TYPE_ACCHECKBOX "ACCheckBox"
#define AUTOCONNECT_JSON_TYPE_ACELEMENT "ACElement"
#define AUTOCONNECT_JSON_TYPE_ACINPUT "ACInput"
#define AUTOCONNECT_JSON_TYPE_ACSELECT "ACSelect"
#define AUTOCONNECT_JSON_TYPE_ACSUBMIT "ACSubmit"
#define AUTOCONNECT_JSON_TYPE_ACTEXT "ACText"
/**
* AutoConnectAux element base with handling with JSON object.
* Placed a raw text that can be added by user sketch.
* @param name A name string for the element.
* @param value A raw text to be placed in HTML.
*/
class AutoConnectElementJson : virtual public AutoConnectElementBasis {
public:
explicit AutoConnectElementJson(const char* name = "", const char* value = "") {
AutoConnectElementBasis::name = name;
AutoConnectElementBasis::value = value;
}
~AutoConnectElementJson() {}
virtual bool loadElement(const JsonObject& json);
protected:
void _setElement(const JsonObject& json);
};
/**
* Button arrangement class, a part of AutoConnectAux element with
* handling JSON object.
* Place a labeled button that can be added by user sketch.
* @param name Button element name string.
* @param value Value string with the placed button.
* @param action Script code to execute with the button pushed.
*/
class AutoConnectButtonJson : public AutoConnectElementJson, public AutoConnectButtonBasis {
public:
explicit AutoConnectButtonJson(const char* name = "", const char* value = "", const String action = String()) {
AutoConnectButtonBasis::name = name;
AutoConnectButtonBasis::value = value;
AutoConnectButtonBasis::action = action;
}
~AutoConnectButtonJson() {}
bool loadElement(const JsonObject& json);
};
/**
* Checkbox arrangement class, a part of AutoConnectAux element with
* handling JSON object.
* Place a optionally labeled input-box that can be added by user sketch.
* @param name Checkbox name string.
* @param value A string value associated with the input.
* @param label A label string that follows checkbox, optionally.
* The label is placed on the right side of the checkbox.
*/
class AutoConnectCheckboxJson : public AutoConnectElementJson, public AutoConnectCheckboxBasis {
public:
explicit AutoConnectCheckboxJson(const char* name = "", const char* value = "", const char* label = "", const bool checked = false) {
AutoConnectCheckboxBasis::name = name;
AutoConnectCheckboxBasis::value = value;
AutoConnectCheckboxBasis::label = label;
AutoConnectCheckboxBasis::checked = checked;
}
~AutoConnectCheckboxJson() {}
bool loadElement(const JsonObject& json);
};
/**
* Input-box arrangement class, a part of AutoConnectAux element with
* handling JSON object.
* Place a optionally labeled input-box that can be added by user sketch.
* @param name Input-box name string.
* @param value Default value string. This string display as a placeholder by the default.
* @param label A label string that follows Input-box, optionally.
* The label is placed in front of Input-box.
*/
class AutoConnectInputJson : public AutoConnectElementJson, public AutoConnectInputBasis {
public:
explicit AutoConnectInputJson(const char* name = "", const char* value = "", const char* label = "") {
AutoConnectInputBasis::name = name;
AutoConnectInputBasis::value = value;
AutoConnectInputBasis::label = label;
}
~AutoConnectInputJson() {}
bool loadElement(const JsonObject& json);
};
/**
* Selection-box arrangement class, A part of AutoConnectAux element.
* Place a optionally labeled Selection-box that can be added by user sketch.
* @param name Input-box name string.
* @param options String array display in a selection list.
* @param label A label string that follows Input-box, optionally.
* The label is placed in front of Input-box.
*/
class AutoConnectSelectJson : public AutoConnectElementJson, public AutoConnectSelectBasis {
public:
explicit AutoConnectSelectJson(const char* name = "", std::vector<String> options = {}, const char* label = "") {
AutoConnectSelectBasis::name = name;
AutoConnectSelectBasis::_options = options;
AutoConnectSelectBasis::label = label;
}
~AutoConnectSelectJson() {}
bool loadElement(const JsonObject& json);
};
/**
* Submit button arrangement class, a part of AutoConnectAux element.
* Place a submit button with a label that can be added by user sketch.
* With the button behavior, the values of the elements contained in
* the form would be sent using the post method.
* @param name Button name string.
* @param value Sending value string.
* @param uri Sending uri string.
*/
class AutoConnectSubmitJson : public AutoConnectElementJson, public AutoConnectSubmitBasis {
public:
explicit AutoConnectSubmitJson(const char* name = "", const char* value = "", const char* uri = "") {
AutoConnectSubmitBasis::name = name;
AutoConnectSubmitBasis::value = value;
AutoConnectSubmitBasis::uri = uri;
}
~AutoConnectSubmitJson() {}
bool loadElement(const JsonObject& json);
};
/**
* Text arrangement class, a part of AutoConnectAux element.
* @param
* @param name Text name string.
* @param value Text value string.
* @param style A string of style-code for decoration, optionally.
* An arrangement text would be placed with <div> contains. A string
* of style-codes are given for '<div style=>'.
*/
class AutoConnectTextJson : public AutoConnectElementJson, public AutoConnectTextBasis {
public:
explicit AutoConnectTextJson(const char* name = "", const char* value = "", const char* style = "") {
AutoConnectTextBasis::name = name;
AutoConnectTextBasis::value = value;
AutoConnectTextBasis::style = style;
}
~AutoConnectTextJson() {}
bool loadElement(const JsonObject& json);
};
#endif // _AUTOCONNECTELEMENTJSON_H_

@ -0,0 +1,140 @@
/**
* Implementation of AutoConnectElementJson classes.
* @file AutoConnectElementImpl.h
* @author hieromon@gmail.com
* @version 0.9.7
* @date 2018-11-17
* @copyright MIT license.
*/
#ifndef _AUTOCONNECTELEMENTJSONIMPL_H_
#define _AUTOCONNECTELEMENTJSONIMPL_H_
#include "AutoConnectElementJson.h"
/**
* Set items common to any type of AutoConnectElement from JSON objects.
* @param json A JSON object with the definition of AutoConnectElement.
*/
void AutoConnectElementJson::_setElement(const JsonObject& json) {
name = json.get<String>(F(AUTOCONNECT_JSON_KEY_NAME));
value = json.get<String>(F(AUTOCONNECT_JSON_KEY_VALUE));
}
/**
* Load an element member value from the JSON object.
* @param json A JSON object with the definition of AutoConnectElement.
* @return true AutoConnectElement loaded
* @return false Type of AutoConnectElement is mismatched.
*/
bool AutoConnectElementJson::loadElement(const JsonObject& json) {
String type = json.get<String>(F(AUTOCONNECT_JSON_KEY_TYPE));
if (type.equalsIgnoreCase(F(AUTOCONNECT_JSON_TYPE_ACELEMENT))) {
_setElement(json);
return true;
}
return false;
}
/**
* Load a button element attribute member from the JSON object.
* @param json A JSON object with the definition of AutoConnectElement.
* @return true AutoConnectElement loaded
* @return false Type of AutoConnectElement is mismatched.
*/
bool AutoConnectButtonJson::loadElement(const JsonObject& json) {
String type = json.get<String>(F(AUTOCONNECT_JSON_KEY_TYPE));
if (type.equalsIgnoreCase(F(AUTOCONNECT_JSON_TYPE_ACBUTTON))) {
_setElement(json);
action = json.get<String>(F(AUTOCONNECT_JSON_KEY_ACTION));
return true;
}
return false;
}
/**
* Load a checkbox element attribute member from the JSON object.
* @param json A JSON object with the definition of AutoConnectElement.
* @return true AutoConnectElement loaded
* @return false Type of AutoConnectElement is mismatched.
*/
bool AutoConnectCheckboxJson::loadElement(const JsonObject& json) {
String type = json.get<String>(F(AUTOCONNECT_JSON_KEY_TYPE));
if (type.equalsIgnoreCase(F(AUTOCONNECT_JSON_TYPE_ACCHECKBOX))) {
_setElement(json);
label = json.get<String>(F(AUTOCONNECT_JSON_KEY_LABEL));
checked = json.get<bool>(F(AUTOCONNECT_JSON_KEY_CHECKED));
return true;
}
return false;
}
/**
* Load a input-box element attribute member from the JSON object.
* @param json A JSON object with the definition of AutoConnectElement.
* @return true AutoConnectElement loaded
* @return false Type of AutoConnectElement is mismatched.
*/
bool AutoConnectInputJson::loadElement(const JsonObject& json) {
String type = json.get<String>(F(AUTOCONNECT_JSON_KEY_TYPE));
if (type.equalsIgnoreCase(F(AUTOCONNECT_JSON_TYPE_ACINPUT))) {
_setElement(json);
label = json.get<String>(F(AUTOCONNECT_JSON_KEY_LABEL));
return true;
}
return false;
}
/**
* Load a select element attribute member from the JSON object.
* @param json A JSON object with the definition of AutoConnectElement.
* @return true AutoConnectElement loaded
* @return false Type of AutoConnectElement is mismatched.
*/
bool AutoConnectSelectJson::loadElement(const JsonObject& json) {
String type = json.get<String>(F(AUTOCONNECT_JSON_KEY_TYPE));
if (type.equalsIgnoreCase(F(AUTOCONNECT_JSON_TYPE_ACSELECT))) {
_setElement(json);
empty();
label = json.get<String>(F(AUTOCONNECT_JSON_KEY_LABEL));
JsonArray& optionArray = json[AUTOCONNECT_JSON_KEY_OPTIONS];
for (auto value : optionArray)
option(value.as<String>());
return true;
}
return false;
}
/**
* Load a submit element attribute member from the JSON object.
* @param json A JSON object with the definition of AutoConnectElement.
* @return true AutoConnectElement loaded
* @return false Type of AutoConnectElement is mismatched.
*/
bool AutoConnectSubmitJson::loadElement(const JsonObject& json) {
String type = json.get<String>(F(AUTOCONNECT_JSON_KEY_TYPE));
if (type.equalsIgnoreCase(F(AUTOCONNECT_JSON_TYPE_ACSUBMIT))) {
_setElement(json);
uri = json.get<String>(F(AUTOCONNECT_JSON_KEY_URI));
return true;
}
return false;
}
/**
* Load a text element attribute member from the JSON object.
* @param json A JSON object with the definition of AutoConnectElement.
* @return true AutoConnectElement loaded
* @return false Type of AutoConnectElement is mismatched.
*/
bool AutoConnectTextJson::loadElement(const JsonObject& json) {
String type = json.get<String>(F(AUTOCONNECT_JSON_KEY_TYPE));
if (type.equalsIgnoreCase(F(AUTOCONNECT_JSON_TYPE_ACTEXT))) {
_setElement(json);
style = json.get<String>(F(AUTOCONNECT_JSON_KEY_STYLE));
return true;
}
return false;
}
#endif // _AUTOCONNECTELEMENTJSONIMPL_H_
Loading…
Cancel
Save