Update.ino 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /*
  2. Update.ino, Example for the AutoConnect library.
  3. Copyright (c) 2019, Hieromon Ikasamo
  4. https://github.com/Hieromon/AutoConnect
  5. This software is released under the MIT License.
  6. https://opensource.org/licenses/MIT
  7. This example presents the simplest OTA Updates scheme.
  8. */
  9. #if defined(ARDUINO_ARCH_ESP8266)
  10. #include <ESP8266WiFi.h>
  11. #include <ESP8266WebServer.h>
  12. using WebServerClass = ESP8266WebServer;
  13. #elif defined(ARDUINO_ARCH_ESP32)
  14. #include <WiFi.h>
  15. #include <WebServer.h>
  16. using WebServerClass = WebServer;
  17. #endif
  18. #include <AutoConnect.h>
  19. // Update server setting page
  20. static const char SETUP_PAGE[] PROGMEM = R"(
  21. {
  22. "title": "Update setup",
  23. "uri": "/setup",
  24. "menu": true,
  25. "element": [
  26. {
  27. "name": "caption",
  28. "type": "ACText",
  29. "value": "OTA update setup",
  30. "style": ""
  31. },
  32. {
  33. "name": "isvalid",
  34. "type": "ACText",
  35. "style": "color:red"
  36. },
  37. {
  38. "name": "server",
  39. "type": "ACInput",
  40. "label": "Update server",
  41. "pattern": "^((([a-zA-Z]|[a-zA-Z][a-zA-Z0-9-]*[a-zA-Z0-9]).)*([A-Za-z]|[A-Za-z][A-Za-z0-9-]*[A-Za-z0-9]))|((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3})$",
  42. "placeholder": "Your update server address"
  43. },
  44. {
  45. "name": "port",
  46. "type": "ACInput",
  47. "label": "port",
  48. "pattern": "[0-9]{1,4}"
  49. },
  50. {
  51. "name": "path",
  52. "type": "ACInput",
  53. "label": "path"
  54. },
  55. {
  56. "name": "apply",
  57. "type": "ACSubmit",
  58. "value": "Apply",
  59. "uri": "/apply"
  60. },
  61. {
  62. "name": "cancel",
  63. "type": "ACSubmit",
  64. "value": "Discard",
  65. "uri": "/"
  66. }
  67. ]
  68. }
  69. )";
  70. // The /apply handler validates the update server settings entered on
  71. // the setup page. APPLY_PAGE exists to enable the /apply handler,
  72. // and its role is a page redirector. If the /apply handler detects some
  73. // errors, the page will redirect to the /setup page with error message.
  74. static const char APPLY_PAGE[] PROGMEM = R"(
  75. {
  76. "title": "Update setup",
  77. "uri": "/apply",
  78. "menu": false,
  79. "element": [
  80. {
  81. "name": "redirect",
  82. "type": "ACElement",
  83. "value": "<script type=\"text/javascript\">location.href='__REDIRECT__';</script>"
  84. }
  85. ]
  86. }
  87. )";
  88. WebServerClass server;
  89. AutoConnect portal(server);
  90. AutoConnectAux setupPage;
  91. AutoConnectAux applyPage;
  92. AutoConnectUpdate update;
  93. #define UPDATESERVER_URL "" // Define to suit your environment
  94. #define UPDATESERVER_PORT 8000
  95. #define UPDATESERVER_PATH "bin"
  96. void loadAux() {
  97. setupPage.load(SETUP_PAGE);
  98. setupPage["server"].value = UPDATESERVER_URL;
  99. setupPage["port"].value = String(UPDATESERVER_PORT);
  100. setupPage["path"].value = UPDATESERVER_PATH;
  101. applyPage.load(APPLY_PAGE);
  102. }
  103. // The onSetup handler clears the error message field of the /setup page.
  104. // Its field will be cleared after the /setup page generating by the
  105. // effect of the AC_EXIT_LATER option.
  106. String onSetup(AutoConnectAux& aux, PageArgument& arg) {
  107. setupPage["isvalid"].value = String();
  108. return String();
  109. }
  110. // The onApply handler validates the update server configuration.
  111. // It does not do any semantic analysis but only verifies that the
  112. // settings match the pattern defined in each field.
  113. // The AutoConnectInput isValid function checks if the current value
  114. // matches the pattern.
  115. String onApply(AutoConnectAux& aux, PageArgument& arg) {
  116. String returnUri;
  117. AutoConnectInput& host = setupPage["server"].as<AutoConnectInput>();
  118. AutoConnectInput& port = setupPage["port"].as<AutoConnectInput>();
  119. AutoConnectInput& path = setupPage["path"].as<AutoConnectInput>();
  120. Serial.printf("host: %s\n", host.value.c_str());
  121. Serial.printf("port: %s\n", port.value.c_str());
  122. Serial.printf("uri: %s\n", path.value.c_str());
  123. if (host.isValid() & port.isValid()) {
  124. update.host = host.value;
  125. update.port = port.value.toInt();
  126. update.uri = path.value;
  127. setupPage["isvalid"].value = String();
  128. returnUri = "/";
  129. }
  130. else {
  131. setupPage["isvalid"].value = String("Incorrect value specified.");
  132. returnUri = "/setup";
  133. }
  134. applyPage["redirect"].value.replace("__REDIRECT__", returnUri);
  135. return String();
  136. }
  137. void setup() {
  138. delay(1000);
  139. Serial.begin(115200);
  140. Serial.println();
  141. // Responder of root page and apply page handled directly from WebServer class.
  142. server.on("/", []() {
  143. String content = R"(
  144. <!DOCTYPE html>
  145. <html>
  146. <head>
  147. <meta charset="UTF-8" name="viewport" content="width=device-width, initial-scale=1">
  148. </head>
  149. <body>
  150. Place the root page with the sketch application.&ensp;
  151. __AC_LINK__
  152. </body>
  153. </html>
  154. )";
  155. content.replace("__AC_LINK__", String(AUTOCONNECT_LINK(COG_16)));
  156. server.send(200, "text/html", content);
  157. });
  158. // AUX page loading
  159. loadAux();
  160. setupPage.on(onSetup, AC_EXIT_LATER);
  161. applyPage.on(onApply);
  162. portal.join({ setupPage, applyPage });
  163. portal.begin();
  164. update.attach(portal);
  165. }
  166. void loop() {
  167. portal.handleClient();
  168. }