mirror of
https://github.com/jomjol/AI-on-the-edge-device.git
synced 2025-12-11 22:16:56 +03:00
Initial Code v0.1.0
This commit is contained in:
10
code/src/CMakeLists.txt
Normal file
10
code/src/CMakeLists.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
# This file was automatically generated for projects
|
||||
# without default 'CMakeLists.txt' file.
|
||||
|
||||
FILE(GLOB_RECURSE app_sources ${CMAKE_SOURCE_DIR}/src/*.*)
|
||||
|
||||
# idf_component_register(SRCS ${app_sources})
|
||||
|
||||
idf_component_register(SRCS ${app_sources}
|
||||
INCLUDE_DIRS "."
|
||||
EMBED_FILES "favicon.ico" "upload_script.html")
|
||||
BIN
code/src/favicon.ico
Normal file
BIN
code/src/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.3 KiB |
139
code/src/main.cpp
Normal file
139
code/src/main.cpp
Normal file
@@ -0,0 +1,139 @@
|
||||
#include <string>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/event_groups.h"
|
||||
|
||||
#include "driver/gpio.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "ClassLogFile.h"
|
||||
|
||||
|
||||
//#include "esp_wifi.h"
|
||||
//#include "protocol_examples_common.h"
|
||||
|
||||
#include "connect_wlan.h"
|
||||
|
||||
#include <esp_http_server.h>
|
||||
|
||||
#include "lwip/err.h"
|
||||
#include "lwip/sockets.h"
|
||||
#include "lwip/sys.h"
|
||||
#include "lwip/netdb.h"
|
||||
#include "lwip/dns.h"
|
||||
|
||||
|
||||
#include <sys/unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include "esp_log.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_event_loop.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_vfs_fat.h"
|
||||
#include "driver/sdmmc_host.h"
|
||||
#include "driver/sdmmc_defs.h"
|
||||
#include "sdmmc_cmd.h"
|
||||
|
||||
#include "server_main.h"
|
||||
#include "server_camera.h"
|
||||
#include "server_tflite.h"
|
||||
#include "server_file.h"
|
||||
#include "server_ota.h"
|
||||
#include "time_sntp.h"
|
||||
#include "ClassControllCamera.h"
|
||||
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/event_groups.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
|
||||
// SD-Card
|
||||
#include "nvs_flash.h"
|
||||
#include "esp_vfs_fat.h"
|
||||
#include "sdmmc_cmd.h"
|
||||
|
||||
#include "server_main.h"
|
||||
#include "server_camera.h"
|
||||
#include "ClassControllCamera.h"
|
||||
#include "connect_wlan.h"
|
||||
#include "time_sntp.h"
|
||||
|
||||
static const char *TAGMAIN = "connect_wlan_main";
|
||||
|
||||
#define FLASH_GPIO GPIO_NUM_4
|
||||
|
||||
void Init_NVS_SDCard()
|
||||
{
|
||||
esp_err_t ret = nvs_flash_init();
|
||||
if (ret == ESP_ERR_NVS_NO_FREE_PAGES) {
|
||||
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||
ret = nvs_flash_init();
|
||||
}
|
||||
|
||||
ESP_LOGI(TAGMAIN, "Initializing SD card");
|
||||
sdmmc_host_t host = SDMMC_HOST_DEFAULT();
|
||||
host.flags = SDMMC_HOST_FLAG_1BIT;
|
||||
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
|
||||
esp_vfs_fat_sdmmc_mount_config_t mount_config = { };
|
||||
mount_config.format_if_mount_failed = false;
|
||||
mount_config.max_files = 5;
|
||||
|
||||
sdmmc_card_t* card;
|
||||
ret = esp_vfs_fat_sdmmc_mount("/sdcard", &host, &slot_config, &mount_config, &card);
|
||||
if (ret != ESP_OK) {
|
||||
if (ret == ESP_FAIL) {
|
||||
ESP_LOGE(TAGMAIN, "Failed to mount filesystem. If you want the card to be formatted, set format_if_mount_failed = true.");
|
||||
} else {
|
||||
ESP_LOGE(TAGMAIN, "Failed to initialize the card (%d). Make sure SD card lines have pull-up resistors in place.", ret);
|
||||
}
|
||||
return;
|
||||
}
|
||||
sdmmc_card_print_info(stdout, card);
|
||||
|
||||
// Init the GPIO
|
||||
// Flash ausschalten
|
||||
gpio_pad_select_gpio(FLASH_GPIO);
|
||||
gpio_set_direction(FLASH_GPIO, GPIO_MODE_OUTPUT);
|
||||
gpio_set_level(FLASH_GPIO, 0);
|
||||
}
|
||||
|
||||
|
||||
extern "C" void app_main()
|
||||
{
|
||||
Init_NVS_SDCard();
|
||||
|
||||
CheckOTAUpdate();
|
||||
|
||||
std::string ssid = "";
|
||||
std::string password = "";
|
||||
LoadWlanFromFile("/sdcard/wlan.ini", ssid, password);
|
||||
printf("WLan: %s, %s\n", ssid.c_str(), password.c_str());
|
||||
|
||||
initialise_wifi(ssid, password);
|
||||
|
||||
setup_time();
|
||||
LogFile.WriteToFile("===== Main Started =====");
|
||||
|
||||
std::string zw = gettimestring("%Y%m%d-%H%M%S");
|
||||
printf("time %s\n", zw.c_str());
|
||||
|
||||
Camera.InitCam();
|
||||
Camera.LightOnOff(false);
|
||||
server = start_webserver();
|
||||
register_server_camera_uri(server);
|
||||
register_server_tflite_uri(server);
|
||||
register_server_file_uri(server, "/sdcard");
|
||||
register_server_ota_sdcard_uri(server);
|
||||
register_server_main_uri(server, "/sdcard");
|
||||
|
||||
TFliteDoAutoStart();
|
||||
|
||||
zw = gettimestring("%Y%m%d-%H%M%S");
|
||||
printf("time %s\n", zw.c_str());
|
||||
|
||||
printf("Test für OTA-Update v3\n");
|
||||
}
|
||||
7
code/src/partition.csv
Normal file
7
code/src/partition.csv
Normal file
@@ -0,0 +1,7 @@
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
|
||||
nvs, data, nvs, , 0x4000,
|
||||
otadata, data, ota, , 0x2000,
|
||||
phy_init, data, phy, , 0x1000,
|
||||
factory, app, factory, , 1900k,
|
||||
ota_0, app, ota_0, , 1900k,
|
||||
|
113
code/src/server_help.cpp
Normal file
113
code/src/server_help.cpp
Normal file
@@ -0,0 +1,113 @@
|
||||
#include "server_help.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "esp_http_server.h"
|
||||
|
||||
|
||||
static const char *TAG = "serverhelp";
|
||||
|
||||
#define SCRATCH_BUFSIZE 8192
|
||||
char scratch[SCRATCH_BUFSIZE];
|
||||
|
||||
|
||||
#define IS_FILE_EXT(filename, ext) \
|
||||
(strcasecmp(&filename[strlen(filename) - sizeof(ext) + 1], ext) == 0)
|
||||
|
||||
|
||||
esp_err_t send_file(httpd_req_t *req, std::string filename, struct stat * file_stat)
|
||||
{
|
||||
FILE *fd = fopen(filename.c_str(), "r");
|
||||
if (!fd) {
|
||||
ESP_LOGE(TAG, "Failed to read existing file : %s", filename.c_str());
|
||||
/* Respond with 500 Internal Server Error */
|
||||
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to read existing file");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Sending file : %s (%ld bytes)...", filename.c_str(), file_stat->st_size);
|
||||
set_content_type_from_file(req, filename.c_str());
|
||||
|
||||
/* Retrieve the pointer to scratch buffer for temporary storage */
|
||||
char *chunk = scratch;
|
||||
size_t chunksize;
|
||||
do {
|
||||
/* Read file in chunks into the scratch buffer */
|
||||
chunksize = fread(chunk, 1, SCRATCH_BUFSIZE, fd);
|
||||
|
||||
/* Send the buffer contents as HTTP response chunk */
|
||||
if (httpd_resp_send_chunk(req, chunk, chunksize) != ESP_OK) {
|
||||
fclose(fd);
|
||||
ESP_LOGE(TAG, "File sending failed!");
|
||||
/* Abort sending file */
|
||||
httpd_resp_sendstr_chunk(req, NULL);
|
||||
/* Respond with 500 Internal Server Error */
|
||||
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to send file");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
/* Keep looping till the whole file is sent */
|
||||
} while (chunksize != 0);
|
||||
|
||||
/* Close file after sending complete */
|
||||
fclose(fd);
|
||||
ESP_LOGI(TAG, "File sending complete");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Copies the full path into destination buffer and returns
|
||||
* pointer to path (skipping the preceding base path) */
|
||||
const char* get_path_from_uri(char *dest, const char *base_path, const char *uri, size_t destsize)
|
||||
{
|
||||
const size_t base_pathlen = strlen(base_path);
|
||||
size_t pathlen = strlen(uri);
|
||||
|
||||
const char *quest = strchr(uri, '?');
|
||||
if (quest) {
|
||||
pathlen = MIN(pathlen, quest - uri);
|
||||
}
|
||||
const char *hash = strchr(uri, '#');
|
||||
if (hash) {
|
||||
pathlen = MIN(pathlen, hash - uri);
|
||||
}
|
||||
|
||||
if (base_pathlen + pathlen + 1 > destsize) {
|
||||
/* Full path string won't fit into destination buffer */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Construct full path (base + path) */
|
||||
strcpy(dest, base_path);
|
||||
strlcpy(dest + base_pathlen, uri, pathlen + 1);
|
||||
|
||||
/* Return pointer to path, skipping the base */
|
||||
return dest + base_pathlen;
|
||||
}
|
||||
|
||||
|
||||
/* Set HTTP response content type according to file extension */
|
||||
esp_err_t set_content_type_from_file(httpd_req_t *req, const char *filename)
|
||||
{
|
||||
if (IS_FILE_EXT(filename, ".pdf")) {
|
||||
return httpd_resp_set_type(req, "application/pdf");
|
||||
} else if (IS_FILE_EXT(filename, ".html")) {
|
||||
return httpd_resp_set_type(req, "text/html");
|
||||
} else if (IS_FILE_EXT(filename, ".jpeg")) {
|
||||
return httpd_resp_set_type(req, "image/jpeg");
|
||||
} else if (IS_FILE_EXT(filename, ".ico")) {
|
||||
return httpd_resp_set_type(req, "image/x-icon");
|
||||
}
|
||||
/* This is a limited set only */
|
||||
/* For any other type always set as plain text */
|
||||
return httpd_resp_set_type(req, "text/plain");
|
||||
}
|
||||
10
code/src/server_help.h
Normal file
10
code/src/server_help.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#include <string>
|
||||
//#include <sys/param.h>
|
||||
#include "esp_http_server.h"
|
||||
|
||||
|
||||
const char* get_path_from_uri(char *dest, const char *base_path, const char *uri, size_t destsize);
|
||||
|
||||
esp_err_t send_file(httpd_req_t *req, std::string filename, struct stat * file_stat);
|
||||
|
||||
esp_err_t set_content_type_from_file(httpd_req_t *req, const char *filename);
|
||||
302
code/src/server_main.cpp
Normal file
302
code/src/server_main.cpp
Normal file
@@ -0,0 +1,302 @@
|
||||
#include "server_main.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "server_help.h"
|
||||
|
||||
#include "time_sntp.h"
|
||||
|
||||
|
||||
httpd_handle_t server = NULL;
|
||||
|
||||
|
||||
std::string starttime = "";
|
||||
|
||||
|
||||
/* An HTTP GET handler */
|
||||
esp_err_t hello_get_handler(httpd_req_t *req)
|
||||
{
|
||||
char* buf;
|
||||
size_t buf_len;
|
||||
printf("req uri:\n");
|
||||
printf(req->uri);
|
||||
printf("\n");
|
||||
|
||||
/* Get header value string length and allocate memory for length + 1,
|
||||
* extra byte for null termination */
|
||||
buf_len = httpd_req_get_hdr_value_len(req, "Host") + 1;
|
||||
if (buf_len > 1) {
|
||||
buf = (char*) malloc(buf_len);
|
||||
/* Copy null terminated value string into buffer */
|
||||
if (httpd_req_get_hdr_value_str(req, "Host", buf, buf_len) == ESP_OK) {
|
||||
ESP_LOGI(TAG, "Found header => Host: %s", buf);
|
||||
}
|
||||
free(buf);
|
||||
}
|
||||
|
||||
buf_len = httpd_req_get_hdr_value_len(req, "Test-Header-2") + 1;
|
||||
if (buf_len > 1) {
|
||||
buf = (char*) malloc(buf_len);
|
||||
if (httpd_req_get_hdr_value_str(req, "Test-Header-2", buf, buf_len) == ESP_OK) {
|
||||
ESP_LOGI(TAG, "Found header => Test-Header-2: %s", buf);
|
||||
}
|
||||
free(buf);
|
||||
}
|
||||
|
||||
buf_len = httpd_req_get_hdr_value_len(req, "Test-Header-1") + 1;
|
||||
if (buf_len > 1) {
|
||||
buf = (char*) malloc(buf_len);
|
||||
if (httpd_req_get_hdr_value_str(req, "Test-Header-1", buf, buf_len) == ESP_OK) {
|
||||
ESP_LOGI(TAG, "Found header => Test-Header-1: %s", buf);
|
||||
}
|
||||
free(buf);
|
||||
}
|
||||
|
||||
/* Read URL query string length and allocate memory for length + 1,
|
||||
* extra byte for null termination */
|
||||
buf_len = httpd_req_get_url_query_len(req) + 1;
|
||||
if (buf_len > 1) {
|
||||
buf = (char*) malloc(buf_len);
|
||||
if (httpd_req_get_url_query_str(req, buf, buf_len) == ESP_OK) {
|
||||
ESP_LOGI(TAG, "Found URL query => %s", buf);
|
||||
char param[32];
|
||||
/* Get value of expected key from query string */
|
||||
if (httpd_query_key_value(buf, "query1", param, sizeof(param)) == ESP_OK) {
|
||||
ESP_LOGI(TAG, "Found URL query parameter => query1=%s", param);
|
||||
}
|
||||
if (httpd_query_key_value(buf, "query3", param, sizeof(param)) == ESP_OK) {
|
||||
ESP_LOGI(TAG, "Found URL query parameter => query3=%s", param);
|
||||
}
|
||||
if (httpd_query_key_value(buf, "query2", param, sizeof(param)) == ESP_OK) {
|
||||
ESP_LOGI(TAG, "Found URL query parameter => query2=%s", param);
|
||||
}
|
||||
}
|
||||
free(buf);
|
||||
}
|
||||
|
||||
/* Set some custom headers */
|
||||
httpd_resp_set_hdr(req, "Custom-Header-1", "Custom-Value-1");
|
||||
httpd_resp_set_hdr(req, "Custom-Header-2", "Custom-Value-2");
|
||||
|
||||
/* Send response with custom headers and body set as the
|
||||
* string passed in user context*/
|
||||
const char* resp_str = (const char*) req->user_ctx;
|
||||
httpd_resp_send(req, resp_str, strlen(resp_str));
|
||||
|
||||
/* After sending the HTTP response the old HTTP request
|
||||
* headers are lost. Check if HTTP request headers can be read now. */
|
||||
if (httpd_req_get_hdr_value_len(req, "Host") == 0) {
|
||||
ESP_LOGI(TAG, "Request headers lost");
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t starttime_get_handler(httpd_req_t *req)
|
||||
{
|
||||
httpd_resp_send(req, starttime.c_str(), strlen(starttime.c_str()));
|
||||
/* Respond with an empty chunk to signal HTTP response completion */
|
||||
httpd_resp_send_chunk(req, NULL, 0);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t hello_main_handler(httpd_req_t *req)
|
||||
{
|
||||
char filepath[50];
|
||||
struct stat file_stat;
|
||||
printf("uri: %s\n", req->uri);
|
||||
|
||||
char *base_path = (char*) req->user_ctx;
|
||||
std::string filetosend(base_path);
|
||||
|
||||
const char *filename = get_path_from_uri(filepath, base_path,
|
||||
req->uri - 1, sizeof(filepath));
|
||||
printf("1 uri: %s, filename: %s, filepath: %s\n", req->uri, filename, filepath);
|
||||
|
||||
if ((strcmp(req->uri, "/") == 0))
|
||||
{
|
||||
filetosend = filetosend + "/html/index.html";
|
||||
}
|
||||
else
|
||||
{
|
||||
filetosend = filetosend + "/html" + std::string(req->uri);
|
||||
}
|
||||
|
||||
printf("File to upload: %s\n", filetosend.c_str());
|
||||
|
||||
if (!filename) {
|
||||
ESP_LOGE(TAG, "Filename is too long");
|
||||
/* Respond with 500 Internal Server Error */
|
||||
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Filename too long");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if (stat(filetosend.c_str(), &file_stat) == -1) {
|
||||
/* If file not present on SPIFFS check if URI
|
||||
* corresponds to one of the hardcoded paths */
|
||||
ESP_LOGE(TAG, "Failed to stat file : %s", filetosend.c_str());
|
||||
/* Respond with 404 Not Found */
|
||||
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "File does not exist");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t res = send_file(req, filetosend, &file_stat);
|
||||
if (res != ESP_OK)
|
||||
return res;
|
||||
|
||||
/* Respond with an empty chunk to signal HTTP response completion */
|
||||
httpd_resp_send_chunk(req, NULL, 0);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
esp_err_t img_tmp_handler(httpd_req_t *req)
|
||||
{
|
||||
char filepath[50];
|
||||
struct stat file_stat;
|
||||
printf("uri: %s\n", req->uri);
|
||||
|
||||
char *base_path = (char*) req->user_ctx;
|
||||
std::string filetosend(base_path);
|
||||
|
||||
const char *filename = get_path_from_uri(filepath, base_path,
|
||||
req->uri + sizeof("/img_tmp") - 1, sizeof(filepath));
|
||||
printf("1 uri: %s, filename: %s, filepath: %s\n", req->uri, filename, filepath);
|
||||
|
||||
filetosend = filetosend + "/img_tmp/" + std::string(filename);
|
||||
printf("File to upload: %s\n", filetosend.c_str());
|
||||
|
||||
if (!filename) {
|
||||
ESP_LOGE(TAG, "Filename is too long");
|
||||
/* Respond with 500 Internal Server Error */
|
||||
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Filename too long");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if (stat(filetosend.c_str(), &file_stat) == -1) {
|
||||
/* If file not present on SPIFFS check if URI
|
||||
* corresponds to one of the hardcoded paths */
|
||||
ESP_LOGE(TAG, "Failed to stat file : %s", filetosend.c_str());
|
||||
/* Respond with 404 Not Found */
|
||||
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "File does not exist");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t res = send_file(req, filetosend, &file_stat);
|
||||
if (res != ESP_OK)
|
||||
return res;
|
||||
|
||||
/* Respond with an empty chunk to signal HTTP response completion */
|
||||
httpd_resp_send_chunk(req, NULL, 0);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void register_server_main_uri(httpd_handle_t server, const char *base_path)
|
||||
{
|
||||
httpd_uri_t starttime_tmp_handle = {
|
||||
.uri = "/starttime", // Match all URIs of type /path/to/file
|
||||
.method = HTTP_GET,
|
||||
.handler = starttime_get_handler,
|
||||
.user_ctx = NULL // Pass server data as context
|
||||
};
|
||||
httpd_register_uri_handler(server, &starttime_tmp_handle);
|
||||
|
||||
|
||||
httpd_uri_t img_tmp_handle = {
|
||||
.uri = "/img_tmp/*", // Match all URIs of type /path/to/file
|
||||
.method = HTTP_GET,
|
||||
.handler = img_tmp_handler,
|
||||
.user_ctx = (void*) base_path // Pass server data as context
|
||||
};
|
||||
httpd_register_uri_handler(server, &img_tmp_handle);
|
||||
|
||||
|
||||
httpd_uri_t main_rest_handle = {
|
||||
.uri = "/*", // Match all URIs of type /path/to/file
|
||||
.method = HTTP_GET,
|
||||
.handler = hello_main_handler,
|
||||
.user_ctx = (void*) base_path // Pass server data as context
|
||||
};
|
||||
httpd_register_uri_handler(server, &main_rest_handle);
|
||||
}
|
||||
|
||||
|
||||
|
||||
httpd_handle_t start_webserver(void)
|
||||
{
|
||||
httpd_handle_t server = NULL;
|
||||
httpd_config_t config = { };
|
||||
|
||||
config.task_priority = tskIDLE_PRIORITY+5;
|
||||
config.stack_size = 16384;
|
||||
config.core_id = tskNO_AFFINITY;
|
||||
config.server_port = 80;
|
||||
config.ctrl_port = 32768;
|
||||
config.max_open_sockets = 7;
|
||||
config.max_uri_handlers = 24;
|
||||
config.max_resp_headers = 8;
|
||||
config.backlog_conn = 5;
|
||||
config.lru_purge_enable = false;
|
||||
config.recv_wait_timeout = 30; // default: 5
|
||||
config.send_wait_timeout = 30; // default: 5
|
||||
config.global_user_ctx = NULL;
|
||||
config.global_user_ctx_free_fn = NULL;
|
||||
config.global_transport_ctx = NULL;
|
||||
config.global_transport_ctx_free_fn = NULL;
|
||||
config.open_fn = NULL;
|
||||
config.close_fn = NULL;
|
||||
// config.uri_match_fn = NULL;
|
||||
config.uri_match_fn = httpd_uri_match_wildcard;
|
||||
|
||||
|
||||
httpd_uri_t hll = {};
|
||||
hll.uri = "/hello";
|
||||
hll.method = HTTP_GET;
|
||||
hll.handler = hello_get_handler;
|
||||
hll.user_ctx = (void*) "Hello World!";
|
||||
|
||||
|
||||
starttime = gettimestring("%Y%m%d-%H%M%S");
|
||||
|
||||
// Start the httpd server
|
||||
ESP_LOGI(TAG, "Starting server on port: '%d'", config.server_port);
|
||||
if (httpd_start(&server, &config) == ESP_OK) {
|
||||
// Set URI handlers
|
||||
ESP_LOGI(TAG, "Registering URI handlers");
|
||||
httpd_register_uri_handler(server, &hll);
|
||||
return server;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Error starting server!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void stop_webserver(httpd_handle_t server)
|
||||
{
|
||||
httpd_stop(server);
|
||||
}
|
||||
|
||||
|
||||
void disconnect_handler(void* arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void* event_data)
|
||||
{
|
||||
httpd_handle_t* server = (httpd_handle_t*) arg;
|
||||
if (*server) {
|
||||
ESP_LOGI(TAG, "Stopping webserver");
|
||||
stop_webserver(*server);
|
||||
*server = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void connect_handler(void* arg, esp_event_base_t event_base,
|
||||
int32_t event_id, void* event_data)
|
||||
{
|
||||
httpd_handle_t* server = (httpd_handle_t*) arg;
|
||||
if (*server == NULL) {
|
||||
ESP_LOGI(TAG, "Starting webserver");
|
||||
*server = start_webserver();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
30
code/src/server_main.h
Normal file
30
code/src/server_main.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef SERVER_MAIN_H
|
||||
#define SERVER_MAIN_H
|
||||
|
||||
#include <esp_wifi.h>
|
||||
#include <esp_event.h>
|
||||
#include <esp_log.h>
|
||||
#include <esp_system.h>
|
||||
#include <nvs_flash.h>
|
||||
#include <sys/param.h>
|
||||
#include "nvs_flash.h"
|
||||
#include "tcpip_adapter.h"
|
||||
#include "esp_eth.h"
|
||||
|
||||
|
||||
#include <esp_http_server.h>
|
||||
|
||||
static const char *TAG = "example";
|
||||
|
||||
extern httpd_handle_t server;
|
||||
|
||||
httpd_handle_t start_webserver(void);
|
||||
|
||||
void register_server_main_uri(httpd_handle_t server, const char *base_path);
|
||||
|
||||
|
||||
//void disconnect_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data);
|
||||
//void connect_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data);
|
||||
|
||||
|
||||
#endif
|
||||
329
code/src/server_tflite.cpp
Normal file
329
code/src/server_tflite.cpp
Normal file
@@ -0,0 +1,329 @@
|
||||
#include "server_tflite.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "string.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
#include "esp_camera.h"
|
||||
#include "time_sntp.h"
|
||||
#include "ClassControllCamera.h"
|
||||
|
||||
#include "ClassFlowControll.h"
|
||||
|
||||
#include "ClassLogFile.h"
|
||||
|
||||
ClassFlowControll tfliteflow;
|
||||
|
||||
TaskHandle_t xHandleblink_task_doFlow = NULL;
|
||||
TaskHandle_t xHandletask_autodoFlow = NULL;
|
||||
|
||||
|
||||
bool flowisrunning = false;
|
||||
|
||||
long auto_intervall = 0;
|
||||
bool auto_isrunning = false;
|
||||
|
||||
void KillTFliteTasks()
|
||||
{
|
||||
printf("Handle: xHandleblink_task_doFlow: %ld\n", (long) xHandleblink_task_doFlow);
|
||||
if (xHandleblink_task_doFlow)
|
||||
{
|
||||
vTaskDelete(xHandleblink_task_doFlow);
|
||||
printf("Killed: xHandleblink_task_doFlow\n");
|
||||
}
|
||||
|
||||
printf("Handle: xHandletask_autodoFlow: %ld\n", (long) xHandletask_autodoFlow);
|
||||
if (xHandletask_autodoFlow)
|
||||
{
|
||||
vTaskDelete(xHandletask_autodoFlow);
|
||||
printf("Killed: xHandletask_autodoFlow\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void doInit(void)
|
||||
{
|
||||
string config = "/sdcard/config/config.ini";
|
||||
printf("Start tfliteflow.InitFlow(config);\n");
|
||||
tfliteflow.InitFlow(config);
|
||||
printf("Finished tfliteflow.InitFlow(config);\n");
|
||||
}
|
||||
|
||||
|
||||
bool doflow(void)
|
||||
{
|
||||
int i;
|
||||
std::string zw_time = gettimestring("%Y%m%d-%H%M%S");
|
||||
printf("doflow - start %s\n", zw_time.c_str());
|
||||
flowisrunning = true;
|
||||
tfliteflow.doFlow(zw_time);
|
||||
flowisrunning = false;
|
||||
|
||||
printf("doflow - end %s\n", zw_time.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
void blink_task_doFlow(void *pvParameter)
|
||||
{
|
||||
printf("blink_task_doFlow\n");
|
||||
if (!flowisrunning)
|
||||
{
|
||||
flowisrunning = true;
|
||||
doflow();
|
||||
flowisrunning = false;
|
||||
}
|
||||
vTaskDelete(NULL); //Delete this task if it exits from the loop above
|
||||
xHandleblink_task_doFlow = NULL;
|
||||
}
|
||||
|
||||
|
||||
esp_err_t handler_init(httpd_req_t *req)
|
||||
{
|
||||
LogFile.WriteToFile("handler_init");
|
||||
printf("handler_doinit uri:\n"); printf(req->uri); printf("\n");
|
||||
|
||||
char* resp_str = "Init started<br>";
|
||||
httpd_resp_send(req, resp_str, strlen(resp_str));
|
||||
|
||||
doInit();
|
||||
|
||||
resp_str = "Init done<br>";
|
||||
httpd_resp_send(req, resp_str, strlen(resp_str));
|
||||
/* Respond with an empty chunk to signal HTTP response completion */
|
||||
httpd_resp_send_chunk(req, NULL, 0);
|
||||
|
||||
return ESP_OK;
|
||||
};
|
||||
|
||||
esp_err_t handler_doflow(httpd_req_t *req)
|
||||
{
|
||||
LogFile.WriteToFile("handler_doflow");
|
||||
char* resp_str;
|
||||
|
||||
printf("handler_doFlow uri: "); printf(req->uri); printf("\n");
|
||||
|
||||
if (flowisrunning)
|
||||
{
|
||||
const char* resp_str = "doFlow läuft bereits und kann nicht nochmal gestartet werden";
|
||||
httpd_resp_send(req, resp_str, strlen(resp_str));
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
xTaskCreate(&blink_task_doFlow, "blink_doFlow", configMINIMAL_STACK_SIZE * 64, NULL, tskIDLE_PRIORITY+1, &xHandleblink_task_doFlow);
|
||||
}
|
||||
resp_str = "doFlow gestartet - dauert ca. 60 Sekunden";
|
||||
httpd_resp_send(req, resp_str, strlen(resp_str));
|
||||
/* Respond with an empty chunk to signal HTTP response completion */
|
||||
httpd_resp_send_chunk(req, NULL, 0);
|
||||
return ESP_OK;
|
||||
};
|
||||
|
||||
|
||||
|
||||
esp_err_t handler_wasserzaehler(httpd_req_t *req)
|
||||
{
|
||||
LogFile.WriteToFile("handler_wasserzaehler");
|
||||
const char* resp_str;
|
||||
string zw;
|
||||
bool _rawValue = false;
|
||||
|
||||
printf("handler_wasserzaehler uri:\n"); printf(req->uri); printf("\n");
|
||||
|
||||
char _query[100];
|
||||
char _size[10];
|
||||
|
||||
if (httpd_req_get_url_query_str(req, _query, 100) == ESP_OK)
|
||||
{
|
||||
// printf("Query: "); printf(_query); printf("\n");
|
||||
if (httpd_query_key_value(_query, "rawvalue", _size, 10) == ESP_OK)
|
||||
{
|
||||
printf("rawvalue is found"); printf(_size); printf("\n");
|
||||
_rawValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
zw = tfliteflow.getReadout(_rawValue);
|
||||
zw = zw + "<br>";
|
||||
resp_str = zw.c_str();
|
||||
httpd_resp_sendstr_chunk(req, resp_str);
|
||||
|
||||
string query = std::string(_query);
|
||||
// printf("Query: %s\n", query.c_str());
|
||||
if (query.find("full") != std::string::npos)
|
||||
{
|
||||
string txt, zw;
|
||||
|
||||
txt = "<p>Aligned Image: <p><img src=\"/img_tmp/alg.jpg\"> <p>\n";
|
||||
txt = txt + "Digital Counter: <p> ";
|
||||
httpd_resp_sendstr_chunk(req, txt.c_str());
|
||||
|
||||
std::vector<HTMLInfo*> htmlinfo;
|
||||
htmlinfo = tfliteflow.GetAllDigital();
|
||||
for (int i = 0; i < htmlinfo.size(); ++i)
|
||||
{
|
||||
if (htmlinfo[i]->val == 10)
|
||||
zw = "NaN";
|
||||
else
|
||||
{
|
||||
zw = to_string((int) htmlinfo[i]->val);
|
||||
}
|
||||
txt = "<img src=\"/img_tmp/" + htmlinfo[i]->filename + "\"> " + zw;
|
||||
httpd_resp_sendstr_chunk(req, txt.c_str());
|
||||
delete htmlinfo[i];
|
||||
}
|
||||
htmlinfo.clear();
|
||||
|
||||
txt = " <p> Analog Meter: <p> ";
|
||||
httpd_resp_sendstr_chunk(req, txt.c_str());
|
||||
|
||||
htmlinfo = tfliteflow.GetAllAnalog();
|
||||
for (int i = 0; i < htmlinfo.size(); ++i)
|
||||
{
|
||||
std::stringstream stream;
|
||||
stream << std::fixed << std::setprecision(1) << htmlinfo[i]->val;
|
||||
zw = stream.str();
|
||||
|
||||
txt = "<img src=\"/img_tmp/" + htmlinfo[i]->filename + "\"> " + zw;
|
||||
httpd_resp_sendstr_chunk(req, txt.c_str());
|
||||
delete htmlinfo[i];
|
||||
}
|
||||
htmlinfo.clear();
|
||||
|
||||
|
||||
/*
|
||||
for i in range(len(resultdigital)):
|
||||
if resultdigital[i] == 'NaN':
|
||||
zw = 'NaN'
|
||||
else:
|
||||
zw = str(int(resultdigital[i]))
|
||||
txt += '<img src=/image_tmp/'+ str(resultcut[1][i][0]) + '.jpg></img>' + zw
|
||||
txt = txt + '<p>'
|
||||
if self.AnalogReadOutEnabled:
|
||||
txt = txt + 'Analog Meter: <p>'
|
||||
for i in range(len(resultanalog)):
|
||||
txt += '<img src=/image_tmp/'+ str(resultcut[0][i][0]) + '.jpg></img>' + "{:.1f}".format(resultanalog[i])
|
||||
txt = txt + '<p>'
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Respond with an empty chunk to signal HTTP response completion */
|
||||
httpd_resp_sendstr_chunk(req, NULL);
|
||||
|
||||
return ESP_OK;
|
||||
};
|
||||
|
||||
|
||||
esp_err_t handler_prevalue(httpd_req_t *req)
|
||||
{
|
||||
LogFile.WriteToFile("handler_prevalue");
|
||||
const char* resp_str;
|
||||
string zw;
|
||||
|
||||
// printf("handler_prevalue:\n"); printf(req->uri); printf("\n");
|
||||
|
||||
char _query[100];
|
||||
char _size[10] = "";
|
||||
|
||||
if (httpd_req_get_url_query_str(req, _query, 100) == ESP_OK)
|
||||
{
|
||||
// printf("Query: "); printf(_query); printf("\n");
|
||||
if (httpd_query_key_value(_query, "value", _size, 10) == ESP_OK)
|
||||
{
|
||||
printf("Value: "); printf(_size); printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (strlen(_size) == 0)
|
||||
zw = "Actual PreValue: " + tfliteflow.GetPrevalue();
|
||||
else
|
||||
zw = "SetPrevalue to " + tfliteflow.UpdatePrevalue(_size);
|
||||
|
||||
resp_str = zw.c_str();
|
||||
|
||||
httpd_resp_send(req, resp_str, strlen(resp_str));
|
||||
/* Respond with an empty chunk to signal HTTP response completion */
|
||||
httpd_resp_send_chunk(req, NULL, 0);
|
||||
|
||||
return ESP_OK;
|
||||
};
|
||||
|
||||
|
||||
void task_autodoFlow(void *pvParameter)
|
||||
{
|
||||
int64_t fr_start, fr_delta_ms;
|
||||
|
||||
doInit();
|
||||
|
||||
auto_isrunning = tfliteflow.isAutoStart(auto_intervall);
|
||||
|
||||
while (auto_isrunning)
|
||||
{
|
||||
LogFile.WriteToFile("task_autodoFlow - next round");
|
||||
printf("Autoflow: start\n");
|
||||
fr_start = esp_timer_get_time();
|
||||
|
||||
if (flowisrunning)
|
||||
{
|
||||
printf("Autoflow: doFLow laeuft bereits!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Autoflow: doFLow wird gestartet\n");
|
||||
flowisrunning = true;
|
||||
doflow();
|
||||
}
|
||||
|
||||
LogFile.WriteToFile("task_autodoFlow - round done");
|
||||
fr_delta_ms = (esp_timer_get_time() - fr_start) / 1000;
|
||||
const TickType_t xDelay = (auto_intervall - fr_delta_ms) / portTICK_PERIOD_MS;
|
||||
printf("Autoflow: sleep for : %ldms\n", (long) xDelay);
|
||||
vTaskDelay( xDelay );
|
||||
}
|
||||
vTaskDelete(NULL); //Delete this task if it exits from the loop above
|
||||
xHandletask_autodoFlow = NULL;
|
||||
}
|
||||
|
||||
void TFliteDoAutoStart()
|
||||
{
|
||||
xTaskCreate(&task_autodoFlow, "task_autodoFlow", configMINIMAL_STACK_SIZE * 64, NULL, tskIDLE_PRIORITY+1, &xHandletask_autodoFlow);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void register_server_tflite_uri(httpd_handle_t server)
|
||||
{
|
||||
ESP_LOGI(TAGTFLITE, "server_part_camera - Registering URI handlers");
|
||||
|
||||
httpd_uri_t camuri = { };
|
||||
camuri.method = HTTP_GET;
|
||||
|
||||
camuri.uri = "/doinit";
|
||||
camuri.handler = handler_init;
|
||||
camuri.user_ctx = (void*) "Light On";
|
||||
httpd_register_uri_handler(server, &camuri);
|
||||
|
||||
camuri.uri = "/setPreValue.html";
|
||||
camuri.handler = handler_prevalue;
|
||||
camuri.user_ctx = (void*) "Prevalue";
|
||||
httpd_register_uri_handler(server, &camuri);
|
||||
|
||||
camuri.uri = "/doflow";
|
||||
camuri.handler = handler_doflow;
|
||||
camuri.user_ctx = (void*) "Light Off";
|
||||
httpd_register_uri_handler(server, &camuri);
|
||||
|
||||
camuri.uri = "/wasserzaehler.html";
|
||||
camuri.handler = handler_wasserzaehler;
|
||||
camuri.user_ctx = (void*) "Wasserzaehler";
|
||||
httpd_register_uri_handler(server, &camuri);
|
||||
}
|
||||
13
code/src/server_tflite.h
Normal file
13
code/src/server_tflite.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#include <esp_log.h>
|
||||
|
||||
#include <esp_http_server.h>
|
||||
|
||||
//#include "ClassControllCamera.h"
|
||||
|
||||
static const char *TAGTFLITE = "server_tflite";
|
||||
|
||||
void register_server_tflite_uri(httpd_handle_t server);
|
||||
|
||||
void KillTFliteTasks();
|
||||
|
||||
void TFliteDoAutoStart();
|
||||
101
code/src/upload_script.html
Normal file
101
code/src/upload_script.html
Normal file
@@ -0,0 +1,101 @@
|
||||
<table class="fixed" border="0">
|
||||
<col width="300px" /><col width="200px" />
|
||||
<tr><td>
|
||||
<h2>ESP32 File Server</h2>
|
||||
</td><td>
|
||||
<button id="dirup" type="button" onclick="dirup()">Directory up</button>
|
||||
</td>
|
||||
<td>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td>
|
||||
<label for="newfile">Upload a file</label>
|
||||
</td>
|
||||
<td colspan="2">
|
||||
<input id="newfile" type="file" onchange="setpath()" style="width:100%;">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="filepath">Set path on server</label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="filepath" type="text" style="width:100%;">
|
||||
</td>
|
||||
<td>
|
||||
<button id="upload" type="button" onclick="upload()">Upload</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td></tr>
|
||||
</table>
|
||||
<script>
|
||||
function setpath() {
|
||||
var fileserverpraefix = "/fileserver";
|
||||
var anz_zeichen_fileserver = fileserverpraefix.length;
|
||||
var default_path = window.location.pathname.substring(anz_zeichen_fileserver) + document.getElementById("newfile").files[0].name;
|
||||
document.getElementById("filepath").value = default_path;
|
||||
}
|
||||
|
||||
function dirup() {
|
||||
var str = window.location.href;
|
||||
str = str.substring(0, str.length-1);
|
||||
var zw = str.indexOf("/");
|
||||
var found = zw;
|
||||
while (zw >= 0)
|
||||
{
|
||||
zw = str.indexOf("/", found+1);
|
||||
if (zw >= 0)
|
||||
found = zw;
|
||||
}
|
||||
var res = str.substring(0, found+1);
|
||||
window.location.href = res;
|
||||
}
|
||||
|
||||
function upload() {
|
||||
var filePath = document.getElementById("filepath").value;
|
||||
var upload_path = "/upload/" + filePath;
|
||||
var fileInput = document.getElementById("newfile").files;
|
||||
|
||||
/* Max size of an individual file. Make sure this
|
||||
* value is same as that set in file_server.c */
|
||||
var MAX_FILE_SIZE = 2000*1024;
|
||||
var MAX_FILE_SIZE_STR = "2000KB";
|
||||
|
||||
if (fileInput.length == 0) {
|
||||
alert("No file selected!");
|
||||
} else if (filePath.length == 0) {
|
||||
alert("File path on server is not set!");
|
||||
} else if (filePath.indexOf(' ') >= 0) {
|
||||
alert("File path on server cannot have spaces!");
|
||||
} else if (filePath[filePath.length-1] == '/') {
|
||||
alert("File name not specified after path!");
|
||||
} else if (fileInput[0].size > 2000*1024) {
|
||||
alert("File size must be less than 2000KB!");
|
||||
} else {
|
||||
document.getElementById("newfile").disabled = true;
|
||||
document.getElementById("filepath").disabled = true;
|
||||
document.getElementById("upload").disabled = true;
|
||||
|
||||
var file = fileInput[0];
|
||||
var xhttp = new XMLHttpRequest();
|
||||
xhttp.onreadystatechange = function() {
|
||||
if (xhttp.readyState == 4) {
|
||||
if (xhttp.status == 200) {
|
||||
document.open();
|
||||
document.write(xhttp.responseText);
|
||||
document.close();
|
||||
} else if (xhttp.status == 0) {
|
||||
alert("Server closed the connection abruptly!");
|
||||
location.reload()
|
||||
} else {
|
||||
alert(xhttp.status + " Error!\n" + xhttp.responseText);
|
||||
location.reload()
|
||||
}
|
||||
}
|
||||
};
|
||||
xhttp.open("POST", upload_path, true);
|
||||
xhttp.send(file);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user