mirror of
https://github.com/jomjol/AI-on-the-edge-device.git
synced 2025-12-12 22:47:01 +03:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
81a57d32a8 | ||
|
|
331e3533cc | ||
|
|
b24b7d5ce2 | ||
|
|
c2a55e7c86 | ||
|
|
03c84a1ff3 | ||
|
|
b5e0d6ee66 |
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -7,3 +7,6 @@
|
||||
[submodule "code/components/tflite-micro-esp-examples"]
|
||||
path = code/components/tflite-micro-esp-examples
|
||||
url = https://github.com/espressif/tflite-micro-esp-examples.git
|
||||
[submodule "code/components/stb"]
|
||||
path = code/components/stb
|
||||
url = https://github.com/nothings/stb.git
|
||||
|
||||
86
Changelog.md
86
Changelog.md
@@ -1,3 +1,85 @@
|
||||
## [15.2.3] - 2023-05-01
|
||||
|
||||
### Changes
|
||||
|
||||
For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/v15.2.1...v15.2.2)
|
||||
|
||||
#### Changed
|
||||
- Updated PlatformIO to `6.2.0`
|
||||
- [#2376](https://github.com/jomjol/AI-on-the-edge-device/pull/2376) Improve logging if Autostart is not enabled
|
||||
|
||||
#### Fixed
|
||||
- [#2373](https://github.com/jomjol/AI-on-the-edge-device/pull/2373) Allow the Alignment Mark step while status is "Initializing" or "Initialization (delayed)" or while in setup mode
|
||||
- [#2381](https://github.com/jomjol/AI-on-the-edge-device/pull/2381) Fix broken sysinfo REST API
|
||||
|
||||
|
||||
## [15.2.1] - 2023-04-27
|
||||
|
||||
### Changes
|
||||
|
||||
For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/v15.2.0...v15.2.1)
|
||||
|
||||
#### Fixed
|
||||
- [#2357](https://github.com/jomjol/AI-on-the-edge-device/pull/2357) Fix Alignment Mark issue
|
||||
|
||||
|
||||
## [15.2.0] - 2023-04-23
|
||||
|
||||
### Changes
|
||||
|
||||
For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/v15.1.1...v15.2.0)
|
||||
|
||||
#### Added
|
||||
|
||||
- [#2286](https://github.com/jomjol/AI-on-the-edge-device/pull/2286) Implement a camera livestream handler
|
||||
- [#2252](https://github.com/jomjol/AI-on-the-edge-device/pull/2252) Set prevalue using MQTT + set prevalue to RAW value (REST+MQTT)
|
||||
- [#2319](https://github.com/jomjol/AI-on-the-edge-device/pull/2319) Extend InfluxDBv1 with individual topic names
|
||||
|
||||
#### Changed
|
||||
|
||||
- [#2285](https://github.com/jomjol/AI-on-the-edge-device/pull/2285) Re-implemented PSRAM usage
|
||||
- [#2325](https://github.com/jomjol/AI-on-the-edge-device/pull/2325) Keep MainFlowTask alive to handle reboot
|
||||
- [#2233](https://github.com/jomjol/AI-on-the-edge-device/pull/2233) Remove trailing slash in influxDBv1
|
||||
- [#2305](https://github.com/jomjol/AI-on-the-edge-device/pull/2305) Migration of PlatformIO `5.2.0` to `6.1.0` (resp. ESP IDF from `4.4.2` to `5.0.1`)
|
||||
- Various cleanup and refactoring
|
||||
|
||||
#### Fixed
|
||||
|
||||
- [#2326](https://github.com/jomjol/AI-on-the-edge-device/pull/2326) Activate save button after Analogue ROI creationSet prevalue using MQTT + set prevalue to RAW value (REST+MQTT)
|
||||
- [#2283](https://github.com/jomjol/AI-on-the-edge-device/pull/2283) Fix Timezone issues on InfluxDB
|
||||
- Various minor fixes
|
||||
|
||||
#### Removed
|
||||
|
||||
- n.a.
|
||||
|
||||
|
||||
## [15.1.1] - 2023-03-23
|
||||
|
||||
### Changes
|
||||
|
||||
For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/v15.1.0...v15.1.1)
|
||||
|
||||
#### Added
|
||||
|
||||
- [#2206](https://github.com/jomjol/AI-on-the-edge-device/pull/2206) Log PSRAM usage
|
||||
- [#2216](https://github.com/jomjol/AI-on-the-edge-device/pull/2216) Log MQTT connection refused reasons
|
||||
|
||||
#### Changed
|
||||
|
||||
- n.a.
|
||||
|
||||
#### Fixed
|
||||
|
||||
- [#2224](https://github.com/jomjol/AI-on-the-edge-device/pull/2224), [#2213](https://github.com/jomjol/AI-on-the-edge-device/pull/2213) Reverted some of the PSRAM usage changes due to negative sideffects
|
||||
- [#2203](https://github.com/jomjol/AI-on-the-edge-device/issues/2203) Correct API for pure InfluxDB v1
|
||||
- [#2180](https://github.com/jomjol/AI-on-the-edge-device/pull/2180) Fixed links in Parameter Documentation
|
||||
- Various minor fixes
|
||||
|
||||
#### Removed
|
||||
|
||||
- n.a.
|
||||
|
||||
## [15.1.0] - 2023-03-12
|
||||
|
||||
### Update Procedure
|
||||
@@ -903,6 +985,10 @@ External Illumination
|
||||
- Initial Version
|
||||
|
||||
|
||||
[15.2.3]: https://github.com/jomjol/AI-on-the-edge-device/compare/v15.2.1...v15.2.3
|
||||
[15.2.1]: https://github.com/jomjol/AI-on-the-edge-device/compare/v15.2.0...v15.2.1
|
||||
[15.2.0]: https://github.com/jomjol/AI-on-the-edge-device/compare/v15.1.1...v15.2.0
|
||||
[15.1.1]: https://github.com/jomjol/AI-on-the-edge-device/compare/v15.1.0...v15.1.1
|
||||
[15.1.0]: https://github.com/jomjol/AI-on-the-edge-device/compare/v15.0.3...v15.1.0
|
||||
[15.0.3]: https://github.com/jomjol/AI-on-the-edge-device/compare/v14.0.3...v15.0.3
|
||||
[14.0.3]: https://github.com/jomjol/AI-on-the-edge-device/compare/v13.0.8...v14.0.3
|
||||
|
||||
@@ -1,5 +1,32 @@
|
||||
#include "SmartLeds.h"
|
||||
|
||||
|
||||
/* PlatformIO 6 (ESP IDF 5) does no longer allow access to RMTMEM,
|
||||
see https://docs.espressif.com/projects/esp-idf/en/latest/esp32/migration-guides/release-5.x/5.0/peripherals.html?highlight=rmtmem#id5
|
||||
As a dirty workaround, we copy the needed structures from rmt_struct.h
|
||||
In the long run, this should be replaced! */
|
||||
typedef struct rmt_item32_s {
|
||||
union {
|
||||
struct {
|
||||
uint32_t duration0 :15;
|
||||
uint32_t level0 :1;
|
||||
uint32_t duration1 :15;
|
||||
uint32_t level1 :1;
|
||||
};
|
||||
uint32_t val;
|
||||
};
|
||||
} rmt_item32_t;
|
||||
|
||||
//Allow access to RMT memory using RMTMEM.chan[0].data32[8]
|
||||
typedef volatile struct rmt_mem_s {
|
||||
struct {
|
||||
rmt_item32_t data32[64];
|
||||
} chan[8];
|
||||
} rmt_mem_t;
|
||||
extern rmt_mem_t RMTMEM;
|
||||
|
||||
|
||||
|
||||
IsrCore SmartLed::_interruptCore = CoreCurrent;
|
||||
intr_handle_t SmartLed::_interruptHandle = NULL;
|
||||
|
||||
|
||||
@@ -35,6 +35,20 @@
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
#include "esp_idf_version.h"
|
||||
#if (ESP_IDF_VERSION_MAJOR >= 5)
|
||||
#include "soc/periph_defs.h"
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#include "soc/gpio_sig_map.h"
|
||||
#include "soc/gpio_periph.h"
|
||||
#include "soc/io_mux_reg.h"
|
||||
#include "esp_rom_gpio.h"
|
||||
#define gpio_pad_select_gpio esp_rom_gpio_pad_select_gpio
|
||||
#define gpio_matrix_in(a,b,c) esp_rom_gpio_connect_in_signal(a,b,c)
|
||||
#define gpio_matrix_out(a,b,c,d) esp_rom_gpio_connect_out_signal(a,b,c,d)
|
||||
#define ets_delay_us(a) esp_rom_delay_us(a)
|
||||
#endif
|
||||
|
||||
#if defined ( ARDUINO )
|
||||
extern "C" { // ...someone forgot to put in the includes...
|
||||
#include "esp32-hal.h"
|
||||
@@ -65,6 +79,27 @@
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#if (ESP_IDF_VERSION_MAJOR >= 4) && (ESP_IDF_VERSION_MINOR > 1)
|
||||
#include "hal/gpio_ll.h"
|
||||
#else
|
||||
#include "soc/gpio_periph.h"
|
||||
#define esp_rom_delay_us ets_delay_us
|
||||
static inline int gpio_ll_get_level(gpio_dev_t *hw, int gpio_num)
|
||||
{
|
||||
if (gpio_num < 32) {
|
||||
return (hw->in >> gpio_num) & 0x1;
|
||||
} else {
|
||||
return (hw->in1.data >> (gpio_num - 32)) & 0x1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0))
|
||||
#if !(configENABLE_BACKWARD_COMPATIBILITY == 1)
|
||||
#define xSemaphoreHandle SemaphoreHandle_t
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "Color.h"
|
||||
|
||||
namespace detail {
|
||||
|
||||
@@ -6,9 +6,6 @@
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_event.h"
|
||||
|
||||
#include "server_tflite.h"
|
||||
|
||||
#include "esp_log.h"
|
||||
|
||||
@@ -22,8 +19,10 @@
|
||||
#include "ClassLogFile.h"
|
||||
#include "configFile.h"
|
||||
#include "Helper.h"
|
||||
|
||||
#ifdef ENABLE_MQTT
|
||||
#include "interface_mqtt.h"
|
||||
#include "interface_mqtt.h"
|
||||
#include "server_mqtt.h"
|
||||
#endif //ENABLE_MQTT
|
||||
|
||||
|
||||
@@ -331,7 +330,7 @@ bool GpioHandler::readConfig()
|
||||
|
||||
#ifdef ENABLE_MQTT
|
||||
// std::string mainTopicMQTT = "";
|
||||
std::string mainTopicMQTT = GetMQTTMainTopic();
|
||||
std::string mainTopicMQTT = mqttServer_getMainTopic();
|
||||
if (mainTopicMQTT.length() > 0)
|
||||
{
|
||||
mainTopicMQTT = mainTopicMQTT + "/GPIO";
|
||||
|
||||
@@ -4,6 +4,6 @@ list(APPEND EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/proto
|
||||
|
||||
idf_component_register(SRCS ${app_sources}
|
||||
INCLUDE_DIRS "."
|
||||
REQUIRES esp32-camera esp_http_server jomjol_logfile jomjol_image_proc nvs_flash jomjol_fileserver_ota jomjol_controlGPIO)
|
||||
REQUIRES esp_timer esp32-camera esp_http_server jomjol_logfile jomjol_image_proc nvs_flash jomjol_fileserver_ota jomjol_controlGPIO)
|
||||
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <nvs_flash.h>
|
||||
#include <sys/param.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
@@ -28,10 +29,31 @@
|
||||
#include "esp_camera.h"
|
||||
|
||||
#include "driver/ledc.h"
|
||||
#include "server_tflite.h"
|
||||
#include "MainFlowControl.h"
|
||||
|
||||
#if (ESP_IDF_VERSION_MAJOR >= 5)
|
||||
#include "soc/periph_defs.h"
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#include "soc/gpio_sig_map.h"
|
||||
#include "soc/gpio_periph.h"
|
||||
#include "soc/io_mux_reg.h"
|
||||
#include "esp_rom_gpio.h"
|
||||
#define gpio_pad_select_gpio esp_rom_gpio_pad_select_gpio
|
||||
#define gpio_matrix_in(a,b,c) esp_rom_gpio_connect_in_signal(a,b,c)
|
||||
#define gpio_matrix_out(a,b,c,d) esp_rom_gpio_connect_out_signal(a,b,c,d)
|
||||
#define ets_delay_us(a) esp_rom_delay_us(a)
|
||||
#endif
|
||||
|
||||
static const char *TAG = "CAM";
|
||||
|
||||
|
||||
/* Camera live stream */
|
||||
#define PART_BOUNDARY "123456789000000000000987654321"
|
||||
static const char* _STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY;
|
||||
static const char* _STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n";
|
||||
static const char* _STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %u\r\n\r\n";
|
||||
|
||||
|
||||
static camera_config_t camera_config = {
|
||||
.pin_pwdn = CAM_PIN_PWDN,
|
||||
.pin_reset = CAM_PIN_RESET,
|
||||
@@ -311,7 +333,7 @@ esp_err_t CCamera::CaptureToBasisImage(CImageBasis *_Image, int delay)
|
||||
loadNextDemoImage(fb);
|
||||
}
|
||||
|
||||
CImageBasis* _zwImage = new CImageBasis();
|
||||
CImageBasis* _zwImage = new CImageBasis("zwImage");
|
||||
if (_zwImage) {
|
||||
_zwImage->LoadFromMemory(fb->buf, fb->len);
|
||||
}
|
||||
@@ -512,7 +534,7 @@ esp_err_t CCamera::CaptureToHTTP(httpd_req_t *req, int delay)
|
||||
esp_camera_fb_return(fb);
|
||||
int64_t fr_end = esp_timer_get_time();
|
||||
|
||||
ESP_LOGI(TAG, "JPG: %uKB %ums", (uint32_t)(fb_len/1024), (uint32_t)((fr_end - fr_start)/1000));
|
||||
ESP_LOGI(TAG, "JPG: %dKB %dms", (int)(fb_len/1024), (int)((fr_end - fr_start)/1000));
|
||||
|
||||
if (delay > 0)
|
||||
LightOnOff(false);
|
||||
@@ -521,6 +543,74 @@ esp_err_t CCamera::CaptureToHTTP(httpd_req_t *req, int delay)
|
||||
}
|
||||
|
||||
|
||||
esp_err_t CCamera::CaptureToStream(httpd_req_t *req, bool FlashlightOn)
|
||||
{
|
||||
esp_err_t res = ESP_OK;
|
||||
size_t fb_len = 0;
|
||||
int64_t fr_start;
|
||||
char * part_buf[64];
|
||||
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Live stream started");
|
||||
|
||||
if (FlashlightOn) {
|
||||
LEDOnOff(true);
|
||||
LightOnOff(true);
|
||||
}
|
||||
|
||||
//httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); //stream is blocking web interface, only serving to local
|
||||
|
||||
httpd_resp_set_type(req, _STREAM_CONTENT_TYPE);
|
||||
httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY));
|
||||
|
||||
while(1)
|
||||
{
|
||||
fr_start = esp_timer_get_time();
|
||||
camera_fb_t *fb = esp_camera_fb_get();
|
||||
esp_camera_fb_return(fb);
|
||||
fb = esp_camera_fb_get();
|
||||
if (!fb) {
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "CaptureToStream: Camera framebuffer not available");
|
||||
break;
|
||||
}
|
||||
fb_len = fb->len;
|
||||
|
||||
if (res == ESP_OK){
|
||||
size_t hlen = snprintf((char *)part_buf, sizeof(part_buf), _STREAM_PART, fb_len);
|
||||
res = httpd_resp_send_chunk(req, (const char *)part_buf, hlen);
|
||||
}
|
||||
if (res == ESP_OK){
|
||||
res = httpd_resp_send_chunk(req, (const char *)fb->buf, fb_len);
|
||||
}
|
||||
if (res == ESP_OK){
|
||||
res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY));
|
||||
}
|
||||
|
||||
esp_camera_fb_return(fb);
|
||||
|
||||
int64_t fr_end = esp_timer_get_time();
|
||||
ESP_LOGD(TAG, "JPG: %dKB %dms", (int)(fb_len/1024), (int)((fr_end - fr_start)/1000));
|
||||
|
||||
if (res != ESP_OK){ // Exit loop, e.g. also when closing the webpage
|
||||
break;
|
||||
}
|
||||
|
||||
int64_t fr_delta_ms = (fr_end - fr_start) / 1000;
|
||||
if (CAM_LIVESTREAM_REFRESHRATE > fr_delta_ms) {
|
||||
const TickType_t xDelay = (CAM_LIVESTREAM_REFRESHRATE - fr_delta_ms) / portTICK_PERIOD_MS;
|
||||
ESP_LOGD(TAG, "Stream: sleep for: %ldms", (long) xDelay*10);
|
||||
vTaskDelay(xDelay);
|
||||
}
|
||||
}
|
||||
|
||||
LEDOnOff(false);
|
||||
LightOnOff(false);
|
||||
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Live stream stopped");
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
void CCamera::LightOnOff(bool status)
|
||||
{
|
||||
GpioHandler* gpioHandler = gpio_handler_get();
|
||||
|
||||
@@ -40,6 +40,7 @@ class CCamera {
|
||||
void LightOnOff(bool status);
|
||||
void LEDOnOff(bool status);
|
||||
esp_err_t CaptureToHTTP(httpd_req_t *req, int delay = 0);
|
||||
esp_err_t CaptureToStream(httpd_req_t *req, bool FlashlightOn);
|
||||
void SetQualitySize(int qual, framesize_t resol);
|
||||
bool SetBrightnessContrastSaturation(int _brightness, int _contrast, int _saturation);
|
||||
void GetCameraParameter(httpd_req_t *req, int &qual, framesize_t &resol);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
FILE(GLOB_RECURSE app_sources ${CMAKE_CURRENT_SOURCE_DIR}/*.*)
|
||||
|
||||
idf_component_register(SRCS ${app_sources}
|
||||
INCLUDE_DIRS "." "../../include"
|
||||
REQUIRES tflite-lib esp_http_server app_update esp_http_client nvs_flash jomjol_tfliteclass jomjol_flowcontroll spiffs jomjol_helper jomjol_controlGPIO miniz)
|
||||
INCLUDE_DIRS "." "../../include" "miniz"
|
||||
REQUIRES vfs tflite-lib esp_http_server app_update esp_http_client nvs_flash jomjol_tfliteclass jomjol_flowcontroll spiffs jomjol_helper jomjol_controlGPIO)
|
||||
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ extern "C" {
|
||||
#include "../../include/defines.h"
|
||||
#include "ClassLogFile.h"
|
||||
|
||||
#include "server_tflite.h"
|
||||
#include "MainFlowControl.h"
|
||||
|
||||
#include "server_help.h"
|
||||
#ifdef ENABLE_MQTT
|
||||
@@ -47,7 +47,6 @@ extern "C" {
|
||||
#include "Helper.h"
|
||||
#include "miniz.h"
|
||||
|
||||
|
||||
static const char *TAG = "OTA FILE";
|
||||
|
||||
struct file_server_data {
|
||||
@@ -74,7 +73,7 @@ static esp_err_t send_datafile(httpd_req_t *req, bool send_full_file);
|
||||
|
||||
esp_err_t get_numbers_file_handler(httpd_req_t *req)
|
||||
{
|
||||
std::string ret = tfliteflow.getNumbersName();
|
||||
std::string ret = flowctrl.getNumbersName();
|
||||
|
||||
// ESP_LOGI(TAG, "Result get_numbers_file_handler: %s", ret.c_str());
|
||||
|
||||
|
||||
@@ -3,7 +3,10 @@
|
||||
#include <string>
|
||||
#include "string.h"
|
||||
|
||||
#include <esp_int_wdt.h>
|
||||
/* TODO Rethink the usage of the int watchdog. It is no longer to be used, see
|
||||
https://docs.espressif.com/projects/esp-idf/en/latest/esp32/migration-guides/release-5.x/5.0/system.html?highlight=esp_int_wdt */
|
||||
#include "esp_private/esp_int_wdt.h"
|
||||
|
||||
#include <esp_task_wdt.h>
|
||||
|
||||
|
||||
@@ -11,14 +14,13 @@
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_log.h"
|
||||
#include <esp_ota_ops.h>
|
||||
#include "esp_http_client.h"
|
||||
#include "esp_flash_partitions.h"
|
||||
#include "esp_partition.h"
|
||||
#include <nvs.h>
|
||||
#include "esp_app_format.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "driver/gpio.h"
|
||||
// #include "protocol_examples_common.h"
|
||||
@@ -26,7 +28,7 @@
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "server_tflite.h"
|
||||
#include "MainFlowControl.h"
|
||||
#include "server_file.h"
|
||||
#include "server_GPIO.h"
|
||||
#ifdef ENABLE_MQTT
|
||||
@@ -157,12 +159,12 @@ static bool ota_update_task(std::string fn)
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "(This can happen if either the OTA boot data or preferred boot image become somehow corrupted.)");
|
||||
}
|
||||
ESP_LOGI(TAG, "Running partition type %d subtype %d (offset 0x%08x)",
|
||||
running->type, running->subtype, running->address);
|
||||
running->type, running->subtype, (unsigned int)running->address);
|
||||
|
||||
|
||||
update_partition = esp_ota_get_next_update_partition(NULL);
|
||||
ESP_LOGI(TAG, "Writing to partition subtype %d at offset 0x%x",
|
||||
update_partition->subtype, update_partition->address);
|
||||
update_partition->subtype, (unsigned int)update_partition->address);
|
||||
// assert(update_partition != NULL);
|
||||
|
||||
int binary_file_length = 0;
|
||||
@@ -467,7 +469,7 @@ esp_err_t handler_ota_update(httpd_req_t *req)
|
||||
{
|
||||
const char* resp_str;
|
||||
|
||||
KillTFliteTasks();
|
||||
DeleteMainFlowTask();
|
||||
gpio_handler_deinit();
|
||||
if (ota_update_task(fn))
|
||||
{
|
||||
@@ -546,7 +548,7 @@ esp_err_t handler_ota_update(httpd_req_t *req)
|
||||
/*
|
||||
const char* resp_str;
|
||||
|
||||
KillTFliteTasks();
|
||||
DeleteMainFlowTask();
|
||||
gpio_handler_deinit();
|
||||
if (ota_update_task(fn))
|
||||
{
|
||||
@@ -570,13 +572,19 @@ esp_err_t handler_ota_update(httpd_req_t *req)
|
||||
|
||||
void hard_restart()
|
||||
{
|
||||
esp_task_wdt_init(1,true);
|
||||
esp_task_wdt_config_t twdt_config = {
|
||||
.timeout_ms = 1,
|
||||
.idle_core_mask = (1 << portNUM_PROCESSORS) - 1, // Bitmask of all cores
|
||||
.trigger_panic = true,
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_task_wdt_init(&twdt_config));
|
||||
|
||||
esp_task_wdt_add(NULL);
|
||||
while(true);
|
||||
}
|
||||
|
||||
|
||||
void task_reboot(void *KillAutoFlow)
|
||||
void task_reboot(void *DeleteMainFlow)
|
||||
{
|
||||
// write a reboot, to identify a reboot by purpouse
|
||||
FILE* pfile = fopen("/sdcard/reboot.txt", "w");
|
||||
@@ -586,8 +594,8 @@ void task_reboot(void *KillAutoFlow)
|
||||
|
||||
vTaskDelay(3000 / portTICK_PERIOD_MS);
|
||||
|
||||
if ((bool)KillAutoFlow) {
|
||||
KillTFliteTasks(); // Kill autoflow task if executed in extra task, if not don't kill parent task
|
||||
if ((bool)DeleteMainFlow) {
|
||||
DeleteMainFlowTask(); // Kill autoflow task if executed in extra task, if not don't kill parent task
|
||||
}
|
||||
|
||||
Camera.LightOnOff(false);
|
||||
@@ -617,7 +625,7 @@ void doReboot()
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Reboot triggered by Software (5s)");
|
||||
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "Reboot in 5sec");
|
||||
|
||||
BaseType_t xReturned = xTaskCreate(&task_reboot, "task_reboot", configMINIMAL_STACK_SIZE * 3, (void*) true, 10, NULL);
|
||||
BaseType_t xReturned = xTaskCreate(&task_reboot, "task_reboot", configMINIMAL_STACK_SIZE * 4, (void*) true, 10, NULL);
|
||||
if( xReturned != pdPASS )
|
||||
{
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "task_reboot not created -> force reboot without killing flow");
|
||||
|
||||
@@ -2,6 +2,6 @@ FILE(GLOB_RECURSE app_sources ${CMAKE_CURRENT_SOURCE_DIR}/*.*)
|
||||
|
||||
idf_component_register(SRCS ${app_sources}
|
||||
INCLUDE_DIRS "."
|
||||
REQUIRES jomjol_tfliteclass jomjol_helper jomjol_controlcamera jomjol_mqtt jomjol_influxdb jomjol_fileserver_ota jomjol_image_proc jomjol_wlan)
|
||||
REQUIRES esp_timer esp_wifi jomjol_tfliteclass jomjol_helper jomjol_controlcamera jomjol_mqtt jomjol_influxdb jomjol_fileserver_ota jomjol_image_proc jomjol_wlan)
|
||||
|
||||
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
#include "ClassFlowAlignment.h"
|
||||
#include "ClassFlowTakeImage.h"
|
||||
#include "ClassFlow.h"
|
||||
#include "server_tflite.h"
|
||||
#include "MainFlowControl.h"
|
||||
|
||||
#include "CRotateImage.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
|
||||
#include "ClassLogFile.h"
|
||||
#include "psram.h"
|
||||
#include "../../include/defines.h"
|
||||
|
||||
|
||||
@@ -31,7 +32,7 @@ void ClassFlowAlignment::SetInitialParameter(void)
|
||||
ImageBasis = NULL;
|
||||
ImageTMP = NULL;
|
||||
#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG
|
||||
AlgROI = (ImageData*)heap_caps_malloc(sizeof(ImageData), MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);
|
||||
AlgROI = (ImageData*)malloc_psram_heap(std::string(TAG) + "->AlgROI", sizeof(ImageData), MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);
|
||||
#endif
|
||||
previousElement = NULL;
|
||||
disabled = false;
|
||||
@@ -55,7 +56,7 @@ ClassFlowAlignment::ClassFlowAlignment(std::vector<ClassFlow*>* lfc)
|
||||
if (!ImageBasis) // the function take pictures does not exist --> must be created first ONLY FOR TEST PURPOSES
|
||||
{
|
||||
ESP_LOGD(TAG, "CImageBasis had to be created");
|
||||
ImageBasis = new CImageBasis(namerawimage);
|
||||
ImageBasis = new CImageBasis("ImageBasis", namerawimage);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,17 +190,17 @@ bool ClassFlowAlignment::doFlow(string time)
|
||||
|
||||
if (!ImageTMP)
|
||||
{
|
||||
ImageTMP = new CImageBasis(ImageBasis);
|
||||
ImageTMP = new CImageBasis("tmpImage", ImageBasis); // Make sure the name does not get change, it is relevant for the PSRAM allocation!
|
||||
if (!ImageTMP)
|
||||
{
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Can't allocate ImageTMP -> Exec this round aborted!");
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Can't allocate tmpImage -> Exec this round aborted!");
|
||||
LogFile.WriteHeapInfo("ClassFlowAlignment-doFlow");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
delete AlignAndCutImage;
|
||||
AlignAndCutImage = new CAlignAndCutImage(ImageBasis, ImageTMP);
|
||||
AlignAndCutImage = new CAlignAndCutImage("AlignAndCutImage", ImageBasis, ImageTMP);
|
||||
if (!AlignAndCutImage)
|
||||
{
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Can't allocate AlignAndCutImage -> Exec this round aborted!");
|
||||
@@ -207,7 +208,7 @@ bool ClassFlowAlignment::doFlow(string time)
|
||||
return false;
|
||||
}
|
||||
|
||||
CRotateImage rt(AlignAndCutImage, ImageTMP, initialflip);
|
||||
CRotateImage rt("rawImage", AlignAndCutImage, ImageTMP, initialflip);
|
||||
if (initialflip)
|
||||
{
|
||||
int _zw = ImageBasis->height;
|
||||
@@ -255,8 +256,8 @@ bool ClassFlowAlignment::doFlow(string time)
|
||||
if(References[0].alignment_algo != 3){
|
||||
DrawRef(ImageTMP);
|
||||
}
|
||||
tfliteflow.DigitalDrawROI(ImageTMP);
|
||||
tfliteflow.AnalogDrawROI(ImageTMP);
|
||||
flowctrl.DigitalDrawROI(ImageTMP);
|
||||
flowctrl.AnalogDrawROI(ImageTMP);
|
||||
ImageTMP->writeToMemoryAsJPG((ImageData*)AlgROI, 90);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -374,15 +374,20 @@ bool ClassFlowCNNGeneral::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
}
|
||||
}
|
||||
|
||||
if (!getNetworkParameter())
|
||||
if (!getNetworkParameter()) {
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "An error occured on setting up the Network -> Disabling it!");
|
||||
disabled = true; // An error occured, disable this CNN!
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
for (int _ana = 0; _ana < GENERAL.size(); ++_ana)
|
||||
for (int i = 0; i < GENERAL[_ana]->ROI.size(); ++i)
|
||||
{
|
||||
GENERAL[_ana]->ROI[i]->image = new CImageBasis(modelxsize, modelysize, modelchannel);
|
||||
GENERAL[_ana]->ROI[i]->image_org = new CImageBasis(GENERAL[_ana]->ROI[i]->deltax, GENERAL[_ana]->ROI[i]->deltay, 3);
|
||||
GENERAL[_ana]->ROI[i]->image = new CImageBasis("ROI " + GENERAL[_ana]->ROI[i]->name,
|
||||
modelxsize, modelysize, modelchannel);
|
||||
GENERAL[_ana]->ROI[i]->image_org = new CImageBasis("ROI " + GENERAL[_ana]->ROI[i]->name + " original",
|
||||
GENERAL[_ana]->ROI[i]->deltax, GENERAL[_ana]->ROI[i]->deltay, 3);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -25,10 +25,10 @@ extern "C" {
|
||||
#endif //ENABLE_MQTT
|
||||
|
||||
#include "server_help.h"
|
||||
#include "server_tflite.h"
|
||||
#include "MainFlowControl.h"
|
||||
#include "../../include/defines.h"
|
||||
|
||||
static const char* TAG = "CTRL";
|
||||
static const char* TAG = "FLOWCTRL";
|
||||
|
||||
//#define DEBUG_DETAIL_ON
|
||||
|
||||
@@ -99,8 +99,6 @@ std::string ClassFlowControll::TranslateAktstatus(std::string _input)
|
||||
#endif //ENABLE_INFLUXDB
|
||||
if (_input.compare("ClassFlowPostProcessing") == 0)
|
||||
return ("Post-Processing");
|
||||
if (_input.compare("ClassFlowWriteList") == 0)
|
||||
return ("Writing List");
|
||||
|
||||
return "Unkown Status";
|
||||
}
|
||||
@@ -164,16 +162,8 @@ void ClassFlowControll::AnalogDrawROI(CImageBasis *_zw)
|
||||
|
||||
|
||||
#ifdef ENABLE_MQTT
|
||||
string ClassFlowControll::GetMQTTMainTopic()
|
||||
bool ClassFlowControll::StartMQTTService()
|
||||
{
|
||||
for (int i = 0; i < FlowControll.size(); ++i)
|
||||
if (FlowControll[i]->name().compare("ClassFlowMQTT") == 0)
|
||||
return ((ClassFlowMQTT*) (FlowControll[i]))->GetMQTTMainTopic();
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
bool ClassFlowControll::StartMQTTService() {
|
||||
/* Start the MQTT service */
|
||||
for (int i = 0; i < FlowControll.size(); ++i) {
|
||||
if (FlowControll[i]->name().compare("ClassFlowMQTT") == 0) {
|
||||
@@ -200,10 +190,15 @@ void ClassFlowControll::SetInitialParameter(void)
|
||||
}
|
||||
|
||||
|
||||
bool ClassFlowControll::isAutoStart(long &_interval)
|
||||
bool ClassFlowControll::getIsAutoStart(void)
|
||||
{
|
||||
return AutoStart;
|
||||
}
|
||||
|
||||
|
||||
void ClassFlowControll::setAutoStartInterval(long &_interval)
|
||||
{
|
||||
_interval = AutoInterval * 60 * 1000; // AutoInterval: minutes -> ms
|
||||
return AutoStart;
|
||||
}
|
||||
|
||||
|
||||
@@ -243,8 +238,6 @@ ClassFlow* ClassFlowControll::CreateClassFlow(std::string _type)
|
||||
if (toUpper(_type).compare("[INFLUXDBV2]") == 0)
|
||||
cfc = new ClassFlowInfluxDBv2(&FlowControll);
|
||||
#endif //ENABLE_INFLUXDB
|
||||
if (toUpper(_type).compare("[WRITELIST]") == 0)
|
||||
cfc = new ClassFlowWriteList(&FlowControll);
|
||||
|
||||
if (toUpper(_type).compare("[POSTPROCESSING]") == 0)
|
||||
{
|
||||
@@ -385,7 +378,7 @@ bool ClassFlowControll::doFlow(string time)
|
||||
zw_time = getCurrentTimeString("%H:%M:%S");
|
||||
aktstatus = TranslateAktstatus(FlowControll[i]->name());
|
||||
aktstatusWithTime = aktstatus + " (" + zw_time + ")";
|
||||
//LogFile.WriteToFile(ESP_LOG_INFO, TAG, aktstatusWithTime);
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Status: " + aktstatusWithTime);
|
||||
#ifdef ENABLE_MQTT
|
||||
MQTTPublish(mqttServer_getMainTopic() + "/" + "status", aktstatus, qos, false);
|
||||
#endif //ENABLE_MQTT
|
||||
@@ -470,10 +463,10 @@ string ClassFlowControll::getReadoutAll(int _type)
|
||||
}
|
||||
|
||||
|
||||
string ClassFlowControll::getReadout(bool _rawvalue = false, bool _noerror = false)
|
||||
string ClassFlowControll::getReadout(bool _rawvalue = false, bool _noerror = false, int _number = 0)
|
||||
{
|
||||
if (flowpostprocessing)
|
||||
return flowpostprocessing->getReadoutParam(_rawvalue, _noerror);
|
||||
return flowpostprocessing->getReadoutParam(_rawvalue, _noerror, _number);
|
||||
|
||||
string zw = "";
|
||||
string result = "";
|
||||
@@ -501,37 +494,40 @@ string ClassFlowControll::GetPrevalue(std::string _number)
|
||||
return flowpostprocessing->GetPreValue(_number);
|
||||
}
|
||||
|
||||
|
||||
return std::string("");
|
||||
}
|
||||
|
||||
|
||||
std::string ClassFlowControll::UpdatePrevalue(std::string _newvalue, std::string _numbers, bool _extern)
|
||||
bool ClassFlowControll::UpdatePrevalue(std::string _newvalue, std::string _numbers, bool _extern)
|
||||
{
|
||||
float zw;
|
||||
double newvalueAsDouble;
|
||||
char* p;
|
||||
|
||||
_newvalue = trim(_newvalue);
|
||||
// ESP_LOGD(TAG, "Input UpdatePreValue: %s", _newvalue.c_str());
|
||||
//ESP_LOGD(TAG, "Input UpdatePreValue: %s", _newvalue.c_str());
|
||||
|
||||
if (_newvalue.compare("0.0") == 0)
|
||||
{
|
||||
zw = 0;
|
||||
if (_newvalue.substr(0,8).compare("0.000000") == 0 || _newvalue.compare("0.0") == 0 || _newvalue.compare("0") == 0) {
|
||||
newvalueAsDouble = 0; // preset to value = 0
|
||||
}
|
||||
else
|
||||
{
|
||||
zw = strtof(_newvalue.c_str(), &p);
|
||||
if (zw == 0)
|
||||
return "- Error in String to Value Conversion!!! Must be of format value=123.456";
|
||||
else {
|
||||
newvalueAsDouble = strtod(_newvalue.c_str(), &p);
|
||||
if (newvalueAsDouble == 0) {
|
||||
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "UpdatePrevalue: No valid value for processing: " + _newvalue);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (flowpostprocessing)
|
||||
{
|
||||
flowpostprocessing->SetPreValue(zw, _numbers, _extern);
|
||||
return _newvalue;
|
||||
if (flowpostprocessing) {
|
||||
if (flowpostprocessing->SetPreValue(newvalueAsDouble, _numbers, _extern))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "UpdatePrevalue: ERROR - Class Post-Processing not initialized");
|
||||
return false;
|
||||
}
|
||||
|
||||
return std::string();
|
||||
}
|
||||
|
||||
|
||||
@@ -737,7 +733,7 @@ esp_err_t ClassFlowControll::GetJPGStream(std::string _fn, httpd_req_t *req)
|
||||
|
||||
httpd_resp_set_type(req, "image/jpeg");
|
||||
result = httpd_resp_send(req, (const char *)fileBuffer, fileSize);
|
||||
delete fileBuffer;
|
||||
free(fileBuffer);
|
||||
}
|
||||
else if (aktstatus.find("Initialization") != -1) {
|
||||
FILE* file = fopen("/sdcard/html/Flowstate_initialization.jpg", "rb");
|
||||
@@ -764,7 +760,7 @@ esp_err_t ClassFlowControll::GetJPGStream(std::string _fn, httpd_req_t *req)
|
||||
|
||||
httpd_resp_set_type(req, "image/jpeg");
|
||||
result = httpd_resp_send(req, (const char *)fileBuffer, fileSize);
|
||||
delete fileBuffer;
|
||||
free(fileBuffer);
|
||||
}
|
||||
else if (aktstatus.find("Take Image") != -1) {
|
||||
if (flowalignment && flowalignment->AlgROI) {
|
||||
@@ -826,7 +822,7 @@ esp_err_t ClassFlowControll::GetJPGStream(std::string _fn, httpd_req_t *req)
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
_send = new CImageBasis(flowalignment->ImageBasis);
|
||||
_send = new CImageBasis("alg_roi", flowalignment->ImageBasis);
|
||||
|
||||
if (_send->ImageOkay()) {
|
||||
if (flowalignment) flowalignment->DrawRef(_send);
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#include "ClassFlowInfluxDBv2.h"
|
||||
#endif //ENABLE_INFLUXDB
|
||||
#include "ClassFlowCNNGeneral.h"
|
||||
#include "ClassFlowWriteList.h"
|
||||
|
||||
class ClassFlowControll :
|
||||
public ClassFlow
|
||||
@@ -46,9 +45,9 @@ public:
|
||||
bool doFlow(string time);
|
||||
void doFlowTakeImageOnly(string time);
|
||||
bool getStatusSetupModus(){return SetupModeActive;};
|
||||
string getReadout(bool _rawvalue, bool _noerror);
|
||||
string getReadout(bool _rawvalue, bool _noerror, int _number);
|
||||
string getReadoutAll(int _type);
|
||||
string UpdatePrevalue(std::string _newvalue, std::string _numbers, bool _extern);
|
||||
bool UpdatePrevalue(std::string _newvalue, std::string _numbers, bool _extern);
|
||||
string GetPrevalue(std::string _number = "");
|
||||
bool ReadParameter(FILE* pfile, string& aktparamgraph);
|
||||
string getJSON();
|
||||
@@ -56,10 +55,6 @@ public:
|
||||
|
||||
string TranslateAktstatus(std::string _input);
|
||||
|
||||
#ifdef ENABLE_MQTT
|
||||
string GetMQTTMainTopic();
|
||||
#endif //ENABLE_MQTT
|
||||
|
||||
#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG
|
||||
void DigitalDrawROI(CImageBasis *_zw);
|
||||
void AnalogDrawROI(CImageBasis *_zw);
|
||||
@@ -70,7 +65,8 @@ public:
|
||||
|
||||
std::string doSingleStep(std::string _stepname, std::string _host);
|
||||
|
||||
bool isAutoStart(long &_interval);
|
||||
bool getIsAutoStart();
|
||||
void setAutoStartInterval(long &_interval);
|
||||
|
||||
std::string* getActStatusWithTime();
|
||||
std::string* getActStatus();
|
||||
|
||||
@@ -50,7 +50,12 @@ struct NumberPost {
|
||||
int DecimalShiftInitial;
|
||||
float AnalogDigitalTransitionStart; // When is the digit > x.1, i.e. when does it start to tilt?
|
||||
int Nachkomma;
|
||||
string Fieldname; // Fieldname in InfluxDB2
|
||||
|
||||
string FieldV1; // Fieldname in InfluxDBv1
|
||||
string MeasurementV1; // Measurement in InfluxDBv1
|
||||
|
||||
string FieldV2; // Fieldname in InfluxDBv2
|
||||
string MeasurementV2; // Measurement in InfluxDBv2
|
||||
|
||||
bool isExtendedResolution;
|
||||
|
||||
|
||||
@@ -17,7 +17,8 @@ extern "C" {
|
||||
#include "esp_log.h"
|
||||
#include "../../include/defines.h"
|
||||
|
||||
static const char* TAG = "IMG";
|
||||
static const char* TAG = "FLOWIMAGE";
|
||||
|
||||
|
||||
ClassFlowImage::ClassFlowImage(const char* logTag)
|
||||
{
|
||||
|
||||
@@ -15,13 +15,12 @@
|
||||
|
||||
#include <time.h>
|
||||
|
||||
static const char* TAG = "class_flow_influxDb";
|
||||
static const char* TAG = "INFLUXDB";
|
||||
|
||||
void ClassFlowInfluxDB::SetInitialParameter(void)
|
||||
{
|
||||
uri = "";
|
||||
database = "";
|
||||
measurement = "";
|
||||
|
||||
OldValue = "";
|
||||
flowpostprocessing = NULL;
|
||||
@@ -86,33 +85,39 @@ bool ClassFlowInfluxDB::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
{
|
||||
ESP_LOGD(TAG, "while loop reading line: %s", aktparamgraph.c_str());
|
||||
splitted = ZerlegeZeile(aktparamgraph);
|
||||
if ((toUpper(splitted[0]) == "USER") && (splitted.size() > 1))
|
||||
std::string _param = GetParameterName(splitted[0]);
|
||||
|
||||
if ((toUpper(_param) == "USER") && (splitted.size() > 1))
|
||||
{
|
||||
this->user = splitted[1];
|
||||
}
|
||||
if ((toUpper(splitted[0]) == "PASSWORD") && (splitted.size() > 1))
|
||||
if ((toUpper(_param) == "PASSWORD") && (splitted.size() > 1))
|
||||
{
|
||||
this->password = splitted[1];
|
||||
}
|
||||
if ((toUpper(splitted[0]) == "URI") && (splitted.size() > 1))
|
||||
if ((toUpper(_param) == "URI") && (splitted.size() > 1))
|
||||
{
|
||||
this->uri = splitted[1];
|
||||
}
|
||||
if (((toUpper(splitted[0]) == "MEASUREMENT")) && (splitted.size() > 1))
|
||||
{
|
||||
this->measurement = splitted[1];
|
||||
}
|
||||
if (((toUpper(splitted[0]) == "DATABASE")) && (splitted.size() > 1))
|
||||
if (((toUpper(_param) == "DATABASE")) && (splitted.size() > 1))
|
||||
{
|
||||
this->database = splitted[1];
|
||||
}
|
||||
if (((toUpper(_param) == "MEASUREMENT")) && (splitted.size() > 1))
|
||||
{
|
||||
handleMeasurement(splitted[0], splitted[1]);
|
||||
}
|
||||
if (((toUpper(_param) == "FIELD")) && (splitted.size() > 1))
|
||||
{
|
||||
handleFieldname(splitted[0], splitted[1]);
|
||||
}
|
||||
}
|
||||
|
||||
if ((uri.length() > 0) && (database.length() > 0) && (measurement.length() > 0))
|
||||
if ((uri.length() > 0) && (database.length() > 0))
|
||||
{
|
||||
// ESP_LOGD(TAG, "Init InfluxDB with uri: %s, measurement: %s, user: %s, password: %s", uri.c_str(), measurement.c_str(), user.c_str(), password.c_str());
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Init InfluxDB with uri: " + uri + ", measurement: " + measurement + ", user: " + user + ", password: " + password);
|
||||
InfluxDBInit(uri, database, measurement, user, password);
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Init InfluxDB with uri: " + uri + ", user: " + user + ", password: " + password);
|
||||
InfluxDBInit(uri, database, user, password);
|
||||
InfluxDBenable = true;
|
||||
} else {
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "InfluxDB init skipped as we are missing some parameters");
|
||||
@@ -121,19 +126,13 @@ bool ClassFlowInfluxDB::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
string ClassFlowInfluxDB::GetInfluxDBMeasurement()
|
||||
{
|
||||
return measurement;
|
||||
}
|
||||
|
||||
|
||||
bool ClassFlowInfluxDB::doFlow(string zwtime)
|
||||
{
|
||||
if (!InfluxDBenable)
|
||||
return true;
|
||||
|
||||
std::string result;
|
||||
std::string measurement;
|
||||
std::string resulterror = "";
|
||||
std::string resultraw = "";
|
||||
std::string resultrate = "";
|
||||
@@ -147,20 +146,28 @@ bool ClassFlowInfluxDB::doFlow(string zwtime)
|
||||
|
||||
for (int i = 0; i < (*NUMBERS).size(); ++i)
|
||||
{
|
||||
measurement = (*NUMBERS)[i]->MeasurementV1;
|
||||
result = (*NUMBERS)[i]->ReturnValue;
|
||||
resultraw = (*NUMBERS)[i]->ReturnRawValue;
|
||||
resulterror = (*NUMBERS)[i]->ErrorMessageText;
|
||||
resultrate = (*NUMBERS)[i]->ReturnRateValue;
|
||||
resulttimestamp = (*NUMBERS)[i]->timeStamp;
|
||||
|
||||
namenumber = (*NUMBERS)[i]->name;
|
||||
if (namenumber == "default")
|
||||
namenumber = "value";
|
||||
if ((*NUMBERS)[i]->FieldV1.length() > 0)
|
||||
{
|
||||
namenumber = (*NUMBERS)[i]->FieldV1;
|
||||
}
|
||||
else
|
||||
namenumber = namenumber + "/value";
|
||||
{
|
||||
namenumber = (*NUMBERS)[i]->name;
|
||||
if (namenumber == "default")
|
||||
namenumber = "value";
|
||||
else
|
||||
namenumber = namenumber + "/value";
|
||||
}
|
||||
|
||||
if (result.length() > 0 && resulttimestamp.length() > 0)
|
||||
InfluxDBPublish(namenumber, result, resulttimestamp);
|
||||
if (result.length() > 0)
|
||||
InfluxDBPublish(measurement, namenumber, result, resulttimestamp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,4 +176,50 @@ bool ClassFlowInfluxDB::doFlow(string zwtime)
|
||||
return true;
|
||||
}
|
||||
|
||||
void ClassFlowInfluxDB::handleMeasurement(string _decsep, string _value)
|
||||
{
|
||||
string _digit, _decpos;
|
||||
int _pospunkt = _decsep.find_first_of(".");
|
||||
// ESP_LOGD(TAG, "Name: %s, Pospunkt: %d", _decsep.c_str(), _pospunkt);
|
||||
if (_pospunkt > -1)
|
||||
_digit = _decsep.substr(0, _pospunkt);
|
||||
else
|
||||
_digit = "default";
|
||||
for (int j = 0; j < flowpostprocessing->NUMBERS.size(); ++j)
|
||||
{
|
||||
if (_digit == "default") // Set to default first (if nothing else is set)
|
||||
{
|
||||
flowpostprocessing->NUMBERS[j]->MeasurementV1 = _value;
|
||||
}
|
||||
if (flowpostprocessing->NUMBERS[j]->name == _digit)
|
||||
{
|
||||
flowpostprocessing->NUMBERS[j]->MeasurementV1 = _value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ClassFlowInfluxDB::handleFieldname(string _decsep, string _value)
|
||||
{
|
||||
string _digit, _decpos;
|
||||
int _pospunkt = _decsep.find_first_of(".");
|
||||
// ESP_LOGD(TAG, "Name: %s, Pospunkt: %d", _decsep.c_str(), _pospunkt);
|
||||
if (_pospunkt > -1)
|
||||
_digit = _decsep.substr(0, _pospunkt);
|
||||
else
|
||||
_digit = "default";
|
||||
for (int j = 0; j < flowpostprocessing->NUMBERS.size(); ++j)
|
||||
{
|
||||
if (_digit == "default") // Set to default first (if nothing else is set)
|
||||
{
|
||||
flowpostprocessing->NUMBERS[j]->FieldV1 = _value;
|
||||
}
|
||||
if (flowpostprocessing->NUMBERS[j]->name == _digit)
|
||||
{
|
||||
flowpostprocessing->NUMBERS[j]->FieldV1 = _value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif //ENABLE_INFLUXDB
|
||||
@@ -21,14 +21,19 @@ protected:
|
||||
std::string user, password;
|
||||
bool InfluxDBenable;
|
||||
|
||||
void SetInitialParameter(void);
|
||||
void SetInitialParameter(void);
|
||||
|
||||
void handleFieldname(string _decsep, string _value);
|
||||
void handleMeasurement(string _decsep, string _value);
|
||||
|
||||
|
||||
|
||||
public:
|
||||
ClassFlowInfluxDB();
|
||||
ClassFlowInfluxDB(std::vector<ClassFlow*>* lfc);
|
||||
ClassFlowInfluxDB(std::vector<ClassFlow*>* lfc, ClassFlow *_prev);
|
||||
|
||||
string GetInfluxDBMeasurement();
|
||||
// string GetInfluxDBMeasurement();
|
||||
|
||||
bool ReadParameter(FILE* pfile, string& aktparamgraph);
|
||||
bool doFlow(string time);
|
||||
|
||||
@@ -15,13 +15,12 @@
|
||||
|
||||
#include <time.h>
|
||||
|
||||
static const char* TAG = "class_flow_influxDbv2";
|
||||
static const char* TAG = "INFLUXDBV2";
|
||||
|
||||
void ClassFlowInfluxDBv2::SetInitialParameter(void)
|
||||
{
|
||||
uri = "";
|
||||
database = "";
|
||||
measurement = "";
|
||||
dborg = "";
|
||||
dbtoken = "";
|
||||
// dbfield = "";
|
||||
@@ -102,14 +101,14 @@ bool ClassFlowInfluxDBv2::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
{
|
||||
this->uri = splitted[1];
|
||||
}
|
||||
if (((toUpper(_param) == "MEASUREMENT")) && (splitted.size() > 1))
|
||||
{
|
||||
this->measurement = splitted[1];
|
||||
}
|
||||
if (((toUpper(_param) == "FIELDNAME")) && (splitted.size() > 1))
|
||||
if (((toUpper(_param) == "FIELD")) && (splitted.size() > 1))
|
||||
{
|
||||
handleFieldname(splitted[0], splitted[1]);
|
||||
}
|
||||
if (((toUpper(_param) == "MEASUREMENT")) && (splitted.size() > 1))
|
||||
{
|
||||
handleMeasurement(splitted[0], splitted[1]);
|
||||
}
|
||||
if (((toUpper(splitted[0]) == "DATABASE")) && (splitted.size() > 1))
|
||||
{
|
||||
this->database = splitted[1];
|
||||
@@ -117,15 +116,14 @@ bool ClassFlowInfluxDBv2::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
}
|
||||
|
||||
printf("uri: %s\n", uri.c_str());
|
||||
printf("measurement: %s\n", measurement.c_str());
|
||||
printf("org: %s\n", dborg.c_str());
|
||||
printf("token: %s\n", dbtoken.c_str());
|
||||
|
||||
if ((uri.length() > 0) && (database.length() > 0) && (measurement.length() > 0) && (dbtoken.length() > 0) && (dborg.length() > 0))
|
||||
if ((uri.length() > 0) && (database.length() > 0) && (dbtoken.length() > 0) && (dborg.length() > 0))
|
||||
{
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Init InfluxDB with uri: " + uri + ", measurement: " + measurement + ", org: " + dborg + ", token: *****");
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Init InfluxDB with uri: " + uri + ", org: " + dborg + ", token: *****");
|
||||
// printf("vor V2 Init\n");
|
||||
InfluxDB_V2_Init(uri, database, measurement, dborg, dbtoken);
|
||||
InfluxDB_V2_Init(uri, database, dborg, dbtoken);
|
||||
// printf("nach V2 Init\n");
|
||||
InfluxDBenable = true;
|
||||
} else {
|
||||
@@ -135,11 +133,12 @@ bool ClassFlowInfluxDBv2::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
string ClassFlowInfluxDBv2::GetInfluxDBMeasurement()
|
||||
{
|
||||
return measurement;
|
||||
}
|
||||
*/
|
||||
|
||||
void ClassFlowInfluxDBv2::handleFieldname(string _decsep, string _value)
|
||||
{
|
||||
@@ -154,15 +153,36 @@ void ClassFlowInfluxDBv2::handleFieldname(string _decsep, string _value)
|
||||
{
|
||||
if (_digit == "default") // Set to default first (if nothing else is set)
|
||||
{
|
||||
flowpostprocessing->NUMBERS[j]->Fieldname = _value;
|
||||
flowpostprocessing->NUMBERS[j]->FieldV2 = _value;
|
||||
}
|
||||
if (flowpostprocessing->NUMBERS[j]->name == _digit)
|
||||
{
|
||||
flowpostprocessing->NUMBERS[j]->Fieldname = _value;
|
||||
flowpostprocessing->NUMBERS[j]->FieldV2 = _value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ClassFlowInfluxDBv2::handleMeasurement(string _decsep, string _value)
|
||||
{
|
||||
string _digit, _decpos;
|
||||
int _pospunkt = _decsep.find_first_of(".");
|
||||
// ESP_LOGD(TAG, "Name: %s, Pospunkt: %d", _decsep.c_str(), _pospunkt);
|
||||
if (_pospunkt > -1)
|
||||
_digit = _decsep.substr(0, _pospunkt);
|
||||
else
|
||||
_digit = "default";
|
||||
for (int j = 0; j < flowpostprocessing->NUMBERS.size(); ++j)
|
||||
{
|
||||
if (_digit == "default") // Set to default first (if nothing else is set)
|
||||
{
|
||||
flowpostprocessing->NUMBERS[j]->MeasurementV2 = _value;
|
||||
}
|
||||
if (flowpostprocessing->NUMBERS[j]->name == _digit)
|
||||
{
|
||||
flowpostprocessing->NUMBERS[j]->MeasurementV2 = _value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool ClassFlowInfluxDBv2::doFlow(string zwtime)
|
||||
@@ -170,6 +190,7 @@ bool ClassFlowInfluxDBv2::doFlow(string zwtime)
|
||||
if (!InfluxDBenable)
|
||||
return true;
|
||||
|
||||
std::string measurement;
|
||||
std::string result;
|
||||
std::string resulterror = "";
|
||||
std::string resultraw = "";
|
||||
@@ -178,21 +199,23 @@ bool ClassFlowInfluxDBv2::doFlow(string zwtime)
|
||||
string zw = "";
|
||||
string namenumber = "";
|
||||
|
||||
|
||||
if (flowpostprocessing)
|
||||
{
|
||||
std::vector<NumberPost*>* NUMBERS = flowpostprocessing->GetNumbers();
|
||||
|
||||
for (int i = 0; i < (*NUMBERS).size(); ++i)
|
||||
{
|
||||
measurement = (*NUMBERS)[i]->MeasurementV2;
|
||||
result = (*NUMBERS)[i]->ReturnValue;
|
||||
resultraw = (*NUMBERS)[i]->ReturnRawValue;
|
||||
resulterror = (*NUMBERS)[i]->ErrorMessageText;
|
||||
resultrate = (*NUMBERS)[i]->ReturnRateValue;
|
||||
resulttimestamp = (*NUMBERS)[i]->timeStamp;
|
||||
|
||||
if ((*NUMBERS)[i]->Fieldname.length() > 0)
|
||||
if ((*NUMBERS)[i]->FieldV2.length() > 0)
|
||||
{
|
||||
namenumber = (*NUMBERS)[i]->Fieldname;
|
||||
namenumber = (*NUMBERS)[i]->FieldV2;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -206,7 +229,7 @@ bool ClassFlowInfluxDBv2::doFlow(string zwtime)
|
||||
printf("vor sende Influx_DB_V2 - namenumber. %s, result: %s, timestampt: %s", namenumber.c_str(), result.c_str(), resulttimestamp.c_str());
|
||||
|
||||
if (result.length() > 0)
|
||||
InfluxDB_V2_Publish(namenumber, result, resulttimestamp);
|
||||
InfluxDB_V2_Publish(measurement, namenumber, result, resulttimestamp);
|
||||
// InfluxDB_V2_Publish(namenumber, result, resulttimestamp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ class ClassFlowInfluxDBv2 :
|
||||
public ClassFlow
|
||||
{
|
||||
protected:
|
||||
std::string uri, database, measurement;
|
||||
std::string uri, database;
|
||||
std::string dborg, dbtoken, dbfield;
|
||||
std::string OldValue;
|
||||
ClassFlowPostProcessing* flowpostprocessing;
|
||||
@@ -24,13 +24,15 @@ protected:
|
||||
void SetInitialParameter(void);
|
||||
|
||||
void handleFieldname(string _decsep, string _value);
|
||||
void handleMeasurement(string _decsep, string _value);
|
||||
|
||||
|
||||
public:
|
||||
ClassFlowInfluxDBv2();
|
||||
ClassFlowInfluxDBv2(std::vector<ClassFlow*>* lfc);
|
||||
ClassFlowInfluxDBv2(std::vector<ClassFlow*>* lfc, ClassFlow *_prev);
|
||||
|
||||
string GetInfluxDBMeasurement();
|
||||
// string GetInfluxDBMeasurement();
|
||||
|
||||
bool ReadParameter(FILE* pfile, string& aktparamgraph);
|
||||
bool doFlow(string time);
|
||||
|
||||
@@ -183,12 +183,6 @@ bool ClassFlowMQTT::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
}
|
||||
|
||||
|
||||
string ClassFlowMQTT::GetMQTTMainTopic()
|
||||
{
|
||||
return maintopic;
|
||||
}
|
||||
|
||||
|
||||
bool ClassFlowMQTT::Start(float AutoInterval)
|
||||
{
|
||||
roundInterval = AutoInterval; // Minutes
|
||||
|
||||
@@ -31,7 +31,6 @@ public:
|
||||
ClassFlowMQTT(std::vector<ClassFlow*>* lfc);
|
||||
ClassFlowMQTT(std::vector<ClassFlow*>* lfc, ClassFlow *_prev);
|
||||
|
||||
string GetMQTTMainTopic();
|
||||
bool Start(float AutoInterval);
|
||||
|
||||
bool ReadParameter(FILE* pfile, string& aktparamgraph);
|
||||
|
||||
@@ -96,27 +96,49 @@ string ClassFlowPostProcessing::GetPreValue(std::string _number)
|
||||
return result;
|
||||
}
|
||||
|
||||
void ClassFlowPostProcessing::SetPreValue(double zw, string _numbers, bool _extern)
|
||||
|
||||
bool ClassFlowPostProcessing::SetPreValue(double _newvalue, string _numbers, bool _extern)
|
||||
{
|
||||
ESP_LOGD(TAG, "SetPrevalue: %f, %s", zw, _numbers.c_str());
|
||||
for (int j = 0; j < NUMBERS.size(); ++j)
|
||||
{
|
||||
// ESP_LOGD(TAG, "Number %d, %s", j, NUMBERS[j]->name.c_str());
|
||||
if (NUMBERS[j]->name == _numbers)
|
||||
{
|
||||
NUMBERS[j]->PreValue = zw;
|
||||
NUMBERS[j]->ReturnPreValue = std::to_string(zw);
|
||||
//ESP_LOGD(TAG, "SetPrevalue: %f, %s", zw, _numbers.c_str());
|
||||
|
||||
for (int j = 0; j < NUMBERS.size(); ++j) {
|
||||
//ESP_LOGD(TAG, "Number %d, %s", j, NUMBERS[j]->name.c_str());
|
||||
if (NUMBERS[j]->name == _numbers) {
|
||||
if (_newvalue >= 0) { // if new value posivive, use provided value to preset PreValue
|
||||
NUMBERS[j]->PreValue = _newvalue;
|
||||
}
|
||||
else { // if new value negative, use last raw value to preset PreValue
|
||||
char* p;
|
||||
double ReturnRawValueAsDouble = strtod(NUMBERS[j]->ReturnRawValue.c_str(), &p);
|
||||
if (ReturnRawValueAsDouble == 0) {
|
||||
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "SetPreValue: RawValue not a valid value for further processing: "
|
||||
+ NUMBERS[j]->ReturnRawValue);
|
||||
return false;
|
||||
}
|
||||
NUMBERS[j]->PreValue = ReturnRawValueAsDouble;
|
||||
}
|
||||
|
||||
NUMBERS[j]->ReturnPreValue = std::to_string(NUMBERS[j]->PreValue);
|
||||
NUMBERS[j]->PreValueOkay = true;
|
||||
|
||||
if (_extern)
|
||||
{
|
||||
time(&(NUMBERS[j]->lastvalue));
|
||||
localtime(&(NUMBERS[j]->lastvalue));
|
||||
}
|
||||
// ESP_LOGD(TAG, "Found %d! - set to %f", j, NUMBERS[j]->PreValue);
|
||||
//ESP_LOGD(TAG, "Found %d! - set to %.8f", j, NUMBERS[j]->PreValue);
|
||||
|
||||
UpdatePreValueINI = true; // Only update prevalue file if a new value is set
|
||||
SavePreValue();
|
||||
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "SetPreValue: PreValue for " + NUMBERS[j]->name + " set to " +
|
||||
std::to_string(NUMBERS[j]->PreValue));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
UpdatePreValueINI = true;
|
||||
SavePreValue();
|
||||
|
||||
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "SetPreValue: Numbersname not found or not valid");
|
||||
return false; // No new value was set (e.g. wrong numbersname, no numbers at all)
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ public:
|
||||
void SavePreValue();
|
||||
string getJsonFromNumber(int i, std::string _lineend);
|
||||
string GetPreValue(std::string _number = "");
|
||||
void SetPreValue(double zw, string _numbers, bool _extern = false);
|
||||
bool SetPreValue(double zw, string _numbers, bool _extern = false);
|
||||
|
||||
std::string GetJSON(std::string _lineend = "\n");
|
||||
std::string getNumbersName();
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_log.h"
|
||||
#include "../../include/defines.h"
|
||||
#include "psram.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
@@ -15,7 +16,7 @@
|
||||
|
||||
// #define WIFITURNOFF
|
||||
|
||||
static const char* TAG = "flow_make_image";
|
||||
static const char* TAG = "TAKEIMAGE";
|
||||
|
||||
esp_err_t ClassFlowTakeImage::camera_capture(){
|
||||
string nm = namerawimage;
|
||||
@@ -154,7 +155,7 @@ bool ClassFlowTakeImage::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
|
||||
image_width = Camera.image_width;
|
||||
image_height = Camera.image_height;
|
||||
rawImage = new CImageBasis();
|
||||
rawImage = new CImageBasis("rawImage");
|
||||
rawImage->CreateEmptyImage(image_width, image_height, 3);
|
||||
|
||||
waitbeforepicture_store = waitbeforepicture;
|
||||
@@ -183,6 +184,8 @@ string ClassFlowTakeImage::getHTMLSingleStep(string host)
|
||||
|
||||
bool ClassFlowTakeImage::doFlow(string zwtime)
|
||||
{
|
||||
psram_init_shared_memory_for_take_image_step();
|
||||
|
||||
string logPath = CreateLogFolder(zwtime);
|
||||
|
||||
int flash_duration = (int) (waitbeforepicture * 1000);
|
||||
@@ -215,6 +218,8 @@ bool ClassFlowTakeImage::doFlow(string zwtime)
|
||||
LogFile.WriteHeapInfo("ClassFlowTakeImage::doFlow - After RemoveOldLogs");
|
||||
#endif
|
||||
|
||||
psram_deinit_shared_memory_for_take_image_step();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -231,7 +236,7 @@ esp_err_t ClassFlowTakeImage::SendRawJPG(httpd_req_t *req)
|
||||
|
||||
ImageData* ClassFlowTakeImage::SendRawImage()
|
||||
{
|
||||
CImageBasis *zw = new CImageBasis(rawImage);
|
||||
CImageBasis *zw = new CImageBasis("SendRawImage", rawImage);
|
||||
ImageData *id;
|
||||
int flash_duration = (int) (waitbeforepicture * 1000);
|
||||
Camera.CaptureToBasisImage(zw, flash_duration);
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
#include <sstream>
|
||||
#include "ClassFlowWriteList.h"
|
||||
#include "Helper.h"
|
||||
|
||||
#include "time_sntp.h"
|
||||
#include "../../include/defines.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
void ClassFlowWriteList::SetInitialParameter(void)
|
||||
{
|
||||
flowpostprocessing = NULL;
|
||||
previousElement = NULL;
|
||||
ListFlowControll = NULL;
|
||||
disabled = false;
|
||||
}
|
||||
|
||||
ClassFlowWriteList::ClassFlowWriteList()
|
||||
{
|
||||
SetInitialParameter();
|
||||
}
|
||||
|
||||
ClassFlowWriteList::ClassFlowWriteList(std::vector<ClassFlow*>* lfc)
|
||||
{
|
||||
SetInitialParameter();
|
||||
|
||||
ListFlowControll = lfc;
|
||||
for (int i = 0; i < ListFlowControll->size(); ++i)
|
||||
{
|
||||
if (((*ListFlowControll)[i])->name().compare("ClassFlowPostProcessing") == 0)
|
||||
{
|
||||
flowpostprocessing = (ClassFlowPostProcessing*) (*ListFlowControll)[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool ClassFlowWriteList::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
{
|
||||
std::vector<string> splitted;
|
||||
|
||||
aktparamgraph = trim(aktparamgraph);
|
||||
|
||||
if (aktparamgraph.size() == 0)
|
||||
if (!this->GetNextParagraph(pfile, aktparamgraph))
|
||||
return false;
|
||||
|
||||
if (toUpper(aktparamgraph).compare("[MQTT]") != 0)
|
||||
return false;
|
||||
|
||||
while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph))
|
||||
{
|
||||
splitted = ZerlegeZeile(aktparamgraph);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool ClassFlowWriteList::doFlow(string zwtime)
|
||||
{
|
||||
std::string line = "";
|
||||
|
||||
std::string result;
|
||||
std::string resulterror = "";
|
||||
std::string resultraw = "";
|
||||
std::string resultrate = "";
|
||||
std::string resulttimestamp = "";
|
||||
string zw = "";
|
||||
string namenumber = "";
|
||||
|
||||
if (flowpostprocessing)
|
||||
{
|
||||
std::vector<NumberPost*>* NUMBERS = flowpostprocessing->GetNumbers();
|
||||
|
||||
for (int i = 0; i < (*NUMBERS).size(); ++i)
|
||||
{
|
||||
result = (*NUMBERS)[i]->ReturnValue;
|
||||
resultraw = (*NUMBERS)[i]->ReturnRawValue;
|
||||
resulterror = (*NUMBERS)[i]->ErrorMessageText;
|
||||
resultrate = (*NUMBERS)[i]->ReturnRateValue;
|
||||
resulttimestamp = (*NUMBERS)[i]->timeStamp;
|
||||
|
||||
line = line + resulttimestamp + "\t" + resultraw + "\t" + result + "\t" + resultraw + "\t" + resultrate + "\t" + resulttimestamp + "\t";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef CLASSFFLOWPWRITELIST_H
|
||||
#define CLASSFFLOWPWRITELIST_H
|
||||
|
||||
#include "ClassFlow.h"
|
||||
#include "ClassFlowPostProcessing.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
class ClassFlowWriteList :
|
||||
public ClassFlow
|
||||
{
|
||||
protected:
|
||||
ClassFlowPostProcessing* flowpostprocessing;
|
||||
void SetInitialParameter(void);
|
||||
|
||||
public:
|
||||
ClassFlowWriteList();
|
||||
ClassFlowWriteList(std::vector<ClassFlow*>* lfc);
|
||||
|
||||
bool ReadParameter(FILE* pfile, string& aktparamgraph);
|
||||
bool doFlow(string time);
|
||||
string name(){return "ClassFlowWriteList";};
|
||||
};
|
||||
|
||||
#endif //CLASSFFLOWPWRITELIST_H
|
||||
@@ -1,9 +1,10 @@
|
||||
#include "server_tflite.h"
|
||||
#include "MainFlowControl.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "string.h"
|
||||
#include "esp_log.h"
|
||||
#include <esp_timer.h>
|
||||
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
@@ -25,9 +26,14 @@
|
||||
|
||||
#include "read_wlanini.h"
|
||||
#include "connect_wlan.h"
|
||||
#include "psram.h"
|
||||
|
||||
// support IDF 5.x
|
||||
#ifndef portTICK_RATE_MS
|
||||
#define portTICK_RATE_MS portTICK_PERIOD_MS
|
||||
#endif
|
||||
|
||||
ClassFlowControll tfliteflow;
|
||||
ClassFlowControll flowctrl;
|
||||
|
||||
TaskHandle_t xHandletask_autodoFlow = NULL;
|
||||
|
||||
@@ -35,12 +41,13 @@ bool bTaskAutoFlowCreated = false;
|
||||
bool flowisrunning = false;
|
||||
|
||||
long auto_interval = 0;
|
||||
bool auto_isrunning = false;
|
||||
bool autostartIsEnabled = false;
|
||||
|
||||
int countRounds = 0;
|
||||
bool isPlannedReboot = false;
|
||||
|
||||
static const char *TAG = "TFLITE SERVER";
|
||||
static const char *TAG = "MAINCTRL";
|
||||
|
||||
|
||||
//#define DEBUG_DETAIL_ON
|
||||
|
||||
@@ -74,26 +81,26 @@ int getCountFlowRounds()
|
||||
|
||||
esp_err_t GetJPG(std::string _filename, httpd_req_t *req)
|
||||
{
|
||||
return tfliteflow.GetJPGStream(_filename, req);
|
||||
return flowctrl.GetJPGStream(_filename, req);
|
||||
}
|
||||
|
||||
|
||||
esp_err_t GetRawJPG(httpd_req_t *req)
|
||||
{
|
||||
return tfliteflow.SendRawJPG(req);
|
||||
return flowctrl.SendRawJPG(req);
|
||||
}
|
||||
|
||||
|
||||
bool isSetupModusActive() {
|
||||
return tfliteflow.getStatusSetupModus();
|
||||
return false;
|
||||
bool isSetupModusActive()
|
||||
{
|
||||
return flowctrl.getStatusSetupModus();
|
||||
}
|
||||
|
||||
|
||||
void KillTFliteTasks()
|
||||
void DeleteMainFlowTask()
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "KillTFliteTasks: xHandletask_autodoFlow: %ld", (long) xHandletask_autodoFlow);
|
||||
ESP_LOGD(TAG, "DeleteMainFlowTask: xHandletask_autodoFlow: %ld", (long) xHandletask_autodoFlow);
|
||||
#endif
|
||||
if( xHandletask_autodoFlow != NULL )
|
||||
{
|
||||
@@ -108,19 +115,19 @@ void KillTFliteTasks()
|
||||
|
||||
void doInit(void)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Start tfliteflow.InitFlow(config);");
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Start flowctrl.InitFlow(config);");
|
||||
#endif
|
||||
tfliteflow.InitFlow(CONFIG_FILE);
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Finished tfliteflow.InitFlow(config);");
|
||||
flowctrl.InitFlow(CONFIG_FILE);
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Finished flowctrl.InitFlow(config);");
|
||||
#endif
|
||||
|
||||
/* GPIO handler has to be initialized before MQTT init to ensure proper topic subscription */
|
||||
gpio_handler_init();
|
||||
|
||||
#ifdef ENABLE_MQTT
|
||||
tfliteflow.StartMQTTService();
|
||||
flowctrl.StartMQTTService();
|
||||
#endif //ENABLE_MQTT
|
||||
}
|
||||
|
||||
@@ -130,7 +137,7 @@ bool doflow(void)
|
||||
std::string zw_time = getCurrentTimeString(LOGFILE_TIME_FORMAT);
|
||||
ESP_LOGD(TAG, "doflow - start %s", zw_time.c_str());
|
||||
flowisrunning = true;
|
||||
tfliteflow.doFlow(zw_time);
|
||||
flowctrl.doFlow(zw_time);
|
||||
flowisrunning = false;
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
@@ -151,12 +158,12 @@ esp_err_t handler_get_heap(httpd_req_t *req)
|
||||
std::string zw = "Heap info:<br>" + getESPHeapInfo();
|
||||
|
||||
#ifdef TASK_ANALYSIS_ON
|
||||
char* pcTaskList = (char*) heap_caps_calloc(1, sizeof(char) * 768, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);
|
||||
char* pcTaskList = (char*) calloc_psram_heap(std::string(TAG) + "->pcTaskList", 1, sizeof(char) * 768, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);
|
||||
if (pcTaskList) {
|
||||
vTaskList(pcTaskList);
|
||||
zw = zw + "<br><br>Task info:<br><pre>Name | State | Prio | Lowest stacksize | Creation order | CPU (-1=NoAffinity)<br>"
|
||||
+ std::string(pcTaskList) + "</pre>";
|
||||
heap_caps_free(pcTaskList);
|
||||
free_psram_heap(std::string(TAG) + "->pcTaskList", pcTaskList);
|
||||
}
|
||||
else {
|
||||
zw = zw + "<br><br>Task info:<br>ERROR - Allocation of TaskList buffer in PSRAM failed";
|
||||
@@ -206,6 +213,40 @@ esp_err_t handler_init(httpd_req_t *req)
|
||||
}
|
||||
|
||||
|
||||
esp_err_t handler_stream(httpd_req_t *req)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_stream - Start");
|
||||
ESP_LOGD(TAG, "handler_stream uri: %s", req->uri);
|
||||
#endif
|
||||
|
||||
char _query[50];
|
||||
char _value[10];
|
||||
bool flashlightOn = false;
|
||||
|
||||
if (httpd_req_get_url_query_str(req, _query, 50) == ESP_OK)
|
||||
{
|
||||
// ESP_LOGD(TAG, "Query: %s", _query);
|
||||
if (httpd_query_key_value(_query, "flashlight", _value, 10) == ESP_OK)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "flashlight is found%s", _size);
|
||||
#endif
|
||||
if (strlen(_value) > 0)
|
||||
flashlightOn = true;
|
||||
}
|
||||
}
|
||||
|
||||
Camera.CaptureToStream(req, flashlightOn);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_stream - Done");
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
esp_err_t handler_flow_start(httpd_req_t *req) {
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
@@ -216,7 +257,7 @@ esp_err_t handler_flow_start(httpd_req_t *req) {
|
||||
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
|
||||
if (auto_isrunning) {
|
||||
if (autostartIsEnabled) {
|
||||
xTaskAbortDelay(xHandletask_autodoFlow); // Delay will be aborted if task is in blocked (waiting) state. If task is already running, no action
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Flow start triggered by REST API /flow_start");
|
||||
const char* resp_str = "The flow is going to be started immediately or is already running";
|
||||
@@ -245,7 +286,7 @@ esp_err_t MQTTCtrlFlowStart(std::string _topic) {
|
||||
|
||||
ESP_LOGD(TAG, "MQTTCtrlFlowStart: topic %s", _topic.c_str());
|
||||
|
||||
if (auto_isrunning)
|
||||
if (autostartIsEnabled)
|
||||
{
|
||||
xTaskAbortDelay(xHandletask_autodoFlow); // Delay will be aborted if task is in blocked (waiting) state. If task is already running, no action
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Flow start triggered by MQTT topic " + _topic);
|
||||
@@ -277,7 +318,7 @@ esp_err_t handler_json(httpd_req_t *req)
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
httpd_resp_set_type(req, "application/json");
|
||||
|
||||
std::string zw = tfliteflow.getJSON();
|
||||
std::string zw = flowctrl.getJSON();
|
||||
if (zw.length() > 0)
|
||||
{
|
||||
httpd_resp_send(req, zw.c_str(), zw.length());
|
||||
@@ -370,7 +411,7 @@ esp_err_t handler_wasserzaehler(httpd_req_t *req)
|
||||
_intype = READOUT_TYPE_ERROR;
|
||||
|
||||
|
||||
zw = tfliteflow.getReadoutAll(_intype);
|
||||
zw = flowctrl.getReadoutAll(_intype);
|
||||
ESP_LOGD(TAG, "ZW: %s", zw.c_str());
|
||||
if (zw.length() > 0)
|
||||
httpd_resp_send(req, zw.c_str(), zw.length());
|
||||
@@ -379,7 +420,7 @@ esp_err_t handler_wasserzaehler(httpd_req_t *req)
|
||||
}
|
||||
|
||||
|
||||
std::string *status = tfliteflow.getActStatus();
|
||||
std::string *status = flowctrl.getActStatus();
|
||||
string query = std::string(_query);
|
||||
// ESP_LOGD(TAG, "Query: %s, query.c_str());
|
||||
if (query.find("full") != std::string::npos)
|
||||
@@ -397,8 +438,7 @@ esp_err_t handler_wasserzaehler(httpd_req_t *req)
|
||||
httpd_resp_sendstr_chunk(req, txt.c_str());
|
||||
}
|
||||
|
||||
|
||||
zw = tfliteflow.getReadout(_rawValue, _noerror);
|
||||
zw = flowctrl.getReadout(_rawValue, _noerror, 0);
|
||||
if (zw.length() > 0)
|
||||
httpd_resp_sendstr_chunk(req, zw.c_str());
|
||||
|
||||
@@ -417,11 +457,11 @@ esp_err_t handler_wasserzaehler(httpd_req_t *req)
|
||||
txt += "<table style=\"border-spacing: 5px\"><tr style=\"text-align: center; vertical-align: top;\">\n";
|
||||
|
||||
std::vector<HTMLInfo*> htmlinfodig;
|
||||
htmlinfodig = tfliteflow.GetAllDigital();
|
||||
htmlinfodig = flowctrl.GetAllDigital();
|
||||
|
||||
for (int i = 0; i < htmlinfodig.size(); ++i)
|
||||
{
|
||||
if (tfliteflow.GetTypeDigital() == Digital)
|
||||
if (flowctrl.GetTypeDigital() == Digital)
|
||||
{
|
||||
if (htmlinfodig[i]->val == 10)
|
||||
zw = "NaN";
|
||||
@@ -452,7 +492,7 @@ esp_err_t handler_wasserzaehler(httpd_req_t *req)
|
||||
txt += "<table style=\"border-spacing: 5px\"><tr style=\"text-align: center; vertical-align: top;\">\n";
|
||||
|
||||
std::vector<HTMLInfo*> htmlinfoana;
|
||||
htmlinfoana = tfliteflow.GetAllAnalog();
|
||||
htmlinfoana = flowctrl.GetAllAnalog();
|
||||
for (int i = 0; i < htmlinfoana.size(); ++i)
|
||||
{
|
||||
std::stringstream stream;
|
||||
@@ -617,20 +657,40 @@ esp_err_t handler_editflow(httpd_req_t *req)
|
||||
|
||||
string out2 = out.substr(0, out.length() - 4) + "_org.jpg";
|
||||
|
||||
CAlignAndCutImage *caic = new CAlignAndCutImage(in);
|
||||
caic->CutAndSave(out2, x, y, dx, dy);
|
||||
delete caic;
|
||||
std::string state = *flowctrl.getActStatus();
|
||||
|
||||
CImageBasis *cim = new CImageBasis(out2);
|
||||
if (enhance)
|
||||
{
|
||||
cim->Contrast(90);
|
||||
/* To be able to provide the image, several conditions must be met due to the shared PSRAM usage:
|
||||
- Ether the round most be completed or not started yet
|
||||
- Or we must be in Setup Mode
|
||||
- Additionally, the initialization of the shared PSRAM must be successful */
|
||||
if (((state == "Flow finished") || (state == "Initialization") || (state == "Initialization (delayed)") || isSetupModusActive()) &&
|
||||
psram_init_shared_memory_for_take_image_step()) {
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Taking image for Alignment Mark Update...");
|
||||
|
||||
CAlignAndCutImage *caic = new CAlignAndCutImage("cutref", in);
|
||||
caic->CutAndSave(out2, x, y, dx, dy);
|
||||
delete caic;
|
||||
|
||||
CImageBasis *cim = new CImageBasis("cutref", out2);
|
||||
if (enhance)
|
||||
{
|
||||
cim->Contrast(90);
|
||||
}
|
||||
|
||||
cim->SaveToFile(out);
|
||||
delete cim;
|
||||
|
||||
psram_deinit_shared_memory_for_take_image_step();
|
||||
|
||||
|
||||
zw = "CutImage Done";
|
||||
}
|
||||
else {
|
||||
LogFile.WriteToFile(ESP_LOG_WARN, TAG, std::string("Taking image for Alignment Mark not possible while device") +
|
||||
" is busy with a round (Current State: '" + state + "')!");
|
||||
zw = "Device Busy";
|
||||
}
|
||||
|
||||
cim->SaveToFile(out);
|
||||
delete cim;
|
||||
|
||||
zw = "CutImage Done";
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
httpd_resp_send(req, zw.c_str(), zw.length());
|
||||
|
||||
@@ -674,7 +734,7 @@ esp_err_t handler_editflow(httpd_req_t *req)
|
||||
Camera.SetBrightnessContrastSaturation(bri, con, sat);
|
||||
Camera.SetLEDIntensity(intens);
|
||||
ESP_LOGD(TAG, "test_take - vor TakeImage");
|
||||
std::string zw = tfliteflow.doSingleStep("[TakeImage]", _host);
|
||||
std::string zw = flowctrl.doSingleStep("[TakeImage]", _host);
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
httpd_resp_send(req, zw.c_str(), zw.length());
|
||||
}
|
||||
@@ -689,7 +749,7 @@ esp_err_t handler_editflow(httpd_req_t *req)
|
||||
// ESP_LOGD(TAG, "Parameter host: %s", _host.c_str());
|
||||
|
||||
// string zwzw = "Do " + _task + " start\n"; ESP_LOGD(TAG, zwzw.c_str());
|
||||
std::string zw = tfliteflow.doSingleStep("[Alignment]", _host);
|
||||
std::string zw = flowctrl.doSingleStep("[Alignment]", _host);
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
httpd_resp_send(req, zw.c_str(), zw.length());
|
||||
}
|
||||
@@ -705,7 +765,7 @@ esp_err_t handler_editflow(httpd_req_t *req)
|
||||
esp_err_t handler_statusflow(httpd_req_t *req)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_prevalue - Start");
|
||||
LogFile.WriteHeapInfo("handler_statusflow - Start");
|
||||
#endif
|
||||
|
||||
const char* resp_str;
|
||||
@@ -714,10 +774,10 @@ esp_err_t handler_statusflow(httpd_req_t *req)
|
||||
if (bTaskAutoFlowCreated)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "handler_prevalue: %s", req->uri);
|
||||
ESP_LOGD(TAG, "handler_statusflow: %s", req->uri);
|
||||
#endif
|
||||
|
||||
string* zw = tfliteflow.getActStatusWithTime();
|
||||
string* zw = flowctrl.getActStatusWithTime();
|
||||
resp_str = zw->c_str();
|
||||
|
||||
httpd_resp_send(req, resp_str, HTTPD_RESP_USE_STRLEN);
|
||||
@@ -729,7 +789,7 @@ esp_err_t handler_statusflow(httpd_req_t *req)
|
||||
}
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_prevalue - Done");
|
||||
LogFile.WriteHeapInfo("handler_statusflow - Done");
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
@@ -801,50 +861,81 @@ esp_err_t handler_uptime(httpd_req_t *req)
|
||||
esp_err_t handler_prevalue(httpd_req_t *req)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_prevalue - Start");
|
||||
#endif
|
||||
|
||||
const char* resp_str;
|
||||
string zw;
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_prevalue - Start");
|
||||
ESP_LOGD(TAG, "handler_prevalue: %s", req->uri);
|
||||
#endif
|
||||
|
||||
char _query[100];
|
||||
char _size[10] = "";
|
||||
char _numbers[50] = "default";
|
||||
// Default usage message when handler gets called without any parameter
|
||||
const std::string RESTUsageInfo =
|
||||
"00: Handler usage:<br>"
|
||||
"- To retrieve actual PreValue, please provide only a numbersname, e.g. /setPreValue?numbers=main<br>"
|
||||
"- To set PreValue to a new value, please provide a numbersname and a value, e.g. /setPreValue?numbers=main&value=1234.5678<br>"
|
||||
"NOTE:<br>"
|
||||
"value >= 0.0: Set PreValue to provided value<br>"
|
||||
"value < 0.0: Set PreValue to actual RAW value (as long RAW value is a valid number, without N)";
|
||||
|
||||
if (httpd_req_get_url_query_str(req, _query, 100) == ESP_OK)
|
||||
{
|
||||
// Default return error message when no return is programmed
|
||||
std::string sReturnMessage = "E90: Uninitialized";
|
||||
|
||||
char _query[100];
|
||||
char _numbersname[50] = "default";
|
||||
char _value[20] = "";
|
||||
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
|
||||
if (httpd_req_get_url_query_str(req, _query, 100) == ESP_OK) {
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Query: %s", _query);
|
||||
#endif
|
||||
|
||||
if (httpd_query_key_value(_query, "value", _size, 10) == ESP_OK)
|
||||
{
|
||||
if (httpd_query_key_value(_query, "numbers", _numbersname, 50) != ESP_OK) { // If request is incomplete
|
||||
sReturnMessage = "E91: Query parameter incomplete or not valid!<br> "
|
||||
"Call /setPreValue to show REST API usage info and/or check documentation";
|
||||
httpd_resp_send(req, sReturnMessage.c_str(), sReturnMessage.length());
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (httpd_query_key_value(_query, "value", _value, 20) == ESP_OK) {
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Value: %s", _size);
|
||||
#endif
|
||||
}
|
||||
|
||||
httpd_query_key_value(_query, "numbers", _numbers, 50);
|
||||
}
|
||||
|
||||
if (strlen(_size) == 0)
|
||||
{
|
||||
zw = tfliteflow.GetPrevalue(std::string(_numbers));
|
||||
}
|
||||
else
|
||||
{
|
||||
zw = "SetPrevalue to " + tfliteflow.UpdatePrevalue(_size, _numbers, true);
|
||||
}
|
||||
|
||||
resp_str = zw.c_str();
|
||||
else { // if no parameter is provided, print handler usage
|
||||
httpd_resp_send(req, RESTUsageInfo.c_str(), RESTUsageInfo.length());
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
|
||||
httpd_resp_send(req, resp_str, HTTPD_RESP_USE_STRLEN);
|
||||
if (strlen(_value) == 0) { // If no value is povided --> return actual PreValue
|
||||
sReturnMessage = flowctrl.GetPrevalue(std::string(_numbersname));
|
||||
|
||||
if (sReturnMessage.empty()) {
|
||||
sReturnMessage = "E92: Numbers name not found";
|
||||
httpd_resp_send(req, sReturnMessage.c_str(), sReturnMessage.length());
|
||||
return ESP_FAIL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// New value is positive: Set PreValue to provided value and return value
|
||||
// New value is negative and actual RAW value is a valid number: Set PreValue to RAW value and return value
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "REST API handler_prevalue called: numbersname: " + std::string(_numbersname) +
|
||||
", value: " + std::string(_value));
|
||||
if (!flowctrl.UpdatePrevalue(_value, _numbersname, true)) {
|
||||
sReturnMessage = "E93: Update request rejected. Please check device logs for more details";
|
||||
httpd_resp_send(req, sReturnMessage.c_str(), sReturnMessage.length());
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
sReturnMessage = flowctrl.GetPrevalue(std::string(_numbersname));
|
||||
|
||||
if (sReturnMessage.empty()) {
|
||||
sReturnMessage = "E94: Numbers name not found";
|
||||
httpd_resp_send(req, sReturnMessage.c_str(), sReturnMessage.length());
|
||||
return ESP_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
httpd_resp_send(req, sReturnMessage.c_str(), sReturnMessage.length());
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_prevalue - End");
|
||||
@@ -862,7 +953,7 @@ void task_autodoFlow(void *pvParameter)
|
||||
|
||||
if (!isPlannedReboot && (esp_reset_reason() == ESP_RST_PANIC))
|
||||
{
|
||||
tfliteflow.setActStatus("Initialization (delayed)");
|
||||
flowctrl.setActStatus("Initialization (delayed)");
|
||||
//#ifdef ENABLE_MQTT
|
||||
//MQTTPublish(mqttServer_getMainTopic() + "/" + "status", "Initialization (delayed)", false); // Right now, not possible -> MQTT Service is going to be started later
|
||||
//#endif //ENABLE_MQTT
|
||||
@@ -872,16 +963,25 @@ void task_autodoFlow(void *pvParameter)
|
||||
ESP_LOGD(TAG, "task_autodoFlow: start");
|
||||
doInit();
|
||||
|
||||
auto_isrunning = tfliteflow.isAutoStart(auto_interval);
|
||||
flowctrl.setAutoStartInterval(auto_interval);
|
||||
autostartIsEnabled = flowctrl.getIsAutoStart();
|
||||
|
||||
if (isSetupModusActive())
|
||||
{
|
||||
auto_isrunning = false;
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "We are in Setup Mode -> Not starting Auto Flow!");
|
||||
autostartIsEnabled = false;
|
||||
std::string zw_time = getCurrentTimeString(LOGFILE_TIME_FORMAT);
|
||||
tfliteflow.doFlowTakeImageOnly(zw_time);
|
||||
flowctrl.doFlowTakeImageOnly(zw_time);
|
||||
}
|
||||
|
||||
if (autostartIsEnabled) {
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Starting Flow...");
|
||||
}
|
||||
else {
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Autostart is not enabled -> Not starting Flow");
|
||||
}
|
||||
|
||||
while (auto_isrunning)
|
||||
while (autostartIsEnabled)
|
||||
{
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "----------------------------------------------------------------"); // Clear separation between runs
|
||||
std::string _zw = "Round #" + std::to_string(++countRounds) + " started";
|
||||
@@ -943,13 +1043,19 @@ void task_autodoFlow(void *pvParameter)
|
||||
vTaskDelay( xDelay );
|
||||
}
|
||||
}
|
||||
|
||||
while(1) // Keep flow task running to handle necessary sub tasks like reboot handler, etc..
|
||||
{
|
||||
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
|
||||
vTaskDelete(NULL); //Delete this task if it exits from the loop above
|
||||
xHandletask_autodoFlow = NULL;
|
||||
ESP_LOGD(TAG, "task_autodoFlow: end");
|
||||
}
|
||||
|
||||
|
||||
void TFliteDoAutoStart()
|
||||
void InitializeFlowTask()
|
||||
{
|
||||
BaseType_t xReturned;
|
||||
|
||||
@@ -966,17 +1072,9 @@ void TFliteDoAutoStart()
|
||||
}
|
||||
|
||||
|
||||
#ifdef ENABLE_MQTT
|
||||
std::string GetMQTTMainTopic()
|
||||
void register_server_main_flow_task_uri(httpd_handle_t server)
|
||||
{
|
||||
return tfliteflow.GetMQTTMainTopic();
|
||||
}
|
||||
#endif//ENABLE_MQTT
|
||||
|
||||
|
||||
void register_server_tflite_uri(httpd_handle_t server)
|
||||
{
|
||||
ESP_LOGI(TAG, "server_part_camera - Registering URI handlers");
|
||||
ESP_LOGI(TAG, "server_main_flow_task - Registering URI handlers");
|
||||
|
||||
httpd_uri_t camuri = { };
|
||||
camuri.method = HTTP_GET;
|
||||
@@ -1070,4 +1168,10 @@ void register_server_tflite_uri(httpd_handle_t server)
|
||||
camuri.handler = handler_get_heap;
|
||||
camuri.user_ctx = (void*) "Heap";
|
||||
httpd_register_uri_handler(server, &camuri);
|
||||
|
||||
camuri.uri = "/stream";
|
||||
camuri.handler = handler_stream;
|
||||
camuri.user_ctx = (void*) "stream";
|
||||
httpd_register_uri_handler(server, &camuri);
|
||||
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef SERVERTFLITE_H
|
||||
#define SERVERTFLITE_H
|
||||
#ifndef MAINFLOWCONTROL_H
|
||||
#define MAINFLOWCONTROL_H
|
||||
|
||||
#include <esp_log.h>
|
||||
#include <string>
|
||||
@@ -10,25 +10,25 @@
|
||||
#include "CImageBasis.h"
|
||||
#include "ClassFlowControll.h"
|
||||
|
||||
//#include "ClassControllCamera.h"
|
||||
extern ClassFlowControll flowctrl;
|
||||
|
||||
extern ClassFlowControll tfliteflow;
|
||||
void register_server_tflite_uri(httpd_handle_t server);
|
||||
|
||||
void KillTFliteTasks();
|
||||
void TFliteDoAutoStart();
|
||||
bool isSetupModusActive();
|
||||
int getCountFlowRounds();
|
||||
void register_server_main_flow_task_uri(httpd_handle_t server);
|
||||
|
||||
void CheckIsPlannedReboot();
|
||||
bool getIsPlannedReboot();
|
||||
|
||||
esp_err_t GetJPG(std::string _filename, httpd_req_t *req);
|
||||
esp_err_t GetRawJPG(httpd_req_t *req);
|
||||
void InitializeFlowTask();
|
||||
void DeleteMainFlowTask();
|
||||
bool isSetupModusActive();
|
||||
|
||||
int getCountFlowRounds();
|
||||
|
||||
#ifdef ENABLE_MQTT
|
||||
std::string GetMQTTMainTopic();
|
||||
esp_err_t MQTTCtrlFlowStart(std::string);
|
||||
esp_err_t MQTTCtrlFlowStart(std::string _topic);
|
||||
#endif //ENABLE_MQTT
|
||||
|
||||
#endif //SERVERTFLITE_H
|
||||
esp_err_t GetRawJPG(httpd_req_t *req);
|
||||
esp_err_t GetJPG(std::string _filename, httpd_req_t *req);
|
||||
|
||||
#endif //MAINFLOWCONTROL_H
|
||||
@@ -2,6 +2,6 @@ FILE(GLOB_RECURSE app_sources ${CMAKE_CURRENT_SOURCE_DIR}/*.*)
|
||||
|
||||
idf_component_register(SRCS ${app_sources}
|
||||
INCLUDE_DIRS "."
|
||||
REQUIRES tflite-lib jomjol_logfile fatfs sdmmc)
|
||||
REQUIRES esp_timer tflite-lib jomjol_logfile fatfs sdmmc)
|
||||
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@ extern "C" {
|
||||
|
||||
#include <string.h>
|
||||
#include <esp_log.h>
|
||||
#include <esp_mac.h>
|
||||
#include <esp_timer.h>
|
||||
#include "../../include/defines.h"
|
||||
|
||||
|
||||
@@ -64,14 +66,14 @@ string getESPHeapInfo(){
|
||||
|
||||
sprintf(aMsgBuf," | SPI Free: %ld", (long) aFreeSPIHeapSize);
|
||||
espInfoResultStr += string(aMsgBuf);
|
||||
sprintf(aMsgBuf," | SPI Larg Block: %ld", (long) aHeapLargestFreeBlockSize);
|
||||
sprintf(aMsgBuf," | SPI Large Block: %ld", (long) aHeapLargestFreeBlockSize);
|
||||
espInfoResultStr += string(aMsgBuf);
|
||||
sprintf(aMsgBuf," | SPI Min Free: %ld", (long) aMinFreeHeapSize);
|
||||
espInfoResultStr += string(aMsgBuf);
|
||||
|
||||
sprintf(aMsgBuf," | Int Free: %ld", (long) (aFreeInternalHeapSize));
|
||||
espInfoResultStr += string(aMsgBuf);
|
||||
sprintf(aMsgBuf," | Int Larg Block: %ld", (long) aHeapIntLargestFreeBlockSize);
|
||||
sprintf(aMsgBuf," | Int Large Block: %ld", (long) aHeapIntLargestFreeBlockSize);
|
||||
espInfoResultStr += string(aMsgBuf);
|
||||
sprintf(aMsgBuf," | Int Min Free: %ld", (long) (aMinFreeInternalHeapSize));
|
||||
espInfoResultStr += string(aMsgBuf);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#ifdef DEBUG_ENABLE_SYSINFO
|
||||
|
||||
#include "esp_sys.h"
|
||||
#include "esp_chip_info.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
@@ -121,7 +122,7 @@ std::string get_device_info()
|
||||
}
|
||||
|
||||
#ifdef USE_HIMEM_IF_AVAILABLE
|
||||
sprintf(aMsgBuf,"spiram size %u\n", esp_spiram_get_size());
|
||||
sprintf(aMsgBuf,"spiram size %u\n", esp_psram_get_size());
|
||||
espInfoResultStr += std::string(aMsgBuf);
|
||||
sprintf(aMsgBuf,"himem free %u\n", esp_himem_get_free_size());
|
||||
espInfoResultStr += std::string(aMsgBuf);
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
#include <esp_spi_flash.h>
|
||||
#include <esp_heap_caps.h>
|
||||
|
||||
// for esp_spiram_get_size
|
||||
// for esp_psram_get_size
|
||||
extern "C" {
|
||||
#include <esp32/spiram.h>
|
||||
#include "esp_psram.h"
|
||||
#ifdef USE_HIMEM_IF_AVAILABLE
|
||||
#include <esp32/himem.h>
|
||||
#endif
|
||||
|
||||
211
code/components/jomjol_helper/psram.cpp
Normal file
211
code/components/jomjol_helper/psram.cpp
Normal file
@@ -0,0 +1,211 @@
|
||||
#include "ClassLogFile.h"
|
||||
#include "../../include/defines.h"
|
||||
#include "psram.h"
|
||||
|
||||
static const char* TAG = "PSRAM";
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
void *shared_region = NULL;
|
||||
uint32_t allocatedBytesForSTBI = 0;
|
||||
std::string sharedMemoryInUseFor = "";
|
||||
|
||||
|
||||
/** Reserve a large block in the PSRAM which will be shared between the different steps.
|
||||
* Each step uses it differently but only wiuthin itself. */
|
||||
bool reserve_psram_shared_region(void) {
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Allocating shared PSRAM region (" +
|
||||
std::to_string(TENSOR_ARENA_SIZE + MAX_MODEL_SIZE) + " bytes)...");
|
||||
shared_region = malloc_psram_heap("Shared PSRAM region", TENSOR_ARENA_SIZE + MAX_MODEL_SIZE,
|
||||
MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
|
||||
|
||||
if (shared_region == NULL) {
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to allocating shared PSRAM region!");
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* Memory used in Take Image (STBI)
|
||||
*******************************************************************/
|
||||
bool psram_init_shared_memory_for_take_image_step(void) {
|
||||
if (sharedMemoryInUseFor != "") {
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Shared memory in PSRAM already in use for " + sharedMemoryInUseFor + "!");
|
||||
return false;
|
||||
}
|
||||
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Init shared memory for step 'Take Image' (STBI buffers)");
|
||||
allocatedBytesForSTBI = 0;
|
||||
sharedMemoryInUseFor = "TakeImage";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void psram_deinit_shared_memory_for_take_image_step(void) {
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Deinit shared memory for step 'Take Image' (STBI buffers)");
|
||||
allocatedBytesForSTBI = 0;
|
||||
sharedMemoryInUseFor = "";
|
||||
}
|
||||
|
||||
|
||||
void *psram_reserve_shared_stbi_memory(size_t size) {
|
||||
/* Only large buffers should be placed in the shared PSRAM
|
||||
* If we also place all smaller STBI buffers here, we get artefacts for some reasons. */
|
||||
if (size >= 100000) {
|
||||
if ((allocatedBytesForSTBI + size) > TENSOR_ARENA_SIZE + MAX_MODEL_SIZE) { // Check if it still fits in the shared region
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Shared memory in PSRAM too small (STBI) to fit additional " +
|
||||
std::to_string(size) + " bytes! Available: " + std::to_string(TENSOR_ARENA_SIZE + MAX_MODEL_SIZE - allocatedBytesForSTBI) + " bytes!");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Allocating memory (" + std::to_string(size) + " bytes) for STBI (use shared memory in PSRAM)...");
|
||||
allocatedBytesForSTBI += size;
|
||||
return (uint8_t *)shared_region + allocatedBytesForSTBI - size;
|
||||
}
|
||||
else { // Normal PSRAM
|
||||
return malloc_psram_heap("STBI", size, MALLOC_CAP_SPIRAM);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void *psram_reallocate_shared_stbi_memory(void *ptr, size_t newsize) {
|
||||
char buf[20];
|
||||
sprintf(buf, "%p", ptr);
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "STBI requested realloc for " + std::string(buf) + " but this is currently unsupported!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void psram_free_shared_stbi_memory(void *p) {
|
||||
if ((p >= shared_region) && (p <= ((uint8_t *)shared_region + allocatedBytesForSTBI))) { // was allocated inside the shared memory
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Part of shared memory used for STBI (PSRAM, part of shared memory) is free again");
|
||||
}
|
||||
else { // Normal PSRAM
|
||||
free_psram_heap("STBI", p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* Memory used in Aligning Step
|
||||
* During this step we only use the shared part of the PSRAM
|
||||
* for the tmpImage.
|
||||
*******************************************************************/
|
||||
void *psram_reserve_shared_tmp_image_memory(void) {
|
||||
if (sharedMemoryInUseFor != "") {
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Shared memory in PSRAM already in use for " + sharedMemoryInUseFor + "!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Allocating tmpImage (" + std::to_string(IMAGE_SIZE) + " bytes, use shared memory in PSRAM)...");
|
||||
sharedMemoryInUseFor = "Aligning";
|
||||
return shared_region; // Use 1th part of the shared memory for the tmpImage (only user)
|
||||
}
|
||||
|
||||
|
||||
void psram_free_shared_temp_image_memory(void) {
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Shared memory used for tmpImage (PSRAM, part of shared memory) is free again");
|
||||
sharedMemoryInUseFor = "";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* Memory used in Digitalization Steps
|
||||
* During this step we only use the shared part of the PSRAM for the
|
||||
* Tensor Arena and one of the Models.
|
||||
* The shared memory is large enough for the largest model and the
|
||||
* Tensor Arena. Therefore we do not need to monitor the usage.
|
||||
*******************************************************************/
|
||||
void *psram_get_shared_tensor_arena_memory(void) {
|
||||
if ((sharedMemoryInUseFor == "") || (sharedMemoryInUseFor == "Digitalization_Model")) {
|
||||
sharedMemoryInUseFor = "Digitalization_Tensor";
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Allocating Tensor Arena (" + std::to_string(TENSOR_ARENA_SIZE) + " bytes, use shared memory in PSRAM)...");
|
||||
return shared_region; // Use 1th part of the shared memory for Tensor
|
||||
}
|
||||
else {
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Shared memory in PSRAM already in use for " + sharedMemoryInUseFor + "!");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void *psram_get_shared_model_memory(void) {
|
||||
if ((sharedMemoryInUseFor == "") || (sharedMemoryInUseFor == "Digitalization_Tensor")) {
|
||||
sharedMemoryInUseFor = "Digitalization_Model";
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Allocating Model memory (" + std::to_string(MAX_MODEL_SIZE) + " bytes, use shared memory in PSRAM)...");
|
||||
return (uint8_t *)shared_region + TENSOR_ARENA_SIZE; // Use 2nd part of the shared memory (after Tensor Arena) for the model
|
||||
}
|
||||
else {
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Shared memory in PSRAM already in use for " + sharedMemoryInUseFor + "!");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void psram_free_shared_tensor_arena_and_model_memory(void) {
|
||||
sharedMemoryInUseFor = "";
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Shared memory used for Tensor Arena and model (PSRAM, part of shared memory) is free again");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* General
|
||||
*******************************************************************/
|
||||
void *malloc_psram_heap(std::string name, size_t size, uint32_t caps) {
|
||||
void *ptr;
|
||||
|
||||
ptr = heap_caps_malloc(size, caps);
|
||||
if (ptr != NULL) {
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Allocated " + to_string(size) + " bytes in PSRAM for '" + name + "'");
|
||||
}
|
||||
else {
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to allocate " + to_string(size) + " bytes in PSRAM for '" + name + "'!");
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
void *realloc_psram_heap(std::string name, void *ptr, size_t size, uint32_t caps) {
|
||||
ptr = heap_caps_realloc(ptr, size, caps);
|
||||
if (ptr != NULL) {
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Reallocated " + to_string(size) + " bytes in PSRAM for '" + name + "'");
|
||||
}
|
||||
else {
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to reallocate " + to_string(size) + " bytes in PSRAM for '" + name + "'!");
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
void *calloc_psram_heap(std::string name, size_t n, size_t size, uint32_t caps) {
|
||||
void *ptr;
|
||||
|
||||
ptr = heap_caps_calloc(n, size, caps);
|
||||
if (ptr != NULL) {
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Allocated " + to_string(size) + " bytes in PSRAM for '" + name + "'");
|
||||
}
|
||||
else {
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to allocate " + to_string(size) + " bytes in PSRAM for '" + name + "'!");
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
void free_psram_heap(std::string name, void *ptr) {
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Freeing memory in PSRAM used for '" + name + "'...");
|
||||
heap_caps_free(ptr);
|
||||
}
|
||||
35
code/components/jomjol_helper/psram.h
Normal file
35
code/components/jomjol_helper/psram.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
#ifndef PSRAM_h
|
||||
#define PSRAM_h
|
||||
|
||||
#include "esp_heap_caps.h"
|
||||
|
||||
|
||||
bool reserve_psram_shared_region(void);
|
||||
|
||||
|
||||
/* Memory used in Take Image Step */
|
||||
bool psram_init_shared_memory_for_take_image_step(void);
|
||||
void psram_deinit_shared_memory_for_take_image_step(void);
|
||||
void *psram_reserve_shared_stbi_memory(size_t size);
|
||||
void *psram_reallocate_shared_stbi_memory(void *ptr, size_t newsize);
|
||||
void psram_free_shared_stbi_memory(void *p);
|
||||
|
||||
|
||||
/* Memory used in Aligning Step */
|
||||
void *psram_reserve_shared_tmp_image_memory(void);
|
||||
void psram_free_shared_temp_image_memory(void);
|
||||
|
||||
/* Memory used in Digitalization Steps */
|
||||
void *psram_get_shared_tensor_arena_memory(void);
|
||||
void *psram_get_shared_model_memory(void);
|
||||
void psram_free_shared_tensor_arena_and_model_memory(void);
|
||||
|
||||
/* General */
|
||||
void *malloc_psram_heap(std::string name, size_t size, uint32_t caps);
|
||||
void *realloc_psram_heap(std::string name, void *ptr, size_t size, uint32_t caps);
|
||||
void *calloc_psram_heap(std::string name, size_t n, size_t size, uint32_t caps);
|
||||
|
||||
void free_psram_heap(std::string name, void *ptr);
|
||||
|
||||
#endif // PSRAM_h
|
||||
@@ -7,6 +7,11 @@
|
||||
#include "ClassLogFile.h"
|
||||
#include "../../include/defines.h"
|
||||
|
||||
// define `gpio_pad_select_gpip` for newer versions of IDF
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 3, 0))
|
||||
#include "esp_rom_gpio.h"
|
||||
#define gpio_pad_select_gpio esp_rom_gpio_pad_select_gpio
|
||||
#endif
|
||||
|
||||
static const char* TAG = "STATUSLED";
|
||||
|
||||
|
||||
@@ -5,12 +5,14 @@
|
||||
#include <math.h>
|
||||
#include <algorithm>
|
||||
#include <esp_log.h>
|
||||
#include "psram.h"
|
||||
#include "../../include/defines.h"
|
||||
|
||||
static const char* TAG = "c_align_and_cut_image";
|
||||
|
||||
CAlignAndCutImage::CAlignAndCutImage(CImageBasis *_org, CImageBasis *_temp)
|
||||
CAlignAndCutImage::CAlignAndCutImage(std::string _name, CImageBasis *_org, CImageBasis *_temp) : CImageBasis(_name)
|
||||
{
|
||||
name = _name;
|
||||
rgb_image = _org->rgb_image;
|
||||
channels = _org->channels;
|
||||
width = _org->width;
|
||||
@@ -37,7 +39,7 @@ bool CAlignAndCutImage::Align(RefInfo *_temp1, RefInfo *_temp2)
|
||||
int r0_x, r0_y, r1_x, r1_y;
|
||||
bool isSimilar1, isSimilar2;
|
||||
|
||||
CFindTemplate* ft = new CFindTemplate(rgb_image, channels, width, height, bpp);
|
||||
CFindTemplate* ft = new CFindTemplate("align", rgb_image, channels, width, height, bpp);
|
||||
|
||||
r0_x = _temp1->target_x;
|
||||
r0_y = _temp1->target_y;
|
||||
@@ -81,7 +83,7 @@ bool CAlignAndCutImage::Align(RefInfo *_temp1, RefInfo *_temp2)
|
||||
LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", zw);
|
||||
#endif*/
|
||||
|
||||
CRotateImage rt(this, ImageTMP);
|
||||
CRotateImage rt("Align", this, ImageTMP);
|
||||
rt.Translate(dx, dy);
|
||||
rt.Rotate(d_winkel, _temp1->target_x, _temp1->target_y);
|
||||
ESP_LOGD(TAG, "Alignment: dx %d - dy %d - rot %f", dx, dy, d_winkel);
|
||||
@@ -107,7 +109,7 @@ void CAlignAndCutImage::CutAndSave(std::string _template1, int x1, int y1, int d
|
||||
dy = y2 - y1;
|
||||
|
||||
int memsize = dx * dy * channels;
|
||||
uint8_t* odata = (unsigned char*) GET_MEMORY(memsize);
|
||||
uint8_t* odata = (unsigned char*) malloc_psram_heap(std::string(TAG) + "->odata", memsize, MALLOC_CAP_SPIRAM);
|
||||
|
||||
stbi_uc* p_target;
|
||||
stbi_uc* p_source;
|
||||
@@ -186,7 +188,7 @@ CImageBasis* CAlignAndCutImage::CutAndSave(int x1, int y1, int dx, int dy)
|
||||
dy = y2 - y1;
|
||||
|
||||
int memsize = dx * dy * channels;
|
||||
uint8_t* odata = (unsigned char*)GET_MEMORY(memsize);
|
||||
uint8_t* odata = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->odata", memsize, MALLOC_CAP_SPIRAM);
|
||||
|
||||
stbi_uc* p_target;
|
||||
stbi_uc* p_source;
|
||||
@@ -202,7 +204,7 @@ CImageBasis* CAlignAndCutImage::CutAndSave(int x1, int y1, int dx, int dy)
|
||||
p_target[_channels] = p_source[_channels];
|
||||
}
|
||||
|
||||
CImageBasis* rs = new CImageBasis(odata, channels, dx, dy, bpp);
|
||||
CImageBasis* rs = new CImageBasis("CutAndSave", odata, channels, dx, dy, bpp);
|
||||
RGBImageRelease();
|
||||
rs->SetIndepended();
|
||||
return rs;
|
||||
|
||||
@@ -12,9 +12,9 @@ class CAlignAndCutImage : public CImageBasis
|
||||
public:
|
||||
int t0_dx, t0_dy, t1_dx, t1_dy;
|
||||
CImageBasis *ImageTMP;
|
||||
CAlignAndCutImage(std::string _image) : CImageBasis(_image) {ImageTMP = NULL;};
|
||||
CAlignAndCutImage(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp) : CImageBasis(_rgb_image, _channels, _width, _height, _bpp) {ImageTMP = NULL;};
|
||||
CAlignAndCutImage(CImageBasis *_org, CImageBasis *_temp);
|
||||
CAlignAndCutImage(std::string name, std::string _image) : CImageBasis(name, _image) {ImageTMP = NULL;};
|
||||
CAlignAndCutImage(std::string name, uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp) : CImageBasis(name, _rgb_image, _channels, _width, _height, _bpp) {ImageTMP = NULL;};
|
||||
CAlignAndCutImage(std::string name, CImageBasis *_org, CImageBasis *_temp);
|
||||
|
||||
bool Align(RefInfo *_temp1, RefInfo *_temp2);
|
||||
// void Align(std::string _template1, int x1, int y1, std::string _template2, int x2, int y2, int deltax = 40, int deltay = 40, std::string imageROI = "");
|
||||
|
||||
@@ -32,7 +32,7 @@ class CFindTemplate : public CImageBasis
|
||||
{
|
||||
public:
|
||||
int tpl_width, tpl_height, tpl_bpp;
|
||||
CFindTemplate(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp) : CImageBasis(_rgb_image, _channels, _width, _height, _bpp) {};
|
||||
CFindTemplate(std::string name, uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp) : CImageBasis(name, _rgb_image, _channels, _width, _height, _bpp) {};
|
||||
|
||||
bool FindTemplate(RefInfo *_ref);
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "CImageBasis.h"
|
||||
#include "Helper.h"
|
||||
#include "psram.h"
|
||||
#include "ClassLogFile.h"
|
||||
#include "server_ota.h"
|
||||
|
||||
@@ -360,8 +361,9 @@ void CImageBasis::drawCircle(int x1, int y1, int rad, int r, int g, int b, int t
|
||||
}
|
||||
|
||||
|
||||
CImageBasis::CImageBasis()
|
||||
CImageBasis::CImageBasis(string _name)
|
||||
{
|
||||
name = _name;
|
||||
externalImage = false;
|
||||
rgb_image = NULL;
|
||||
width = 0;
|
||||
@@ -384,8 +386,9 @@ void CImageBasis::CreateEmptyImage(int _width, int _height, int _channels)
|
||||
LogFile.WriteHeapInfo("CreateEmptyImage");
|
||||
#endif
|
||||
|
||||
int memsize = width * height * channels;
|
||||
rgb_image = (unsigned char*)GET_MEMORY(memsize);
|
||||
memsize = width * height * channels;
|
||||
|
||||
rgb_image = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->CImageBasis (" + name + ")", memsize, MALLOC_CAP_SPIRAM);
|
||||
|
||||
if (rgb_image == NULL)
|
||||
{
|
||||
@@ -435,8 +438,10 @@ void CImageBasis::LoadFromMemory(stbi_uc *_buffer, int len)
|
||||
{
|
||||
RGBImageLock();
|
||||
|
||||
if (rgb_image)
|
||||
if (rgb_image != NULL) {
|
||||
stbi_image_free(rgb_image);
|
||||
//free_psram_heap(std::string(TAG) + "->rgb_image (LoadFromMemory)", rgb_image);
|
||||
}
|
||||
|
||||
rgb_image = stbi_load_from_memory(_buffer, len, &width, &height, &channels, 3);
|
||||
bpp = channels;
|
||||
@@ -454,8 +459,9 @@ void CImageBasis::LoadFromMemory(stbi_uc *_buffer, int len)
|
||||
}
|
||||
|
||||
|
||||
CImageBasis::CImageBasis(CImageBasis *_copyfrom)
|
||||
CImageBasis::CImageBasis(string _name, CImageBasis *_copyfrom)
|
||||
{
|
||||
name = _name;
|
||||
islocked = false;
|
||||
externalImage = false;
|
||||
channels = _copyfrom->channels;
|
||||
@@ -469,8 +475,15 @@ CImageBasis::CImageBasis(CImageBasis *_copyfrom)
|
||||
LogFile.WriteHeapInfo("CImageBasis_copyfrom - Start");
|
||||
#endif
|
||||
|
||||
int memsize = width * height * channels;
|
||||
rgb_image = (unsigned char*)GET_MEMORY(memsize);
|
||||
memsize = width * height * channels;
|
||||
|
||||
|
||||
if (name == "tmpImage") {
|
||||
rgb_image = (unsigned char*)psram_reserve_shared_tmp_image_memory();
|
||||
}
|
||||
else {
|
||||
rgb_image = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->CImageBasis (" + name + ")", memsize, MALLOC_CAP_SPIRAM);
|
||||
}
|
||||
|
||||
if (rgb_image == NULL)
|
||||
{
|
||||
@@ -489,8 +502,9 @@ CImageBasis::CImageBasis(CImageBasis *_copyfrom)
|
||||
}
|
||||
|
||||
|
||||
CImageBasis::CImageBasis(int _width, int _height, int _channels)
|
||||
CImageBasis::CImageBasis(string _name, int _width, int _height, int _channels)
|
||||
{
|
||||
name = _name;
|
||||
islocked = false;
|
||||
externalImage = false;
|
||||
channels = _channels;
|
||||
@@ -504,8 +518,9 @@ CImageBasis::CImageBasis(int _width, int _height, int _channels)
|
||||
LogFile.WriteHeapInfo("CImageBasis_width,height,ch - Start");
|
||||
#endif
|
||||
|
||||
int memsize = width * height * channels;
|
||||
rgb_image = (unsigned char*)GET_MEMORY(memsize);
|
||||
memsize = width * height * channels;
|
||||
|
||||
rgb_image = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->CImageBasis (" + name + ")", memsize, MALLOC_CAP_SPIRAM);
|
||||
|
||||
if (rgb_image == NULL)
|
||||
{
|
||||
@@ -523,8 +538,9 @@ CImageBasis::CImageBasis(int _width, int _height, int _channels)
|
||||
}
|
||||
|
||||
|
||||
CImageBasis::CImageBasis(std::string _image)
|
||||
CImageBasis::CImageBasis(string _name, std::string _image)
|
||||
{
|
||||
name = _name;
|
||||
islocked = false;
|
||||
channels = 3;
|
||||
externalImage = false;
|
||||
@@ -569,8 +585,9 @@ bool CImageBasis::ImageOkay(){
|
||||
}
|
||||
|
||||
|
||||
CImageBasis::CImageBasis(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp)
|
||||
CImageBasis::CImageBasis(string _name, uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp)
|
||||
{
|
||||
name = _name;
|
||||
islocked = false;
|
||||
rgb_image = _rgb_image;
|
||||
channels = _channels;
|
||||
@@ -607,8 +624,21 @@ CImageBasis::~CImageBasis()
|
||||
{
|
||||
RGBImageLock();
|
||||
|
||||
if (!externalImage)
|
||||
stbi_image_free(rgb_image);
|
||||
|
||||
if (!externalImage) {
|
||||
if (name == "tmpImage") { // This image should be placed in the shared part of PSRAM
|
||||
psram_free_shared_temp_image_memory();
|
||||
}
|
||||
else { // All other images are much smaller and can go into the normal PSRAM region
|
||||
//stbi_image_free(rgb_image);
|
||||
if (memsize == 0) {
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Not freeing (" + name + " as there was never PSRAM allocated for it)");
|
||||
}
|
||||
else {
|
||||
free_psram_heap(std::string(TAG) + "->CImageBasis (" + name + ", " + to_string(memsize) + ")", rgb_image);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RGBImageRelease();
|
||||
}
|
||||
@@ -637,19 +667,19 @@ void CImageBasis::SaveToFile(std::string _imageout)
|
||||
|
||||
void CImageBasis::Resize(int _new_dx, int _new_dy)
|
||||
{
|
||||
int memsize = _new_dx * _new_dy * channels;
|
||||
uint8_t* odata = (unsigned char*)GET_MEMORY(memsize);
|
||||
memsize = _new_dx * _new_dy * channels;
|
||||
uint8_t* odata = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->odata", memsize, MALLOC_CAP_SPIRAM);
|
||||
|
||||
RGBImageLock();
|
||||
|
||||
stbir_resize_uint8(rgb_image, width, height, 0, odata, _new_dx, _new_dy, 0, channels);
|
||||
stbi_image_free(rgb_image);
|
||||
|
||||
rgb_image = (unsigned char*)GET_MEMORY(memsize);
|
||||
rgb_image = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->CImageBasis Resize (" + name + ")", memsize, MALLOC_CAP_SPIRAM);
|
||||
memCopy(odata, rgb_image, memsize);
|
||||
width = _new_dx;
|
||||
height = _new_dy;
|
||||
stbi_image_free(odata);
|
||||
|
||||
free_psram_heap(std::string(TAG) + "->odata", odata);
|
||||
|
||||
RGBImageRelease();
|
||||
}
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "stb_image.h"
|
||||
#include "stb_image_write.h"
|
||||
#include "stb_image_resize.h"
|
||||
#include "../stb/stb_image.h"
|
||||
#include "../stb/stb_image_write.h"
|
||||
#include "../stb/stb_image_resize.h"
|
||||
|
||||
#include "esp_heap_caps.h"
|
||||
|
||||
@@ -30,6 +30,8 @@ class CImageBasis
|
||||
protected:
|
||||
bool externalImage;
|
||||
std::string filename;
|
||||
std::string name; // Just used for diagnostics
|
||||
int memsize = 0;
|
||||
|
||||
void memCopy(uint8_t* _source, uint8_t* _target, int _size);
|
||||
bool isInImage(int x, int y);
|
||||
@@ -37,7 +39,7 @@ class CImageBasis
|
||||
bool islocked;
|
||||
|
||||
public:
|
||||
uint8_t* rgb_image;
|
||||
uint8_t* rgb_image = NULL;
|
||||
int channels;
|
||||
int width, height, bpp;
|
||||
|
||||
@@ -64,11 +66,11 @@ class CImageBasis
|
||||
void EmptyImage();
|
||||
|
||||
|
||||
CImageBasis();
|
||||
CImageBasis(std::string _image);
|
||||
CImageBasis(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp);
|
||||
CImageBasis(int _width, int _height, int _channels);
|
||||
CImageBasis(CImageBasis *_copyfrom);
|
||||
CImageBasis(std::string name);
|
||||
CImageBasis(std::string name, std::string _image);
|
||||
CImageBasis(std::string name, uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp);
|
||||
CImageBasis(std::string name, int _width, int _height, int _channels);
|
||||
CImageBasis(std::string name, CImageBasis *_copyfrom);
|
||||
|
||||
void Resize(int _new_dx, int _new_dy);
|
||||
void Resize(int _new_dx, int _new_dy, CImageBasis *_target);
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
#include <string>
|
||||
#include "CRotateImage.h"
|
||||
#include "psram.h"
|
||||
|
||||
static const char *TAG = "C ROTATE IMG";
|
||||
|
||||
CRotateImage::CRotateImage(CImageBasis *_org, CImageBasis *_temp, bool _flip)
|
||||
CRotateImage::CRotateImage(std::string _name, CImageBasis *_org, CImageBasis *_temp, bool _flip) : CImageBasis(_name)
|
||||
{
|
||||
rgb_image = _org->rgb_image;
|
||||
channels = _org->channels;
|
||||
@@ -15,6 +18,7 @@ CRotateImage::CRotateImage(CImageBasis *_org, CImageBasis *_temp, bool _flip)
|
||||
doflip = _flip;
|
||||
}
|
||||
|
||||
|
||||
void CRotateImage::Mirror(){
|
||||
int memsize = width * height * channels;
|
||||
uint8_t* odata;
|
||||
@@ -24,7 +28,7 @@ void CRotateImage::Mirror(){
|
||||
}
|
||||
else
|
||||
{
|
||||
odata = (unsigned char*)GET_MEMORY(memsize);
|
||||
odata = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->odata", memsize, MALLOC_CAP_SPIRAM);
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +54,7 @@ void CRotateImage::Mirror(){
|
||||
// memcpy(rgb_image, odata, memsize);
|
||||
memCopy(odata, rgb_image, memsize);
|
||||
if (!ImageTMP)
|
||||
stbi_image_free(odata);
|
||||
free_psram_heap(std::string(TAG) + "->odata", odata);
|
||||
|
||||
if (ImageTMP)
|
||||
ImageTMP->RGBImageRelease();
|
||||
@@ -109,7 +113,7 @@ void CRotateImage::Rotate(float _angle, int _centerx, int _centery)
|
||||
}
|
||||
else
|
||||
{
|
||||
odata = (unsigned char*)GET_MEMORY(memsize);
|
||||
odata = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->odata", memsize, MALLOC_CAP_SPIRAM);
|
||||
}
|
||||
|
||||
|
||||
@@ -148,7 +152,7 @@ void CRotateImage::Rotate(float _angle, int _centerx, int _centery)
|
||||
|
||||
if (!ImageTMP)
|
||||
{
|
||||
stbi_image_free(odata);
|
||||
free_psram_heap(std::string(TAG) + "->odata", odata);
|
||||
}
|
||||
if (ImageTMP)
|
||||
ImageTMP->RGBImageRelease();
|
||||
@@ -209,7 +213,7 @@ void CRotateImage::RotateAntiAliasing(float _angle, int _centerx, int _centery)
|
||||
}
|
||||
else
|
||||
{
|
||||
odata = (unsigned char*)GET_MEMORY(memsize);
|
||||
odata = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->odata", memsize, MALLOC_CAP_SPIRAM);
|
||||
}
|
||||
|
||||
|
||||
@@ -269,7 +273,7 @@ void CRotateImage::RotateAntiAliasing(float _angle, int _centerx, int _centery)
|
||||
|
||||
if (!ImageTMP)
|
||||
{
|
||||
stbi_image_free(odata);
|
||||
free_psram_heap(std::string(TAG) + "->odata", odata);
|
||||
}
|
||||
if (ImageTMP)
|
||||
ImageTMP->RGBImageRelease();
|
||||
@@ -300,7 +304,7 @@ void CRotateImage::Translate(int _dx, int _dy)
|
||||
}
|
||||
else
|
||||
{
|
||||
odata = (unsigned char*)GET_MEMORY(memsize);
|
||||
odata = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->odata", memsize, MALLOC_CAP_SPIRAM);
|
||||
}
|
||||
|
||||
|
||||
@@ -336,7 +340,7 @@ void CRotateImage::Translate(int _dx, int _dy)
|
||||
memCopy(odata, rgb_image, memsize);
|
||||
if (!ImageTMP)
|
||||
{
|
||||
stbi_image_free(odata);
|
||||
free_psram_heap(std::string(TAG) + "->odata", odata);
|
||||
}
|
||||
|
||||
if (ImageTMP)
|
||||
|
||||
@@ -8,12 +8,13 @@
|
||||
|
||||
class CRotateImage: public CImageBasis
|
||||
{
|
||||
|
||||
public:
|
||||
CImageBasis *ImageTMP, *ImageOrg;
|
||||
bool doflip;
|
||||
CRotateImage(std::string _image, bool _flip = false) : CImageBasis(_image) {ImageTMP = NULL; ImageOrg = NULL; doflip = _flip;};
|
||||
CRotateImage(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp, bool _flip = false) : CImageBasis(_rgb_image, _channels, _width, _height, _bpp) {ImageTMP = NULL; ImageOrg = NULL; doflip = _flip;};
|
||||
CRotateImage(CImageBasis *_org, CImageBasis *_temp, bool _flip = false);
|
||||
CRotateImage(std::string name, std::string _image, bool _flip = false) : CImageBasis(name, _image) {ImageTMP = NULL; ImageOrg = NULL; doflip = _flip;};
|
||||
CRotateImage(std::string name, uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp, bool _flip = false) : CImageBasis(name, _rgb_image, _channels, _width, _height, _bpp) {ImageTMP = NULL; ImageOrg = NULL; doflip = _flip;};
|
||||
CRotateImage(std::string name, CImageBasis *_org, CImageBasis *_temp, bool _flip = false);
|
||||
|
||||
void Rotate(float _angle);
|
||||
void RotateAntiAliasing(float _angle);
|
||||
|
||||
@@ -1,13 +1,28 @@
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include "psram.h"
|
||||
|
||||
#include "../../include/defines.h"
|
||||
|
||||
|
||||
#define USE_SHARED_PSRAM_FOR_STBI
|
||||
|
||||
#ifdef USE_SHARED_PSRAM_FOR_STBI
|
||||
#define STBI_MALLOC(sz) psram_reserve_shared_stbi_memory(sz)
|
||||
#define STBI_REALLOC(p,newsz) psram_reallocate_shared_stbi_memory(p, newsz)
|
||||
#define STBI_FREE(p) psram_free_shared_stbi_memory(p)
|
||||
#else // Use normal PSRAM
|
||||
#define STBI_MALLOC(sz) malloc_psram_heap("STBI", sz, MALLOC_CAP_SPIRAM)
|
||||
#define STBI_REALLOC(p,newsz) realloc_psram_heap("STBI", p, newsz, MALLOC_CAP_SPIRAM)
|
||||
#define STBI_FREE(p) free_psram_heap("STBI", p)
|
||||
#endif
|
||||
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "stb_image.h"
|
||||
#include "../stb/stb_image.h"
|
||||
|
||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
#include "stb_image_write.h"
|
||||
#include "../stb/stb_image_write.h"
|
||||
|
||||
#define STB_IMAGE_RESIZE_IMPLEMENTATION
|
||||
#include "stb_image_resize.h"
|
||||
#include "../stb/stb_image_resize.h"
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,214 +0,0 @@
|
||||
#ifdef ENABLE_INFLUXDB
|
||||
#include "interface_influxdb.h"
|
||||
|
||||
#include "esp_log.h"
|
||||
#include <time.h>
|
||||
#include "ClassLogFile.h"
|
||||
#include "esp_http_client.h"
|
||||
#include "../../include/defines.h"
|
||||
|
||||
|
||||
static const char *TAG = "INFLUXDB";
|
||||
|
||||
std::string _influxDBURI;
|
||||
std::string _influxDBDatabase;
|
||||
std::string _influxDBMeasurement;
|
||||
std::string _influxDBUser;
|
||||
std::string _influxDBPassword;
|
||||
|
||||
static esp_err_t http_event_handler(esp_http_client_event_t *evt)
|
||||
{
|
||||
switch(evt->event_id)
|
||||
{
|
||||
case HTTP_EVENT_ERROR:
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP Client Error encountered");
|
||||
break;
|
||||
case HTTP_EVENT_ON_CONNECTED:
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP Client Error encountered");
|
||||
ESP_LOGI(TAG, "HTTP Client Connected");
|
||||
break;
|
||||
case HTTP_EVENT_HEADERS_SENT:
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP Client sent all request headers");
|
||||
break;
|
||||
case HTTP_EVENT_ON_HEADER:
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Header: key=" + std::string(evt->header_key) + ", value=" + std::string(evt->header_value));
|
||||
break;
|
||||
case HTTP_EVENT_ON_DATA:
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP Client data recevied: len=" + std::to_string(evt->data_len));
|
||||
break;
|
||||
case HTTP_EVENT_ON_FINISH:
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP Client finished");
|
||||
break;
|
||||
case HTTP_EVENT_DISCONNECTED:
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP Client Disconnected");
|
||||
break;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void InfluxDBPublish(std::string _key, std::string _content, std::string _timestamp) {
|
||||
char response_buffer[MAX_HTTP_OUTPUT_BUFFER] = {0};
|
||||
esp_http_client_config_t http_config = {
|
||||
.user_agent = "ESP32 Meter reader",
|
||||
.method = HTTP_METHOD_POST,
|
||||
.event_handler = http_event_handler,
|
||||
.buffer_size = MAX_HTTP_OUTPUT_BUFFER,
|
||||
.user_data = response_buffer
|
||||
};
|
||||
|
||||
if (_influxDBUser.length() && _influxDBPassword.length()){
|
||||
http_config.username = _influxDBUser.c_str();
|
||||
http_config.password = _influxDBPassword.c_str();
|
||||
http_config.auth_type = HTTP_AUTH_TYPE_BASIC;
|
||||
}
|
||||
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "InfluxDBPublish - Key: " + _key + ", Content: " + _content + ", Timestamp: " + _timestamp);
|
||||
|
||||
char nowTimestamp[21];
|
||||
std::string payload;
|
||||
|
||||
if (_timestamp.length() > 0)
|
||||
{
|
||||
struct tm tm;
|
||||
strptime(_timestamp.c_str(), PREVALUE_TIME_FORMAT_OUTPUT, &tm);
|
||||
time_t t = mktime(&tm); // Time in Localtime (looks like timezone is not used by strptime)
|
||||
|
||||
struct tm * ptm;
|
||||
ptm = gmtime ( &t );
|
||||
time_t utc = mktime(ptm);
|
||||
utc = 2*t - utc; // Take care of timezone (looks difficult, but is easy: t = t + (t - utc), weil t-utc = timezone)
|
||||
|
||||
sprintf(nowTimestamp,"%ld000000000", (long) utc); // UTC
|
||||
|
||||
payload = _influxDBMeasurement + " " + _key + "=" + _content + " " + nowTimestamp;
|
||||
// payload = _influxDBMeasurement + " " + _key + "=774 " + nowTimestamp;
|
||||
}
|
||||
else
|
||||
{
|
||||
payload = _influxDBMeasurement + " " + _key + "=" + _content;
|
||||
}
|
||||
|
||||
payload.shrink_to_fit();
|
||||
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "sending line to influxdb:" + payload);
|
||||
|
||||
|
||||
// use the default retention policy of the database
|
||||
std::string apiURI = _influxDBURI + "/api/v2/write?bucket=" + _influxDBDatabase + "/";
|
||||
apiURI.shrink_to_fit();
|
||||
http_config.url = apiURI.c_str();
|
||||
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "API URI: " + apiURI);
|
||||
|
||||
esp_http_client_handle_t http_client = esp_http_client_init(&http_config);
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "client is initialized");
|
||||
|
||||
esp_http_client_set_header(http_client, "Content-Type", "text/plain");
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "header is set");
|
||||
|
||||
ESP_ERROR_CHECK(esp_http_client_set_post_field(http_client, payload.c_str(), payload.length()));
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "post payload is set");
|
||||
|
||||
esp_err_t err = ESP_ERROR_CHECK_WITHOUT_ABORT(esp_http_client_perform(http_client));
|
||||
|
||||
if( err == ESP_OK ) {
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP request was performed");
|
||||
int status_code = esp_http_client_get_status_code(http_client);
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP status code" + std::to_string(status_code));
|
||||
} else {
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP request failed");
|
||||
}
|
||||
esp_http_client_cleanup(http_client);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
void InfluxDBPublish(std::string _key, std::string _content, std::string _timestamp) {
|
||||
char response_buffer[MAX_HTTP_OUTPUT_BUFFER] = {0};
|
||||
esp_http_client_config_t http_config = {
|
||||
.user_agent = "ESP32 Meter reader",
|
||||
.method = HTTP_METHOD_POST,
|
||||
.event_handler = http_event_handler,
|
||||
.buffer_size = MAX_HTTP_OUTPUT_BUFFER,
|
||||
.user_data = response_buffer
|
||||
};
|
||||
|
||||
if (_influxDBUser.length() && _influxDBPassword.length()){
|
||||
http_config.username = _influxDBUser.c_str();
|
||||
http_config.password = _influxDBPassword.c_str();
|
||||
http_config.auth_type = HTTP_AUTH_TYPE_BASIC;
|
||||
}
|
||||
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "InfluxDBPublish - Key: " + _key + ", Content: " + _content + ", Timestamp: " + _timestamp);
|
||||
|
||||
// Format: #define PREVALUE_TIME_FORMAT_OUTPUT "%Y-%m-%dT%H:%M:%S%z"
|
||||
struct tm tm;
|
||||
strptime(_timestamp.c_str(), PREVALUE_TIME_FORMAT_OUTPUT, &tm);
|
||||
time_t t = mktime(&tm); // t is now your desired time_t
|
||||
|
||||
struct tm * ptm;
|
||||
ptm = gmtime ( &t );
|
||||
time_t utc = mktime(ptm);
|
||||
|
||||
// time_t now;
|
||||
// time(&now);
|
||||
char nowTimestamp[21];
|
||||
// pad with zeroes to get nanoseconds
|
||||
// sprintf(nowTimestamp,"%ld000000000", (long) now);
|
||||
// sprintf(nowTimestamp,"%ld000000000", (long) t); // Localtime
|
||||
sprintf(nowTimestamp,"%ld000000000", (long) utc); // UTC
|
||||
|
||||
|
||||
// LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Test Time Conversion - t: " + std::to_string(t) + ", utc: " + std::to_string(utc));
|
||||
// LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Test Time Conversion - now: " + std::to_string(now) + ", timestamp: " + std::to_string(t) + "(correct time not used yet)");
|
||||
|
||||
std::string payload = _influxDBMeasurement + " " + _key + "=" + _content + " " + nowTimestamp;
|
||||
payload.shrink_to_fit();
|
||||
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "sending line to influxdb:" + payload);
|
||||
|
||||
|
||||
// use the default retention policy of the database
|
||||
std::string apiURI = _influxDBURI + "/api/v2/write?bucket=" + _influxDBDatabase + "/";
|
||||
apiURI.shrink_to_fit();
|
||||
http_config.url = apiURI.c_str();
|
||||
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "API URI: " + apiURI);
|
||||
|
||||
esp_http_client_handle_t http_client = esp_http_client_init(&http_config);
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "client is initialized");
|
||||
|
||||
esp_http_client_set_header(http_client, "Content-Type", "text/plain");
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "header is set");
|
||||
|
||||
ESP_ERROR_CHECK(esp_http_client_set_post_field(http_client, payload.c_str(), payload.length()));
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "post payload is set");
|
||||
|
||||
esp_err_t err = ESP_ERROR_CHECK_WITHOUT_ABORT(esp_http_client_perform(http_client));
|
||||
|
||||
if( err == ESP_OK ) {
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP request was performed");
|
||||
int status_code = esp_http_client_get_status_code(http_client);
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP status code" + std::to_string(status_code));
|
||||
} else {
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP request failed");
|
||||
}
|
||||
esp_http_client_cleanup(http_client);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
void InfluxDBInit(std::string _uri, std::string _database, std::string _measurement, std::string _user, std::string _password){
|
||||
_influxDBURI = _uri;
|
||||
_influxDBDatabase = _database;
|
||||
_influxDBMeasurement = _measurement;
|
||||
_influxDBUser = _user;
|
||||
_influxDBPassword = _password;
|
||||
|
||||
}
|
||||
|
||||
void InfluxDBdestroy() {
|
||||
}
|
||||
|
||||
#endif //ENABLE_INFLUXDB
|
||||
@@ -1,24 +0,0 @@
|
||||
#ifdef ENABLE_INFLUXDB
|
||||
|
||||
#pragma once
|
||||
#ifndef INTERFACE_INFLUXDB_H
|
||||
#define INTERFACE_INFLUXDB_H
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <functional>
|
||||
|
||||
// Interface to InfluxDB v1.x
|
||||
void InfluxDBInit(std::string _influxDBURI, std::string _database, std::string _measurement, std::string _user, std::string _password);
|
||||
void InfluxDBPublish(std::string _key, std::string _content, std::string _timestamp);
|
||||
|
||||
// Interface to InfluxDB v2.x
|
||||
void InfluxDB_V2_Init(std::string _uri, std::string _database, std::string _measurement, std::string _org, std::string _token);
|
||||
void InfluxDB_V2_Publish(std::string _key, std::string _content, std::string _timestamp);
|
||||
|
||||
|
||||
|
||||
void InfluxDBdestroy();
|
||||
|
||||
#endif //INTERFACE_INFLUXDB_H
|
||||
#endif //ENABLE_INFLUXDB
|
||||
@@ -12,28 +12,25 @@ static const char *TAG = "INFLUXDB";
|
||||
|
||||
std::string _influxDBURI;
|
||||
std::string _influxDBDatabase;
|
||||
std::string _influxDBMeasurement;
|
||||
std::string _influxDBUser;
|
||||
std::string _influxDBPassword;
|
||||
|
||||
std::string _influxDB_V2_URI;
|
||||
std::string _influxDB_V2_Database;
|
||||
std::string _influxDB_V2_Measurement;
|
||||
std::string _influxDB_V2_Token;
|
||||
std::string _influxDB_V2_Org;
|
||||
|
||||
static esp_err_t http_event_handler(esp_http_client_event_t *evt);
|
||||
|
||||
void InfluxDB_V2_Init(std::string _uri, std::string _database, std::string _measurement, std::string _org, std::string _token)
|
||||
void InfluxDB_V2_Init(std::string _uri, std::string _database, std::string _org, std::string _token)
|
||||
{
|
||||
_influxDB_V2_URI = _uri;
|
||||
_influxDB_V2_Database = _database;
|
||||
_influxDB_V2_Measurement = _measurement;
|
||||
_influxDB_V2_Org = _org;
|
||||
_influxDB_V2_Token = _token;
|
||||
}
|
||||
|
||||
void InfluxDB_V2_Publish(std::string _key, std::string _content, std::string _timestamp)
|
||||
void InfluxDB_V2_Publish(std::string _measurement, std::string _key, std::string _content, std::string _timestamp)
|
||||
{
|
||||
char response_buffer[MAX_HTTP_OUTPUT_BUFFER] = {0};
|
||||
esp_http_client_config_t http_config = {
|
||||
@@ -46,10 +43,8 @@ void InfluxDB_V2_Publish(std::string _key, std::string _content, std::string _ti
|
||||
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "InfluxDB_V2_Publish - Key: " + _key + ", Content: " + _content + ", Timestamp: " + _timestamp);
|
||||
|
||||
// Format: #define PREVALUE_TIME_FORMAT_OUTPUT "%Y-%m-%dT%H:%M:%S%z"
|
||||
|
||||
char nowTimestamp[21];
|
||||
std::string payload;
|
||||
char nowTimestamp[21];
|
||||
|
||||
if (_timestamp.length() > 0)
|
||||
{
|
||||
@@ -57,20 +52,22 @@ void InfluxDB_V2_Publish(std::string _key, std::string _content, std::string _ti
|
||||
strptime(_timestamp.c_str(), PREVALUE_TIME_FORMAT_OUTPUT, &tm);
|
||||
time_t t = mktime(&tm); // Time in Localtime (looks like timezone is not used by strptime)
|
||||
|
||||
struct tm * ptm;
|
||||
ptm = gmtime ( &t );
|
||||
time_t utc = mktime(ptm);
|
||||
utc = 2*t - utc; // Take care of timezone (looks difficult, but is easy: t = t + (t - utc), weil t-utc = timezone)
|
||||
// struct tm * ptm;
|
||||
// ptm = gmtime ( &t );
|
||||
// time_t utc = mktime(ptm);
|
||||
|
||||
sprintf(nowTimestamp,"%ld000000000", (long) utc); // UTC
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Use handover timestamp: " + _timestamp + " converted GMT timestamp: " + std::to_string(t));
|
||||
|
||||
payload = _influxDB_V2_Measurement + " " + _key + "=" + _content + " " + nowTimestamp;
|
||||
// payload = _influxDB_V2_Measurement + " " + _key + "=774 " + nowTimestamp;
|
||||
// utc = 2*t - utc; // Take care of timezone (looks difficult, but is easy: t = t + (t - utc), weil t-utc = timezone)
|
||||
// LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "time conversion utc after: " + std::to_string(utc));
|
||||
|
||||
sprintf(nowTimestamp,"%ld000000000", (long) t); // UTC
|
||||
|
||||
payload = _measurement + " " + _key + "=" + _content + " " + nowTimestamp;
|
||||
}
|
||||
else
|
||||
{
|
||||
payload = _influxDB_V2_Measurement + " " + _key + "=" + _content;
|
||||
// payload = _influxDB_V2_Measurement + " " + _key + "=774";
|
||||
payload = _measurement + " " + _key + "=" + _content;
|
||||
}
|
||||
|
||||
payload.shrink_to_fit();
|
||||
@@ -137,11 +134,14 @@ static esp_err_t http_event_handler(esp_http_client_event_t *evt)
|
||||
case HTTP_EVENT_DISCONNECTED:
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP Client Disconnected");
|
||||
break;
|
||||
case HTTP_EVENT_REDIRECT:
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP Redirect");
|
||||
break;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void InfluxDBPublish(std::string _key, std::string _content, std::string _timestamp) {
|
||||
void InfluxDBPublish(std::string _measurement, std::string _key, std::string _content, std::string _timestamp) {
|
||||
char response_buffer[MAX_HTTP_OUTPUT_BUFFER] = {0};
|
||||
esp_http_client_config_t http_config = {
|
||||
.user_agent = "ESP32 Meter reader",
|
||||
@@ -157,10 +157,10 @@ void InfluxDBPublish(std::string _key, std::string _content, std::string _timest
|
||||
http_config.auth_type = HTTP_AUTH_TYPE_BASIC;
|
||||
}
|
||||
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "InfluxDBPublish - Key: " + _key + ", Content: " + _content + ", Timestamp: " + _timestamp);
|
||||
|
||||
char nowTimestamp[21];
|
||||
std::string payload;
|
||||
char nowTimestamp[21];
|
||||
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "InfluxDBPublish - Key: " + _key + ", Content: " + _content + ", Timestamp: " + _timestamp);
|
||||
|
||||
if (_timestamp.length() > 0)
|
||||
{
|
||||
@@ -168,19 +168,22 @@ void InfluxDBPublish(std::string _key, std::string _content, std::string _timest
|
||||
strptime(_timestamp.c_str(), PREVALUE_TIME_FORMAT_OUTPUT, &tm);
|
||||
time_t t = mktime(&tm); // Time in Localtime (looks like timezone is not used by strptime)
|
||||
|
||||
struct tm * ptm;
|
||||
ptm = gmtime ( &t );
|
||||
time_t utc = mktime(ptm);
|
||||
utc = 2*t - utc; // Take care of timezone (looks difficult, but is easy: t = t + (t - utc), weil t-utc = timezone)
|
||||
// struct tm * ptm;
|
||||
// ptm = gmtime ( &t );
|
||||
// time_t utc = mktime(ptm);
|
||||
|
||||
sprintf(nowTimestamp,"%ld000000000", (long) utc); // UTC
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Use handover timestamp: " + _timestamp + " converted GMT timestamp: " + std::to_string(t));
|
||||
|
||||
payload = _influxDBMeasurement + " " + _key + "=" + _content + " " + nowTimestamp;
|
||||
// payload = _influxDBMeasurement + " " + _key + "=774 " + nowTimestamp;
|
||||
// utc = 2*t - utc; // Take care of timezone (looks difficult, but is easy: t = t + (t - utc), weil t-utc = timezone)
|
||||
// LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "time conversion utc after: " + std::to_string(utc));
|
||||
|
||||
sprintf(nowTimestamp,"%ld000000000", (long) t); // UTC
|
||||
|
||||
payload = _measurement + " " + _key + "=" + _content + " " + nowTimestamp;
|
||||
}
|
||||
else
|
||||
{
|
||||
payload = _influxDBMeasurement + " " + _key + "=" + _content;
|
||||
payload = _measurement + " " + _key + "=" + _content;
|
||||
}
|
||||
|
||||
payload.shrink_to_fit();
|
||||
@@ -189,7 +192,9 @@ void InfluxDBPublish(std::string _key, std::string _content, std::string _timest
|
||||
|
||||
|
||||
// use the default retention policy of the database
|
||||
std::string apiURI = _influxDBURI + "/api/v2/write?bucket=" + _influxDBDatabase + "/";
|
||||
std::string apiURI = _influxDBURI + "/write?db=" + _influxDBDatabase;
|
||||
// std::string apiURI = _influxDBURI + "/api/v2/write?bucket=" + _influxDBDatabase + "/";
|
||||
|
||||
apiURI.shrink_to_fit();
|
||||
http_config.url = apiURI.c_str();
|
||||
|
||||
@@ -217,10 +222,9 @@ void InfluxDBPublish(std::string _key, std::string _content, std::string _timest
|
||||
}
|
||||
|
||||
|
||||
void InfluxDBInit(std::string _uri, std::string _database, std::string _measurement, std::string _user, std::string _password){
|
||||
void InfluxDBInit(std::string _uri, std::string _database, std::string _user, std::string _password){
|
||||
_influxDBURI = _uri;
|
||||
_influxDBDatabase = _database;
|
||||
_influxDBMeasurement = _measurement;
|
||||
_influxDBUser = _user;
|
||||
_influxDBPassword = _password;
|
||||
|
||||
|
||||
@@ -9,12 +9,12 @@
|
||||
#include <functional>
|
||||
|
||||
// Interface to InfluxDB v1.x
|
||||
void InfluxDBInit(std::string _influxDBURI, std::string _database, std::string _measurement, std::string _user, std::string _password);
|
||||
void InfluxDBPublish(std::string _key, std::string _content, std::string _timestamp);
|
||||
void InfluxDBInit(std::string _influxDBURI, std::string _database, std::string _user, std::string _password);
|
||||
void InfluxDBPublish(std::string _measurement, std::string _key, std::string _content, std::string _timestamp);
|
||||
|
||||
// Interface to InfluxDB v2.x
|
||||
void InfluxDB_V2_Init(std::string _uri, std::string _database, std::string _measurement, std::string _org, std::string _token);
|
||||
void InfluxDB_V2_Publish(std::string _key, std::string _content, std::string _timestamp);
|
||||
void InfluxDB_V2_Init(std::string _uri, std::string _database, std::string _org, std::string _token);
|
||||
void InfluxDB_V2_Publish(std::string _measurement, std::string _key, std::string _content, std::string _timestamp);
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2,4 +2,4 @@ FILE(GLOB_RECURSE app_sources ${CMAKE_CURRENT_SOURCE_DIR}/*.*)
|
||||
|
||||
idf_component_register(SRCS ${app_sources}
|
||||
INCLUDE_DIRS "."
|
||||
REQUIRES tflite-lib mqtt jomjol_tfliteclass jomjol_helper jomjol_mqtt jomjol_wlan)
|
||||
REQUIRES esp_timer tflite-lib mqtt jomjol_tfliteclass jomjol_helper jomjol_mqtt jomjol_wlan json)
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
#include "connect_wlan.h"
|
||||
#include "mqtt_client.h"
|
||||
#include "ClassLogFile.h"
|
||||
#include "server_tflite.h"
|
||||
#include "MainFlowControl.h"
|
||||
#include "cJSON.h"
|
||||
#include "../../include/defines.h"
|
||||
|
||||
static const char *TAG = "MQTT IF";
|
||||
@@ -139,6 +140,31 @@ static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event) {
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_ERROR:
|
||||
// http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718033 --> chapter 3.2.2.3
|
||||
|
||||
// The server does not support the level of the MQTT protocol requested by the client
|
||||
// NOTE: Only protocol 3.1.1 is supported (refer to setting in sdkconfig)
|
||||
if (event->error_handle->connect_return_code == MQTT_CONNECTION_REFUSE_PROTOCOL) {
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Connection refused, unacceptable protocol version (0x01)");
|
||||
}
|
||||
// The client identifier is correct UTF-8 but not allowed by the server
|
||||
// e.g. clientID empty (cannot be the case -> default set in firmware)
|
||||
else if (event->error_handle->connect_return_code == MQTT_CONNECTION_REFUSE_ID_REJECTED) {
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Connection refused, identifier rejected (0x02)");
|
||||
}
|
||||
// The network connection has been made but the MQTT service is unavailable
|
||||
else if (event->error_handle->connect_return_code == MQTT_CONNECTION_REFUSE_SERVER_UNAVAILABLE) {
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Connection refused, Server unavailable (0x03)");
|
||||
}
|
||||
// The data in the user name or password is malformed
|
||||
else if (event->error_handle->connect_return_code == MQTT_CONNECTION_REFUSE_BAD_USERNAME) {
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Connection refused, malformed data in username or password (0x04)");
|
||||
}
|
||||
// The client is not authorized to connect
|
||||
else if (event->error_handle->connect_return_code == MQTT_CONNECTION_REFUSE_NOT_AUTHORIZED) {
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Connection refused, not authorized. Check username/password (0x05)");
|
||||
}
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "MQTT_EVENT_ERROR - esp_mqtt_error_codes:");
|
||||
ESP_LOGD(TAG, "error_type:%d", event->error_handle->error_type);
|
||||
@@ -148,7 +174,7 @@ static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event) {
|
||||
ESP_LOGD(TAG, "esp_tls_stack_err:%d", event->error_handle->esp_tls_stack_err);
|
||||
ESP_LOGD(TAG, "esp_tls_cert_verify_flags:%d", event->error_handle->esp_tls_cert_verify_flags);
|
||||
#endif
|
||||
//mqtt_connected = false;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -160,7 +186,7 @@ static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event) {
|
||||
|
||||
|
||||
static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data) {
|
||||
ESP_LOGD(TAG, "Event dispatched from event loop base=%s, event_id=%d", base, event_id);
|
||||
ESP_LOGD(TAG, "Event dispatched from event loop base=%s, event_id=%d", base, (int)event_id);
|
||||
mqtt_event_handler_cb((esp_mqtt_event_handle_t) event_data);
|
||||
}
|
||||
|
||||
@@ -222,25 +248,24 @@ int MQTT_Init() {
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Init");
|
||||
MQTTdestroy_client(false);
|
||||
|
||||
esp_mqtt_client_config_t mqtt_cfg = {
|
||||
.uri = uri.c_str(),
|
||||
.client_id = client_id.c_str(),
|
||||
.lwt_topic = lwt_topic.c_str(),
|
||||
.lwt_msg = lwt_disconnected.c_str(),
|
||||
.lwt_retain = 1,
|
||||
.lwt_msg_len = (int)(lwt_disconnected.length()),
|
||||
.keepalive = keepalive,
|
||||
.disable_auto_reconnect = false, // Reconnection routine active (Default: false)
|
||||
.buffer_size = 1536, // size of MQTT send/receive buffer (Default: 1024)
|
||||
.reconnect_timeout_ms = 15000, // Try to reconnect to broker (Default: 10000ms)
|
||||
.network_timeout_ms = 20000, // Network Timeout (Default: 10000ms)
|
||||
.message_retransmit_timeout = 3000 // Time after message resent when broker not acknowledged (QoS1, QoS2)
|
||||
esp_mqtt_client_config_t mqtt_cfg = { };
|
||||
|
||||
};
|
||||
mqtt_cfg.broker.address.uri = uri.c_str();
|
||||
mqtt_cfg.credentials.client_id = client_id.c_str();
|
||||
mqtt_cfg.network.disable_auto_reconnect = false; // Reconnection routine active (Default: false)
|
||||
mqtt_cfg.network.reconnect_timeout_ms = 15000; // Try to reconnect to broker (Default: 10000ms)
|
||||
mqtt_cfg.network.timeout_ms = 20000; // Network Timeout (Default: 10000ms)
|
||||
mqtt_cfg.session.message_retransmit_timeout = 3000; // Time after message resent when broker not acknowledged (QoS1, QoS2)
|
||||
mqtt_cfg.session.last_will.topic = lwt_topic.c_str();
|
||||
mqtt_cfg.session.last_will.retain = 1;
|
||||
mqtt_cfg.session.last_will.msg = lwt_disconnected.c_str();
|
||||
mqtt_cfg.session.last_will.msg_len = (int)(lwt_disconnected.length());
|
||||
mqtt_cfg.session.keepalive = keepalive;
|
||||
mqtt_cfg.buffer.size = 1536; // size of MQTT send/receive buffer (Default: 1024)
|
||||
|
||||
if (user.length() && password.length()){
|
||||
mqtt_cfg.username = user.c_str();
|
||||
mqtt_cfg.password = password.c_str();
|
||||
mqtt_cfg.credentials.username = user.c_str();
|
||||
mqtt_cfg.credentials.authentication.password = password.c_str();
|
||||
}
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
@@ -312,17 +337,54 @@ bool getMQTTisConnected() {
|
||||
}
|
||||
|
||||
|
||||
bool mqtt_handler_flow_start(std::string _topic, char* _data, int _data_len) {
|
||||
bool mqtt_handler_flow_start(std::string _topic, char* _data, int _data_len)
|
||||
{
|
||||
ESP_LOGD(TAG, "Handler called: topic %s, data %.*s", _topic.c_str(), _data_len, _data);
|
||||
|
||||
if (_data_len > 0) {
|
||||
MQTTCtrlFlowStart(_topic);
|
||||
}
|
||||
else {
|
||||
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "handler_flow_start: handler called, but no data");
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
bool mqtt_handler_set_prevalue(std::string _topic, char* _data, int _data_len)
|
||||
{
|
||||
//ESP_LOGD(TAG, "Handler called: topic %s, data %.*s", _topic.c_str(), _data_len, _data);
|
||||
//example: {"numbersname": "main", "value": 12345.1234567}
|
||||
|
||||
if (_data_len > 0) { // Check if data length > 0
|
||||
cJSON *jsonData = cJSON_Parse(_data);
|
||||
cJSON *numbersname = cJSON_GetObjectItemCaseSensitive(jsonData, "numbersname");
|
||||
cJSON *value = cJSON_GetObjectItemCaseSensitive(jsonData, "value");
|
||||
|
||||
if (cJSON_IsString(numbersname) && (numbersname->valuestring != NULL)) { // Check if numbersname is valid
|
||||
if (cJSON_IsNumber(value)) { // Check if value is a number
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "handler_set_prevalue called: numbersname: " + std::string(numbersname->valuestring) +
|
||||
", value: " + std::to_string(value->valuedouble));
|
||||
if (flowctrl.UpdatePrevalue(std::to_string(value->valuedouble), std::string(numbersname->valuestring), true))
|
||||
return ESP_OK;
|
||||
}
|
||||
else {
|
||||
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "handler_set_prevalue: value not a valid number (\"value\": 12345.12345)");
|
||||
}
|
||||
}
|
||||
else {
|
||||
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "handler_set_prevalue: numbersname not a valid string (\"numbersname\": \"main\")");
|
||||
}
|
||||
}
|
||||
else {
|
||||
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "handler_set_prevalue: handler called, but no data received");
|
||||
}
|
||||
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
|
||||
void MQTTconnected(){
|
||||
if (mqtt_connected) {
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Connected to broker");
|
||||
@@ -334,9 +396,14 @@ void MQTTconnected(){
|
||||
}
|
||||
}
|
||||
|
||||
/* Subcribe to topics */
|
||||
std::function<bool(std::string topic, char* data, int data_len)> subHandler = mqtt_handler_flow_start;
|
||||
MQTTregisterSubscribeFunction(maintopic + "/ctrl/flow_start", subHandler); // subcribe to maintopic/ctrl/flow_start
|
||||
// Subcribe to topics
|
||||
// Note: Further subsriptions are handled in GPIO class
|
||||
//*****************************************
|
||||
std::function<bool(std::string topic, char* data, int data_len)> subHandler1 = mqtt_handler_flow_start;
|
||||
MQTTregisterSubscribeFunction(maintopic + "/ctrl/flow_start", subHandler1); // subcribe to maintopic/ctrl/flow_start
|
||||
|
||||
std::function<bool(std::string topic, char* data, int data_len)> subHandler2 = mqtt_handler_set_prevalue;
|
||||
MQTTregisterSubscribeFunction(maintopic + "/ctrl/set_prevalue", subHandler2); // subcribe to maintopic/ctrl/set_prevalue
|
||||
|
||||
if (subscribeFunktionMap != NULL) {
|
||||
for(std::map<std::string, std::function<bool(std::string, char*, int)>>::iterator it = subscribeFunktionMap->begin(); it != subscribeFunktionMap->end(); ++it) {
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
#include "esp_log.h"
|
||||
#include "esp_heap_caps.h"
|
||||
|
||||
/* Enable this to use the PSRAM for MQTT Publishing.
|
||||
* This saves 10 kBytes of RAM, see https://github.com/jomjol/AI-on-the-edge-device/pull/2113
|
||||
* However we can run into PSRAM fragmentation issues, leading to insufficient large blocks to load the model.
|
||||
* See https://github.com/jomjol/AI-on-the-edge-device/issues/2200 */
|
||||
#define USE_PSRAM
|
||||
|
||||
#ifdef CONFIG_MQTT_CUSTOM_OUTBOX
|
||||
|
||||
@@ -2,6 +2,6 @@ FILE(GLOB_RECURSE app_sources ${CMAKE_CURRENT_SOURCE_DIR}/*.*)
|
||||
|
||||
idf_component_register(SRCS ${app_sources}
|
||||
INCLUDE_DIRS "."
|
||||
REQUIRES jomjol_image_proc jomjol_logfile esp_http_server esp32-camera jomjol_controlcamera jomjol_flowcontroll jomjol_helper)
|
||||
REQUIRES jomjol_image_proc jomjol_logfile jomjol_flowcontroll jomjol_helper)
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "CTfLiteClass.h"
|
||||
#include "ClassLogFile.h"
|
||||
#include "Helper.h"
|
||||
#include "psram.h"
|
||||
#include "esp_log.h"
|
||||
#include "../../include/defines.h"
|
||||
|
||||
@@ -242,15 +243,22 @@ bool CTfLiteClass::ReadFileToModel(std::string _fn)
|
||||
|
||||
if (size == -1)
|
||||
{
|
||||
ESP_LOGE(TAG, "CTfLiteClass::ReadFileToModel: Model file doesn't exist: %s", _fn.c_str());
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Model file doesn't exist: " + _fn + "!");
|
||||
return false;
|
||||
}
|
||||
else if(size > MAX_MODEL_SIZE) {
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Unable to load model '" + _fn + "'! It does not fit in the reserved shared memory in PSRAM!");
|
||||
return false;
|
||||
}
|
||||
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Loading Model " + _fn + " /size: " + std::to_string(size) + " bytes...");
|
||||
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("CTLiteClass::Alloc modelfile start");
|
||||
#endif
|
||||
|
||||
modelfile = (unsigned char*)GET_MEMORY(size);
|
||||
modelfile = (unsigned char*)psram_get_shared_model_memory();
|
||||
|
||||
if(modelfile != NULL)
|
||||
{
|
||||
@@ -303,19 +311,18 @@ CTfLiteClass::CTfLiteClass()
|
||||
this->modelfile = NULL;
|
||||
this->interpreter = nullptr;
|
||||
this->input = nullptr;
|
||||
this->output = nullptr;
|
||||
this->kTensorArenaSize = 800 * 1024; /// according to testfile: 108000 - so far 600;; 2021-09-11: 200 * 1024
|
||||
this->tensor_arena = (uint8_t*)GET_MEMORY(kTensorArenaSize);
|
||||
this->output = nullptr;
|
||||
this->kTensorArenaSize = TENSOR_ARENA_SIZE;
|
||||
this->tensor_arena = (uint8_t*)psram_get_shared_tensor_arena_memory();
|
||||
}
|
||||
|
||||
|
||||
CTfLiteClass::~CTfLiteClass()
|
||||
{
|
||||
free(modelfile);
|
||||
|
||||
free(this->tensor_arena);
|
||||
delete this->interpreter;
|
||||
delete this->error_reporter;
|
||||
|
||||
psram_free_shared_tensor_arena_and_model_memory();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_sleep.h"
|
||||
@@ -72,6 +71,24 @@ void time_sync_notification_cb(struct timeval *tv)
|
||||
}
|
||||
|
||||
|
||||
bool time_manual_reset_sync(void)
|
||||
{
|
||||
sntp_restart();
|
||||
// sntp_init();
|
||||
int retry = 0;
|
||||
const int retry_count = 10;
|
||||
while (sntp_get_sync_status() == SNTP_SYNC_STATUS_RESET && ++retry < retry_count) {
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Waiting for system time to be set... " + std::to_string(retry) + "/" + std::to_string(retry_count));
|
||||
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
if (retry >= retry_count)
|
||||
return false;
|
||||
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Waiting for system time successfull with " + std::to_string(retry) + "/" + std::to_string(retry_count));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void setTimeZone(std::string _tzstring)
|
||||
{
|
||||
setenv("TZ", _tzstring.c_str(), 1);
|
||||
@@ -220,11 +237,16 @@ bool setupTime() {
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Configuring NTP Client...");
|
||||
sntp_setoperatingmode(SNTP_OPMODE_POLL);
|
||||
sntp_setservername(0, timeServer.c_str());
|
||||
sntp_init();
|
||||
|
||||
sntp_set_time_sync_notification_cb(time_sync_notification_cb);
|
||||
|
||||
setTimeZone(timeZone);
|
||||
|
||||
sntp_init();
|
||||
/*
|
||||
if (!wait_for_timesync())
|
||||
{
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Timesync at startup failed.");
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
@@ -250,3 +272,5 @@ bool setupTime() {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_sleep.h"
|
||||
@@ -27,4 +26,7 @@ bool getTimeWasNotSetAtBoot(void);
|
||||
bool getUseNtp(void);
|
||||
bool setupTime();
|
||||
|
||||
bool time_manual_reset_sync(void);
|
||||
|
||||
|
||||
#endif //TIMESNTP_H
|
||||
@@ -2,6 +2,6 @@ FILE(GLOB_RECURSE app_sources ${CMAKE_CURRENT_SOURCE_DIR}/*.*)
|
||||
|
||||
idf_component_register(SRCS ${app_sources}
|
||||
INCLUDE_DIRS "."
|
||||
REQUIRES nvs_flash jomjol_helper jomjol_mqtt wpa_supplicant)
|
||||
REQUIRES esp_wifi nvs_flash jomjol_helper jomjol_mqtt wpa_supplicant)
|
||||
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include "esp_mbo.h"
|
||||
#include "esp_mac.h"
|
||||
#include "esp_netif.h"
|
||||
#include "esp_event.h"
|
||||
#include <netdb.h>
|
||||
#include "esp_log.h"
|
||||
#include "nvs_flash.h"
|
||||
|
||||
@@ -36,6 +36,18 @@
|
||||
|
||||
#include "../../include/defines.h"
|
||||
|
||||
#if (ESP_IDF_VERSION_MAJOR >= 5)
|
||||
#include "soc/periph_defs.h"
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#include "soc/gpio_sig_map.h"
|
||||
#include "soc/gpio_periph.h"
|
||||
#include "soc/io_mux_reg.h"
|
||||
#include "esp_rom_gpio.h"
|
||||
#define gpio_pad_select_gpio esp_rom_gpio_pad_select_gpio
|
||||
#define gpio_matrix_in(a,b,c) esp_rom_gpio_connect_in_signal(a,b,c)
|
||||
#define gpio_matrix_out(a,b,c,d) esp_rom_gpio_connect_out_signal(a,b,c,d)
|
||||
#define ets_delay_us(a) esp_rom_delay_us(a)
|
||||
#endif
|
||||
|
||||
static const char *TAG = "WIFI";
|
||||
|
||||
@@ -43,6 +55,7 @@ static bool APWithBetterRSSI = false;
|
||||
static bool WIFIConnected = false;
|
||||
static int WIFIReconnectCnt = 0;
|
||||
|
||||
esp_netif_t *my_sta;
|
||||
|
||||
|
||||
void strinttoip4(const char *ip, int &a, int &b, int &c, int &d) {
|
||||
@@ -173,7 +186,7 @@ static char * get_btm_neighbor_list(uint8_t *report, size_t report_len)
|
||||
pos += s_len;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Roaming: RMM neigbor report bssid=" MACSTR
|
||||
ESP_LOGI(TAG, "Roaming: RMM neighbor report bssid=" MACSTR
|
||||
" info=0x%x op_class=%u chan=%u phy_type=%u%s%s%s%s",
|
||||
MAC2STR(nr), WPA_GET_LE32(nr + ETH_ALEN),
|
||||
nr[ETH_ALEN + 4], nr[ETH_ALEN + 5],
|
||||
@@ -182,7 +195,7 @@ static char * get_btm_neighbor_list(uint8_t *report, size_t report_len)
|
||||
civic[0] ? " civic=" : "", civic);
|
||||
|
||||
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Roaming: RMM neigbor report BSSID: " + BssidToString((char*)nr) +
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Roaming: RMM neighbor report BSSID: " + BssidToString((char*)nr) +
|
||||
", Channel: " + std::to_string(nr[ETH_ALEN + 5]));
|
||||
|
||||
/* neighbor start */
|
||||
@@ -365,7 +378,7 @@ void wifi_scan(void)
|
||||
else {
|
||||
if (esp_wifi_scan_get_ap_records(&max_number_of_ap_found, wifi_ap_records) != ESP_OK) { // Retrieve results (and free internal heap)
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "wifi_scan: esp_wifi_scan_get_ap_records: Error retrieving datasets");
|
||||
free(wifi_ap_records);
|
||||
delete wifi_ap_records;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -388,7 +401,7 @@ void wifi_scan(void)
|
||||
APWithBetterRSSI = true;
|
||||
}
|
||||
}
|
||||
free(wifi_ap_records);
|
||||
delete wifi_ap_records;
|
||||
}
|
||||
|
||||
|
||||
@@ -517,7 +530,7 @@ esp_err_t wifi_init_sta(void)
|
||||
return retval;
|
||||
}
|
||||
|
||||
esp_netif_t *my_sta = esp_netif_create_default_wifi_sta();
|
||||
my_sta = esp_netif_create_default_wifi_sta();
|
||||
|
||||
if (!wlan_config.ipaddress.empty() && !wlan_config.gateway.empty() && !wlan_config.netmask.empty())
|
||||
{
|
||||
@@ -636,7 +649,7 @@ esp_err_t wifi_init_sta(void)
|
||||
|
||||
if (!wlan_config.hostname.empty())
|
||||
{
|
||||
retval = tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_STA , wlan_config.hostname.c_str());
|
||||
retval = esp_netif_set_hostname(my_sta, wlan_config.hostname.c_str());
|
||||
if(retval != ESP_OK ) {
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to set hostname! Error: " + std::to_string(retval));
|
||||
}
|
||||
@@ -660,6 +673,20 @@ int get_WIFI_RSSI()
|
||||
}
|
||||
|
||||
|
||||
/*std::string getIp() {
|
||||
esp_netif_ip_info_t ip_info;
|
||||
ESP_ERROR_CHECK(esp_netif_get_ip_info(my_sta, ip_info));
|
||||
char ipFormated[4*3+3+1];
|
||||
sprintf(ipFormated, IPSTR, IP2STR(&ip_info.ip));
|
||||
return std::string(ipFormated);
|
||||
}*/
|
||||
|
||||
|
||||
std::string* getHostname() {
|
||||
return &wlan_config.hostname;
|
||||
}
|
||||
|
||||
|
||||
bool getWIFIisConnected()
|
||||
{
|
||||
return WIFIConnected;
|
||||
|
||||
@@ -9,6 +9,8 @@ int wifi_init_sta(void);
|
||||
std::string* getIPAddress();
|
||||
std::string* getSSID();
|
||||
int get_WIFI_RSSI();
|
||||
std::string* getHostname();
|
||||
|
||||
bool getWIFIisConnected();
|
||||
void WIFIDestroy();
|
||||
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
FILE(GLOB_RECURSE app_sources ${CMAKE_CURRENT_SOURCE_DIR}/*.*)
|
||||
|
||||
idf_component_register(SRCS ${app_sources}
|
||||
INCLUDE_DIRS "." "../../include")
|
||||
|
||||
|
||||
1
code/components/stb
Submodule
1
code/components/stb
Submodule
Submodule code/components/stb added at 5736b15f7e
@@ -1,3 +1,3 @@
|
||||
manifest_hash: 4e37bb0f9273c4de05f38688720fe32aa6e5b892452694a4f7a2ca1659f02cf6
|
||||
manifest_hash: 63f5c6c9f0bcebc7b9ca12d2aa8b26b2c5f5218d377dc4b2375d9b9ca1df7815
|
||||
target: esp32
|
||||
version: 1.0.0
|
||||
|
||||
@@ -55,39 +55,48 @@
|
||||
|
||||
//compiler optimization for tflite-micro-esp-examples
|
||||
#define XTENSA
|
||||
//#define CONFIG_IDF_TARGET_ARCH_XTENSA //not needed with platformio/espressif32 @ 5.2.0
|
||||
//#define CONFIG_IDF_TARGET_ARCH_XTENSA //not needed with platformio/espressif32 @ 5.2.0
|
||||
|
||||
|
||||
//ClassControllCamera + ClassFlowTakeImage + connect_wlan + main
|
||||
#define FLASH_GPIO GPIO_NUM_4
|
||||
#define BLINK_GPIO GPIO_NUM_33
|
||||
//Statusled + ClassControllCamera
|
||||
#define BLINK_GPIO GPIO_NUM_33 // PIN for red board LED
|
||||
|
||||
//interface_mqtt + read_wlanini
|
||||
#define __HIDE_PASSWORD
|
||||
|
||||
//ClassControllCamera
|
||||
#define USE_PWM_LEDFLASH // if __LEDGLOBAL is defined, a global variable is used for LED control, otherwise locally and each time a new
|
||||
|
||||
//server_GPIO
|
||||
#define __LEDGLOBAL
|
||||
#define FLASH_GPIO GPIO_NUM_4 // PIN for flashlight LED
|
||||
#define USE_PWM_LEDFLASH // if __LEDGLOBAL is defined, a global variable is used for LED control, otherwise locally and each time a new
|
||||
#define CAM_LIVESTREAM_REFRESHRATE 500 // Camera livestream feature: Waiting time in milliseconds to refresh image
|
||||
|
||||
|
||||
//ClassControllCamera + ClassFlowTakeImage
|
||||
#define CAMERA_MODEL_AI_THINKER
|
||||
#define BOARD_ESP32CAM_AITHINKER
|
||||
|
||||
|
||||
//server_GPIO
|
||||
#define __LEDGLOBAL
|
||||
|
||||
|
||||
//server_GPIO + server_file + SoftAP
|
||||
#define CONFIG_FILE "/sdcard/config/config.ini"
|
||||
#define CONFIG_FILE_BACKUP "/sdcard/config/config.bak"
|
||||
|
||||
|
||||
//interface_mqtt + read_wlanini
|
||||
#define __HIDE_PASSWORD
|
||||
|
||||
|
||||
//ClassFlowControll + Main + SoftAP
|
||||
#define WLAN_CONFIG_FILE "/sdcard/wlan.ini"
|
||||
|
||||
|
||||
//main
|
||||
#define __SD_USE_ONE_LINE_MODE__
|
||||
|
||||
// server_file + Helper
|
||||
#define FILE_PATH_MAX (255) //Max length a file path can have on storage
|
||||
|
||||
|
||||
//server_file +(ota_page.html + upload_script.html)
|
||||
#define MAX_FILE_SIZE (8000*1024) // 8 MB Max size of an individual file. Make sure this value is same as that set in upload_script.html and ota_page.html!
|
||||
#define MAX_FILE_SIZE_STR "8MB"
|
||||
@@ -98,61 +107,66 @@
|
||||
#define SERVER_HELPER_SCRATCH_BUFSIZE 8192
|
||||
#define SERVER_OTA_SCRATCH_BUFSIZE 1024
|
||||
|
||||
|
||||
//server_file + server_help
|
||||
#define IS_FILE_EXT(filename, ext) \
|
||||
(strcasecmp(&filename[strlen(filename) - sizeof(ext) + 1], ext) == 0)
|
||||
|
||||
|
||||
//server_ota
|
||||
#define HASH_LEN 32 // SHA-256 digest length
|
||||
#define OTA_URL_SIZE 256
|
||||
|
||||
|
||||
//ClassFlow + ClassFlowImage + server_tflite
|
||||
#define LOGFILE_TIME_FORMAT "%Y%m%d-%H%M%S"
|
||||
#define LOGFILE_TIME_FORMAT_DATE_EXTR substr(0, 8)
|
||||
#define LOGFILE_TIME_FORMAT_HOUR_EXTR substr(9, 2)
|
||||
|
||||
|
||||
//ClassFlowControll
|
||||
#define READOUT_TYPE_VALUE 0
|
||||
#define READOUT_TYPE_PREVALUE 1
|
||||
#define READOUT_TYPE_RAWVALUE 2
|
||||
#define READOUT_TYPE_ERROR 3
|
||||
|
||||
|
||||
//ClassFlowControll: Serve alg_roi.jpg from memory as JPG
|
||||
#define ALGROI_LOAD_FROM_MEM_AS_JPG // Load ALG_ROI.JPG as rendered JPG from RAM
|
||||
|
||||
|
||||
//ClassFlowMQTT
|
||||
#define LWT_TOPIC "connection"
|
||||
#define LWT_CONNECTED "connected"
|
||||
#define LWT_DISCONNECTED "connection lost"
|
||||
|
||||
|
||||
//ClassFlowPostProcessing
|
||||
#define PREVALUE_TIME_FORMAT_OUTPUT "%Y-%m-%dT%H:%M:%S%z"
|
||||
#define PREVALUE_TIME_FORMAT_INPUT "%d-%d-%dT%d:%d:%d"
|
||||
|
||||
|
||||
//CImageBasis
|
||||
#define HTTP_BUFFER_SENT 1024
|
||||
#define GET_MEMORY(X) heap_caps_malloc(X, MALLOC_CAP_SPIRAM)
|
||||
#define MAX_JPG_SIZE 128000
|
||||
|
||||
|
||||
//CAlignAndCutImage + CImageBasis
|
||||
#define _USE_MATH_DEFINES
|
||||
#define GET_MEMORY(X) heap_caps_malloc(X, MALLOC_CAP_SPIRAM)
|
||||
|
||||
//make_stb + stb_image_resize + stb_image_write + stb_image //do not work if not in make_stb.cpp
|
||||
//#define STB_IMAGE_IMPLEMENTATION
|
||||
//#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
//#define STB_IMAGE_RESIZE_IMPLEMENTATION
|
||||
#define STBI_ONLY_JPEG // (save 2% of Flash, but breaks the alignment mark generation, see https://github.com/jomjol/AI-on-the-edge-device/issues/1721)
|
||||
|
||||
|
||||
//interface_influxdb
|
||||
#define MAX_HTTP_OUTPUT_BUFFER 2048
|
||||
|
||||
|
||||
//server_mqtt
|
||||
#define LWT_TOPIC "connection"
|
||||
#define LWT_CONNECTED "connected"
|
||||
#define LWT_DISCONNECTED "connection lost"
|
||||
|
||||
|
||||
//CTfLiteClass
|
||||
#define TFLITE_MINIMAL_CHECK(x) \
|
||||
if (!(x)) { \
|
||||
@@ -194,6 +208,12 @@
|
||||
//#define DEBUG_DETAIL_ON
|
||||
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//// PSRAM Allocations ////
|
||||
/////////////////////////////////////////////
|
||||
#define MAX_MODEL_SIZE (unsigned int)(1.3 * 1024 * 1024) // Space for the currently largest model (1.1 MB) + some spare
|
||||
#define TENSOR_ARENA_SIZE 800 * 1024 // Space for the Tensor Arena, (819200 Bytes)
|
||||
#define IMAGE_SIZE 640 * 480 * 3 // Space for a extracted image (921600 Bytes)
|
||||
/////////////////////////////////////////////
|
||||
//// Conditionnal definitions ////
|
||||
/////////////////////////////////////////////
|
||||
|
||||
@@ -66,5 +66,4 @@ FILE(GLOB_RECURSE app_sources ${CMAKE_SOURCE_DIR}/main/*.*)
|
||||
|
||||
idf_component_register(SRCS ${app_sources}
|
||||
INCLUDE_DIRS "."
|
||||
# REQUIRES esp_psram) # comming in IDF 5.0
|
||||
)
|
||||
REQUIRES esp_psram)
|
||||
@@ -9,11 +9,14 @@
|
||||
|
||||
//#include "driver/gpio.h"
|
||||
//#include "sdkconfig.h"
|
||||
//#include "esp_psram.h" // Comming in IDF 5.0, see https://docs.espressif.com/projects/esp-idf/en/v5.0-beta1/esp32/migration-guides/release-5.x/system.html?highlight=esp_psram_get_size
|
||||
//#include "spiram.h"
|
||||
#include "esp32/spiram.h"
|
||||
#include "esp_psram.h"
|
||||
#include "esp_pm.h"
|
||||
|
||||
#include "psram.h"
|
||||
|
||||
#include "esp_chip_info.h"
|
||||
|
||||
|
||||
|
||||
// SD-Card ////////////////////
|
||||
//#include "nvs_flash.h"
|
||||
@@ -30,7 +33,7 @@
|
||||
#include "read_wlanini.h"
|
||||
|
||||
#include "server_main.h"
|
||||
#include "server_tflite.h"
|
||||
#include "MainFlowControl.h"
|
||||
#include "server_file.h"
|
||||
#include "server_ota.h"
|
||||
#include "time_sntp.h"
|
||||
@@ -63,6 +66,11 @@
|
||||
#endif
|
||||
#endif //DEBUG_ENABLE_SYSINFO
|
||||
|
||||
// define `gpio_pad_select_gpip` for newer versions of IDF
|
||||
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 3, 0))
|
||||
#include "esp_rom_gpio.h"
|
||||
#define gpio_pad_select_gpio esp_rom_gpio_pad_select_gpio
|
||||
#endif
|
||||
|
||||
#ifdef USE_HIMEM_IF_AVAILABLE
|
||||
#include "esp32/himem.h"
|
||||
@@ -186,15 +194,6 @@ extern "C" void app_main(void)
|
||||
// ********************************************
|
||||
ESP_LOGI(TAG, "\n\n\n\n================ Start app_main =================");
|
||||
|
||||
// Init camera
|
||||
// ********************************************
|
||||
PowerResetCamera();
|
||||
esp_err_t camStatus = Camera.InitCam();
|
||||
Camera.LightOnOff(false);
|
||||
|
||||
xDelay = 2000 / portTICK_PERIOD_MS;
|
||||
ESP_LOGD(TAG, "After camera initialization: sleep for: %ldms", (long) xDelay * CONFIG_FREERTOS_HZ/portTICK_PERIOD_MS);
|
||||
vTaskDelay( xDelay );
|
||||
|
||||
// Init SD card
|
||||
// ********************************************
|
||||
@@ -216,6 +215,105 @@ extern "C" void app_main(void)
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "==================== Start ======================");
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "=================================================");
|
||||
|
||||
|
||||
// Init external PSRAM
|
||||
// ********************************************
|
||||
esp_err_t PSRAMStatus = esp_psram_init();
|
||||
if (PSRAMStatus == ESP_FAIL) { // ESP_FAIL -> Failed to init PSRAM
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "PSRAM init failed (" + std::to_string(PSRAMStatus) + ")! PSRAM not found or defective");
|
||||
setSystemStatusFlag(SYSTEM_STATUS_PSRAM_BAD);
|
||||
StatusLED(PSRAM_INIT, 1, true);
|
||||
}
|
||||
else { // ESP_OK -> PSRAM init OK --> continue to check PSRAM size
|
||||
size_t psram_size = esp_psram_get_size(); // size_t psram_size = esp_psram_get_size(); // comming in IDF 5.0
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "PSRAM size: " + std::to_string(psram_size) + " byte (" + std::to_string(psram_size/1024/1024) +
|
||||
"MB / " + std::to_string(psram_size/1024/1024*8) + "MBit)");
|
||||
|
||||
// Check PSRAM size
|
||||
// ********************************************
|
||||
if (psram_size < (4*1024*1024)) { // PSRAM is below 4 MBytes (32Mbit)
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "PSRAM size >= 4MB (32Mbit) is mandatory to run this application");
|
||||
setSystemStatusFlag(SYSTEM_STATUS_PSRAM_BAD);
|
||||
StatusLED(PSRAM_INIT, 2, true);
|
||||
}
|
||||
else { // PSRAM size OK --> continue to check heap size
|
||||
size_t _hsize = getESPHeapSize();
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Total heap: " + std::to_string(_hsize) + " byte");
|
||||
|
||||
// Check heap memory
|
||||
// ********************************************
|
||||
if (_hsize < 4000000) { // Check available Heap memory for a bit less than 4 MB (a test on a good device showed 4187558 bytes to be available)
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Total heap >= 4000000 byte is mandatory to run this application");
|
||||
setSystemStatusFlag(SYSTEM_STATUS_HEAP_TOO_SMALL);
|
||||
StatusLED(PSRAM_INIT, 3, true);
|
||||
}
|
||||
else { // HEAP size OK --> continue to reserve shared memory block and check camera init
|
||||
/* Allocate static PSRAM memory regions */
|
||||
if (! reserve_psram_shared_region()) {
|
||||
setSystemStatusFlag(SYSTEM_STATUS_HEAP_TOO_SMALL);
|
||||
StatusLED(PSRAM_INIT, 3, true);
|
||||
}
|
||||
else { // OK
|
||||
// Init camera
|
||||
// ********************************************
|
||||
PowerResetCamera();
|
||||
esp_err_t camStatus = Camera.InitCam();
|
||||
Camera.LightOnOff(false);
|
||||
|
||||
xDelay = 2000 / portTICK_PERIOD_MS;
|
||||
ESP_LOGD(TAG, "After camera initialization: sleep for: %ldms", (long) xDelay * CONFIG_FREERTOS_HZ/portTICK_PERIOD_MS);
|
||||
vTaskDelay( xDelay );
|
||||
|
||||
|
||||
// Check camera init
|
||||
// ********************************************
|
||||
if (camStatus != ESP_OK) { // Camera init failed, retry to init
|
||||
char camStatusHex[33];
|
||||
sprintf(camStatusHex,"0x%02x", camStatus);
|
||||
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "Camera init failed (" + std::string(camStatusHex) + "), retrying...");
|
||||
|
||||
PowerResetCamera();
|
||||
camStatus = Camera.InitCam();
|
||||
Camera.LightOnOff(false);
|
||||
|
||||
xDelay = 2000 / portTICK_PERIOD_MS;
|
||||
ESP_LOGD(TAG, "After camera initialization: sleep for: %ldms", (long) xDelay * CONFIG_FREERTOS_HZ/portTICK_PERIOD_MS);
|
||||
vTaskDelay( xDelay );
|
||||
|
||||
if (camStatus != ESP_OK) { // Camera init failed again
|
||||
sprintf(camStatusHex,"0x%02x", camStatus);
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Camera init failed (" + std::string(camStatusHex) +
|
||||
")! Check camera module and/or proper electrical connection");
|
||||
setSystemStatusFlag(SYSTEM_STATUS_CAM_BAD);
|
||||
StatusLED(CAM_INIT, 1, true);
|
||||
}
|
||||
}
|
||||
else { // ESP_OK -> Camera init OK --> continue to perform camera framebuffer check
|
||||
// Camera framebuffer check
|
||||
// ********************************************
|
||||
if (!Camera.testCamera()) {
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Camera framebuffer check failed");
|
||||
// Easiest would be to simply restart here and try again,
|
||||
// how ever there seem to be systems where it fails at startup but still work correctly later.
|
||||
// Therefore we treat it still as successed! */
|
||||
setSystemStatusFlag(SYSTEM_STATUS_CAM_FB_BAD);
|
||||
StatusLED(CAM_INIT, 2, false);
|
||||
}
|
||||
Camera.LightOnOff(false); // make sure flashlight is off before start of flow
|
||||
|
||||
// Print camera infos
|
||||
// ********************************************
|
||||
char caminfo[50];
|
||||
sensor_t * s = esp_camera_sensor_get();
|
||||
sprintf(caminfo, "PID: 0x%02x, VER: 0x%02x, MIDL: 0x%02x, MIDH: 0x%02x", s->id.PID, s->id.VER, s->id.MIDH, s->id.MIDL);
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Camera info: " + std::string(caminfo));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// SD card: basic R/W check
|
||||
// ********************************************
|
||||
int iSDCardStatus = SDCardCheckRW();
|
||||
@@ -337,6 +435,16 @@ extern "C" void app_main(void)
|
||||
ESP_LOGD(TAG, "main: sleep for: %ldms", (long) xDelay * CONFIG_FREERTOS_HZ/portTICK_PERIOD_MS);
|
||||
vTaskDelay( xDelay );
|
||||
|
||||
|
||||
// manual reset the time
|
||||
// ********************************************
|
||||
if (!time_manual_reset_sync())
|
||||
{
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Manual Time Sync failed during startup" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Set log level for wifi component to WARN level (default: INFO; only relevant for serial console)
|
||||
// ********************************************
|
||||
esp_log_level_set("wifi", ESP_LOG_WARN);
|
||||
@@ -360,84 +468,7 @@ extern "C" void app_main(void)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Init external PSRAM
|
||||
// ********************************************
|
||||
esp_err_t PSRAMStatus = esp_spiram_init();
|
||||
if (PSRAMStatus != ESP_OK) { // ESP_FAIL -> Failed to init PSRAM
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "PSRAM init failed (" + std::to_string(PSRAMStatus) + ")! PSRAM not found or defective");
|
||||
setSystemStatusFlag(SYSTEM_STATUS_PSRAM_BAD);
|
||||
StatusLED(PSRAM_INIT, 1, true);
|
||||
}
|
||||
else { // ESP_OK -> PSRAM init OK --> continue to check PSRAM size
|
||||
size_t psram_size = esp_spiram_get_size(); // size_t psram_size = esp_psram_get_size(); // comming in IDF 5.0
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "PSRAM size: " + std::to_string(psram_size) + " byte (" + std::to_string(psram_size/1024/1024) +
|
||||
"MB / " + std::to_string(psram_size/1024/1024*8) + "MBit)");
|
||||
|
||||
// Check PSRAM size
|
||||
// ********************************************
|
||||
if (psram_size < (4*1024*1024)) { // PSRAM is below 4 MBytes (32Mbit)
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "PSRAM size >= 4MB (32Mbit) is mandatory to run this application");
|
||||
setSystemStatusFlag(SYSTEM_STATUS_PSRAM_BAD);
|
||||
StatusLED(PSRAM_INIT, 2, true);
|
||||
}
|
||||
else { // PSRAM size OK --> continue to check heap size
|
||||
size_t _hsize = getESPHeapSize();
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Total heap: " + std::to_string(_hsize) + " byte");
|
||||
|
||||
// Check heap memory
|
||||
// ********************************************
|
||||
if (_hsize < 4000000) { // Check available Heap memory for a bit less than 4 MB (a test on a good device showed 4187558 bytes to be available)
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Total heap >= 4000000 byte is mandatory to run this application");
|
||||
setSystemStatusFlag(SYSTEM_STATUS_HEAP_TOO_SMALL);
|
||||
StatusLED(PSRAM_INIT, 3, true);
|
||||
}
|
||||
else { // HEAP size OK --> continue to check camera init
|
||||
// Check camera init
|
||||
// ********************************************
|
||||
if (camStatus != ESP_OK) { // Camera init failed, retry to init
|
||||
char camStatusHex[33];
|
||||
sprintf(camStatusHex,"0x%02x", camStatus);
|
||||
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "Camera init failed (" + std::string(camStatusHex) + "), retrying...");
|
||||
|
||||
PowerResetCamera();
|
||||
camStatus = Camera.InitCam();
|
||||
Camera.LightOnOff(false);
|
||||
|
||||
xDelay = 2000 / portTICK_PERIOD_MS;
|
||||
ESP_LOGD(TAG, "After camera initialization: sleep for: %ldms", (long) xDelay * CONFIG_FREERTOS_HZ/portTICK_PERIOD_MS);
|
||||
vTaskDelay( xDelay );
|
||||
|
||||
if (camStatus != ESP_OK) { // Camera init failed again
|
||||
sprintf(camStatusHex,"0x%02x", camStatus);
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Camera init failed (" + std::string(camStatusHex) +
|
||||
")! Check camera module and/or proper electrical connection");
|
||||
setSystemStatusFlag(SYSTEM_STATUS_CAM_BAD);
|
||||
StatusLED(CAM_INIT, 1, true);
|
||||
}
|
||||
}
|
||||
else { // ESP_OK -> Camera init OK --> continue to perform camera framebuffer check
|
||||
// Camera framebuffer check
|
||||
// ********************************************
|
||||
if (!Camera.testCamera()) {
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Camera framebuffer check failed");
|
||||
// Easiest would be to simply restart here and try again,
|
||||
// how ever there seem to be systems where it fails at startup but still work correctly later.
|
||||
// Therefore we treat it still as successed! */
|
||||
setSystemStatusFlag(SYSTEM_STATUS_CAM_FB_BAD);
|
||||
StatusLED(CAM_INIT, 2, false);
|
||||
}
|
||||
Camera.LightOnOff(false); // make sure flashlight is off before start of flow
|
||||
|
||||
// Print camera infos
|
||||
// ********************************************
|
||||
char caminfo[50];
|
||||
sensor_t * s = esp_camera_sensor_get();
|
||||
sprintf(caminfo, "PID: 0x%02x, VER: 0x%02x, MIDL: 0x%02x, MIDH: 0x%02x", s->id.PID, s->id.VER, s->id.MIDH, s->id.MIDL);
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Camera info: " + std::string(caminfo));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Print Device info
|
||||
// ********************************************
|
||||
@@ -462,7 +493,7 @@ extern "C" void app_main(void)
|
||||
|
||||
server = start_webserver();
|
||||
register_server_camera_uri(server);
|
||||
register_server_tflite_uri(server);
|
||||
register_server_main_flow_task_uri(server);
|
||||
register_server_file_uri(server, "/sdcard");
|
||||
register_server_ota_sdcard_uri(server);
|
||||
#ifdef ENABLE_MQTT
|
||||
@@ -481,13 +512,13 @@ extern "C" void app_main(void)
|
||||
// Check main init + start TFlite task
|
||||
// ********************************************
|
||||
if (getSystemStatus() == 0) { // No error flag is set
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Initialization completed successfully! Starting flow task ...");
|
||||
TFliteDoAutoStart();
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Initialization completed successfully");
|
||||
InitializeFlowTask();
|
||||
}
|
||||
else if (isSetSystemStatusFlag(SYSTEM_STATUS_CAM_FB_BAD) || // Non critical errors occured, we try to continue...
|
||||
isSetSystemStatusFlag(SYSTEM_STATUS_NTP_BAD)) {
|
||||
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "Initialization completed with errors! Starting flow task ...");
|
||||
TFliteDoAutoStart();
|
||||
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "Initialization completed with non-critical errors!");
|
||||
InitializeFlowTask();
|
||||
}
|
||||
else { // Any other error is critical and makes running the flow impossible. Init is going to abort.
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Initialization failed. Flow task start aborted. Loading reduced web interface...");
|
||||
@@ -608,7 +639,19 @@ void migrateConfiguration(void) {
|
||||
}
|
||||
|
||||
if (section == "[InfluxDB]") {
|
||||
/* Fieldname has a <NUMBER> as prefix! */
|
||||
if (isInString(configLines[i], "Fieldname")) { // It is the parameter "Fieldname"
|
||||
migrated = migrated | replaceString(configLines[i], "Fieldname", "Field"); // Rename it to Field
|
||||
migrated = migrated | replaceString(configLines[i], ";", ""); // Enable it
|
||||
}
|
||||
}
|
||||
|
||||
if (section == "[InfluxDBv2]") {
|
||||
/* Fieldname has a <NUMBER> as prefix! */
|
||||
if (isInString(configLines[i], "Fieldname")) { // It is the parameter "Fieldname"
|
||||
migrated = migrated | replaceString(configLines[i], "Fieldname", "Field"); // Rename it to Field
|
||||
migrated = migrated | replaceString(configLines[i], ";", ""); // Enable it
|
||||
}
|
||||
}
|
||||
|
||||
if (section == "[GPIO]") {
|
||||
|
||||
@@ -13,8 +13,9 @@
|
||||
#include "version.h"
|
||||
|
||||
#include "esp_wifi.h"
|
||||
#include <netdb.h>
|
||||
|
||||
#include "server_tflite.h"
|
||||
#include "MainFlowControl.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -350,11 +351,6 @@ esp_err_t sysinfo_handler(httpd_req_t *req)
|
||||
char freeheapmem[11];
|
||||
sprintf(freeheapmem, "%lu", (long) getESPHeapSize());
|
||||
|
||||
tcpip_adapter_ip_info_t ip_info;
|
||||
ESP_ERROR_CHECK(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip_info));
|
||||
const char *hostname;
|
||||
ESP_ERROR_CHECK(tcpip_adapter_get_hostname(TCPIP_ADAPTER_IF_STA, &hostname));
|
||||
|
||||
zw = string("[{") +
|
||||
"\"firmware\": \"" + gitversion + "\"," +
|
||||
"\"buildtime\": \"" + buildtime + "\"," +
|
||||
@@ -363,8 +359,8 @@ esp_err_t sysinfo_handler(httpd_req_t *req)
|
||||
"\"gitrevision\": \"" + gitrevision + "\"," +
|
||||
"\"html\": \"" + htmlversion + "\"," +
|
||||
"\"cputemp\": \"" + cputemp + "\"," +
|
||||
"\"hostname\": \"" + hostname + "\"," +
|
||||
"\"IPv4\": \"" + ip4addr_ntoa(&ip_info.ip) + "\"," +
|
||||
"\"hostname\": \"" + *getHostname() + "\"," +
|
||||
"\"IPv4\": \"" + *getIPAddress() + "\"," +
|
||||
"\"freeHeapMem\": \"" + freeheapmem + "\"" +
|
||||
"}]";
|
||||
|
||||
@@ -431,7 +427,7 @@ httpd_handle_t start_webserver(void)
|
||||
config.server_port = 80;
|
||||
config.ctrl_port = 32768;
|
||||
config.max_open_sockets = 5; //20210921 --> previously 7
|
||||
config.max_uri_handlers = 38; // previously 24, 20220511: 35, 20221220: 37, 2023-01-02:38
|
||||
config.max_uri_handlers = 39; // previously 24, 20220511: 35, 20221220: 37, 2023-01-02:38
|
||||
config.max_resp_headers = 8;
|
||||
config.backlog_conn = 5;
|
||||
config.lru_purge_enable = true; // this cuts old connections if new ones are needed.
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#include "freertos/task.h"
|
||||
#include "esp_mac.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_event.h"
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "nvs_flash.h"
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
[common:esp32-idf]
|
||||
extends = common:idf
|
||||
platform = platformio/espressif32 @ 5.2.0
|
||||
platform = platformio/espressif32 @ 6.2.0
|
||||
framework = espidf
|
||||
lib_deps =
|
||||
${common:idf.lib_deps}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
##################################################
|
||||
# Application specific configuration
|
||||
# Edit this file instead of sdkconfig.esp32cam!
|
||||
# After editting, make sure to explicitly delete
|
||||
# After editing make sure to explicitly delete
|
||||
# sdkconfig.esp32cam to apply your changes!
|
||||
##################################################
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#CONFIG_ESP_WIFI_SOFTAP_SUPPORT=n
|
||||
#to save 28k of flash
|
||||
|
||||
CONFIG_ESP_TASK_WDT=n
|
||||
CONFIG_TASK_WDT=n
|
||||
CONFIG_TASK_WDT_CHECK_IDLE_TASK=n
|
||||
|
||||
@@ -94,11 +95,13 @@ CONFIG_SPIRAM_SPEED_40M=y
|
||||
CONFIG_SPIRAM=y
|
||||
CONFIG_SPIRAM_BOOT_INIT=y
|
||||
CONFIG_SPIRAM_USE_MALLOC=y
|
||||
#CONFIG_SPIRAM_USE_MEMMAP=y => Does not work: "cam_dma_config(306): frame buffer malloc failed"
|
||||
CONFIG_SPIRAM_MEMTEST=y
|
||||
CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=16384
|
||||
CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=40960
|
||||
CONFIG_SPIRAM_CACHE_WORKAROUND=y
|
||||
CONFIG_SPIRAM_IGNORE_NOTFOUND=y
|
||||
|
||||
CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y
|
||||
CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y
|
||||
|
||||
@@ -122,7 +125,7 @@ CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED=y
|
||||
CONFIG_MQTT_USE_CORE_0=y
|
||||
CONFIG_MQTT_USE_CUSTOM_CONFIG=y
|
||||
#CONFIG_MQTT_OUTBOX_EXPIRED_TIMEOUT_MS=5000
|
||||
CONFIG_MQTT_CUSTOM_OUTBOX=y
|
||||
#CONFIG_MQTT_CUSTOM_OUTBOX=y # -> Use custom outbox in components/jomjol_mqtt/mqtt_outbox.h/cpp. If USE_PSRAM is enabled in there, it will save 10 kBytes of internal RAM. How ever it also leads to memory fragmentation, see https://github.com/jomjol/AI-on-the-edge-device/issues/2200
|
||||
|
||||
CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER=n
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ function fetchFiles(urls, filesData, index, retry, zipFilename) {
|
||||
|
||||
// console.log(url + " started (" + index + "/" + urls.length + ")");
|
||||
if (retry == 0) {
|
||||
setStatus(" - " + getFilenameFromUrl(urls[index]) + " (" + index + "/" + urls.length + ")...");
|
||||
setStatus(" - " + getFilenameFromUrl(urls[index]) + " (" + (index+1) + "/" + urls.length + ")...");
|
||||
}
|
||||
else {
|
||||
setStatus("<span style=\"color: gray\"> Retrying (" + retry + ")...</span>");
|
||||
|
||||
@@ -1,13 +1,7 @@
|
||||
|
||||
/* The UI can also be run locally, but you have to set the IP of your devide accordingly.
|
||||
* And you also might have to disable CORS in your webbrowser! */
|
||||
var domainname_for_testing = "192.168.1.153";
|
||||
|
||||
|
||||
|
||||
function gethost_Version(){
|
||||
return "1.0.0 - 20200910";
|
||||
}
|
||||
var domainname_for_testing = "192.168.178.23";
|
||||
|
||||
|
||||
/* Returns the domainname with prepended protocol.
|
||||
|
||||
@@ -73,7 +73,7 @@ select {
|
||||
<tr>
|
||||
<td style="padding-top: 10px">x: <input type="number" name="refx" id="refx" step=1 onchange="valuemanualchanged()"></td>
|
||||
<td style="padding-top: 10px">dx: <input type="number" name="refdx" id="refdx" step=1 onchange="valuemanualchanged()"></td>
|
||||
<td rowspan="2" style="padding-top: 10px"><input class="button" type="button" value="Update Reference" onclick="CutOutReference()"></td>
|
||||
<td rowspan="2" style="padding-top: 10px"><input class="button" type="button" value="Update Reference Image" onclick="CutOutReference()"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>y: <input type="number" name="refy" id="refy" step=1 onchange="valuemanualchanged()"></td>
|
||||
@@ -133,7 +133,7 @@ function SaveToConfig(){
|
||||
WriteConfigININew();
|
||||
UpdateConfigReference(domainname)
|
||||
SaveConfigToServer(domainname);
|
||||
firework.launch('Configuration got updated. It will get applied after the next reboot!', 'success', 5000);
|
||||
firework.launch('Reference Marks got updated. The change will get applied after the next reboot!', 'success', 5000);
|
||||
}
|
||||
|
||||
function EnhanceContrast(){
|
||||
@@ -144,8 +144,9 @@ function EnhanceContrast(){
|
||||
refInfo[aktindex]["dy"] = document.getElementById("refdy").value;
|
||||
|
||||
enhanceCon = true;
|
||||
MakeContrastImageZW(refInfo[aktindex], enhanceCon, domainname);
|
||||
UpdateReference();
|
||||
if (MakeContrastImageZW(refInfo[aktindex], enhanceCon, domainname)) {
|
||||
UpdateReference();
|
||||
}
|
||||
}
|
||||
|
||||
function UpdateReference(){
|
||||
@@ -250,9 +251,10 @@ function dataURLtoBlob(dataurl) {
|
||||
refInfo[aktindex]["y"] = document.getElementById("refy").value;
|
||||
refInfo[aktindex]["dx"] = document.getElementById("refdx").value;
|
||||
refInfo[aktindex]["dy"] = document.getElementById("refdy").value;
|
||||
MakeRefZW(refInfo[aktindex], domainname);
|
||||
UpdateReference();
|
||||
document.getElementById("enhancecontrast").disabled = false;
|
||||
if (MakeRefZW(refInfo[aktindex], domainname)) {
|
||||
UpdateReference();
|
||||
document.getElementById("enhancecontrast").disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
function drawGrid(){
|
||||
|
||||
@@ -326,6 +326,7 @@ function UpdateROIs(_sel){
|
||||
document.getElementById("deleteROI").disabled = false;
|
||||
document.getElementById("renameROI").disabled = false;
|
||||
document.getElementById("index").disabled = false;
|
||||
document.getElementById("saveroi").disabled = false;
|
||||
}
|
||||
|
||||
var _index = document.getElementById("index");
|
||||
|
||||
@@ -688,16 +688,6 @@ textarea {
|
||||
</td>
|
||||
<td>$TOOLTIP_InfluxDB_Database</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="indent1">
|
||||
<input type="checkbox" id="InfluxDB_Measurement_enabled" value="1" onclick = 'InvertEnableItem("InfluxDB", "Measurement")' unchecked >
|
||||
<label for=InfluxDB_Measurement_enabled><class id="InfluxDB_Measurement_text" style="color:black;">Measurement</class></label>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" id="InfluxDB_Measurement_value1">
|
||||
</td>
|
||||
<td>$TOOLTIP_InfluxDB_Measurement</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="indent1">
|
||||
<input type="checkbox" id="InfluxDB_user_enabled" value="1" onclick = 'InvertEnableItem("InfluxDB", "user")' unchecked >
|
||||
@@ -718,6 +708,34 @@ textarea {
|
||||
</td>
|
||||
<td>$TOOLTIP_InfluxDB_password</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="indent1" colspan="3">
|
||||
<br>
|
||||
<b>InfluxDB Individual Parameters:
|
||||
<select id="NumbersInfluxDB_value1" onchange="numberInfluxDBChanged()">
|
||||
</select></b>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="indent1" style="padding-left: 75px;">
|
||||
<input type="checkbox" id="InfluxDB_Measurement_enabled" value="1" onclick = 'InvertEnableItem("InfluxDB", "Measurement")' unchecked >
|
||||
<label for=InfluxDB_Measurement_enabled><class id="InfluxDB_Measurement_text" style="color:black;">Measurement</class></label>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" id="InfluxDB_Measurement_value1">
|
||||
</td>
|
||||
<td>$TOOLTIP_InfluxDB_NUMBER.Measurement</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="indent1" style="padding-left: 75px;">
|
||||
<input type="checkbox" id="InfluxDB_Field_enabled" value="1" onclick = 'InvertEnableItem("InfluxDB", "Field")' unchecked >
|
||||
<label for=InfluxDB_Field_enabled><class id="InfluxDB_Field_text" style="color:black;">Field</class></label>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" id="InfluxDB_Field_value1">
|
||||
</td>
|
||||
<td>$TOOLTIP_InfluxDB_NUMBER.Field</td>
|
||||
</tr>
|
||||
|
||||
|
||||
|
||||
@@ -749,16 +767,6 @@ textarea {
|
||||
</td>
|
||||
<td>$TOOLTIP_InfluxDBv2_Database</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="indent1">
|
||||
<input type="checkbox" id="InfluxDBv2_Measurement_enabled" value="1" onclick = 'InvertEnableItem("InfluxDBv2", "Measurement")' unchecked >
|
||||
<label for=InfluxDBv2_Measurement_enabled><class id="InfluxDBv2_Measurement_text" style="color:black;">Measurement</class></label>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" id="InfluxDBv2_Measurement_value1">
|
||||
</td>
|
||||
<td>$TOOLTIP_InfluxDBv2_Measurement</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="indent1">
|
||||
<input type="checkbox" id="InfluxDBv2_Org_enabled" value="1" onclick = 'InvertEnableItem("InfluxDBv2", "Org")' unchecked >
|
||||
@@ -782,20 +790,30 @@ textarea {
|
||||
<tr>
|
||||
<td class="indent1" colspan="3">
|
||||
<br>
|
||||
<b>Postprocessing Individual Parameters:
|
||||
<select id="NumbersInfluxDB_value1" onchange="numberInfluxDBChanged()">
|
||||
<b>InfluxDB v2 Individual Parameters:
|
||||
<select id="NumbersInfluxDBv2_value1" onchange="numberInfluxDBv2Changed()">
|
||||
</select></b>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="indent1" style="padding-left: 75px;">
|
||||
<input type="checkbox" id="InfluxDBv2_Fieldname_enabled" value="1" onclick = 'InvertEnableItem("InfluxDBv2", "Fieldname")' unchecked >
|
||||
<label for=InfluxDBv2_Fieldname_enabled><class id="InfluxDBv2_Fieldname_text" style="color:black;">Fieldname</class></label>
|
||||
<input type="checkbox" id="InfluxDBv2_Measurement_enabled" value="1" onclick = 'InvertEnableItem("InfluxDBv2", "Measurement")' unchecked >
|
||||
<label for=InfluxDBv2_Measurement_enabled><class id="InfluxDBv2_Measurement_text" style="color:black;">Measurement</class></label>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" id="InfluxDBv2_Fieldname_value1">
|
||||
<input type="text" id="InfluxDBv2_Measurement_value1">
|
||||
</td>
|
||||
<td>$TOOLTIP_InfluxDBv2_NUMBER.Fieldname</td>
|
||||
<td>$TOOLTIP_InfluxDBv2_NUMBER.Measurement</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="indent1" style="padding-left: 75px;">
|
||||
<input type="checkbox" id="InfluxDBv2_Field_enabled" value="1" onclick = 'InvertEnableItem("InfluxDBv2", "Field")' unchecked >
|
||||
<label for=InfluxDBv2_Field_enabled><class id="InfluxDBv2_Field_text" style="color:black;">Field</class></label>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" id="InfluxDBv2_Field_value1">
|
||||
</td>
|
||||
<td>$TOOLTIP_InfluxDBv2_NUMBER.Field</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -1226,7 +1244,7 @@ textarea {
|
||||
</tr>
|
||||
<tr class="expert" id="ex13">
|
||||
<td class="indent1">
|
||||
<class id="AutoTimer_AutoStart_text" style="color:black;">Automatically Round Start</class>
|
||||
<class id="AutoTimer_AutoStart_text" style="color:black;">Automatic Round Start</class>
|
||||
</td>
|
||||
<td>
|
||||
<select id="AutoTimer_AutoStart_value1">
|
||||
@@ -1423,11 +1441,16 @@ function InitIndivParameter()
|
||||
var _index = document.getElementById("Numbers_value1");
|
||||
while (_index.length)
|
||||
_index.remove(0);
|
||||
var _indexInflux = document.getElementById("NumbersInfluxDB_value1");
|
||||
|
||||
var _indexInflux = document.getElementById("NumbersInfluxDBv2_value1");
|
||||
while (_indexInflux.length)
|
||||
_indexInflux.remove(0);
|
||||
|
||||
for (var i = 0; i < NUMBERS.length; ++i){
|
||||
var _indexInfluxv1 = document.getElementById("NumbersInfluxDB_value1");
|
||||
while (_indexInflux.length)
|
||||
_indexInfluxv1.remove(0);
|
||||
|
||||
for (var i = 0; i < NUMBERS.length; ++i){
|
||||
var option = document.createElement("option");
|
||||
option.text = NUMBERS[i]["name"];
|
||||
option.value = i;
|
||||
@@ -1437,9 +1460,16 @@ function InitIndivParameter()
|
||||
optionInflux.text = NUMBERS[i]["name"];
|
||||
optionInflux.value = i;
|
||||
_indexInflux.add(optionInflux);
|
||||
}
|
||||
|
||||
var optionInfluxv1 = document.createElement("option");
|
||||
optionInfluxv1.text = NUMBERS[i]["name"];
|
||||
optionInfluxv1.value = i;
|
||||
_indexInfluxv1.add(optionInfluxv1);
|
||||
|
||||
}
|
||||
_index.selectedIndex = 0;
|
||||
_indexInflux.selectedIndex = 0;
|
||||
_indexInfluxv1.selectedIndex = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1741,7 +1771,10 @@ function UpdateInputIndividual(sel)
|
||||
ReadParameter(param, "PostProcessing", "ExtendedResolution", false, NUNBERSAkt)
|
||||
ReadParameter(param, "PostProcessing", "IgnoreLeadingNaN", false, NUNBERSAkt)
|
||||
ReadParameter(param, "PostProcessing", "AllowNegativeRates", false, NUNBERSAkt)
|
||||
ReadParameter(param, "InfluxDBv2", "Fieldname", true, NUNBERSAkt)
|
||||
ReadParameter(param, "InfluxDB", "Field", true, NUNBERSAkt)
|
||||
ReadParameter(param, "InfluxDBv2", "Field", true, NUNBERSAkt)
|
||||
ReadParameter(param, "InfluxDB", "Measurement", true, NUNBERSAkt)
|
||||
ReadParameter(param, "InfluxDBv2", "Measurement", true, NUNBERSAkt)
|
||||
}
|
||||
|
||||
// var sel = document.getElementById("Numbers_value1");
|
||||
@@ -1753,7 +1786,10 @@ function UpdateInputIndividual(sel)
|
||||
WriteParameter(param, category, "PostProcessing", "ExtendedResolution", false, NUNBERSAkt);
|
||||
WriteParameter(param, category, "PostProcessing", "IgnoreLeadingNaN", false, NUNBERSAkt);
|
||||
WriteParameter(param, category, "PostProcessing", "AllowNegativeRates", false, NUNBERSAkt);
|
||||
WriteParameter(param, category, "InfluxDBv2", "Fieldname", true, NUNBERSAkt);
|
||||
WriteParameter(param, category, "InfluxDB", "Field", true, NUNBERSAkt);
|
||||
WriteParameter(param, category, "InfluxDBv2", "Field", true, NUNBERSAkt);
|
||||
WriteParameter(param, category, "InfluxDB", "Measurement", true, NUNBERSAkt);
|
||||
WriteParameter(param, category, "InfluxDBv2", "Measurement", true, NUNBERSAkt);
|
||||
}
|
||||
|
||||
function UpdateInput() {
|
||||
@@ -1805,16 +1841,17 @@ function UpdateInput() {
|
||||
|
||||
WriteParameter(param, category, "InfluxDB", "Uri", true);
|
||||
WriteParameter(param, category, "InfluxDB", "Database", true);
|
||||
WriteParameter(param, category, "InfluxDB", "Measurement", true);
|
||||
// WriteParameter(param, category, "InfluxDB", "Measurement", true);
|
||||
WriteParameter(param, category, "InfluxDB", "user", true);
|
||||
WriteParameter(param, category, "InfluxDB", "password", true);
|
||||
// WriteParameter(param, category, "InfluxDB", "Field", true);
|
||||
|
||||
WriteParameter(param, category, "InfluxDBv2", "Uri", true);
|
||||
WriteParameter(param, category, "InfluxDBv2", "Database", true);
|
||||
WriteParameter(param, category, "InfluxDBv2", "Measurement", true);
|
||||
// WriteParameter(param, category, "InfluxDBv2", "Measurement", true);
|
||||
WriteParameter(param, category, "InfluxDBv2", "Org", true);
|
||||
WriteParameter(param, category, "InfluxDBv2", "Token", true);
|
||||
WriteParameter(param, category, "InfluxDBv2", "Fieldname", true);
|
||||
// WriteParameter(param, category, "InfluxDBv2", "Field", true);
|
||||
|
||||
WriteParameter(param, category, "GPIO", "IO0", true);
|
||||
WriteParameter(param, category, "GPIO", "IO1", true);
|
||||
@@ -1945,7 +1982,7 @@ function ReadParameterAll()
|
||||
ReadParameter(param, "InfluxDBv2", "Measurement", true);
|
||||
ReadParameter(param, "InfluxDBv2", "Org", true);
|
||||
ReadParameter(param, "InfluxDBv2", "Token", true);
|
||||
// ReadParameter(param, "InfluxDB", "Fieldname", true);
|
||||
// ReadParameter(param, "InfluxDB", "Field", true);
|
||||
|
||||
ReadParameter(param, "GPIO", "IO0", true);
|
||||
ReadParameter(param, "GPIO", "IO1", true);
|
||||
@@ -2086,11 +2123,26 @@ function numberChanged()
|
||||
_neu = sel.selectedIndex;
|
||||
UpdateInputIndividual(sel);
|
||||
|
||||
var _selInflux = document.getElementById("NumbersInfluxDB_value1");
|
||||
var _selInflux = document.getElementById("NumbersInfluxDBv2_value1");
|
||||
if (_selInflux.selectedIndex != _neu)
|
||||
_selInflux.selectedIndex = _neu
|
||||
}
|
||||
|
||||
function numberInfluxDBv2Changed()
|
||||
{
|
||||
var sel = document.getElementById("NumbersInfluxDBv2_value1");
|
||||
_neu = sel.selectedIndex;
|
||||
UpdateInputIndividual(sel);
|
||||
|
||||
var _sel2 = document.getElementById("Numbers_value1");
|
||||
if (_sel2.selectedIndex != _neu)
|
||||
_sel2.selectedIndex = _neu
|
||||
|
||||
var _sel3 = document.getElementById("NumbersInfluxDB_value1");
|
||||
if (_sel3.selectedIndex != _neu)
|
||||
_sel3.selectedIndex = _neu
|
||||
}
|
||||
|
||||
function numberInfluxDBChanged()
|
||||
{
|
||||
var sel = document.getElementById("NumbersInfluxDB_value1");
|
||||
@@ -2099,7 +2151,11 @@ function numberInfluxDBChanged()
|
||||
|
||||
var _sel2 = document.getElementById("Numbers_value1");
|
||||
if (_sel2.selectedIndex != _neu)
|
||||
_sel2.selectedIndex = _neu
|
||||
_sel2.selectedIndex = _neu
|
||||
|
||||
var _sel3 = document.getElementById("NumbersInfluxDBv2_value1");
|
||||
if (_sel3.selectedIndex != _neu)
|
||||
_sel3.selectedIndex = _neu
|
||||
}
|
||||
|
||||
LoadConfigNeu();
|
||||
|
||||
@@ -272,7 +272,7 @@ table {
|
||||
SaveCanvasToImage(canvas, "/config/reference.jpg", true, getDomainname());
|
||||
showReference(param);
|
||||
UpdatePage();
|
||||
firework.launch('Reference got updated. It will get applied after the next reboot!', 'success', 5000);
|
||||
firework.launch('Reference got saved. It will get applied after the next reboot!', 'success', 5000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
|
||||
function gethost_Version(){
|
||||
return "1.0.0 - 20200910";
|
||||
}
|
||||
|
||||
|
||||
function getbasepath(){
|
||||
var host = window.location.hostname;
|
||||
if (((host == "127.0.0.1") || (host == "localhost") || (host == ""))
|
||||
// && ((window.location.port == "80") || (window.location.port == ""))
|
||||
)
|
||||
|
||||
{
|
||||
// host = "http://192.168.2.219"; // jomjol interner test
|
||||
// host = "http://192.168.178.46"; // jomjol interner test
|
||||
host = "http://192.168.178.44"; // jomjol interner Real
|
||||
// host = "http://192.168.43.191";
|
||||
// host = "."; // jomjol interner localhost
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
host = window.location.protocol + "//" + host;
|
||||
if (window.location.port != "") {
|
||||
host = host + ":" + window.location.port;
|
||||
}
|
||||
}
|
||||
|
||||
return host;
|
||||
}
|
||||
|
||||
function UpdatePage(_dosession = true){
|
||||
var zw = location.href;
|
||||
zw = zw.substr(0, zw.indexOf("?"));
|
||||
if (_dosession) {
|
||||
window.location = zw + '?session=' + Math.floor((Math.random() * 1000000) + 1);
|
||||
}
|
||||
else {
|
||||
window.location = zw;
|
||||
}
|
||||
}
|
||||
@@ -50,39 +50,19 @@
|
||||
|
||||
/* Catch empty fields */
|
||||
if (value == "" || isNaN(value)) {
|
||||
if (traceValue.y.length > 0) {
|
||||
value = traceValue.y[traceValue.y.length-1];
|
||||
}
|
||||
else {
|
||||
value = 0;
|
||||
}
|
||||
value = NaN;
|
||||
}
|
||||
|
||||
if (preValue == "" || isNaN(preValue)) {
|
||||
if (tracePreValue.y.length > 0) {
|
||||
preValue = tracePreValue.y[tracePreValue.y.length-1];
|
||||
}
|
||||
else {
|
||||
preValue = 0;
|
||||
}
|
||||
preValue = NaN;
|
||||
}
|
||||
|
||||
if (changeRate == "" || isNaN(changeRate)) {
|
||||
if (traceChangeRate.y.length > 0) {
|
||||
changeRate = traceChangeRate.y[traceChangeRate.y.length-1];
|
||||
}
|
||||
else {
|
||||
changeRate = 0;
|
||||
}
|
||||
changeRate = NaN;
|
||||
}
|
||||
|
||||
if (changeAbsolute == "" || isNaN(changeAbsolute)) {
|
||||
if (traceChangeAbsolute.y.length > 0) {
|
||||
changeAbsolute = traceChangeAbsolute.y[traceChangeAbsolute.y.length-1];
|
||||
}
|
||||
else {
|
||||
changeAbsolute = 0;
|
||||
}
|
||||
changeAbsolute = NaN;
|
||||
}
|
||||
|
||||
traceValue.y.push(value);
|
||||
@@ -92,7 +72,27 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
//console.log(trace);
|
||||
|
||||
/* If the value trace starts with NaN, replace all those Nans with the first valid value */
|
||||
var firstNonNaNIndex = 0;
|
||||
for(var i = 0; i < traceValue.y.length; i++) {
|
||||
firstNonNaNIndex = i;
|
||||
if (! isNaN(traceValue.y[i])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (firstNonNaNIndex == (traceValue.y.length - 1)) {
|
||||
console.log("No data available for 'value'!");
|
||||
}
|
||||
else if (firstNonNaNIndex > 0) { // Replace all leading NaN with the first valid value
|
||||
console.log("The first leading values have all just NaN, replacing them with the value of",
|
||||
traceValue.y[firstNonNaNIndex], "at", traceValue.x[firstNonNaNIndex], "(Index:", firstNonNaNIndex, ")");
|
||||
for(var i = 0; i < firstNonNaNIndex; i++) {
|
||||
traceValue.y[i] = traceValue.y[firstNonNaNIndex];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Copy time to all traces
|
||||
tracePreValue.x = traceValue.x;
|
||||
@@ -104,6 +104,8 @@
|
||||
var offsetValue = traceValue.y[0];
|
||||
var offsetPreValue = tracePreValue.y[0];
|
||||
|
||||
traceValue.connectgaps = true;
|
||||
|
||||
if (showRrelativeValues) {
|
||||
traceValue.y.forEach(function(part, index, arr) {
|
||||
arr[index] = arr[index] - offsetValue;
|
||||
|
||||
@@ -194,7 +194,7 @@ div {
|
||||
</table>
|
||||
|
||||
<h3>Copyright</h3>
|
||||
Copyright © 2020 - 2022 by <a href="https://github.com/jomjol/AI-on-the-edge-device" target=_blank>Jomjol</a> and others.
|
||||
Copyright © 2020 - 2023 by <a href="https://github.com/jomjol/AI-on-the-edge-device" target=_blank>Jomjol</a> and others.
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -252,11 +252,21 @@ function MakeContrastImageZW(zw, _enhance, _domainname){
|
||||
var xhttp = new XMLHttpRequest();
|
||||
try {
|
||||
xhttp.open("GET", url, false);
|
||||
xhttp.send(); }
|
||||
xhttp.send();
|
||||
}
|
||||
catch (error)
|
||||
{
|
||||
// firework.launch('Deleting Config.ini failed!', 'danger', 30000);
|
||||
}
|
||||
|
||||
if (xhttp.responseText == "CutImage Done") {
|
||||
firework.launch('Reference Image Contrast got enhanced.', 'success', 5000);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
firework.launch("Device is busy, please try again when the Digitalization Round got completed!", 'warning', 10000);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -268,13 +278,23 @@ function MakeRefZW(zw, _domainname){
|
||||
var xhttp = new XMLHttpRequest();
|
||||
try {
|
||||
xhttp.open("GET", url, false);
|
||||
xhttp.send(); }
|
||||
xhttp.send();
|
||||
}
|
||||
catch (error)
|
||||
{
|
||||
// firework.launch('Deleting Config.ini failed!', 'danger', 30000);
|
||||
}
|
||||
_filetarget2 = zw["name"].replace("/config/", "/img_tmp/");
|
||||
// _filetarget2 = _filetarget2.replace(".jpg", "_org.jpg");
|
||||
FileCopyOnServer(_filetarget, _filetarget2, _domainname);
|
||||
|
||||
if (xhttp.responseText == "CutImage Done") {
|
||||
_filetarget2 = zw["name"].replace("/config/", "/img_tmp/");
|
||||
// _filetarget2 = _filetarget2.replace(".jpg", "_org.jpg");
|
||||
FileCopyOnServer(_filetarget, _filetarget2, _domainname);
|
||||
firework.launch('Reference Image got updated.', 'success', 5000);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
firework.launch("Device is busy, please try again when the Digitalization Round got completed!", 'warning', 10000);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@ function getTFLITEList() {
|
||||
}
|
||||
|
||||
tflitelist = tflitelist.split("\t");
|
||||
tflitelist.pop();
|
||||
tflitelist.sort();
|
||||
|
||||
return tflitelist;
|
||||
}
|
||||
@@ -191,9 +191,11 @@ function ParseConfig() {
|
||||
param[catname] = new Object();
|
||||
ParamAddValue(param, catname, "Uri");
|
||||
ParamAddValue(param, catname, "Database");
|
||||
ParamAddValue(param, catname, "Measurement");
|
||||
// ParamAddValue(param, catname, "Measurement");
|
||||
ParamAddValue(param, catname, "user");
|
||||
ParamAddValue(param, catname, "password");
|
||||
ParamAddValue(param, catname, "Measurement", 1, true);
|
||||
ParamAddValue(param, catname, "Field", 1, true);
|
||||
|
||||
var catname = "InfluxDBv2";
|
||||
category[catname] = new Object();
|
||||
@@ -202,10 +204,11 @@ function ParseConfig() {
|
||||
param[catname] = new Object();
|
||||
ParamAddValue(param, catname, "Uri");
|
||||
ParamAddValue(param, catname, "Database");
|
||||
ParamAddValue(param, catname, "Measurement");
|
||||
// ParamAddValue(param, catname, "Measurement");
|
||||
ParamAddValue(param, catname, "Org");
|
||||
ParamAddValue(param, catname, "Token");
|
||||
ParamAddValue(param, catname, "Fieldname", 1, true);
|
||||
ParamAddValue(param, catname, "Measurement", 1, true);
|
||||
ParamAddValue(param, catname, "Field", 1, true);
|
||||
|
||||
var catname = "GPIO";
|
||||
category[catname] = new Object();
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
<link href="firework.css?v=$COMMIT_HASH" rel="stylesheet">
|
||||
<script type="text/javascript" src="jquery-3.6.0.min.js?v=$COMMIT_HASH"></script>
|
||||
<script type="text/javascript" src="firework.js?v=$COMMIT_HASH"></script>
|
||||
<script type="text/javascript" src="/common.js?v=$COMMIT_HASH">
|
||||
</head>
|
||||
<body>
|
||||
<table>
|
||||
|
||||
@@ -36,6 +36,9 @@ def generateHtmlTooltip(section, parameter, markdownFile):
|
||||
# Make all links to be opened in a new page
|
||||
htmlTooltip = htmlTooltip.replace("a href", "a target=_blank href")
|
||||
|
||||
# Replace relative documentation links with absolute ones pointing to the external documentation
|
||||
htmlTooltip = htmlTooltip.replace("href=\"../", "href=\"https://jomjol.github.io/AI-on-the-edge-device-docs/")
|
||||
|
||||
# Add custom styles
|
||||
htmlTooltip = htmlTooltip.replace("<h3>", "<h3 style=\"margin: 0\">")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user