* Testcase for #2145 and debug-log (#2151)

* new models ana-cont-11.0.5, ana-class100-1.5.7, dig-class100-1.6.0

* Testcase for #2145
Added debug log, if allowNegativeRates is handeled

* Fix timezone config parser (#2169)

* make sure to parse the whole config line

* fix crash on empty timezone parameter

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Enhance ROI pages (#2161)

* Check if the ROIs are equidistant. Only if not, untick the checkbox

* renaming

* Check if the ROIs have same y, dy and dx. If so, tick the sync checkbox

* only allow editing space when box is checked

* fix sync check

* show inner frame on all ROIs

* cleanup

* Check if the ROIs have same dy and dx. If so, tick the sync checkbox

* checkbox position

* renaming

* renaming

* show inner frame and cross hairs on all ROIs

* update ROIs on ticking checkboxes

* show timezone hint

* fix deleting last ROI

* cleanup

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* restart timeout on progress, catch error (#2170)

* restart timeout on progress, catch error

* .

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* BugFix #2167

* Release 15.1 preparations (#2171)

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update changelog

* Fix links to PR

* Formating

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

---------

Co-authored-by: Slider0007 <jobbelle@gmx.net>
Co-authored-by: Slider0007 <115730895+Slider0007@users.noreply.github.com>

* fix typo

* Replace relative documentation links with absolute ones pointing to the external documentation (#2180)

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Sort model files in configuration combobox (#2189)

* new models ana-cont-11.0.5, ana-class100-1.5.7, dig-class100-1.6.0

* Testcase for #2145
Added debug log, if allowNegativeRates is handeled

* Sort model files in combobox

* reboot task - increase stack size (#2201)

Avoid stack overflow

* Update interface_influxdb.cpp

* Update Changelog.md

* Show PSRAM usage (#2206)

* centralize PSRAM usage (application code only)

* update logging

* update logging

* fix use after free

* initialize buffer

* free rgb_image before ussing it for new allocation

* use wrapper function

* switch log level to debug

* .

* undo adding free() calls

* .

* add names to all CImage instances

* .

* .

* .

* revert changes of stbi_image_free() with free_psram_heap() on the places where is is not in PSRAM

* .

* typos

* typo

* Added MQTT Outbox explanation/warning

* added CONFIG_SPIRAM_USE_MEMMAP explanation

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Disable custom MQTT Outbox. This also moves the MQTT Publishing memory usage back to the internal RAM!

* log MQTT connection refused reasons (#2216)

* Revert PSRAM usage as it lead to memory fragmentation.
See https://github.com/jomjol/AI-on-the-edge-device/issues/2200 for details

* fix missing value data

* Revert PSRAM usage as it lead to memory fragmentation. (#2224)

See https://github.com/jomjol/AI-on-the-edge-device/issues/2200 for details

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Fix missing value data in graph (#2230)

* fix missing value data

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Update Changelog.md (#2231)

* Update interface_influxdb.cpp (#2233)

* update copyright year

* Cleanup

* Set prevalue using MQTT + set prevalue to RAW value (REST+MQTT) (#2252)

* Use double instead of float

* Error handling + set to RAW if newvalue < 0

* REST SetPrevalue: Set to RAW if newvalue < 0

* set prevalue with MQTT

* removed the stb_image files and re-add them as a submodule. (#2223)

- stb_image.h: Version update 2.25 -> 2.28
- stb_resize.h: Version update 0.96 -> 0.97
- stb_write.h: Version update 1.14 -> 1.16

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Remove obsolete ClassFlowWriteList (#2264)

* Renaming & cleanup of some modules / functions in source code (#2265)

* Rename module tag name

* Rename server_tflite.cpp -> MainFlowControl.cpp

* Remove redundandant MQTTMainTopic function

* Update

* Remove obsolete GetMQTTMainTopic

* Fix last element missing in digit model drop down (#2282)

* Debug influxdb (#2283)

* Fix time offset issues in InfluxDB component. (#2278)

Closes #2273
Closes #2150

* Update interface_influxdb.cpp

* Update interface_influxdb.cpp

* Improve Logging

* Implement TimeSync at beginning

* Update time_sntp.cpp

* Update time_sntp.cpp

* Set Time After WLAN Init

---------

Co-authored-by: Antonin Delpeuch <antonin@delpeuch.eu>

* Implement a camera livestream handler (#2286)

* fix leading NaN (#2310)

* analogROI: Activate save button after ROI creation (#2326)

* Migration of PlatformIO 5.2.0 to 6.1.0 (resp. ESP IDF from 4.4.2 to 5.0.1) (#2305)

* Migration to PlatformIO 6.1.0

* Disable RMTMEM usage as it is no longer allowed -> Smart LEDs not functional!

* moved miniz into subfolder of jomjol_fileserver_ota, else it does not build anymore.

* cleanup

* fix leading NaN (#2310)

* Migration to PlatformIO 6.1.0

* Disable RMTMEM usage as it is no longer allowed -> Smart LEDs not functional!

* moved miniz into subfolder of jomjol_fileserver_ota, else it does not build anymore.

* cleanup

* Task watchdog has new config name

* Fix return value check. It must be something else than ESP_FAIL, but it does not need to be ESP_OK!

* add missing strucures to work around new RMTMEM restriction (untested)

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Keep MainFlowTask alive to handle reboot (#2325)

* Shared PSRAM memory (#2285)

* enable PSRAM logging

* add extra functions for psram shared memroy handling

* CImageBasis objects still should used dynamic memory (eg. rawImage), haw ever tmpImage must be placed inside the shared memory

* Place all STBI allocs inside the shared memory

* The models are placed in the shared PSRAM reagion and must be allocated through the dedicated functions

* .

* renaming

* fix cast warning

* add flag to switch STBI PSRAM usage

* improve PSRAM shared handling

* reserve shared PSRAM as early as possible

* init logging eralier so we can use it in PSRAM shared alloc

* move Wifi_LWIP, BSS_SEG and MQTT Outbox into PSRAM to ffree internal memory

* Check if model fits into reserved shared memory

* Update code/components/jomjol_tfliteclass/CTfLiteClass.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_flowcontroll/ClassFlowControll.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_image_proc/CImageBasis.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* .

* .

* .

* .

* Korrektur Merge Conflict in main.cpp

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>

* fix PSRAM init return value check

* Extend InfluxDBv1 with individual topic names (#2319)

* Implement individual influx topic

* Update interface_influxdb.cpp

* Update interface_influxdb.cpp

* Update FieldName

* analogROI: Activate save button after ROI creation (#2326)

* Migration of PlatformIO 5.2.0 to 6.1.0 (resp. ESP IDF from 4.4.2 to 5.0.1) (#2305)

* Migration to PlatformIO 6.1.0

* Disable RMTMEM usage as it is no longer allowed -> Smart LEDs not functional!

* moved miniz into subfolder of jomjol_fileserver_ota, else it does not build anymore.

* cleanup

* fix leading NaN (#2310)

* Migration to PlatformIO 6.1.0

* Disable RMTMEM usage as it is no longer allowed -> Smart LEDs not functional!

* moved miniz into subfolder of jomjol_fileserver_ota, else it does not build anymore.

* cleanup

* Task watchdog has new config name

* Fix return value check. It must be something else than ESP_FAIL, but it does not need to be ESP_OK!

* add missing strucures to work around new RMTMEM restriction (untested)

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Keep MainFlowTask alive to handle reboot (#2325)

* Shared PSRAM memory (#2285)

* enable PSRAM logging

* add extra functions for psram shared memroy handling

* CImageBasis objects still should used dynamic memory (eg. rawImage), haw ever tmpImage must be placed inside the shared memory

* Place all STBI allocs inside the shared memory

* The models are placed in the shared PSRAM reagion and must be allocated through the dedicated functions

* .

* renaming

* fix cast warning

* add flag to switch STBI PSRAM usage

* improve PSRAM shared handling

* reserve shared PSRAM as early as possible

* init logging eralier so we can use it in PSRAM shared alloc

* move Wifi_LWIP, BSS_SEG and MQTT Outbox into PSRAM to ffree internal memory

* Check if model fits into reserved shared memory

* Update code/components/jomjol_tfliteclass/CTfLiteClass.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_flowcontroll/ClassFlowControll.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_image_proc/CImageBasis.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* .

* .

* .

* .

* Korrektur Merge Conflict in main.cpp

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>

* fix PSRAM init return value check

* Extend incl. indiv. Measurement

* Implement UX

* Update ClassFlowInfluxDBv2.cpp

* Implement individual influx topic

* Update interface_influxdb.cpp

* Update interface_influxdb.cpp

* Update FieldName

* Extend incl. indiv. Measurement

* Implement UX

* Update ClassFlowInfluxDBv2.cpp

* Update main.cpp

---------

Co-authored-by: Slider0007 <115730895+Slider0007@users.noreply.github.com>
Co-authored-by: CaCO3 <caco3@ruinelli.ch>
Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Update Changelog.md (#2344)

* Update Changelog.md

* Update Changelog.md

* merge conflicts

* merge conflicts

* update changelog

---------

Co-authored-by: Frank Haverland <fspapaping@googlemail.com>
Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>
Co-authored-by: Slider0007 <jobbelle@gmx.net>
Co-authored-by: Slider0007 <115730895+Slider0007@users.noreply.github.com>
Co-authored-by: Antonin Delpeuch <antonin@delpeuch.eu>
This commit is contained in:
CaCO3
2023-04-23 17:13:18 +02:00
committed by GitHub
parent 03c84a1ff3
commit c2a55e7c86
84 changed files with 1309 additions and 12780 deletions

View File

@@ -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;

View File

@@ -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 {

View File

@@ -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";

View File

@@ -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)

View File

@@ -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,
@@ -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();

View File

@@ -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);

View File

@@ -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)

View File

@@ -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());

View File

@@ -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);

View File

@@ -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)

View File

@@ -1,7 +1,7 @@
#include "ClassFlowAlignment.h"
#include "ClassFlowTakeImage.h"
#include "ClassFlow.h"
#include "server_tflite.h"
#include "MainFlowControl.h"
#include "CRotateImage.h"
#include "esp_log.h"
@@ -190,10 +190,10 @@ bool ClassFlowAlignment::doFlow(string time)
if (!ImageTMP)
{
ImageTMP = new CImageBasis("ImageTMP", 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;
}
@@ -256,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

View File

@@ -374,8 +374,11 @@ 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)

View File

@@ -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) {
@@ -243,8 +233,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 +373,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 +458,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 +489,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 +728,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 +755,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) {

View File

@@ -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);

View File

@@ -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;

View File

@@ -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)
{

View File

@@ -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

View File

@@ -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);

View File

@@ -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);
}
}

View File

@@ -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);

View File

@@ -183,12 +183,6 @@ bool ClassFlowMQTT::ReadParameter(FILE* pfile, string& aktparamgraph)
}
string ClassFlowMQTT::GetMQTTMainTopic()
{
return maintopic;
}
bool ClassFlowMQTT::Start(float AutoInterval)
{
roundInterval = AutoInterval; // Minutes

View File

@@ -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);

View File

@@ -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)
}

View File

@@ -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();

View File

@@ -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;
@@ -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);

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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>
@@ -27,8 +28,12 @@
#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;
@@ -41,7 +46,8 @@ bool auto_isrunning = false;
int countRounds = 0;
bool isPlannedReboot = false;
static const char *TAG = "TFLITE SERVER";
static const char *TAG = "MAINCTRL";
//#define DEBUG_DETAIL_ON
@@ -75,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 )
{
@@ -109,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
}
@@ -131,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
@@ -207,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
@@ -278,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());
@@ -371,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());
@@ -380,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)
@@ -398,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());
@@ -418,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";
@@ -453,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;
@@ -675,7 +714,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());
}
@@ -690,7 +729,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());
}
@@ -706,7 +745,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;
@@ -715,10 +754,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);
@@ -730,7 +769,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;
@@ -802,50 +841,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");
@@ -863,7 +933,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
@@ -873,13 +943,13 @@ void task_autodoFlow(void *pvParameter)
ESP_LOGD(TAG, "task_autodoFlow: start");
doInit();
auto_isrunning = tfliteflow.isAutoStart(auto_interval);
auto_isrunning = flowctrl.isAutoStart(auto_interval);
if (isSetupModusActive())
{
auto_isrunning = false;
std::string zw_time = getCurrentTimeString(LOGFILE_TIME_FORMAT);
tfliteflow.doFlowTakeImageOnly(zw_time);
flowctrl.doFlowTakeImageOnly(zw_time);
}
while (auto_isrunning)
@@ -944,13 +1014,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 StartMainFlowTask()
{
BaseType_t xReturned;
@@ -967,17 +1043,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;
@@ -1071,4 +1139,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);
}

View File

@@ -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 StartMainFlowTask();
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

View File

@@ -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)

View File

@@ -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"

View File

@@ -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);

View File

@@ -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

View File

@@ -1,11 +1,128 @@
#include "ClassLogFile.h"
#include "esp_heap_caps.h"
#include "../../include/defines.h"
#include "psram.h"
static const char* TAG = "PSRAM";
using namespace std;
void *shared_region = NULL;
uint32_t allocatedBytesForSTBI = 0;
/** 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)
*******************************************************************/
void psram_init_shared_memory_for_take_image_step(void) {
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Init shared memory for step 'Take Image' (STBI buffers)");
allocatedBytesForSTBI = 0;
}
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) {
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Allocating tmpImage (" + std::to_string(IMAGE_SIZE) + " bytes, use shared memory in PSRAM)...");
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");
}
/*******************************************************************
* 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) {
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
}
void *psram_get_shared_model_memory(void) {
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
}
void psram_free_shared_tensor_arena_and_model_memory(void) {
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;
@@ -21,12 +138,25 @@ 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) {
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_DEBUG, TAG, "Allocated " + to_string(size) + " bytes in PSRAM for '" + name + "'");
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 + "'!");
@@ -39,4 +169,4 @@ 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) {
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Freeing memory in PSRAM used for '" + name + "'...");
heap_caps_free(ptr);
}
}

View File

@@ -1,7 +1,34 @@
#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 */
void psram_init_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);
void free_psram_heap(std::string name, void *ptr);
#endif // PSRAM_h

View File

@@ -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";

View File

@@ -477,7 +477,13 @@ CImageBasis::CImageBasis(string _name, CImageBasis *_copyfrom)
memsize = width * height * channels;
rgb_image = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->CImageBasis (" + name + ")", memsize, MALLOC_CAP_SPIRAM);
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)
{
@@ -618,9 +624,20 @@ CImageBasis::~CImageBasis()
{
RGBImageLock();
if (!externalImage) {
//stbi_image_free(rgb_image);
free_psram_heap(std::string(TAG) + "->CImageBasis (" + name + ", " + to_string(memsize) + ")", rgb_image);
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();

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 + "/write?db=" + _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;

View File

@@ -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);

View File

@@ -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)

View File

@@ -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";
@@ -185,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);
}
@@ -247,24 +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
@@ -336,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");
@@ -358,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) {

View File

@@ -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)

View File

@@ -243,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*)malloc_psram_heap(std::string(TAG) + "->modelfile", size, MALLOC_CAP_SPIRAM);
modelfile = (unsigned char*)psram_get_shared_model_memory();
if(modelfile != NULL)
{
@@ -304,9 +311,9 @@ 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*)malloc_psram_heap(std::string(TAG) + "->tensor_arena", kTensorArenaSize, MALLOC_CAP_SPIRAM);
this->output = nullptr;
this->kTensorArenaSize = TENSOR_ARENA_SIZE;
this->tensor_arena = (uint8_t*)psram_get_shared_tensor_arena_memory();
}
@@ -315,8 +322,7 @@ CTfLiteClass::~CTfLiteClass()
delete this->interpreter;
delete this->error_reporter;
free_psram_heap(std::string(TAG) + "->modelfile", modelfile);
free_psram_heap(std::string(TAG) + "->tensor_arena", this->tensor_arena);
psram_free_shared_tensor_arena_and_model_memory();
}

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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)

View File

@@ -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,20 @@
#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
esp_netif_t *sta_netif = NULL;
static const char *TAG = "WIFI";
@@ -173,7 +187,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 +196,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 +379,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 +402,7 @@ void wifi_scan(void)
APWithBetterRSSI = true;
}
}
free(wifi_ap_records);
delete wifi_ap_records;
}
@@ -636,7 +650,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));
}

View File

@@ -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

Submodule code/components/stb added at 5736b15f7e