Fixed memory leaking

pull/41/head
Hieromon Ikasamo 6 years ago
parent ea7cb298ae
commit 661f4c3463
  1. 33
      examples/mqttRSSI/mqttRSSI.ino
  2. 8
      examples/mqttRSSI_FS/data/mqtt_setting.json
  3. 27
      examples/mqttRSSI_FS/data/param.json
  4. 2
      examples/mqttRSSI_FS/mqttRSSI_FS.ino
  5. 4
      src/AutoConnect.cpp
  6. 6
      src/AutoConnectAux.cpp
  7. 3
      src/AutoConnectDefs.h
  8. 2
      src/AutoConnectElement.h
  9. 27
      src/AutoConnectElementBasis.h
  10. 60
      src/AutoConnectElementBasisImpl.h
  11. 3
      src/AutoConnectElementJson.h
  12. 4
      src/AutoConnectElementJsonImpl.h

@ -57,6 +57,7 @@ static const char AUX_mqtt_setting[] PROGMEM = R"raw(
{ {
"name": "mqttserver", "name": "mqttserver",
"type": "ACInput", "type": "ACInput",
"value": "",
"placeholder": "MQTT broker server", "placeholder": "MQTT broker server",
"label": "Server" "label": "Server"
}, },
@ -75,13 +76,26 @@ static const char AUX_mqtt_setting[] PROGMEM = R"raw(
"type": "ACInput", "type": "ACInput",
"label": "API Key" "label": "API Key"
}, },
{
"name": "newline",
"type": "ACElement",
"value": "<hr>"
},
{
"name": "uniqueid",
"type": "ACCheckbox",
"value": "unique",
"label": "Use APID unique",
"checked": false
},
{ {
"name": "period", "name": "period",
"type": "ACRadio", "type": "ACRadio",
"label": "Update period", "label": "Update period",
"value": [ "value": [
"30 sec.", "30 sec.",
"60 sec." "60 sec.",
"180 sec."
], ],
"arrange": "vertical", "arrange": "vertical",
"checked": 1 "checked": 1
@ -91,13 +105,6 @@ static const char AUX_mqtt_setting[] PROGMEM = R"raw(
"type": "ACElement", "type": "ACElement",
"value": "<hr>" "value": "<hr>"
}, },
{
"name": "uniqueid",
"type": "ACCheckbox",
"value": "unique",
"label": "Use APID unique",
"checked": true
},
{ {
"name": "hostname", "name": "hostname",
"type": "ACInput", "type": "ACInput",
@ -223,10 +230,10 @@ String loadParams(AutoConnectAux& aux, PageArgument& args) {
SPIFFS.begin(); SPIFFS.begin();
File param = SPIFFS.open(PARAM_FILE, "r"); File param = SPIFFS.open(PARAM_FILE, "r");
if (param) { if (param) {
// if (aux.loadElement(param)) if (aux.loadElement(param))
// Serial.println(PARAM_FILE " loaded"); Serial.println(PARAM_FILE " loaded");
// else else
// Serial.println(PARAM_FILE " failed to load"); Serial.println(PARAM_FILE " failed to load");
param.close(); param.close();
} }
else else
@ -341,9 +348,11 @@ void setup() {
AutoConnectInput& hostnameElm = setting->getElement<AutoConnectInput>("hostname"); AutoConnectInput& hostnameElm = setting->getElement<AutoConnectInput>("hostname");
if (uniqueidElm.checked) { if (uniqueidElm.checked) {
config.apid = String("ESP") + "_" + String(ESP.getChipId(), HEX); config.apid = String("ESP") + "_" + String(ESP.getChipId(), HEX);
Serial.println("apid set to " + config.apid);
} }
if (hostnameElm.value.length()) { if (hostnameElm.value.length()) {
config.hostName = hostnameElm.value; config.hostName = hostnameElm.value;
Serial.println("hostname set to " + config.hostName);
} }
config.bootUri = AC_ONBOOTURI_HOME; config.bootUri = AC_ONBOOTURI_HOME;
config.homeUri = "/"; config.homeUri = "/";

@ -18,14 +18,14 @@
{ {
"name": "mqttserver", "name": "mqttserver",
"type": "ACInput", "type": "ACInput",
"value": "mqtt.thingspeak.com", "value": "",
"placeholder": "MQTT broker server", "placeholder": "MQTT broker server",
"label": "Server" "label": "Server"
}, },
{ {
"name": "channelid", "name": "channelid",
"type": "ACInput", "type": "ACInput",
"value": "454951", "value": "",
"label": "Channel ID" "label": "Channel ID"
}, },
{ {
@ -37,7 +37,7 @@
{ {
"name": "apikey", "name": "apikey",
"type": "ACInput", "type": "ACInput",
"value": "HBVQ2XV6VYBI4582", "value": "",
"label": "API Key" "label": "API Key"
}, },
{ {
@ -62,7 +62,7 @@
"type": "ACCheckbox", "type": "ACCheckbox",
"value": "unique", "value": "unique",
"label": "Use APID unique", "label": "Use APID unique",
"checked": true "checked": false
}, },
{ {
"name": "hostname", "name": "hostname",

@ -0,0 +1,27 @@
[
{
"name": "mqttserver",
"type": "ACInput",
"value": "mqtt.thingspeak.com",
"placeholder": "MQTT broker server",
"label": "Server"
},
{
"name": "channelid",
"type": "ACInput",
"value": "454951",
"label": "Channel ID"
},
{
"name": "userkey",
"type": "ACInput",
"value": "NRTFYGJ6TJFGX4RC",
"label": "User Key"
},
{
"name": "apikey",
"type": "ACInput",
"value": "HBVQ2XV6VYBI4582",
"label": "API Key"
}
]

@ -236,9 +236,11 @@ void setup() {
AutoConnectInput& hostnameElm = setting->getElement<AutoConnectInput>("hostname"); AutoConnectInput& hostnameElm = setting->getElement<AutoConnectInput>("hostname");
if (uniqueidElm.checked) { if (uniqueidElm.checked) {
config.apid = String("ESP") + "_" + String(ESP.getChipId(), HEX); config.apid = String("ESP") + "_" + String(ESP.getChipId(), HEX);
Serial.println("apid set to " + config.apid);
} }
if (hostnameElm.value.length()) { if (hostnameElm.value.length()) {
config.hostName = hostnameElm.value; config.hostName = hostnameElm.value;
Serial.println("hostname set to " + config.hostName);
} }
config.bootUri = AC_ONBOOTURI_HOME; config.bootUri = AC_ONBOOTURI_HOME;
config.homeUri = "/"; config.homeUri = "/";

@ -662,9 +662,9 @@ bool AutoConnect::_classifyHandle(HTTPMethod method, String uri) {
// If the current request argument contains AutoConnectElement, it is // If the current request argument contains AutoConnectElement, it is
// the form data of the AutoConnectAux page and with this timing save // the form data of the AutoConnectAux page and with this timing save
// the value of each element. // the value of each element.
if (_webServer->hasArg(String(AUTOCONNECT_AUXURI_PARAM))) { if (_webServer->hasArg(AUTOCONNECT_AUXURI_PARAM)) {
String auxUri = _webServer->arg(AUTOCONNECT_AUXURI_PARAM); String auxUri = _webServer->arg(AUTOCONNECT_AUXURI_PARAM);
auxUri.replace(String("&#47;"), String("/")); auxUri.replace("&#47;", "/");
AutoConnectAux* aux = _aux.get(); AutoConnectAux* aux = _aux.get();
while (aux) { while (aux) {
if (aux->_uriStr == auxUri) { if (aux->_uriStr == auxUri) {

@ -263,7 +263,7 @@ const String AutoConnectAux::_injectMenu(PageArgument& args) {
const String AutoConnectAux::_indicateUri(PageArgument& args) { const String AutoConnectAux::_indicateUri(PageArgument& args) {
AC_UNUSED(args); AC_UNUSED(args);
String lastUri = _uriStr; String lastUri = _uriStr;
lastUri.replace(String("/"), String("&#47;")); lastUri.replace("/", "&#47;");
return lastUri; return lastUri;
} }
@ -1118,8 +1118,8 @@ size_t AutoConnectAux::_resultJsonBufferSize() {
return -1; return -1;
} }
else { else {
AC_DBG("json buffer size:%d\n", _jbSize + _jbByte + 200); AC_DBG("json buffer size:%d\n", _jbSize + _jbByte);
return static_cast<size_t>(_jbSize + _jbByte + 200); return static_cast<size_t>(_jbSize + _jbByte);
} }
} }

@ -11,7 +11,7 @@
#define _AUTOCONNECTDEFS_H_ #define _AUTOCONNECTDEFS_H_
// Uncomment the following AC_DEBUG to enable debug output. // Uncomment the following AC_DEBUG to enable debug output.
#define AC_DEBUG //#define AC_DEBUG
// Debug output destination can be defined externally with AC_DEBUG_PORT // Debug output destination can be defined externally with AC_DEBUG_PORT
#ifndef AC_DEBUG_PORT #ifndef AC_DEBUG_PORT
@ -22,6 +22,7 @@
#define AC_DBG(...) do {AC_DEBUG_PORT.print("[AC] "); AC_DEBUG_PORT.printf( __VA_ARGS__ );} while (0) #define AC_DBG(...) do {AC_DEBUG_PORT.print("[AC] "); AC_DEBUG_PORT.printf( __VA_ARGS__ );} while (0)
#else #else
#define AC_DBG(...) #define AC_DBG(...)
#define AC_DBG_DUMB(...)
#endif // !AC_DEBUG #endif // !AC_DEBUG
// Indicator to specify that AutoConnectAux handles elements with JSON. // Indicator to specify that AutoConnectAux handles elements with JSON.

@ -22,7 +22,7 @@ using AutoConnectRadio = AutoConnectRadioJson;
using AutoConnectSelect = AutoConnectSelectJson; using AutoConnectSelect = AutoConnectSelectJson;
using AutoConnectSubmit = AutoConnectSubmitJson; using AutoConnectSubmit = AutoConnectSubmitJson;
using AutoConnectText = AutoConnectTextJson; using AutoConnectText = AutoConnectTextJson;
#define AUTOCONNECT_JSON_BUFFER_SIZE 3000 #define AUTOCONNECT_JSON_BUFFER_SIZE 512
#else #else
using AutoConnectElement = AutoConnectElementBasis; using AutoConnectElement = AutoConnectElementBasis;
using AutoConnectButton = AutoConnectButtonBasis; using AutoConnectButton = AutoConnectButtonBasis;

@ -3,7 +3,7 @@
* @file AutoConnectElementBasis.h * @file AutoConnectElementBasis.h
* @author hieromon@gmail.com * @author hieromon@gmail.com
* @version 0.9.7 * @version 0.9.7
* @date 2018-11-17 * @date 2018-12-29
* @copyright MIT license. * @copyright MIT license.
*/ */
@ -121,23 +121,15 @@ class AutoConnectInputBasis : virtual public AutoConnectElementBasis {
class AutoConnectRadioBasis : virtual public AutoConnectElementBasis { class AutoConnectRadioBasis : virtual public AutoConnectElementBasis {
public: public:
explicit AutoConnectRadioBasis(const char* name = "", std::vector<String> const& values = {}, const char* label = "", const ACArrange_t order = AC_Vertical, const uint8_t checked = 0) : AutoConnectElementBasis(name, ""), label(label), order(order), checked(checked), _values(values) { explicit AutoConnectRadioBasis(const char* name = "", std::vector<String> const& values = {}, const char* label = "", const ACArrange_t order = AC_Vertical, const uint8_t checked = 0) : AutoConnectElementBasis(name, ""), label(label), order(order), checked(checked), _values(values) {
_type = AC_Radio; _type = AC_Radio;
// _values = values;
// for (String v : values) {
// add(v);
// const std::string sv = v.c_str();
// _values.push_back(sv);
// }
} }
virtual ~AutoConnectRadioBasis() {} virtual ~AutoConnectRadioBasis() {}
const String toHTML(void) const override; const String toHTML(void) const override;
void add(const String& value) { _values.push_back(value); } const String& operator [] (const std::size_t n) const { return at(n); }
//void add(const String& value) { void add(const String& value) { _values.push_back(String(value)); }
// std::string sv = value.c_str(); const String& at(const std::size_t n) const { return _values.at(n); }
// _values.push_back(sv);
//}
void empty(const size_t reserve = 0) { _values.reserve(reserve); _values.clear(); std::vector<String>().swap(_values); }
void check(const String& value); void check(const String& value);
void empty(const size_t reserve = 0);
String label; /**< A label for a subsequent radio buttons */ String label; /**< A label for a subsequent radio buttons */
ACArrange_t order; /**< layout order */ ACArrange_t order; /**< layout order */
@ -145,7 +137,6 @@ class AutoConnectRadioBasis : virtual public AutoConnectElementBasis {
protected: protected:
std::vector<String> _values; /**< Items in a group */ std::vector<String> _values; /**< Items in a group */
// std::vector<std::string> _values; /**< Items in a group */
}; };
/** /**
@ -163,8 +154,10 @@ class AutoConnectSelectBasis : virtual public AutoConnectElementBasis {
} }
virtual ~AutoConnectSelectBasis() {} virtual ~AutoConnectSelectBasis() {}
const String toHTML(void) const override; const String toHTML(void) const override;
void add(const String& option) { _options.push_back(option); } const String& operator [] (const std::size_t n) const { return at(n); }
void empty(const size_t reserve = 0) { _options.reserve(reserve); _options.clear(); std::vector<String>().swap(_options); } void add(const String& option) { _options.push_back(String(option)); }
const String& at(const std::size_t n) const { return _options.at(n); }
void empty(const size_t reserve = 0);
String label; /**< A label for a subsequent input box */ String label; /**< A label for a subsequent input box */

@ -3,7 +3,7 @@
* @file AutoConnectElementImpl.h * @file AutoConnectElementImpl.h
* @author hieromon@gmail.com * @author hieromon@gmail.com
* @version 0.9.7 * @version 0.9.7
* @date 2018-11-17 * @date 2018-12-29
* @copyright MIT license. * @copyright MIT license.
*/ */
@ -64,12 +64,38 @@ const String AutoConnectInputBasis::toHTML(void) const {
return html; return html;
} }
/**
* Indicate an entry with the specified value in the value's collection.
* @param value The value to indicates in the collection.
*/
void AutoConnectRadioBasis::check(const String& value) {
for (std::size_t n = 0; n < _values.size(); n++) {
if (at(n).equalsIgnoreCase(value)) {
checked = n + 1;
break;
}
}
}
/**
* Clear value items of AutoConnetRadio and reallocate new storage.
* All hold items are released.
* @param reserve If 'reserve' is greater than 0, this function
* allocates new holding storage with the value.
*/
void AutoConnectRadioBasis::empty(const size_t reserve) {
_values.clear();
std::vector<String>().swap(_values);
if (reserve)
_values.reserve(reserve);
}
/** /**
* Generate an HTML <input type=radio> element with an <option> element. * Generate an HTML <input type=radio> element with an <option> element.
* @return String an HTML string. * @return String an HTML string.
*/ */
const String AutoConnectRadioBasis::toHTML(void) const { const String AutoConnectRadioBasis::toHTML(void) const {
String html = String(); String html = "";
if (label.length()) { if (label.length()) {
html = label; html = label;
@ -77,12 +103,12 @@ const String AutoConnectRadioBasis::toHTML(void) const {
html += String("<br>"); html += String("<br>");
} }
for (std::size_t n = 0; n < _values.size(); n++) { for (std::size_t n = 0; n < _values.size(); n++) {
// String value = _values[n]; String value = at(n);
String value = String(_values[n].c_str()); String id = name + "_" + String(n);
html += String(FPSTR("<input type=\"radio\" name=\"")) + name + String(FPSTR("\" id=\"")) + value + String(FPSTR("\" value=\"")) + value + String("\""); html += String(FPSTR("<input type=\"radio\" name=\"")) + name + String(FPSTR("\" id=\"")) + id + String(FPSTR("\" value=\"")) + value + String("\"");
if (n == checked - 1) if (n == checked - 1)
html += String(FPSTR(" checked")); html += String(FPSTR(" checked"));
html += String(FPSTR("><label for=\"")) + value + String("\">") + value + String(FPSTR("</label>")); html += String(FPSTR("><label for=\"")) + id + String("\">") + value + String(FPSTR("</label>"));
if (order == AC_Vertical) if (order == AC_Vertical)
html += String("<br>"); html += String("<br>");
} }
@ -90,18 +116,16 @@ const String AutoConnectRadioBasis::toHTML(void) const {
} }
/** /**
* Indicate an entry with the specified value in the value's collection. * Clear option items of AutoConnetSelect and reallocate new storage.
* @param value The value to indicates in the collection. * All hold items are released.
* @param reserve If 'reserve' is greater than 0, this function
* allocates new holding storage with the value.
*/ */
void AutoConnectRadioBasis::check(const String& value) { void AutoConnectSelectBasis::empty(const size_t reserve) {
for (std::size_t n = 0; n < _values.size(); n++) { _options.clear();
// String& v = _values[n]; std::vector<String>().swap(_options);
String v = String(_values[n].c_str()); if (reserve)
if (v.equalsIgnoreCase(value)) { _options.reserve(reserve);
checked = n + 1;
break;
}
}
} }
/** /**
@ -113,7 +137,7 @@ void AutoConnectRadioBasis::check(const String& value) {
* @return String an HTML string. * @return String an HTML string.
*/ */
const String AutoConnectSelectBasis::toHTML(void) const { const String AutoConnectSelectBasis::toHTML(void) const {
String html = String(); String html = "";
if (label.length()) if (label.length())
html = String(FPSTR("<label for=\"")) + name + String("\">") + label + String(FPSTR("</label>")); html = String(FPSTR("<label for=\"")) + name + String("\">") + label + String(FPSTR("</label>"));

@ -143,9 +143,6 @@ class AutoConnectRadioJson : public AutoConnectElementJson, public AutoConnectRa
AutoConnectRadioBasis::label = label; AutoConnectRadioBasis::label = label;
AutoConnectRadioBasis::order = order; AutoConnectRadioBasis::order = order;
AutoConnectRadioBasis::checked = checked; AutoConnectRadioBasis::checked = checked;
//for (String v : values) {
// AutoConnectRadioBasis::add(v);
//}
} }
~AutoConnectRadioJson() {} ~AutoConnectRadioJson() {}
const size_t getObjectSize(void) const override; const size_t getObjectSize(void) const override;

@ -216,10 +216,6 @@ void AutoConnectRadioJson::serialize(JsonObject& json) {
json.set(F(AUTOCONNECT_JSON_KEY_TYPE), F(AUTOCONNECT_JSON_TYPE_ACRADIO)); json.set(F(AUTOCONNECT_JSON_KEY_TYPE), F(AUTOCONNECT_JSON_TYPE_ACRADIO));
json.set(F(AUTOCONNECT_JSON_KEY_LABEL), label); json.set(F(AUTOCONNECT_JSON_KEY_LABEL), label);
JsonArray& values = json.createNestedArray(F(AUTOCONNECT_JSON_KEY_VALUE)); JsonArray& values = json.createNestedArray(F(AUTOCONNECT_JSON_KEY_VALUE));
//for (std::string& v : _values) {
// String s = String(v.c_str());
// values.add(s);
//}
for (String v : _values) for (String v : _values)
values.add(v); values.add(v);
switch (order) { switch (order) {

Loading…
Cancel
Save