server_camera.cpp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. #include "server_camera.h"
  2. #include <string>
  3. #include "string.h"
  4. #include "esp_camera.h"
  5. #include "ClassControllCamera.h"
  6. #include "MainFlowControl.h"
  7. #include "ClassLogFile.h"
  8. #include "esp_log.h"
  9. #include "basic_auth.h"
  10. #include "../../include/defines.h"
  11. static const char *TAG = "server_cam";
  12. void PowerResetCamera()
  13. {
  14. // Use reset only if pin is available
  15. if (CAM_PIN_PWDN == GPIO_NUM_NC)
  16. {
  17. LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "No power down pin availbale to reset camera");
  18. }
  19. else
  20. {
  21. ESP_LOGD(TAG, "Resetting camera by power down line");
  22. gpio_config_t conf = {
  23. .pin_bit_mask = 1LL << CAM_PIN_PWDN,
  24. .mode = GPIO_MODE_OUTPUT,
  25. .pull_up_en = GPIO_PULLUP_DISABLE,
  26. .pull_down_en = GPIO_PULLDOWN_DISABLE,
  27. .intr_type = GPIO_INTR_DISABLE,
  28. };
  29. gpio_config(&conf);
  30. // carefull, logic is inverted compared to reset pin
  31. ESP_LOGD(TAG, "Camera power down");
  32. gpio_set_level(CAM_PIN_PWDN, 1);
  33. vTaskDelay(pdMS_TO_TICKS(1000));
  34. ESP_LOGD(TAG, "Camera power up");
  35. gpio_set_level(CAM_PIN_PWDN, 0);
  36. vTaskDelay(pdMS_TO_TICKS(1000));
  37. }
  38. }
  39. esp_err_t handler_lightOn(httpd_req_t *req)
  40. {
  41. #ifdef DEBUG_DETAIL_ON
  42. LogFile.WriteHeapInfo("handler_lightOn - Start");
  43. ESP_LOGD(TAG, "handler_lightOn uri: %s", req->uri);
  44. #endif
  45. if (Camera.getCameraInitSuccessful())
  46. {
  47. Camera.LightOnOff(true);
  48. const char *resp_str = (const char *)req->user_ctx;
  49. httpd_resp_send(req, resp_str, strlen(resp_str));
  50. }
  51. else
  52. {
  53. httpd_resp_send_err(req, HTTPD_403_FORBIDDEN, "Camera not initialized: REST API /lighton not available!");
  54. return ESP_ERR_NOT_FOUND;
  55. }
  56. #ifdef DEBUG_DETAIL_ON
  57. LogFile.WriteHeapInfo("handler_lightOn - Done");
  58. #endif
  59. return ESP_OK;
  60. }
  61. esp_err_t handler_lightOff(httpd_req_t *req)
  62. {
  63. #ifdef DEBUG_DETAIL_ON
  64. LogFile.WriteHeapInfo("handler_lightOff - Start");
  65. ESP_LOGD(TAG, "handler_lightOff uri: %s", req->uri);
  66. #endif
  67. if (Camera.getCameraInitSuccessful())
  68. {
  69. Camera.LightOnOff(false);
  70. const char *resp_str = (const char *)req->user_ctx;
  71. httpd_resp_send(req, resp_str, strlen(resp_str));
  72. }
  73. else
  74. {
  75. httpd_resp_send_err(req, HTTPD_403_FORBIDDEN, "Camera not initialized: REST API /lightoff not available!");
  76. return ESP_ERR_NOT_FOUND;
  77. }
  78. #ifdef DEBUG_DETAIL_ON
  79. LogFile.WriteHeapInfo("handler_lightOff - Done");
  80. #endif
  81. return ESP_OK;
  82. }
  83. esp_err_t handler_capture(httpd_req_t *req)
  84. {
  85. #ifdef DEBUG_DETAIL_ON
  86. LogFile.WriteHeapInfo("handler_capture - Start");
  87. #endif
  88. if (Camera.getCameraInitSuccessful())
  89. {
  90. // If the camera settings were changed by creating a new reference image, they must be reset
  91. if (CFstatus.changedCameraSettings)
  92. {
  93. Camera.setSensorDatenFromCCstatus(); // CCstatus >>> Kamera
  94. Camera.SetQualityZoomSize(CCstatus.ImageQuality, CCstatus.ImageFrameSize, CCstatus.ImageZoomEnabled, CCstatus.ImageZoomOffsetX, CCstatus.ImageZoomOffsetY, CCstatus.ImageZoomSize, CCstatus.ImageVflip);
  95. Camera.LedIntensity = CCstatus.ImageLedIntensity;
  96. CFstatus.changedCameraSettings = false;
  97. }
  98. #ifdef DEBUG_DETAIL_ON
  99. ESP_LOGD(TAG, "Size: %d, Quality: %d", CCstatus.ImageFrameSize, CCstatus.ImageQuality);
  100. #endif
  101. esp_err_t result;
  102. result = Camera.CaptureToHTTP(req);
  103. #ifdef DEBUG_DETAIL_ON
  104. LogFile.WriteHeapInfo("handler_capture - Done");
  105. #endif
  106. return result;
  107. }
  108. else
  109. {
  110. httpd_resp_send_err(req, HTTPD_403_FORBIDDEN, "Camera not initialized: REST API /capture not available!");
  111. return ESP_ERR_NOT_FOUND;
  112. }
  113. }
  114. esp_err_t handler_capture_with_light(httpd_req_t *req)
  115. {
  116. #ifdef DEBUG_DETAIL_ON
  117. LogFile.WriteHeapInfo("handler_capture_with_light - Start");
  118. #endif
  119. if (Camera.getCameraInitSuccessful())
  120. {
  121. char _query[100];
  122. char _delay[10];
  123. int delay = 2500;
  124. if (httpd_req_get_url_query_str(req, _query, 100) == ESP_OK)
  125. {
  126. ESP_LOGD(TAG, "Query: %s", _query);
  127. if (httpd_query_key_value(_query, "delay", _delay, 10) == ESP_OK)
  128. {
  129. #ifdef DEBUG_DETAIL_ON
  130. ESP_LOGD(TAG, "Delay: %s", _delay);
  131. #endif
  132. delay = atoi(_delay);
  133. if (delay < 0)
  134. {
  135. delay = 0;
  136. }
  137. }
  138. }
  139. // If the camera settings were changed by creating a new reference image, they must be reset
  140. if (CFstatus.changedCameraSettings)
  141. {
  142. Camera.setSensorDatenFromCCstatus(); // CCstatus >>> Kamera
  143. Camera.SetQualityZoomSize(CCstatus.ImageQuality, CCstatus.ImageFrameSize, CCstatus.ImageZoomEnabled, CCstatus.ImageZoomOffsetX, CCstatus.ImageZoomOffsetY, CCstatus.ImageZoomSize, CCstatus.ImageVflip);
  144. Camera.LedIntensity = CCstatus.ImageLedIntensity;
  145. CFstatus.changedCameraSettings = false;
  146. }
  147. #ifdef DEBUG_DETAIL_ON
  148. ESP_LOGD(TAG, "Size: %d, Quality: %d", CCstatus.ImageFrameSize, CCstatus.ImageQuality);
  149. #endif
  150. Camera.LightOnOff(true);
  151. const TickType_t xDelay = delay / portTICK_PERIOD_MS;
  152. vTaskDelay(xDelay);
  153. esp_err_t result;
  154. result = Camera.CaptureToHTTP(req);
  155. Camera.LightOnOff(false);
  156. #ifdef DEBUG_DETAIL_ON
  157. LogFile.WriteHeapInfo("handler_capture_with_light - Done");
  158. #endif
  159. return result;
  160. }
  161. else
  162. {
  163. httpd_resp_send_err(req, HTTPD_403_FORBIDDEN, "Camera not initialized: REST API /capture_with_flashlight not available!");
  164. return ESP_ERR_NOT_FOUND;
  165. }
  166. }
  167. esp_err_t handler_capture_save_to_file(httpd_req_t *req)
  168. {
  169. #ifdef DEBUG_DETAIL_ON
  170. LogFile.WriteHeapInfo("handler_capture_save_to_file - Start");
  171. #endif
  172. if (Camera.getCameraInitSuccessful())
  173. {
  174. char _query[100];
  175. char _delay[10];
  176. int delay = 0;
  177. char filename[100];
  178. std::string fn = "/sdcard/";
  179. if (httpd_req_get_url_query_str(req, _query, 100) == ESP_OK)
  180. {
  181. ESP_LOGD(TAG, "Query: %s", _query);
  182. if (httpd_query_key_value(_query, "filename", filename, 100) == ESP_OK)
  183. {
  184. fn.append(filename);
  185. #ifdef DEBUG_DETAIL_ON
  186. ESP_LOGD(TAG, "Filename: %s", fn.c_str());
  187. #endif
  188. }
  189. else
  190. {
  191. fn.append("noname.jpg");
  192. }
  193. if (httpd_query_key_value(_query, "delay", _delay, 10) == ESP_OK)
  194. {
  195. #ifdef DEBUG_DETAIL_ON
  196. ESP_LOGD(TAG, "Delay: %s", _delay);
  197. #endif
  198. delay = atoi(_delay);
  199. if (delay < 0)
  200. {
  201. delay = 0;
  202. }
  203. }
  204. }
  205. else
  206. {
  207. fn.append("noname.jpg");
  208. }
  209. // If the camera settings were changed by creating a new reference image, they must be reset
  210. if (CFstatus.changedCameraSettings)
  211. {
  212. Camera.setSensorDatenFromCCstatus(); // CCstatus >>> Kamera
  213. Camera.SetQualityZoomSize(CCstatus.ImageQuality, CCstatus.ImageFrameSize, CCstatus.ImageZoomEnabled, CCstatus.ImageZoomOffsetX, CCstatus.ImageZoomOffsetY, CCstatus.ImageZoomSize, CCstatus.ImageVflip);
  214. Camera.LedIntensity = CCstatus.ImageLedIntensity;
  215. CFstatus.changedCameraSettings = false;
  216. }
  217. #ifdef DEBUG_DETAIL_ON
  218. ESP_LOGD(TAG, "Size: %d, Quality: %d", CCstatus.ImageFrameSize, CCstatus.ImageQuality);
  219. #endif
  220. esp_err_t result;
  221. result = Camera.CaptureToFile(fn, delay);
  222. const char *resp_str = (const char *)fn.c_str();
  223. httpd_resp_send(req, resp_str, strlen(resp_str));
  224. #ifdef DEBUG_DETAIL_ON
  225. LogFile.WriteHeapInfo("handler_capture_save_to_file - Done");
  226. #endif
  227. return result;
  228. }
  229. else
  230. {
  231. httpd_resp_send_err(req, HTTPD_403_FORBIDDEN, "Camera not initialized: REST API /save not available!");
  232. return ESP_ERR_NOT_FOUND;
  233. }
  234. }
  235. void register_server_camera_uri(httpd_handle_t server)
  236. {
  237. #ifdef DEBUG_DETAIL_ON
  238. ESP_LOGI(TAG, "server_part_camera - Registering URI handlers");
  239. #endif
  240. httpd_uri_t camuri = {};
  241. camuri.method = HTTP_GET;
  242. camuri.uri = "/lighton";
  243. camuri.handler = APPLY_BASIC_AUTH_FILTER(handler_lightOn);
  244. camuri.user_ctx = (void *)"Light On";
  245. httpd_register_uri_handler(server, &camuri);
  246. camuri.uri = "/lightoff";
  247. camuri.handler = APPLY_BASIC_AUTH_FILTER(handler_lightOff);
  248. camuri.user_ctx = (void *)"Light Off";
  249. httpd_register_uri_handler(server, &camuri);
  250. camuri.uri = "/capture";
  251. camuri.handler = APPLY_BASIC_AUTH_FILTER(handler_capture);
  252. camuri.user_ctx = NULL;
  253. httpd_register_uri_handler(server, &camuri);
  254. camuri.uri = "/capture_with_flashlight";
  255. camuri.handler = APPLY_BASIC_AUTH_FILTER(handler_capture_with_light);
  256. camuri.user_ctx = NULL;
  257. httpd_register_uri_handler(server, &camuri);
  258. camuri.uri = "/save";
  259. camuri.handler = APPLY_BASIC_AUTH_FILTER(handler_capture_save_to_file);
  260. camuri.user_ctx = NULL;
  261. httpd_register_uri_handler(server, &camuri);
  262. }