HTTPServer.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. #include "HTTPServer.h"
  2. #include <Arduino.h>
  3. /// <summary>
  4. /// Constructs an HTTPServer instance with the specified port and shutter controller.
  5. /// Creates a new AsyncWebServer instance but does not start it yet.
  6. /// </summary>
  7. HTTPServer::HTTPServer(uint16_t port, IShutterController* controller)
  8. : shutterController(controller)
  9. {
  10. server = new AsyncWebServer(port);
  11. }
  12. /// <summary>
  13. /// Destructor that properly cleans up the AsyncWebServer instance.
  14. /// </summary>
  15. HTTPServer::~HTTPServer()
  16. {
  17. if (server)
  18. {
  19. delete server;
  20. }
  21. }
  22. /// <summary>
  23. /// Configures the ESP8266 as a WiFi access point with the provided credentials.
  24. /// Sets up the static IP configuration and starts the access point.
  25. /// </summary>
  26. void HTTPServer::setupWiFiAP(const char* ssid, const char* password,
  27. IPAddress local_IP, IPAddress gateway, IPAddress subnet)
  28. {
  29. if (!WiFi.softAPConfig(local_IP, gateway, subnet))
  30. {
  31. Serial.println("Failed to config IP");
  32. }
  33. WiFi.softAP(ssid, password);
  34. Serial.println(WiFi.softAPIP());
  35. Serial.println("AP Started - Waiting for connections");
  36. }
  37. /// <summary>
  38. /// Registers all HTTP API routes and their corresponding handlers.
  39. /// Associates each route with its handler method using lambda expressions.
  40. /// </summary>
  41. void HTTPServer::setupRoutes()
  42. {
  43. // Focus endpoint
  44. server->on("/api/focus", HTTP_GET, [this](AsyncWebServerRequest *request) {
  45. handleFocus(request);
  46. });
  47. // Take photo endpoint
  48. server->on("/api/takePhoto", HTTP_GET, [this](AsyncWebServerRequest *request) {
  49. handleTakePhoto(request);
  50. });
  51. // Reset endpoint
  52. server->on("/api/reset", HTTP_GET, [this](AsyncWebServerRequest *request) {
  53. handleReset(request);
  54. });
  55. // Multiple shoot endpoint
  56. server->on("/api/multiple", HTTP_GET, [this](AsyncWebServerRequest *request) {
  57. handleMultiple(request);
  58. });
  59. // Health check endpoint
  60. server->on("/get", HTTP_GET, [this](AsyncWebServerRequest *request) {
  61. handleHealthCheck(request);
  62. });
  63. }
  64. /// <summary>
  65. /// Handles GET /api/focus request to perform a half press (focus) operation.
  66. /// Logs the request, activates the camera focus, and responds with success.
  67. /// </summary>
  68. void HTTPServer::handleFocus(AsyncWebServerRequest *request)
  69. {
  70. onRequestStart("api/focus");
  71. shutterController->halfPress();
  72. onRequestEnd("api/focus");
  73. request->send(200, "application/json", "{\"result\":\"true\"}");
  74. }
  75. /// <summary>
  76. /// Handles GET /api/takePhoto request to take a photograph.
  77. /// Supports optional "msec" query parameter to control the shutter hold duration (default: 1000ms).
  78. /// </summary>
  79. void HTTPServer::handleTakePhoto(AsyncWebServerRequest *request)
  80. {
  81. onRequestStart("api/takePhoto");
  82. if (request->hasParam("msec"))
  83. {
  84. int ms = request->getParam("msec")->value().toInt();
  85. shutterController->pressFullWithDelay(ms);
  86. }
  87. else
  88. {
  89. shutterController->pressFullWithDelay(1000);
  90. }
  91. onRequestEnd("api/takePhoto");
  92. request->send(200, "application/json", "{\"result\":\"true\"}");
  93. }
  94. /// <summary>
  95. /// Handles GET /api/reset request to release the shutter and return to neutral position.
  96. /// Logs the request, releases all controls, and responds with success.
  97. /// </summary>
  98. void HTTPServer::handleReset(AsyncWebServerRequest *request)
  99. {
  100. onRequestStart("api/reset");
  101. shutterController->unPress();
  102. onRequestEnd("api/reset");
  103. request->send(200, "application/json", "{\"result\":\"true\"}");
  104. }
  105. /// <summary>
  106. /// Handles GET /api/multiple request to take multiple photos in sequence.
  107. /// Requires query parameters: "count" (number of photos) and "delay" (ms between shots).
  108. /// Supports optional "msec" parameter for individual shot duration (default: 1000ms).
  109. /// </summary>
  110. void HTTPServer::handleMultiple(AsyncWebServerRequest *request)
  111. {
  112. onRequestStart("api/multiple");
  113. if (request->hasParam("count") && request->hasParam("delay"))
  114. {
  115. int ms = 1000;
  116. int count = request->getParam("count")->value().toInt();
  117. int delayMs = request->getParam("delay")->value().toInt();
  118. if (request->hasParam("msec"))
  119. {
  120. ms = request->getParam("msec")->value().toInt();
  121. }
  122. shutterController->multipleShoot(ms, count, delayMs);
  123. }
  124. onRequestEnd("api/multiple");
  125. request->send(200, "application/json", "{\"result\":\"true\"}");
  126. }
  127. /// <summary>
  128. /// Handles GET /get request as a simple health check endpoint.
  129. /// Returns a plain text "Is working" response to verify server connectivity.
  130. /// </summary>
  131. void HTTPServer::handleHealthCheck(AsyncWebServerRequest *request)
  132. {
  133. onRequestStart("get");
  134. onRequestEnd("get");
  135. request->send(200, "text/plain", "Is working");
  136. }
  137. /// <summary>
  138. /// Logs the start of a request to the serial console and enables the status LED.
  139. /// Called at the beginning of each request handler.
  140. /// </summary>
  141. /// <param name="endpoint">The name of the API endpoint being processed</param>
  142. void HTTPServer::onRequestStart(const char* endpoint)
  143. {
  144. Serial.print("[REQUEST] ");
  145. Serial.println(endpoint);
  146. digitalWrite(LED_BUILTIN, HIGH);
  147. }
  148. /// <summary>
  149. /// Logs the completion of a request to the serial console and disables the status LED.
  150. /// Called at the end of each request handler.
  151. /// </summary>
  152. /// <param name="endpoint">The name of the API endpoint that was processed</param>
  153. void HTTPServer::onRequestEnd(const char* endpoint)
  154. {
  155. digitalWrite(LED_BUILTIN, LOW);
  156. Serial.print("[RESPONSE] ");
  157. Serial.println(endpoint);
  158. }
  159. /// <summary>
  160. /// Initializes the WiFi access point and starts the HTTP server.
  161. /// Must be called during application setup to enable the server.
  162. /// Calls setupWiFiAP() to configure WiFi, setupRoutes() to register endpoints, and starts the server.
  163. /// </summary>
  164. void HTTPServer::begin(const char* ssid, const char* password,
  165. IPAddress local_IP, IPAddress gateway, IPAddress subnet)
  166. {
  167. setupWiFiAP(ssid, password, local_IP, gateway, subnet);
  168. setupRoutes();
  169. server->begin();
  170. Serial.println("HTTP Server started");
  171. }