2020-10-04 01:49:08 +08:00
# include <WiFi.h>
2020-11-01 07:24:05 +08:00
# include <WiFiClient.h>
# include <esp_bt.h>
# include <esp_wifi.h>
# include <esp_sleep.h>
# include <driver/rtc_io.h>
# include "myconfig.h"
# include "esp_camera.h"
# include "camera_pins.h"
# include <AsyncTCP.h>
# include <ESPAsyncWebServer.h>
# include <Update.h>
# include "src/html/firmware.h"
# include "src/html/index_ov2640.h"
# include "src/html/index_ov3660.h"
# include "src/html/index_simple.h"
# include "src/html/css.h"
2020-09-30 21:41:42 +08:00
# include "src/favicons.h"
2020-10-07 08:08:18 +08:00
# include "src/logo.h"
2020-09-27 21:21:44 +08:00
# include "storage.h"
2019-11-15 00:01:37 +08:00
2020-09-09 08:57:37 +08:00
// Functions from the main .ino
2020-09-22 18:03:18 +08:00
extern void flashLED ( int flashtime ) ;
extern void setLamp ( int newVal ) ;
2020-11-01 07:24:05 +08:00
extern void resetWiFiConfig ( ) ;
2020-09-09 08:57:37 +08:00
2020-10-12 00:19:22 +08:00
// External variables declared in the main .ino
2020-11-01 07:24:05 +08:00
extern char camera_name [ ] ;
2020-10-04 01:49:08 +08:00
extern char myVer [ ] ;
2020-10-12 19:17:21 +08:00
extern char baseVersion [ ] ;
2020-11-01 07:24:05 +08:00
extern IPAddress espIP ;
extern IPAddress espSubnet ;
extern IPAddress espGateway ;
2020-10-07 18:19:19 +08:00
extern char streamURL [ ] ;
2020-10-07 21:43:28 +08:00
extern char default_index [ ] ;
2020-10-04 01:49:08 +08:00
extern int myRotation ;
extern int lampVal ;
extern bool filesystem ;
2020-10-12 00:19:22 +08:00
extern bool debugData ;
2020-10-04 01:49:08 +08:00
extern int sketchSize ;
extern int sketchSpace ;
extern String sketchMD5 ;
2019-11-18 09:43:07 +08:00
2019-11-15 00:01:37 +08:00
# include "fb_gfx.h"
# include "fd_forward.h"
# include "fr_forward.h"
2020-11-01 07:24:05 +08:00
# if !defined(HTTP_PORT)
# define HTTP_PORT 80
# endif
int httpPort = HTTP_PORT ;
char httpURL [ 64 ] = { " Undefined " } ;
AsyncWebServer appServer ( httpPort ) ;
bool updating ;
void appServerCB ( void * pvParameters ) ;
size_t jpg_encode_stream ( void * arg , size_t index , const void * data , size_t len ) ;
void capture_handler ( AsyncWebServerRequest * request ) ;
void cmd_handler ( AsyncWebServerRequest * request ) ;
void status_handler ( AsyncWebServerRequest * request ) ;
void favicon_16x16_handler ( AsyncWebServerRequest * request ) ;
void favicon_32x32_handler ( AsyncWebServerRequest * request ) ;
void favicon_ico_handler ( AsyncWebServerRequest * request ) ;
void logo_svg_handler ( AsyncWebServerRequest * request ) ;
void dump_handler ( AsyncWebServerRequest * request ) ;
void style_handler ( AsyncWebServerRequest * request ) ;
void handleIndex ( AsyncWebServerRequest * request ) ;
void handleFirmware ( AsyncWebServerRequest * request ) ;
void handleCameraClient ( ) ;
void startCameraServer ( ) ;
2019-11-15 00:01:37 +08:00
2020-10-26 00:38:29 +08:00
# define PART_BOUNDARY "123456789000000000000987654321";
2019-11-15 00:01:37 +08:00
2020-11-01 07:24:05 +08:00
void capture_handler ( AsyncWebServerRequest * request )
2020-10-26 00:38:29 +08:00
{
camera_fb_t * fb = NULL ;
2020-10-12 00:19:22 +08:00
Serial . println ( " Capture Requested " ) ;
2019-11-19 09:50:01 +08:00
flashLED ( 75 ) ; // little flash of status LED
2019-11-15 00:01:37 +08:00
int64_t fr_start = esp_timer_get_time ( ) ;
fb = esp_camera_fb_get ( ) ;
2020-10-26 00:38:29 +08:00
if ( ! fb )
{
2019-11-15 00:01:37 +08:00
Serial . println ( " Camera capture failed " ) ;
2020-11-01 07:24:05 +08:00
request - > send ( 500 , " text/plain " , " Camera Capture Failed " ) ;
return ;
2019-11-15 00:01:37 +08:00
}
2020-11-01 07:24:05 +08:00
size_t fb_len = 0 ;
if ( fb - > format = = PIXFORMAT_JPEG )
2020-10-26 00:38:29 +08:00
{
2020-11-01 07:24:05 +08:00
fb_len = fb - > len ;
request - > send ( 200 , " image/jpeg " , ( const char * ) fb - > buf ) ;
2019-11-15 00:01:37 +08:00
}
2020-11-01 07:24:05 +08:00
else
2020-10-26 00:38:29 +08:00
{
2020-11-01 07:24:05 +08:00
request - > send ( 500 , " text/plain " , " Camera Capture Failed " ) ;
2019-11-15 00:01:37 +08:00
}
esp_camera_fb_return ( fb ) ;
int64_t fr_end = esp_timer_get_time ( ) ;
2020-11-01 07:24:05 +08:00
Serial . printf ( " JPG: %uB %ums \r \n " , ( uint32_t ) ( fb_len ) , ( uint32_t ) ( ( fr_end - fr_start ) / 1000 ) ) ;
2019-11-15 00:01:37 +08:00
}
2020-11-01 07:24:05 +08:00
void cmd_handler ( AsyncWebServerRequest * request )
2020-10-26 00:38:29 +08:00
{
2020-11-01 07:24:05 +08:00
Serial . println ( " Command received! " ) ;
2020-09-27 21:21:44 +08:00
flashLED ( 75 ) ;
2019-11-15 00:01:37 +08:00
2020-11-01 07:24:05 +08:00
if ( ! request - > hasArg ( " var " ) | | ! request - > hasArg ( " val " ) )
2020-10-26 00:38:29 +08:00
{
2020-11-01 07:24:05 +08:00
Serial . println ( " No var or val " ) ;
request - > send ( 404 , " text/plain " , " Invalid parameters " ) ;
return ;
2019-11-15 00:01:37 +08:00
}
2020-09-29 02:32:12 +08:00
2020-11-01 07:24:05 +08:00
String variable = request - > arg ( " var " ) . c_str ( ) ;
String value = request - > arg ( " val " ) . c_str ( ) ;
Serial . print ( " Var " ) ;
Serial . println ( variable ) ;
int val = atoi ( value . c_str ( ) ) ;
2020-10-26 00:38:29 +08:00
sensor_t * s = esp_camera_sensor_get ( ) ;
2019-11-15 00:01:37 +08:00
int res = 0 ;
2020-11-01 07:24:05 +08:00
if ( variable . compareTo ( " framesize " ) = = 0 )
2020-10-26 00:38:29 +08:00
{
if ( s - > pixformat = = PIXFORMAT_JPEG )
res = s - > set_framesize ( s , ( framesize_t ) val ) ;
}
2020-11-01 07:24:05 +08:00
else if ( variable . compareTo ( " quality " ) = = 0 )
2020-10-26 00:38:29 +08:00
res = s - > set_quality ( s , val ) ;
2020-11-01 07:24:05 +08:00
else if ( variable . compareTo ( " contrast " ) = = 0 )
2020-10-26 00:38:29 +08:00
res = s - > set_contrast ( s , val ) ;
2020-11-01 07:24:05 +08:00
else if ( variable . compareTo ( " brightness " ) = = 0 )
2020-10-26 00:38:29 +08:00
res = s - > set_brightness ( s , val ) ;
2020-11-01 07:24:05 +08:00
else if ( variable . compareTo ( " saturation " ) = = 0 )
2020-10-26 00:38:29 +08:00
res = s - > set_saturation ( s , val ) ;
2020-11-01 07:24:05 +08:00
else if ( variable . compareTo ( " gainceiling " ) = = 0 )
2020-10-26 00:38:29 +08:00
res = s - > set_gainceiling ( s , ( gainceiling_t ) val ) ;
2020-11-01 07:24:05 +08:00
else if ( variable . compareTo ( " colorbar " ) = = 0 )
2020-10-26 00:38:29 +08:00
res = s - > set_colorbar ( s , val ) ;
2020-11-01 07:24:05 +08:00
else if ( variable . compareTo ( " awb " ) = = 0 )
2020-10-26 00:38:29 +08:00
res = s - > set_whitebal ( s , val ) ;
2020-11-01 07:24:05 +08:00
else if ( variable . compareTo ( " agc " ) = = 0 )
2020-10-26 00:38:29 +08:00
res = s - > set_gain_ctrl ( s , val ) ;
2020-11-01 07:24:05 +08:00
else if ( variable . compareTo ( " aec " ) = = 0 )
2020-10-26 00:38:29 +08:00
res = s - > set_exposure_ctrl ( s , val ) ;
2020-11-01 07:24:05 +08:00
else if ( variable . compareTo ( " hmirror " ) = = 0 )
2020-10-26 00:38:29 +08:00
res = s - > set_hmirror ( s , val ) ;
2020-11-01 07:24:05 +08:00
else if ( variable . compareTo ( " vFlip " ) = = 0 )
2020-10-26 00:38:29 +08:00
res = s - > set_vflip ( s , val ) ;
2020-11-01 07:24:05 +08:00
else if ( variable . compareTo ( " awb_gain " ) = = 0 )
2020-10-26 00:38:29 +08:00
res = s - > set_awb_gain ( s , val ) ;
2020-11-01 07:24:05 +08:00
else if ( variable . compareTo ( " agc_gain " ) = = 0 )
2020-10-26 00:38:29 +08:00
res = s - > set_agc_gain ( s , val ) ;
2020-11-01 07:24:05 +08:00
else if ( variable . compareTo ( " aec_value " ) = = 0 )
2020-10-26 00:38:29 +08:00
res = s - > set_aec_value ( s , val ) ;
2020-11-01 07:24:05 +08:00
else if ( variable . compareTo ( " aec2 " ) = = 0 )
2020-10-26 00:38:29 +08:00
res = s - > set_aec2 ( s , val ) ;
2020-11-01 07:24:05 +08:00
else if ( variable . compareTo ( " dcw " ) = = 0 )
2020-10-26 00:38:29 +08:00
res = s - > set_dcw ( s , val ) ;
2020-11-01 07:24:05 +08:00
else if ( variable . compareTo ( " bpc " ) = = 0 )
2020-10-26 00:38:29 +08:00
res = s - > set_bpc ( s , val ) ;
2020-11-01 07:24:05 +08:00
else if ( variable . compareTo ( " wpc " ) = = 0 )
2020-10-26 00:38:29 +08:00
res = s - > set_wpc ( s , val ) ;
2020-11-01 07:24:05 +08:00
else if ( variable . compareTo ( " raw_gma " ) = = 0 )
2020-10-26 00:38:29 +08:00
res = s - > set_raw_gma ( s , val ) ;
2020-11-01 07:24:05 +08:00
else if ( variable . compareTo ( " lenc " ) = = 0 )
2020-10-26 00:38:29 +08:00
res = s - > set_lenc ( s , val ) ;
2020-11-01 07:24:05 +08:00
else if ( variable . compareTo ( " special_effect " ) = = 0 )
2020-10-26 00:38:29 +08:00
res = s - > set_special_effect ( s , val ) ;
2020-11-01 07:24:05 +08:00
else if ( variable . compareTo ( " wb_mode " ) = = 0 )
2020-10-26 00:38:29 +08:00
res = s - > set_wb_mode ( s , val ) ;
2020-11-01 07:24:05 +08:00
else if ( variable . compareTo ( " ae_level " ) = = 0 )
2020-10-26 00:38:29 +08:00
res = s - > set_ae_level ( s , val ) ;
2020-11-01 07:24:05 +08:00
else if ( variable . compareTo ( " rotate " ) = = 0 )
2020-10-26 00:38:29 +08:00
myRotation = val ;
2020-11-01 07:24:05 +08:00
else if ( variable . compareTo ( " lamp " ) = = 0 )
2020-10-26 00:38:29 +08:00
{
lampVal = constrain ( val , 0 , 100 ) ;
2020-09-27 21:21:44 +08:00
setLamp ( lampVal ) ;
}
2020-11-01 07:24:05 +08:00
else if ( variable . compareTo ( " save_prefs " ) = = 0 )
2020-10-26 00:38:29 +08:00
{
if ( filesystem )
savePrefs ( SPIFFS ) ;
2020-09-29 02:32:12 +08:00
}
2020-11-01 07:24:05 +08:00
else if ( variable . compareTo ( " clear_prefs " ) = = 0 )
2020-10-26 00:38:29 +08:00
{
if ( filesystem )
removePrefs ( SPIFFS ) ;
2020-09-29 02:32:12 +08:00
}
2020-11-01 07:24:05 +08:00
else if ( variable . compareTo ( " reboot " ) = = 0 )
2020-10-26 00:38:29 +08:00
{
2020-11-01 07:24:05 +08:00
request - > send ( 200 , " text/plain " , " Rebooting... " ) ;
2020-09-27 21:21:44 +08:00
Serial . print ( " REBOOT requested " ) ;
2020-10-26 00:38:29 +08:00
for ( int i = 0 ; i < 20 ; i + + )
{
flashLED ( 50 ) ;
delay ( 150 ) ;
Serial . print ( ' . ' ) ;
2020-09-27 21:21:44 +08:00
}
2020-11-01 07:24:05 +08:00
Serial . printf ( " Thats all folks! \r \n \r \n " ) ;
2020-09-27 21:21:44 +08:00
ESP . restart ( ) ;
2019-11-15 00:01:37 +08:00
}
2020-11-01 07:24:05 +08:00
else if ( variable . compareTo ( " clear_wifi " ) = = 0 )
{
request - > send ( 200 , " text/plain " , " Reseting WiFi... " ) ;
Serial . println ( " Wifi reset requested " ) ;
resetWiFiConfig ( ) ;
}
2020-10-26 00:38:29 +08:00
else
{
2019-11-15 00:01:37 +08:00
res = - 1 ;
}
2020-10-26 00:38:29 +08:00
if ( res )
{
2020-11-01 07:24:05 +08:00
Serial . print ( " Unable to determine command: " ) ;
Serial . println ( variable ) ;
request - > send ( 404 , " text/plain " , " Invalid parameters " ) ;
return ;
2019-11-15 00:01:37 +08:00
}
2020-11-01 07:24:05 +08:00
request - > send ( 200 ) ;
return ;
2019-11-15 00:01:37 +08:00
}
2020-11-01 07:24:05 +08:00
void status_handler ( AsyncWebServerRequest * request )
2020-10-26 00:38:29 +08:00
{
2020-11-01 07:24:05 +08:00
char json_response [ 1024 ] ;
2020-10-26 00:38:29 +08:00
sensor_t * s = esp_camera_sensor_get ( ) ;
char * p = json_response ;
2020-09-15 06:04:45 +08:00
* p + + = ' { ' ;
2020-10-26 00:38:29 +08:00
p + = sprintf ( p , " \" lamp \" :%d, " , lampVal ) ;
p + = sprintf ( p , " \" framesize \" :%u, " , s - > status . framesize ) ;
p + = sprintf ( p , " \" quality \" :%u, " , s - > status . quality ) ;
p + = sprintf ( p , " \" brightness \" :%d, " , s - > status . brightness ) ;
p + = sprintf ( p , " \" contrast \" :%d, " , s - > status . contrast ) ;
p + = sprintf ( p , " \" saturation \" :%d, " , s - > status . saturation ) ;
p + = sprintf ( p , " \" sharpness \" :%d, " , s - > status . sharpness ) ;
p + = sprintf ( p , " \" special_effect \" :%u, " , s - > status . special_effect ) ;
p + = sprintf ( p , " \" wb_mode \" :%u, " , s - > status . wb_mode ) ;
p + = sprintf ( p , " \" awb \" :%u, " , s - > status . awb ) ;
p + = sprintf ( p , " \" awb_gain \" :%u, " , s - > status . awb_gain ) ;
p + = sprintf ( p , " \" aec \" :%u, " , s - > status . aec ) ;
p + = sprintf ( p , " \" aec2 \" :%u, " , s - > status . aec2 ) ;
p + = sprintf ( p , " \" ae_level \" :%d, " , s - > status . ae_level ) ;
p + = sprintf ( p , " \" aec_value \" :%u, " , s - > status . aec_value ) ;
p + = sprintf ( p , " \" agc \" :%u, " , s - > status . agc ) ;
p + = sprintf ( p , " \" agc_gain \" :%u, " , s - > status . agc_gain ) ;
p + = sprintf ( p , " \" gainceiling \" :%u, " , s - > status . gainceiling ) ;
p + = sprintf ( p , " \" bpc \" :%u, " , s - > status . bpc ) ;
p + = sprintf ( p , " \" wpc \" :%u, " , s - > status . wpc ) ;
p + = sprintf ( p , " \" raw_gma \" :%u, " , s - > status . raw_gma ) ;
p + = sprintf ( p , " \" lenc \" :%u, " , s - > status . lenc ) ;
p + = sprintf ( p , " \" vflip \" :%u, " , s - > status . vflip ) ;
p + = sprintf ( p , " \" hmirror \" :%u, " , s - > status . hmirror ) ;
p + = sprintf ( p , " \" dcw \" :%u, " , s - > status . dcw ) ;
p + = sprintf ( p , " \" colorbar \" :%u, " , s - > status . colorbar ) ;
2020-11-01 07:24:05 +08:00
p + = sprintf ( p , " \" cam_name \" : \" %s \" , " , camera_name ) ;
2020-10-26 00:38:29 +08:00
p + = sprintf ( p , " \" code_ver \" : \" %s \" , " , myVer ) ;
p + = sprintf ( p , " \" rotate \" : \" %d \" , " , myRotation ) ;
p + = sprintf ( p , " \" stream_url \" : \" %s \" " , streamURL ) ;
2019-11-15 00:01:37 +08:00
* p + + = ' } ' ;
* p + + = 0 ;
2020-11-01 07:24:05 +08:00
request - > send ( 200 , " application/json " , json_response ) ;
2019-11-15 00:01:37 +08:00
}
2020-11-01 07:24:05 +08:00
void favicon_16x16_handler ( AsyncWebServerRequest * request )
2020-10-26 00:38:29 +08:00
{
2020-11-01 07:24:05 +08:00
request - > send ( 200 , " image/png " , ( const char * ) favicon_16x16_png ) ;
2020-09-10 10:26:34 +08:00
}
2020-11-01 07:24:05 +08:00
void favicon_32x32_handler ( AsyncWebServerRequest * request )
2020-10-26 00:38:29 +08:00
{
2020-11-01 07:24:05 +08:00
request - > send ( 200 , " image/png " , ( const char * ) favicon_32x32_png ) ;
2020-09-10 10:26:34 +08:00
}
2020-11-01 07:24:05 +08:00
void favicon_ico_handler ( AsyncWebServerRequest * request )
2020-10-26 00:38:29 +08:00
{
2020-11-01 07:24:05 +08:00
request - > send ( 200 , " image/png " , ( const char * ) favicon_ico ) ;
2020-09-10 10:26:34 +08:00
}
2020-11-01 07:24:05 +08:00
void logo_svg_handler ( AsyncWebServerRequest * request )
2020-10-26 00:38:29 +08:00
{
2020-11-01 07:24:05 +08:00
request - > send ( 200 , " image/svg+xml " , ( const char * ) logo_svg ) ;
2020-10-07 08:08:18 +08:00
}
2020-11-01 07:24:05 +08:00
void dump_handler ( AsyncWebServerRequest * request )
2020-10-26 00:38:29 +08:00
{
2020-09-27 21:21:44 +08:00
flashLED ( 75 ) ;
2020-11-01 07:24:05 +08:00
Serial . println ( " \r \n Dump Requested " ) ;
2020-10-04 01:49:08 +08:00
Serial . print ( " Preferences file: " ) ;
2020-09-27 21:21:44 +08:00
dumpPrefs ( SPIFFS ) ;
2020-11-01 07:24:05 +08:00
char dumpOut [ 1200 ] = " " ;
2020-10-26 00:38:29 +08:00
char * d = dumpOut ;
2020-10-04 01:49:08 +08:00
// Header
2020-11-01 07:24:05 +08:00
d + = sprintf ( d , " <html><head><meta charset= \" utf-8 \" > \r \n " ) ;
d + = sprintf ( d , " <meta name= \" viewport \" content= \" width=device-width,initial-scale=1 \" > \r \n " ) ;
d + = sprintf ( d , " <title>%s - Status</title> \r \n " , camera_name ) ;
d + = sprintf ( d , " <link rel= \" icon \" type= \" image/png \" sizes= \" 32x32 \" href= \" /favicon-32x32.png \" > \r \n " ) ;
d + = sprintf ( d , " <link rel= \" icon \" type= \" image/png \" sizes= \" 16x16 \" href= \" /favicon-16x16.png \" > \r \n " ) ;
d + = sprintf ( d , " <link rel= \" stylesheet \" type= \" text/css \" href= \" /style.css \" > \r \n " ) ;
d + = sprintf ( d , " </head> \r \n <body> \r \n " ) ;
d + = sprintf ( d , " <img src= \" /logo.svg \" style= \" position: relative; float: right; \" > \r \n " ) ;
d + = sprintf ( d , " <h1>ESP32 Cam Webserver</h1> \r \n " ) ;
2020-10-04 01:49:08 +08:00
// Module
2020-11-01 07:24:05 +08:00
d + = sprintf ( d , " Name: %s<br> \r \n " , camera_name ) ;
Serial . printf ( " Name: %s \r \n " , camera_name ) ;
d + = sprintf ( d , " Firmware: %s (base: %s)<br> \r \n " , myVer , baseVersion ) ;
Serial . printf ( " Firmware: %s (base: %s) \r \n " , myVer , baseVersion ) ;
2020-10-04 01:49:08 +08:00
float sketchPct = 100 * sketchSize / sketchSpace ;
2020-11-01 07:24:05 +08:00
d + = sprintf ( d , " Sketch Size: %i (total: %i, %.1f%% used)<br> \r \n " , sketchSize , sketchSpace , sketchPct ) ;
Serial . printf ( " Sketch Size: %i (total: %i, %.1f%% used) \r \n " , sketchSize , sketchSpace , sketchPct ) ;
d + = sprintf ( d , " MD5: %s<br> \r \n " , sketchMD5 . c_str ( ) ) ;
Serial . printf ( " MD5: %s \r \n " , sketchMD5 . c_str ( ) ) ;
d + = sprintf ( d , " ESP sdk: %s<br> \r \n " , ESP . getSdkVersion ( ) ) ;
Serial . printf ( " ESP sdk: %s \r \n " , ESP . getSdkVersion ( ) ) ;
2020-10-04 01:49:08 +08:00
// Network
2020-11-01 07:24:05 +08:00
d + = sprintf ( d , " <h2>WiFi</h2> \r \n " ) ;
d + = sprintf ( d , " Mode: Client<br> \r \n " ) ;
Serial . printf ( " Mode: Client \r \n " ) ;
String ssidName = WiFi . SSID ( ) ;
d + = sprintf ( d , " SSID: %s<br> \r \n " , ssidName . c_str ( ) ) ;
Serial . printf ( " Ssid: %s \r \n " , ssidName . c_str ( ) ) ;
d + = sprintf ( d , " Rssi: %i<br> \r \n " , WiFi . RSSI ( ) ) ;
Serial . printf ( " Rssi: %i \r \n " , WiFi . RSSI ( ) ) ;
String bssid = WiFi . BSSIDstr ( ) ;
d + = sprintf ( d , " BSSID: %s<br> \r \n " , bssid . c_str ( ) ) ;
Serial . printf ( " BSSID: %s \r \n " , bssid . c_str ( ) ) ;
d + = sprintf ( d , " IP address: %d.%d.%d.%d<br> \r \n " , espIP [ 0 ] , espIP [ 1 ] , espIP [ 2 ] , espIP [ 3 ] ) ;
Serial . printf ( " IP address: %d.%d.%d.%d \r \n " , espIP [ 0 ] , espIP [ 1 ] , espIP [ 2 ] , espIP [ 3 ] ) ;
d + = sprintf ( d , " Http port: %i<br> \r \n " , httpPort ) ;
Serial . printf ( " Http port: %i \r \n " , httpPort ) ;
2020-10-06 19:29:54 +08:00
byte mac [ 6 ] ;
WiFi . macAddress ( mac ) ;
2020-11-01 07:24:05 +08:00
d + = sprintf ( d , " MAC: %02X:%02X:%02X:%02X:%02X:%02X<br> \r \n " , mac [ 0 ] , mac [ 1 ] , mac [ 2 ] , mac [ 3 ] , mac [ 4 ] , mac [ 5 ] ) ;
Serial . printf ( " MAC: %02X:%02X:%02X:%02X:%02X:%02X \r \n " , mac [ 0 ] , mac [ 1 ] , mac [ 2 ] , mac [ 3 ] , mac [ 4 ] , mac [ 5 ] ) ;
2020-10-06 19:29:54 +08:00
2020-10-04 01:49:08 +08:00
// System
2020-11-01 07:24:05 +08:00
d + = sprintf ( d , " <h2>System</h2> \r \n " ) ;
2020-10-04 01:49:08 +08:00
int64_t sec = esp_timer_get_time ( ) / 1000000 ;
2020-10-26 00:38:29 +08:00
int64_t upDays = int64_t ( floor ( sec / 86400 ) ) ;
int upHours = int64_t ( floor ( sec / 3600 ) ) % 24 ;
int upMin = int64_t ( floor ( sec / 60 ) ) % 60 ;
2020-10-04 01:49:08 +08:00
int upSec = sec % 60 ;
2020-11-01 07:24:05 +08:00
d + = sprintf ( d , " Up: % " PRId64 " :%02i:%02i:%02i (d:h:m:s)<br> \r \n " , upDays , upHours , upMin , upSec ) ;
Serial . printf ( " Up: % " PRId64 " :%02i:%02i:%02i (d:h:m:s) \r \n " , upDays , upHours , upMin , upSec ) ;
d + = sprintf ( d , " Freq: %i MHz<br> \r \n " , ESP . getCpuFreqMHz ( ) ) ;
Serial . printf ( " Freq: %i MHz \r \n " , ESP . getCpuFreqMHz ( ) ) ;
d + = sprintf ( d , " Heap: %i, free: %i, min free: %i, max block: %i<br> \r \n " , ESP . getHeapSize ( ) , ESP . getFreeHeap ( ) , ESP . getMinFreeHeap ( ) , ESP . getMaxAllocHeap ( ) ) ;
Serial . printf ( " Heap: %i, free: %i, min free: %i, max block: %i \r \n " , ESP . getHeapSize ( ) , ESP . getFreeHeap ( ) , ESP . getMinFreeHeap ( ) , ESP . getMaxAllocHeap ( ) ) ;
d + = sprintf ( d , " Psram: %i, free: %i, min free: %i, max block: %i<br> \r \n " , ESP . getPsramSize ( ) , ESP . getFreePsram ( ) , ESP . getMinFreePsram ( ) , ESP . getMaxAllocPsram ( ) ) ;
Serial . printf ( " Psram: %i, free: %i, min free: %i, max block: %i \r \n " , ESP . getPsramSize ( ) , ESP . getFreePsram ( ) , ESP . getMinFreePsram ( ) , ESP . getMaxAllocPsram ( ) ) ;
2020-10-26 00:38:29 +08:00
if ( filesystem )
{
2020-11-01 07:24:05 +08:00
d + = sprintf ( d , " Spiffs: %i, used: %i<br> \r \n " , SPIFFS . totalBytes ( ) , SPIFFS . usedBytes ( ) ) ;
Serial . printf ( " Spiffs: %i, used: %i \r \n " , SPIFFS . totalBytes ( ) , SPIFFS . usedBytes ( ) ) ;
2020-10-04 01:49:08 +08:00
}
2020-10-12 00:19:22 +08:00
2020-10-04 01:49:08 +08:00
// Footer
2020-11-01 07:24:05 +08:00
d + = sprintf ( d , " <br><div class= \" input-group \" > \r \n " ) ;
d + = sprintf ( d , " <button title= \" Refresh this page \" onclick= \" location.replace(document.URL) \" >Refresh</button> \r \n " ) ;
d + = sprintf ( d , " <button title= \" Close this page \" onclick= \" javascript:window.close() \" >Close</button> \r \n " ) ;
d + = sprintf ( d , " </div> \r \n </body> \r \n </html> \r \n " ) ;
2020-10-04 01:49:08 +08:00
* d + + = 0 ;
2020-11-01 07:24:05 +08:00
request - > send ( 200 , " image/html " , dumpOut ) ;
2020-09-27 21:21:44 +08:00
}
2020-11-01 07:24:05 +08:00
void style_handler ( AsyncWebServerRequest * request )
2020-10-26 00:38:29 +08:00
{
2020-11-01 07:24:05 +08:00
request - > send ( 200 , " text/css " , ( const char * ) style_css ) ;
2020-09-13 21:28:38 +08:00
}
2020-11-01 07:24:05 +08:00
void handleIndex ( AsyncWebServerRequest * request )
2020-10-26 00:38:29 +08:00
{
2020-10-07 08:08:18 +08:00
2020-11-01 07:24:05 +08:00
flashLED ( 150 ) ;
2020-10-07 18:19:19 +08:00
// See if we have a specific target (full/simple/portal) and serve as appropriate
2020-11-01 07:24:05 +08:00
String view = default_index ;
if ( request - > hasArg ( " view " ) )
2020-10-26 00:38:29 +08:00
{
2020-11-01 07:24:05 +08:00
view = request - > arg ( " view " ) . c_str ( ) ;
2020-10-07 08:08:18 +08:00
}
2020-11-01 07:24:05 +08:00
if ( strncmp ( view . c_str ( ) , " simple " , sizeof ( view ) ) = = 0 )
2020-10-26 00:38:29 +08:00
{
2020-10-07 08:08:18 +08:00
Serial . println ( " Simple index page requested " ) ;
2020-11-01 07:24:05 +08:00
request - > send_P ( 200 , " text/html " , ( const char * ) index_simple_html ) ;
return ;
2020-10-26 00:38:29 +08:00
}
2020-11-01 07:24:05 +08:00
else if ( strncmp ( view . c_str ( ) , " full " , sizeof ( view ) ) = = 0 )
2020-10-26 00:38:29 +08:00
{
2020-11-01 07:24:05 +08:00
2020-10-26 00:38:29 +08:00
sensor_t * s = esp_camera_sensor_get ( ) ;
2020-11-01 07:24:05 +08:00
2020-10-26 00:38:29 +08:00
if ( s - > id . PID = = OV3660_PID )
{
2020-11-01 07:24:05 +08:00
Serial . println ( " Full OV3660 index page requested " ) ;
request - > send_P ( 200 , " text/html " , ( const char * ) index_ov3660_html ) ;
return ;
}
Serial . println ( " Full OV2640 index page requested " ) ;
request - > send_P ( 200 , " text/html " , ( const char * ) index_ov2640_html ) ;
return ;
}
Serial . print ( " Unknown page requested: " ) ;
Serial . println ( view ) ;
request - > send ( 404 , " text/plain " , " Unknown page requested " ) ;
}
void handleFirmware ( AsyncWebServerRequest * request )
{
flashLED ( 75 ) ;
// See if we have a specific target (full/simple/portal) and serve as appropriate
Serial . println ( " Firmware page requested " ) ;
request - > send ( 200 , " text/html " , firmware_html . c_str ( ) ) ;
}
String getHTMLHead ( )
{
String header = F ( " <!DOCTYPE html><html lang= \" en \" ><head> " ) ;
header + = F ( " <link href= \" /local.css \" rel= \" stylesheet \" > " ) ;
header + = F ( " </head> " ) ;
header + = F ( " <body> " ) ;
return header ;
}
String getHTMLFoot ( )
{
return F ( " </body></html> " ) ;
}
void handleUpdate ( AsyncWebServerRequest * request )
{
String response_message ;
response_message . reserve ( 1000 ) ;
response_message = getHTMLHead ( ) ;
response_message + = " <script> function notify_update() {document.getElementById( \" update \" ).innerHTML = \" <h2>Updating...</h2> \" \ ; } </script> " ;
response_message + = " Firmware = *.esp32.bin<br>SPIFFS = *.spiffs.bin<br> \
< form method = ' POST ' action = ' / doUpdate ' enctype = ' multipart / form - data ' target = ' _self ' onsubmit = ' notify_update ( ) ' > \
< input type = ' file ' name = ' update ' > < br > \
< input type = ' submit ' value = ' Do update ' > < / form > \
< div id = \ " update \" ></div> " ;
response_message + = getHTMLFoot ( ) ;
request - > send ( 200 , " text/html " , response_message ) ;
} ;
void handleDoUpdate ( AsyncWebServerRequest * request , const String & filename , size_t index , uint8_t * data , size_t len , bool final )
{
updating = true ;
delay ( 500 ) ;
if ( ! index )
{
// check file names for type
int cmd = ( filename . indexOf ( F ( " .spiffs.bin " ) ) > - 1 ) ? U_SPIFFS : U_FLASH ;
if ( cmd = = U_FLASH & & ! ( filename . indexOf ( F ( " esp32.bin " ) ) > - 1 ) )
return ; // wrong image for ESP32
if ( ! Update . begin ( UPDATE_SIZE_UNKNOWN , cmd ) )
{
Update . printError ( Serial ) ;
2020-10-07 08:08:18 +08:00
}
2020-10-26 00:38:29 +08:00
}
2020-11-01 07:24:05 +08:00
if ( Update . write ( data , len ) ! = len )
2020-10-26 00:38:29 +08:00
{
2020-11-01 07:24:05 +08:00
Update . printError ( Serial ) ;
2020-10-26 00:38:29 +08:00
}
2020-11-01 07:24:05 +08:00
if ( final )
2020-10-26 00:38:29 +08:00
{
2020-11-01 07:24:05 +08:00
if ( ! Update . end ( true ) )
{
Update . printError ( Serial ) ;
}
else
{
String response_message ;
response_message . reserve ( 1000 ) ;
response_message = getHTMLHead ( ) ;
response_message + = " <h2>Please wait while the device reboots</h2> <meta http-equiv= \" refresh \" content= \" 20;url=/ \" /> " ;
response_message + = getHTMLFoot ( ) ;
AsyncWebServerResponse * response = request - > beginResponse ( 200 , " text/html " , response_message ) ;
response - > addHeader ( " Refresh " , " 20 " ) ;
response - > addHeader ( " Location " , " / " ) ;
request - > send ( response ) ;
delay ( 100 ) ;
ESP . restart ( ) ;
}
2019-11-15 00:01:37 +08:00
}
}
2020-10-26 00:38:29 +08:00
void startCameraServer ( )
{
2020-11-01 07:24:05 +08:00
Serial . printf ( " Starting web server on port: '%d' \r \n " , httpPort ) ;
appServer . on ( " / " , HTTP_GET , [ ] ( AsyncWebServerRequest * request ) {
handleIndex ( request ) ;
} ) ;
appServer . on ( " /firmware " , HTTP_GET , handleFirmware ) ;
appServer . on ( " /status " , HTTP_GET , status_handler ) ;
appServer . on ( " /control " , HTTP_GET , cmd_handler ) ;
appServer . on ( " /capture " , HTTP_GET , capture_handler ) ;
appServer . on ( " /style.css " , HTTP_GET , style_handler ) ;
appServer . on ( " /favicon-16x16.png " , HTTP_GET , favicon_16x16_handler ) ;
appServer . on ( " /favicon-32x32.png " , HTTP_GET , favicon_32x32_handler ) ;
appServer . on ( " /favicon.ico " , HTTP_GET , favicon_ico_handler ) ;
appServer . on ( " /logo.svg " , HTTP_GET , logo_svg_handler ) ;
appServer . on ( " /dump " , HTTP_GET , dump_handler ) ;
/*handling uploading firmware file */
appServer . on ( " /update " , HTTP_GET , [ ] ( AsyncWebServerRequest * request ) {
handleUpdate ( request ) ;
} ) ;
appServer . on (
" /doUpdate " , HTTP_POST , [ ] ( AsyncWebServerRequest * request ) { } , [ ] ( AsyncWebServerRequest * request , const String & filename , size_t index , uint8_t * data , size_t len , bool final ) { handleDoUpdate ( request , filename , index , data , len , final ) ; } ) ;
DefaultHeaders : : Instance ( ) . addHeader ( " Access-Control-Allow-Origin " , " * " ) ;
appServer . begin ( ) ;
Serial . println ( " Web server started! " ) ;
sprintf ( httpURL , " http://%d.%d.%d.%d:%d/ " , espIP [ 0 ] , espIP [ 1 ] , espIP [ 2 ] , espIP [ 3 ] , httpPort ) ;
2019-11-15 00:01:37 +08:00
}