wifimgr.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. #include "wifimgr.h"
  2. fs::SPIFFSFS& FlashFS = SPIFFS;
  3. #define CONFIG_FILE "/config.json"
  4. const char hostname[] = "esp32";
  5. std::vector<String> const& config_elements = { "HOSTNAME", "OSC_TARGET_IP", "OSC_TARGET_PORT", "OSC_INPUT_PORT"} ;
  6. static const char PAGE_CONFIG[] PROGMEM = R"(
  7. {
  8. "uri": "/config",
  9. "title": "Sensor Configuration",
  10. "menu": true,
  11. "element": [
  12. {
  13. "name": "tablecss",
  14. "type": "ACStyle",
  15. "value": "table{font-family:arial,sans-serif;border-collapse:collapse;width:100%;color:black;}td,th{border:1px solid #dddddd;text-align:center;padding:8px;}tr:nth-child(even){background-color:#dddddd;}"
  16. },
  17. {
  18. "name": "hr",
  19. "type": "ACElement",
  20. "value": "<hr style=\"height:1px;border-width:0;color:gray;background-color:#52a6ed\">",
  21. "posterior": "par"
  22. },
  23. {
  24. "name": "HOSTNAME",
  25. "type": "ACInput",
  26. "label": "Hostname",
  27. "placeholder": "This area accepts hostname patterns",
  28. "pattern": "^(([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])$"
  29. },
  30. {
  31. "name": "OSC_SECTION_TEXT",
  32. "type": "ACText",
  33. "value": "OSC CONFIGURATION",
  34. "style": "font-family:Arial;font-size:18px;font-weight:400;color:#191970"
  35. },
  36. {
  37. "name": "OSC_TARGET_IP",
  38. "type": "ACInput",
  39. "label": "OSC target IP",
  40. "placeholder": "This area accepts IP patterns"
  41. },
  42. {
  43. "name": "OSC_TARGET_PORT",
  44. "type": "ACInput",
  45. "label": "OSC target port",
  46. "value": "",
  47. "apply": "number",
  48. "pattern": "\\d*"
  49. },
  50. {
  51. "name": "OSC_INPUT_PORT",
  52. "type": "ACInput",
  53. "label": "OSC input port",
  54. "value": "",
  55. "apply": "number",
  56. "pattern": "\\d*"
  57. },
  58. {
  59. "name": "hr2",
  60. "type": "ACElement",
  61. "value": "<hr style=\"height:1px;border-width:0;color:gray;background-color:#52a6ed\">",
  62. "posterior": "par"
  63. },
  64. {
  65. "name": "save",
  66. "type": "ACSubmit",
  67. "value": "Save",
  68. "uri": "/save"
  69. },
  70. {
  71. "name": "adjust_width",
  72. "type": "ACElement",
  73. "value": "<script type=\"text/javascript\">window.onload=function(){var t=document.querySelectorAll(\"input[type='text']\");for(i=0;i<t.length;i++){var e=t[i].getAttribute(\"placeholder\");e&&t[i].setAttribute(\"size\",e.length*.8)}};</script>"
  74. }
  75. ]
  76. }
  77. )";
  78. static const char PAGE_SAVE[] PROGMEM = R"(
  79. {
  80. "uri": "/save",
  81. "title": "Elements",
  82. "menu": false,
  83. "element": [
  84. {
  85. "name": "caption",
  86. "type": "ACText",
  87. "format": "Elements have been saved to %s",
  88. "style": "font-family:Arial;font-size:18px;font-weight:400;color:#191970"
  89. },
  90. {
  91. "name": "validated",
  92. "type": "ACText",
  93. "style": "color:red"
  94. },
  95. {
  96. "name": "echo",
  97. "type": "ACText",
  98. "style": "font-family:monospace;font-size:small;white-space:pre;"
  99. },
  100. {
  101. "name": "ok",
  102. "type": "ACSubmit",
  103. "value": "Apply",
  104. "uri": "/reset"
  105. }
  106. ]
  107. }
  108. )";
  109. WebServerClass server;
  110. AutoConnect portal(server);
  111. AutoConnectConfig config;
  112. AutoConnectAux configAux;
  113. AutoConnectAux saveAux;
  114. ///////////////////////// SETUP //////////////////////////////////
  115. void setup_wifimgr(void) {
  116. // Responder of root page handled directly from WebServer class.
  117. server.on("/", []() {
  118. String content = "<head> <meta http-equiv=\"refresh\" content=\"0; URL=/config\" /></head>";
  119. content += AUTOCONNECT_LINK(COG_24);
  120. server.send(200, "text/html", content);
  121. });
  122. server.on("/reset", []() {
  123. String content = "<head> <meta http-equiv=\"refresh\" content=\"15; URL=/config\" /></head>";
  124. content += "waiting 15s for sensor to reboot";
  125. server.send(200, "text/html", content);
  126. delay(100);
  127. ESP.restart();
  128. });
  129. // Load a custom web page described in JSON as PAGE_ELEMENT and
  130. // register a handler. This handler will be invoked from
  131. // AutoConnectSubmit named the Load defined on the same page.
  132. configAux.load(FPSTR(PAGE_CONFIG));
  133. configAux.on([] (AutoConnectAux& aux, PageArgument& arg) {
  134. if (portal.where() == "/config") {
  135. // Use the AutoConnect::where function to identify the referer.
  136. // Since this handler only supports AutoConnectSubmit called the
  137. // Load, it uses the uri of the custom web page placed to
  138. // determine whether the Load was called me or not.
  139. FlashFS.begin();
  140. File param = FlashFS.open(CONFIG_FILE, "r");
  141. if (param) {
  142. aux.loadElement(param, config_elements );
  143. param.close();
  144. }
  145. FlashFS.end();
  146. }
  147. return String();
  148. });
  149. saveAux.load(FPSTR(PAGE_SAVE));
  150. saveAux.on([] (AutoConnectAux& aux, PageArgument& arg) {
  151. // You can validate input values ​​before saving with
  152. // AutoConnectInput::isValid function.
  153. // Verification is using performed regular expression set in the
  154. // pattern attribute in advance.
  155. AutoConnectInput& input = configAux["hostname"].as<AutoConnectInput>();
  156. aux["validated"].value = input.isValid() ? String() : String("Hostname data pattern missmatched.");
  157. input = configAux["OSC_TARGET_IP"].as<AutoConnectInput>();
  158. aux["validated"].value = input.isValid() ? String() : String("IP data pattern missmatched.");
  159. // The following line sets only the value, but it is HTMLified as
  160. // formatted text using the format attribute.
  161. aux["caption"].value = CONFIG_FILE;
  162. FlashFS.begin(true);
  163. File param = FlashFS.open(CONFIG_FILE, "w");
  164. if (param) {
  165. // Save as a loadable set for parameters.
  166. configAux.saveElement(param, config_elements);
  167. param.close();
  168. // Read the saved elements again to display.
  169. param = FlashFS.open(CONFIG_FILE, "r");
  170. aux["echo"].value = param.readString();
  171. param.close();
  172. }
  173. else {
  174. aux["echo"].value = "Filesystem failed to open.";
  175. }
  176. FlashFS.end();
  177. return String();
  178. });
  179. //Read config file to start with good config values
  180. FlashFS.begin();
  181. File param = FlashFS.open(CONFIG_FILE, "r");
  182. if (param) {
  183. configAux.loadElement(param, config_elements );
  184. param.close();
  185. }
  186. FlashFS.end();
  187. portal.join({ configAux, saveAux });
  188. config.autoReconnect = true ;
  189. config.auth = AC_AUTH_NONE;
  190. config.authScope = AC_AUTHSCOPE_AUX;
  191. config.ticker = true;
  192. config.hostName = hostname;
  193. portal.config(config);
  194. portal.begin();
  195. }