Compare commits

...

48 Commits

Author SHA1 Message Date
jomjol
fa3e300c37 Update platformio.ini 2021-02-06 12:04:00 +01:00
jomjol
78744840eb Update 2021-01-20 19:52:26 +01:00
jomjol
46cfe45cf6 Merge branch 'rolling' into master 2021-01-20 19:43:33 +01:00
jomjol
91ff41a9d9 Prepare for v6.1.0 2021-01-20 19:39:10 +01:00
jomjol
3869da9d06 Rolling 20210119 2021-01-19 20:14:37 +01:00
jomjol
2530691347 Update Rolling 20210118 2021-01-18 21:15:23 +01:00
jomjol
c65de27e9d Update Rolling 2021-01-17 12:44:20 +01:00
jomjol
9bb715fcb2 Update Versioninfo 2021-01-05 20:46:14 +01:00
jomjol
8c4f39ab49 Update version info 2021-01-05 18:16:46 +01:00
jomjol
e5206091dd Update version file 2021-01-05 08:32:07 +01:00
jomjol
e53c6fe64c Merge branch 'rolling-speed-up-alignment' into rolling 2021-01-05 08:17:21 +01:00
jomjol
b893b24d88 Update README.md 2021-01-05 08:11:22 +01:00
jomjol
c7caa55223 Prepare update rolling 2021-01-05 07:49:58 +01:00
jomjol
c675019ef3 Almost done 2021-01-04 22:49:36 +01:00
jomjol
f2fea0a402 Merge pull request #82 from jomjol/master
Update Rolling from Master Release v6.0.0
2021-01-02 09:00:50 +01:00
jomjol
aeafd631d5 Update 2021-01-02 08:59:02 +01:00
jomjol
aa442632ea Merge pull request #81 from jomjol/rolling
Update to v6.0.0
2021-01-02 08:54:05 +01:00
jomjol
2a4b5f88a7 Preparation for v6.0.0 2021-01-02 08:50:20 +01:00
jomjol
0e36010937 Bug-fixing 2021-01-01 14:59:07 +01:00
jomjol
8a06825871 Rolling 20210101 2021-01-01 10:58:20 +01:00
jomjol
ce2f1bcde6 Merge pull request #77 from jomjol/rolling-update-cimage
Improvment of CBasisImage handling
2021-01-01 10:14:04 +01:00
jomjol
c59826471c Update 2021-01-01 10:13:00 +01:00
jomjol
9c8f64f602 Bug-Fixing 2020-12-31 12:13:03 +01:00
jomjol
d4342a77c8 Update README.md 2020-12-31 11:57:48 +01:00
jomjol
054d2296c4 Update README.md 2020-12-31 11:54:52 +01:00
jomjol
ae116981ef MQTT: LWT 2020-12-30 10:35:50 +01:00
jomjol
becb886ab7 Update digital CNN, bug fixing 2020-12-29 22:27:48 +01:00
jomjol
3502ac9263 Bug fixing 2020-12-29 10:42:42 +01:00
jomjol
c64cb94b7d Merge pull request #75 from jomjol/rolling-reduce-sd-use
Update with reduced SD card usage
2020-12-28 16:27:29 +01:00
jomjol
dffb28816d Update for rolling 2020-12-28 16:26:05 +01:00
jomjol
6e521f07c4 Modify ClassControllCamera_MakeImage 2020-12-27 17:36:08 +01:00
jomjol
c05313aefc Limit Image to VGA-Size 2020-12-26 20:11:22 +01:00
jomjol
db0ca1cb9b Improved Logfile, extended Logging 2020-12-26 09:18:16 +01:00
jomjol
584a73255a TimeServer 2020-12-24 16:08:58 +01:00
jomjol
3a66385059 Update README.md 2020-12-23 22:06:48 +01:00
jomjol
7e4f83c2f5 Waitmissing for missing memory 2020-12-23 11:09:27 +01:00
jomjol
9971c82e99 Restructure Image Processing 2020-12-23 08:00:11 +01:00
jomjol
b418525b3b Inital 2020-12-22 08:08:07 +01:00
jomjol
f5c28107d4 rolling 2020-12-07 21:38:43 +01:00
jomjol
793f928e6e Rolling - fixed IP 2020-12-06 21:13:27 +01:00
jomjol
a8fb2e37d5 Merge pull request #71 from jomjol/master
Update Rolling
2020-12-06 19:36:03 +01:00
jomjol
11fed9394a Update 2020-12-06 19:34:52 +01:00
jomjol
bcdd0c66c0 Merge pull request #70 from jomjol/rolling
Update to v5.0.0
2020-12-06 19:31:04 +01:00
jomjol
e988215d8a Prepare for v5.0.0 2020-12-06 19:28:17 +01:00
jomjol
f616643335 Rolling 2020-06-12 2020-12-06 08:24:32 +01:00
jomjol
816f93222b Rolling 20201204 2020-12-04 22:09:20 +01:00
jomjol
9e85b1240a Rolling - 202-12-03 2020-12-03 20:38:28 +01:00
jomjol
c5059b4568 Merge pull request #69 from jomjol/master
Sync rolling master to v4.1.1
2020-12-02 21:58:42 +01:00
115 changed files with 4853 additions and 1938 deletions

1
.gitignore vendored
View File

@@ -4,6 +4,7 @@
.code-workspace
.helper/
/sd-card/htm./.vscode/
/code/build
CMakeLists.txt.user
CMakeCache.txt

View File

@@ -13,24 +13,78 @@ A 3d-printable housing can be found here: https://www.thingiverse.com/thing:4571
## Donate
------
If you would like to support the developer with a cup of coffee you can do that via [Paypal](https://www.paypal.com/donate?hosted_button_id=8TRSVYNYKDSWL).
<form action="https://www.paypal.com/donate" method="post" target="_top">
<input type="hidden" name="hosted_button_id" value="8TRSVYNYKDSWL" />
<input type="image" src="https://www.paypalobjects.com/en_US/DK/i/btn/btn_donateCC_LG.gif" border="0" name="submit" title="PayPal - The safer, easier way to pay online!" alt="Donate with PayPal button" />
<img alt="" border="0" src="https://www.paypal.com/en_DE/i/scr/pixel.gif" width="1" height="1" />
</form>
## Change log
------
### Known Issues
* Reboot on extensive web access due to the limits of the internal web server
* slow response of web server during picture analysis
* spontaneous reboots (mostly due to html access during image processing) - self recovery implemented
------
**General remark:** Beside the `firmware.bin`, typically also the content of `/html` needs to be updated!
##### 6.1.0 Image Processing in Memory - (2021-01-20)
* Disabling of analog / digital counters in configuration
* Improved Alignment Algorithm (`AlignmentAlgo` = `Default`, `Accurate` , `Fast`)
* Analog counters: `ExtendedResolution` (last digit is extended by sub comma value of CNN)
* `config.ini`: additional parameter `hostname` (additional to wlan.ini)
* Switching of GPIO12/13 via http-interface: `/GPIO?GPIO=12&Status=high/low`
* Bug fixing: html configuration page, wlan password ("=" now possible)
##### 6.0.0 Image Processing in Memory - (2021-01-02)
* **Major change**: image processing fully in memory - no need of SD card buffer anymore
* Need to limit camera resolution to VGA (due to memory limits)
* MQTT: Last Will Testament (LWT) implemented: "connection lost" in case of connection lost to `TopicError`
* Disabled `CheckDigitIncreaseConsistency` in default configuration - must now be explicit enabled if needed
* Update digital CNN to v7.2.1 (additional digital images trained)
* Setting of arbitrary time server in `config.ini`
* Option for fixed IP-, DNS-Settings in `wlan.ini`
* Increased stability (internal image and camera handling)
* Bug fixing: edit digits, handling PreValue, html-bugs
##### 5.0.0 Setup Modus - (2020-12-06)
* Implementation of initial setup modus for fresh installation
* Code restructuring (full compatibility between pure ESP-IDF and Platformio w/ espressif)
##### 4.1.1 Configuration editor - (2020-12-02)
* Bug fixing: internal improvement of file handling (reduce not responding)
##### 4.1.0 Configuration editor - (2020-11-30)
* Implementation of configuration editor (including basic and expert mode)
@@ -47,7 +101,6 @@ A 3d-printable housing can be found here: https://www.thingiverse.com/thing:4571
##### 4.0.0 Tflite Core - (2020-11-15)
* Implementation of rolling log-files

View File

@@ -11,6 +11,10 @@
#include <fstream>
#include <string>
#include <vector>
#include <sstream>
#include <iostream>
#include <arpa/inet.h>
#include "Helper.h"
@@ -23,6 +27,9 @@ std::string ssid;
std::string passphrase;
std::string hostname;
std::string ipaddress;
std::string gw;
std::string netmask;
std::string dns;
std::string std_hostname = "watermeter";
@@ -86,7 +93,7 @@ static esp_err_t event_handler(void *ctx, system_event_t *event)
{
switch(event->event_id) {
case SYSTEM_EVENT_STA_START:
blinkstatus(200, 5);
blinkstatus(200, 1);
wifi_connect();
break;
case SYSTEM_EVENT_STA_GOT_IP:
@@ -125,10 +132,163 @@ void initialise_wifi(std::string _ssid, std::string _passphrase, std::string _ho
tcpip_adapter_ip_info_t ip_info;
ESP_ERROR_CHECK(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip_info));
ipaddress = std::string(ip4addr_ntoa(&ip_info.ip));
netmask = std::string(ip4addr_ntoa(&ip_info.netmask));
gw = std::string(ip4addr_ntoa(&ip_info.gw));
printf("IPv4 : %s\n", ip4addr_ntoa(&ip_info.ip));
printf("HostName : %s\n", hostname.c_str());
}
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
void strinttoip4(std::string ip, int &a, int &b, int &c, int &d) {
std::stringstream s(ip);
char ch; //to temporarily store the '.'
s >> a >> ch >> b >> ch >> c >> ch >> d;
}
void initialise_wifi_fixed_ip(std::string _ip, std::string _gw, std::string _netmask, std::string _ssid, std::string _passphrase, std::string _hostname, std::string _dns)
{
ssid = _ssid;
passphrase = _passphrase;
hostname = _hostname;
dns = _dns;
wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
esp_netif_t *my_sta = esp_netif_create_default_wifi_sta();
esp_netif_dhcpc_stop(my_sta);
esp_netif_ip_info_t ip_info;
int a, b, c, d;
strinttoip4(_ip, a, b, c, d);
IP4_ADDR(&ip_info.ip, a, b, c, d);
strinttoip4(_gw, a, b, c, d);
IP4_ADDR(&ip_info.gw, a, b, c, d);
strinttoip4(_netmask, a, b, c, d);
IP4_ADDR(&ip_info.netmask, a, b, c, d);
esp_netif_set_ip_info(my_sta, &ip_info);
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
if (dns.length() > 0) {
esp_netif_dns_info_t dns_info;
ip4_addr_t ip;
ip.addr = esp_ip4addr_aton(dns.c_str());
ip_addr_set_ip4_u32(&dns_info.ip, ip.addr);
ESP_ERROR_CHECK(esp_netif_set_dns_info(my_sta, ESP_NETIF_DNS_MAIN, &dns_info));
}
ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL) );
wifi_config_t wifi_config = { };
strcpy((char*)wifi_config.sta.ssid, (const char*)ssid.c_str());
strcpy((char*)wifi_config.sta.password, (const char*)passphrase.c_str());
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) );
ESP_ERROR_CHECK(esp_wifi_start() );
ESP_LOGI(MAIN_TAG, "wifi_init_sta finished.");
EventBits_t bits = xEventGroupWaitBits(wifi_event_group,CONNECTED_BIT,true,true,portMAX_DELAY);
if (bits & CONNECTED_BIT) {
ESP_LOGI(MAIN_TAG, "connected to ap SSID:%s password:%s",
ssid.c_str(), passphrase.c_str());
} else {
ESP_LOGI(MAIN_TAG, "Failed to connect to SSID:%s, password:%s",
ssid.c_str(), passphrase.c_str());
}
tcpip_adapter_ip_info_t ip_info2;
ESP_ERROR_CHECK(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip_info2));
ipaddress = std::string(ip4addr_ntoa(&ip_info2.ip));
netmask = std::string(ip4addr_ntoa(&ip_info2.netmask));
gw = std::string(ip4addr_ntoa(&ip_info2.gw));
// vEventGroupDelete(wifi_event_group);
}
bool ChangeHostName(std::string fn, std::string _newhostname)
{
if (_newhostname == hostname)
return false;
string line = "";
std::vector<string> zerlegt;
bool found = false;
std::vector<string> neuesfile;
FILE* pFile;
fn = FormatFileName(fn);
pFile = OpenFileAndWait(fn.c_str(), "r");
printf("file loaded\n");
if (pFile == NULL)
return false;
char zw[1024];
fgets(zw, 1024, pFile);
line = std::string(zw);
while ((line.size() > 0) || !(feof(pFile)))
{
printf("%s", line.c_str());
zerlegt = ZerlegeZeile(line, "=");
zerlegt[0] = trim(zerlegt[0], " ");
if ((zerlegt.size() > 1) && (toUpper(zerlegt[0]) == "HOSTNAME")){
line = "hostname = \"" + _newhostname + "\"\n";
found = true;
}
neuesfile.push_back(line);
if (fgets(zw, 1024, pFile) == NULL)
{
line = "";
}
else
{
line = std::string(zw);
}
}
if (!found)
{
line = "hostname = \"" + _newhostname + "\"\n";
neuesfile.push_back(line);
}
fclose(pFile);
pFile = OpenFileAndWait(fn.c_str(), "w+");
for (int i = 0; i < neuesfile.size(); ++i)
{
fputs(neuesfile[i].c_str(), pFile);
}
fclose(pFile);
return true;
}
void LoadWlanFromFile(std::string fn, std::string &_ssid, std::string &_passphrase, std::string &_hostname)
{
@@ -138,7 +298,9 @@ void LoadWlanFromFile(std::string fn, std::string &_ssid, std::string &_passphra
FILE* pFile;
fn = FormatFileName(fn);
pFile = fopen(fn.c_str(), "r");
pFile = OpenFileAndWait(fn.c_str(), "r");
printf("file loaded\n");
if (pFile == NULL)
return;
@@ -149,9 +311,11 @@ void LoadWlanFromFile(std::string fn, std::string &_ssid, std::string &_passphra
while ((line.size() > 0) || !(feof(pFile)))
{
// printf("%s", line.c_str());
printf("%s", line.c_str());
zerlegt = ZerlegeZeile(line, "=");
zerlegt[0] = trim(zerlegt[0], " ");
for (int i = 2; i < zerlegt.size(); ++i)
zerlegt[i] = zerlegt[i-1] + zerlegt[i];
if ((zerlegt.size() > 1) && (toUpper(zerlegt[0]) == "HOSTNAME")){
_hostname = trim(zerlegt[1]);
@@ -192,6 +356,71 @@ void LoadWlanFromFile(std::string fn, std::string &_ssid, std::string &_passphra
}
}
void LoadNetConfigFromFile(std::string fn, std::string &_ip, std::string &_gw, std::string &_netmask, std::string &_dns)
{
string line = "";
std::vector<string> zerlegt;
FILE* pFile;
fn = FormatFileName(fn);
pFile = OpenFileAndWait(fn.c_str(), "r");
printf("file loaded\n");
if (pFile == NULL)
return;
char zw[1024];
fgets(zw, 1024, pFile);
line = std::string(zw);
while ((line.size() > 0) || !(feof(pFile)))
{
printf("%s", line.c_str());
zerlegt = ZerlegeZeile(line, "=");
zerlegt[0] = trim(zerlegt[0], " ");
if ((zerlegt.size() > 1) && (toUpper(zerlegt[0]) == "IP")){
_ip = zerlegt[1];
if ((_ip[0] == '"') && (_ip[_ip.length()-1] == '"')){
_ip = _ip.substr(1, _ip.length()-2);
}
}
if ((zerlegt.size() > 1) && (toUpper(zerlegt[0]) == "GATEWAY")){
_gw = zerlegt[1];
if ((_gw[0] == '"') && (_gw[_gw.length()-1] == '"')){
_gw = _gw.substr(1, _gw.length()-2);
}
}
if ((zerlegt.size() > 1) && (toUpper(zerlegt[0]) == "NETMASK")){
_netmask = zerlegt[1];
if ((_netmask[0] == '"') && (_netmask[_netmask.length()-1] == '"')){
_netmask = _netmask.substr(1, _netmask.length()-2);
}
}
if ((zerlegt.size() > 1) && (toUpper(zerlegt[0]) == "DNS")){
_dns = zerlegt[1];
if ((_dns[0] == '"') && (_dns[_dns.length()-1] == '"')){
_dns = _dns.substr(1, _dns.length()-2);
}
}
if (fgets(zw, 1024, pFile) == NULL)
{
line = "";
}
else
{
line = std::string(zw);
}
}
fclose(pFile);
}
std::string getHostname(){
return hostname;
@@ -204,3 +433,12 @@ std::string getIPAddress(){
std::string getSSID(){
return ssid;
}
std::string getNetMask(){
return netmask;
}
std::string getGW(){
return gw;
}

View File

@@ -7,11 +7,18 @@
const int CONNECTED_BIT = BIT0;
void initialise_wifi(std::string _ssid, std::string _passphrase, std::string _hostname);
void initialise_wifi_fixed_ip(std::string _ip, std::string _gw, std::string _netmask, std::string _ssid, std::string _passphrase, std::string _hostname, std::string _dns = "");
void LoadWlanFromFile(std::string fn, std::string &_ssid, std::string &_passphrase, std::string &_hostname);
void LoadNetConfigFromFile(std::string fn, std::string &_ip, std::string &_gw, std::string &_netmask, std::string &_dns);
bool ChangeHostName(std::string fn, std::string _newhostname);
std::string getHostname();
std::string getIPAddress();
std::string getSSID();
std::string getNetMask();
std::string getGW();
#endif

View File

@@ -0,0 +1,9 @@
FILE(GLOB_RECURSE app_sources ${CMAKE_CURRENT_SOURCE_DIR}/*.*)
list(APPEND EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
idf_component_register(SRCS ${app_sources}
INCLUDE_DIRS "."
REQUIRES esp_http_server jomjol_logfile)

View File

@@ -0,0 +1,124 @@
#include <string>
#include "string.h"
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_event.h"
#include "esp_log.h"
#include "driver/gpio.h"
//#include "errno.h"
#include <sys/stat.h>
#include "server_GPIO.h"
#include "ClassLogFile.h"
#include "Helper.h"
// #define DEBUG_DETAIL_ON
esp_err_t handler_switch_GPIO(httpd_req_t *req)
{
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_switch_GPIO - Start");
#endif
LogFile.WriteToFile("handler_switch_GPIO");
char _query[200];
char _valueGPIO[30];
char _valueStatus[30];
std::string gpio, status, zw;
int gpionum = 0;
gpio_num_t gpio_num;
if (httpd_req_get_url_query_str(req, _query, 200) == ESP_OK)
{
printf("Query: "); printf(_query); printf("\n");
if (httpd_query_key_value(_query, "GPIO", _valueGPIO, 30) == ESP_OK)
{
printf("GPIO is found"); printf(_valueGPIO); printf("\n");
gpio = std::string(_valueGPIO);
}
if (httpd_query_key_value(_query, "Status", _valueStatus, 30) == ESP_OK)
{
printf("Status is found"); printf(_valueStatus); printf("\n");
status = std::string(_valueStatus);
}
};
status = toUpper(status);
if (!(status == "HIGH") && !(status == "LOW"))
{
zw = "Status not valid: " + status;;
httpd_resp_sendstr_chunk(req, zw.c_str());
httpd_resp_sendstr_chunk(req, NULL);
return ESP_OK;
}
gpionum = stoi(gpio);
// frei: 16; 12-15; 2; 4 // nur 12 und 13 funktionieren 2: reboot, 4: BlitzLED, 14/15: DMA für SDKarte ???
switch (gpionum) {
case 12:
gpio_num = GPIO_NUM_12;
break;
case 13:
gpio_num = GPIO_NUM_13;
break;
default:
zw = "GPIO" + std::to_string(gpionum) + " not support - only 12 & 13 free";
httpd_resp_sendstr_chunk(req, zw.c_str());
httpd_resp_sendstr_chunk(req, NULL);
return ESP_OK;
}
if (status == "HIGH")
gpio_set_level(gpio_num, 1);
else
gpio_set_level(gpio_num, 0);
zw = "GPIO" + std::to_string(gpionum) + " switched to " + status;
httpd_resp_sendstr_chunk(req, zw.c_str());
httpd_resp_sendstr_chunk(req, NULL);
return ESP_OK;
};
void initGPIO()
{
gpio_config_t io_conf;
//disable interrupt
io_conf.intr_type = GPIO_INTR_DISABLE;
//set as output mode
io_conf.mode = GPIO_MODE_OUTPUT;
//bit mask of the pins that you want to set,e.g.GPIO18/19
// io_conf.pin_bit_mask = ((1ULL<<GPIO_OUTPUT_IO_0) | (1ULL<<GPIO_OUTPUT_IO_1));
// io_conf.pin_bit_mask = ((1ULL << GPIO_NUM_12) | (1ULL << GPIO_NUM_2) | (1ULL << GPIO_NUM_4) | (1ULL << GPIO_NUM_12) | (1ULL << GPIO_NUM_13) | (1ULL << GPIO_NUM_14) | (1ULL << GPIO_NUM_15));
io_conf.pin_bit_mask = ((1ULL << GPIO_NUM_12) | (1ULL << GPIO_NUM_13));
//disable pull-down mode
io_conf.pull_down_en = (gpio_pulldown_t) 0;
//disable pull-up mode
io_conf.pull_up_en = (gpio_pullup_t) 0;
//configure GPIO with the given settings
gpio_config(&io_conf);
}
void register_server_GPIO_uri(httpd_handle_t server)
{
ESP_LOGI(TAGPARTGPIO, "server_GPIO - Registering URI handlers");
httpd_uri_t camuri = { };
camuri.method = HTTP_GET;
camuri.uri = "/GPIO";
camuri.handler = handler_switch_GPIO;
camuri.user_ctx = (void*) "switch GPIO";
httpd_register_uri_handler(server, &camuri);
initGPIO();
}

View File

@@ -0,0 +1,10 @@
#include <esp_log.h>
#include <esp_http_server.h>
//#include "ClassControllCamera.h"
static const char *TAGPARTGPIO = "server_GPIO";
void register_server_GPIO_uri(httpd_handle_t server);

View File

@@ -1,4 +1,5 @@
#include "ClassControllCamera.h"
#include "ClassLogFile.h"
#include <stdio.h>
#include "driver/gpio.h"
@@ -6,34 +7,11 @@
#include "esp_log.h"
#include "Helper.h"
#include "CFindTemplate.h"
#include "CImageBasis.h"
// #include "camera_define.h"
/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
#define BOARD_ESP32CAM_AITHINKER
/**
* 2. Kconfig setup
*
* If you have a Kconfig file, copy the content from
* https://github.com/espressif/esp32-camera/blob/master/Kconfig into it.
* In case you haven't, copy and paste this Kconfig file inside the src directory.
* This Kconfig file has definitions that allows more control over the camera and
* how it will be initialized.
*/
/**
* 3. Enable PSRAM on sdkconfig:
*
* CONFIG_ESP32_SPIRAM_SUPPORT=y
*
* More info on
* https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/kconfig.html#config-esp32-spiram-support
*/
// ================================ CODE ======================================
#include <esp_event_loop.h>
#include <esp_log.h>
@@ -47,31 +25,10 @@
#include "esp_camera.h"
// WROVER-KIT PIN Map
#ifdef BOARD_WROVER_KIT
// #define DEBUG_DETAIL_ON
#define CAM_PIN_PWDN -1 //power down is not used
#define CAM_PIN_RESET -1 //software reset will be performed
#define CAM_PIN_XCLK 21
#define CAM_PIN_SIOD 26
#define CAM_PIN_SIOC 27
#define CAM_PIN_D7 35
#define CAM_PIN_D6 34
#define CAM_PIN_D5 39
#define CAM_PIN_D4 36
#define CAM_PIN_D3 19
#define CAM_PIN_D2 18
#define CAM_PIN_D1 5
#define CAM_PIN_D0 4
#define CAM_PIN_VSYNC 25
#define CAM_PIN_HREF 23
#define CAM_PIN_PCLK 22
#endif
// ESP32Cam (AiThinker) PIN Map
#ifdef BOARD_ESP32CAM_AITHINKER
#define CAM_PIN_PWDN (gpio_num_t) 32
#define CAM_PIN_RESET -1 //software reset will be performed
@@ -91,8 +48,6 @@
#define CAM_PIN_HREF 23
#define CAM_PIN_PCLK 22
#endif
static const char *TAG = "example:take_picture";
static camera_config_t camera_config = {
@@ -115,12 +70,14 @@ static camera_config_t camera_config = {
.pin_pclk = CAM_PIN_PCLK,
//XCLK 20MHz or 10MHz for OV2640 double FPS (Experimental)
.xclk_freq_hz = 20000000,
// .xclk_freq_hz = 20000000, // Orginalwert
.xclk_freq_hz = 5000000, // Test, um die Bildfehler los zu werden !!!!
.ledc_timer = LEDC_TIMER_0,
.ledc_channel = LEDC_CHANNEL_0,
.pixel_format = PIXFORMAT_JPEG, //YUV422,GRAYSCALE,RGB565,JPEG
.frame_size = FRAMESIZE_UXGA, //QQVGA-UXGA Do not use sizes above QVGA when not JPEG
.frame_size = FRAMESIZE_VGA, //QQVGA-UXGA Do not use sizes above QVGA when not JPEG
// .frame_size = FRAMESIZE_UXGA, //QQVGA-UXGA Do not use sizes above QVGA when not JPEG
@@ -128,15 +85,13 @@ static camera_config_t camera_config = {
.fb_count = 1 //if more than one, i2s runs in continuous mode. Use only with JPEG
};
/////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////
#include "driver/ledc.h"
CCamera Camera;
#define FLASH_GPIO GPIO_NUM_4
#define BLINK_GPIO GPIO_NUM_33
typedef struct {
httpd_req_t *req;
@@ -144,8 +99,6 @@ typedef struct {
} jpg_chunking_t;
///////////////////////////////////////////////////////////////////////////////////////////////////////
#define LEDC_LS_CH2_GPIO (4)
#define LEDC_LS_CH2_CHANNEL LEDC_CHANNEL_2
#define LEDC_LS_TIMER LEDC_TIMER_1
@@ -171,14 +124,6 @@ void test(){
////////////////////////////////////////////////////////////////////////////////////////////////////////
static size_t jpg_encode_stream(void * arg, size_t index, const void* data, size_t len){
jpg_chunking_t *j = (jpg_chunking_t *)arg;
if(!index){
@@ -199,14 +144,145 @@ void CCamera::SetQualitySize(int qual, framesize_t resol)
s->set_framesize(s, resol);
ActualResolution = resol;
ActualQuality = qual;
if (resol == FRAMESIZE_QVGA)
{
image_height = 240;
image_width = 320;
}
if (resol == FRAMESIZE_VGA)
{
image_height = 480;
image_width = 640;
}
// No higher Mode than VGA, damit der Kameraspeicher ausreicht.
/*
if (resol == FRAMESIZE_SVGA)
{
image_height = 600;
image_width = 800;
}
if (resol == FRAMESIZE_XGA)
{
image_height = 768;
image_width = 1024;
}
if (resol == FRAMESIZE_SXGA)
{
image_height = 1024;
image_width = 1280;
}
if (resol == FRAMESIZE_UXGA)
{
image_height = 1200;
image_width = 1600;
}
*/
}
esp_err_t CCamera::CaptureToBasisImage(CImageBasis *_Image, int delay)
{
string ftype;
uint8_t *zwischenspeicher = NULL;
LEDOnOff(true);
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("CCamera::CaptureToBasisImage - Start");
#endif
if (delay > 0)
{
LightOnOff(true);
const TickType_t xDelay = delay / portTICK_PERIOD_MS;
vTaskDelay( xDelay );
}
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("CCamera::CaptureToBasisImage - After LightOn");
#endif
camera_fb_t * fb = esp_camera_fb_get();
if (!fb) {
ESP_LOGE(TAGCAMERACLASS, "Camera Capture Failed");
LEDOnOff(false);
return ESP_FAIL;
}
int _size = fb->len;
zwischenspeicher = (uint8_t*) malloc(_size);
for (int i = 0; i < _size; ++i)
*(zwischenspeicher + i) = *(fb->buf + i);
esp_camera_fb_return(fb);
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("CCamera::CaptureToBasisImage - After fb_get");
#endif
LEDOnOff(false);
if (delay > 0)
LightOnOff(false);
// TickType_t xDelay = 1000 / portTICK_PERIOD_MS;
// vTaskDelay( xDelay ); // wait for power to recover
uint8_t * buf = NULL;
CImageBasis _zwImage;
_zwImage.LoadFromMemory(zwischenspeicher, _size);
free(zwischenspeicher);
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("CCamera::CaptureToBasisImage - After LoadFromMemory");
#endif
stbi_uc* p_target;
stbi_uc* p_source;
int channels = 3;
int width = image_width;
int height = image_height;
#ifdef DEBUG_DETAIL_ON
std::string _zw = "Targetimage: " + std::to_string((int) _Image->rgb_image) + " Size: " + std::to_string(_Image->width) + ", " + std::to_string(_Image->height);
_zw = _zw + " _zwImage: " + std::to_string((int) _zwImage.rgb_image) + " Size: " + std::to_string(_zwImage.width) + ", " + std::to_string(_zwImage.height);
LogFile.WriteToFile(_zw);
#endif
for (int x = 0; x < width; ++x)
for (int y = 0; y < height; ++y)
{
p_target = _Image->rgb_image + (channels * (y * width + x));
p_source = _zwImage.rgb_image + (channels * (y * width + x));
p_target[0] = p_source[0];
p_target[1] = p_source[1];
p_target[2] = p_source[2];
}
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("CCamera::CaptureToBasisImage - After Copy To Target");
#endif
free(buf);
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("CCamera::CaptureToBasisImage - Done");
#endif
return ESP_OK;
}
esp_err_t CCamera::CaptureToFile(std::string nm, int delay)
{
// nm = "/sdcard/josef_zw.bmp";
string ftype;
LEDOnOff(true); // Abgeschaltet, um Strom zu sparen !!!!!!
if (delay > 0)
{
LightOnOff(true);
@@ -217,14 +293,26 @@ esp_err_t CCamera::CaptureToFile(std::string nm, int delay)
camera_fb_t * fb = esp_camera_fb_get();
if (!fb) {
ESP_LOGE(TAGCAMERACLASS, "Camera Capture Failed");
LEDOnOff(false);
return ESP_FAIL;
}
LEDOnOff(false);
#ifdef DEBUG_DETAIL_ON
printf("w %d, h %d, size %d\n", fb->width, fb->height, fb->len);
#endif
nm = FormatFileName(nm);
#ifdef DEBUG_DETAIL_ON
printf("Save Camera to : %s\n", nm.c_str());
#endif
ftype = toUpper(getFileType(nm));
#ifdef DEBUG_DETAIL_ON
printf("Filetype: %s\n", ftype.c_str());
#endif
uint8_t * buf = NULL;
size_t buf_len = 0;
@@ -249,7 +337,7 @@ esp_err_t CCamera::CaptureToFile(std::string nm, int delay)
}
}
FILE * fp = fopen(nm.c_str(), "wb");
FILE * fp = OpenFileAndWait(nm.c_str(), "wb");
if (fp == NULL) /* If an error occurs during the file creation */
{
fprintf(stderr, "fopen() failed for '%s'\n", nm.c_str());
@@ -280,15 +368,29 @@ esp_err_t CCamera::CaptureToHTTP(httpd_req_t *req, int delay)
size_t fb_len = 0;
int64_t fr_start = esp_timer_get_time();
LEDOnOff(true);
if (delay > 0)
{
LightOnOff(true);
const TickType_t xDelay = delay / portTICK_PERIOD_MS;
vTaskDelay( xDelay );
}
fb = esp_camera_fb_get();
if (!fb) {
ESP_LOGE(TAGCAMERACLASS, "Camera capture failed");
httpd_resp_send_500(req);
return ESP_FAIL;
}
LEDOnOff(false);
res = httpd_resp_set_type(req, "image/jpeg");
if(res == ESP_OK){
res = httpd_resp_set_hdr(req, "Content-Disposition", "inline; filename=capture.jpg");
res = httpd_resp_set_hdr(req, "Content-Disposition", "inline; filename=raw.jpg");
}
if(res == ESP_OK){
@@ -306,6 +408,12 @@ esp_err_t CCamera::CaptureToHTTP(httpd_req_t *req, int delay)
int64_t fr_end = esp_timer_get_time();
ESP_LOGI(TAGCAMERACLASS, "JPG: %uKB %ums", (uint32_t)(fb_len/1024), (uint32_t)((fr_end - fr_start)/1000));
if (delay > 0)
{
LightOnOff(false);
}
return res;
}
@@ -322,6 +430,20 @@ void CCamera::LightOnOff(bool status)
gpio_set_level(FLASH_GPIO, 0);
}
void CCamera::LEDOnOff(bool status)
{
// Init the GPIO
gpio_pad_select_gpio(BLINK_GPIO);
/* Set the GPIO as a push/pull output */
gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT);
if (!status)
gpio_set_level(BLINK_GPIO, 1);
else
gpio_set_level(BLINK_GPIO, 0);
}
void CCamera::GetCameraParameter(httpd_req_t *req, int &qual, framesize_t &resol)
{
char _query[100];
@@ -337,7 +459,9 @@ void CCamera::GetCameraParameter(httpd_req_t *req, int &qual, framesize_t &resol
printf("Query: "); printf(_query); printf("\n");
if (httpd_query_key_value(_query, "size", _size, 10) == ESP_OK)
{
#ifdef DEBUG_DETAIL_ON
printf("Size: "); printf(_size); printf("\n");
#endif
if (strcmp(_size, "QVGA") == 0)
resol = FRAMESIZE_QVGA; // 320x240
if (strcmp(_size, "VGA") == 0)
@@ -349,11 +473,13 @@ void CCamera::GetCameraParameter(httpd_req_t *req, int &qual, framesize_t &resol
if (strcmp(_size, "SXGA") == 0)
resol = FRAMESIZE_SXGA; // 1280x1024
if (strcmp(_size, "UXGA") == 0)
resol = FRAMESIZE_UXGA; // 1600x1200
resol = FRAMESIZE_UXGA; // 1600x1200
}
if (httpd_query_key_value(_query, "quality", _qual, 10) == ESP_OK)
{
#ifdef DEBUG_DETAIL_ON
printf("Quality: "); printf(_qual); printf("\n");
#endif
qual = atoi(_qual);
if (qual > 63)
@@ -384,13 +510,13 @@ framesize_t CCamera::TextToFramesize(const char * _size)
CCamera::CCamera()
{
#ifdef DEBUG_DETAIL_ON
printf("CreateClassCamera\n");
#endif
}
esp_err_t CCamera::InitCam()
{
printf("Init Flash\n");
//power up the camera if PWDN pin is defined
if(CAM_PIN_PWDN != -1){
// Init the GPIO
gpio_pad_select_gpio(CAM_PIN_PWDN);

View File

@@ -10,6 +10,7 @@
#include "esp_camera.h"
#include <string>
#include <esp_http_server.h>
#include "CImageBasis.h"
#define CAMERA_MODEL_AI_THINKER
@@ -24,23 +25,24 @@ class CCamera {
framesize_t ActualResolution;
public:
int image_height, image_width;
CCamera();
esp_err_t InitCam();
void LightOnOff(bool status);
void LEDOnOff(bool status);
esp_err_t CaptureToHTTP(httpd_req_t *req, int delay = 0);
void SetQualitySize(int qual, framesize_t resol);
void GetCameraParameter(httpd_req_t *req, int &qual, framesize_t &resol);
framesize_t TextToFramesize(const char * text);
esp_err_t CaptureToFile(std::string nm, int delay = 0);
esp_err_t CaptureToBasisImage(CImageBasis *_Image, int delay = 0);
};
extern CCamera Camera;
#endif

View File

@@ -11,6 +11,9 @@
#define SCRATCH_BUFSIZE2 8192
char scratch2[SCRATCH_BUFSIZE2];
//#define DEBUG_DETAIL_ON
void PowerResetCamera(){
ESP_LOGD(TAGPARTCAMERA, "Resetting camera by power down line");
@@ -29,43 +32,72 @@ void PowerResetCamera(){
esp_err_t handler_lightOn(httpd_req_t *req)
{
LogFile.WriteToFile("handler_lightOn");
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_lightOn - Start");
printf("handler_lightOn uri:\n"); printf(req->uri); printf("\n");
#endif
Camera.LightOnOff(true);
const char* resp_str = (const char*) req->user_ctx;
httpd_resp_send(req, resp_str, strlen(resp_str));
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_lightOn - Done");
#endif
return ESP_OK;
};
esp_err_t handler_lightOff(httpd_req_t *req)
{
LogFile.WriteToFile("handler_lightOff");
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_lightOff - Start");
printf("handler_lightOff uri:\n"); printf(req->uri); printf("\n");
#endif
Camera.LightOnOff(false);
const char* resp_str = (const char*) req->user_ctx;
httpd_resp_send(req, resp_str, strlen(resp_str));
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_lightOff - Done");
#endif
return ESP_OK;
};
esp_err_t handler_capture(httpd_req_t *req)
{
LogFile.WriteToFile("handler_capture");
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_capture - Start");
#endif
int quality;
framesize_t res;
Camera.GetCameraParameter(req, quality, res);
#ifdef DEBUG_DETAIL_ON
printf("Size: %d", res); printf(" Quality: %d\n", quality);
#endif
Camera.SetQualitySize(quality, res);
esp_err_t ressult;
ressult = Camera.CaptureToHTTP(req);
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_capture - Done");
#endif
return ressult;
};
esp_err_t handler_capture_with_ligth(httpd_req_t *req)
{
LogFile.WriteToFile("handler_capture_with_ligth");
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_capture_with_ligth - Start");
#endif
char _query[100];
char _delay[10];
@@ -78,7 +110,9 @@ esp_err_t handler_capture_with_ligth(httpd_req_t *req)
printf("Query: "); printf(_query); printf("\n");
if (httpd_query_key_value(_query, "delay", _delay, 10) == ESP_OK)
{
#ifdef DEBUG_DETAIL_ON
printf("Delay: "); printf(_delay); printf("\n");
#endif
delay = atoi(_delay);
if (delay < 0)
@@ -87,9 +121,12 @@ esp_err_t handler_capture_with_ligth(httpd_req_t *req)
};
Camera.GetCameraParameter(req, quality, res);
printf("Size: %d", res); printf(" Quality: %d\n", quality);
Camera.SetQualitySize(quality, res);
#ifdef DEBUG_DETAIL_ON
printf("Size: %d", res); printf(" Quality: %d\n", quality);
#endif
Camera.SetQualitySize(quality, res);
Camera.LightOnOff(true);
const TickType_t xDelay = delay / portTICK_PERIOD_MS;
vTaskDelay( xDelay );
@@ -99,6 +136,10 @@ esp_err_t handler_capture_with_ligth(httpd_req_t *req)
Camera.LightOnOff(false);
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_capture_with_ligth - Done");
#endif
return ressult;
};
@@ -106,7 +147,10 @@ esp_err_t handler_capture_with_ligth(httpd_req_t *req)
esp_err_t handler_capture_save_to_file(httpd_req_t *req)
{
LogFile.WriteToFile("handler_capture_save_to_file");
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_capture_save_to_file - Start");
#endif
char _query[100];
char _delay[10];
int delay = 0;
@@ -123,14 +167,18 @@ esp_err_t handler_capture_save_to_file(httpd_req_t *req)
if (httpd_query_key_value(_query, "filename", filename, 100) == ESP_OK)
{
fn.append(filename);
#ifdef DEBUG_DETAIL_ON
printf("Filename: "); printf(fn.c_str()); printf("\n");
#endif
}
else
fn.append("noname.jpg");
if (httpd_query_key_value(_query, "delay", _delay, 10) == ESP_OK)
{
#ifdef DEBUG_DETAIL_ON
printf("Delay: "); printf(_delay); printf("\n");
#endif
delay = atoi(_delay);
if (delay < 0)
@@ -142,7 +190,9 @@ esp_err_t handler_capture_save_to_file(httpd_req_t *req)
fn.append("noname.jpg");
Camera.GetCameraParameter(req, quality, res);
#ifdef DEBUG_DETAIL_ON
printf("Size: %d", res); printf(" Quality: %d\n", quality);
#endif
Camera.SetQualitySize(quality, res);
esp_err_t ressult;
@@ -151,6 +201,10 @@ esp_err_t handler_capture_save_to_file(httpd_req_t *req)
const char* resp_str = (const char*) fn.c_str();
httpd_resp_send(req, resp_str, strlen(resp_str));
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_capture_save_to_file - Done");
#endif
return ressult;
};
@@ -158,7 +212,9 @@ esp_err_t handler_capture_save_to_file(httpd_req_t *req)
void register_server_camera_uri(httpd_handle_t server)
{
#ifdef DEBUG_DETAIL_ON
ESP_LOGI(TAGPARTCAMERA, "server_part_camera - Registering URI handlers");
#endif
httpd_uri_t camuri = { };
camuri.method = HTTP_GET;

View File

@@ -65,21 +65,6 @@ static esp_err_t index_html_get_handler(httpd_req_t *req)
return ESP_OK;
}
/* Handler to respond with an icon file embedded in flash.
* Browsers expect to GET website icon at URI /favicon.ico.
* This can be overridden by uploading file with same name */
static esp_err_t favicon_get_handler(httpd_req_t *req)
{
extern const unsigned char favicon_ico_start[] asm("_binary_favicon_ico_start");
extern const unsigned char favicon_ico_end[] asm("_binary_favicon_ico_end");
const size_t favicon_ico_size = (favicon_ico_end - favicon_ico_start);
httpd_resp_set_type(req, "image/x-icon");
httpd_resp_send(req, (const char *)favicon_ico_start, favicon_ico_size);
/* Respond with an empty chunk to signal HTTP response completion */
httpd_resp_send_chunk(req, NULL, 0);
return ESP_OK;
}
/* Send HTTP response with a run-time generated html consisting of
* a list of all files and folders under the requested path.
* In case of SPIFFS this returns empty list when path is any
@@ -121,7 +106,7 @@ static esp_err_t http_resp_dir_html(httpd_req_t *req, const char *dirpath, const
/////////////////////////////////////////////////
if (!readonly) {
FILE *fd = fopen("/sdcard/html/upload_script.html", "r");
FILE *fd = OpenFileAndWait("/sdcard/html/upload_script.html", "r");
char *chunk = ((struct file_server_data *)req->user_ctx)->scratch;
size_t chunksize;
do {
@@ -231,7 +216,7 @@ static esp_err_t logfileact_get_handler(httpd_req_t *req)
std::string currentfilename = LogFile.GetCurrentFileName();
fd = fopen(currentfilename.c_str(), "r");
fd = OpenFileAndWait(currentfilename.c_str(), "r");
if (!fd) {
ESP_LOGE(TAG, "Failed to read existing file : %s", filepath);
/* Respond with 500 Internal Server Error */
@@ -337,7 +322,7 @@ static esp_err_t download_get_handler(httpd_req_t *req)
return ESP_FAIL;
}
fd = fopen(filepath, "r");
fd = OpenFileAndWait(filepath, "r");
if (!fd) {
ESP_LOGE(TAG, "Failed to read existing file : %s", filepath);
/* Respond with 500 Internal Server Error */
@@ -424,7 +409,7 @@ static esp_err_t upload_post_handler(httpd_req_t *req)
return ESP_FAIL;
}
fd = fopen(filepath, "w");
fd = OpenFileAndWait(filepath, "w");
if (!fd) {
ESP_LOGE(TAG, "Failed to create file : %s", filepath);
/* Respond with 500 Internal Server Error */
@@ -710,7 +695,7 @@ void unzip(std::string _in_zip_file, std::string _target_directory){
zw = std::string(archive_filename);
zw = _target_directory + zw;
printf("Filename to extract: %s", zw.c_str());
FILE* fpTargetFile = fopen(zw.c_str(), "wb");
FILE* fpTargetFile = OpenFileAndWait(zw.c_str(), "wb");
fwrite(p, 1, (uint)uncomp_size, fpTargetFile);
fclose(fpTargetFile);

View File

@@ -10,6 +10,8 @@
#include "esp_err.h"
#include "esp_log.h"
#include "Helper.h"
#include "esp_http_server.h"
@@ -23,9 +25,9 @@ char scratch[SCRATCH_BUFSIZE];
(strcasecmp(&filename[strlen(filename) - sizeof(ext) + 1], ext) == 0)
esp_err_t send_file(httpd_req_t *req, std::string filename, struct stat * file_stat)
esp_err_t send_file(httpd_req_t *req, std::string filename)
{
FILE *fd = fopen(filename.c_str(), "r");
FILE *fd = OpenFileAndWait(filename.c_str(), "r");
if (!fd) {
ESP_LOGE(TAG, "Failed to read existing file : %s", filename.c_str());
/* Respond with 500 Internal Server Error */
@@ -33,7 +35,7 @@ esp_err_t send_file(httpd_req_t *req, std::string filename, struct stat * file_
return ESP_FAIL;
}
ESP_LOGI(TAG, "Sending file : %s (%ld bytes)...", filename.c_str(), file_stat->st_size);
ESP_LOGI(TAG, "Sending file : %s ...", filename.c_str());
set_content_type_from_file(req, filename.c_str());
/* Retrieve the pointer to scratch buffer for temporary storage */
@@ -65,6 +67,7 @@ esp_err_t send_file(httpd_req_t *req, std::string filename, struct stat * file_
/* Copies the full path into destination buffer and returns
* pointer to path (skipping the preceding base path) */
const char* get_path_from_uri(char *dest, const char *base_path, const char *uri, size_t destsize)

View File

@@ -5,6 +5,6 @@
const char* get_path_from_uri(char *dest, const char *base_path, const char *uri, size_t destsize);
esp_err_t send_file(httpd_req_t *req, std::string filename, struct stat * file_stat);
esp_err_t send_file(httpd_req_t *req, std::string filename);
esp_err_t set_content_type_from_file(httpd_req_t *req, const char *filename);

View File

@@ -31,6 +31,10 @@
#include "ClassLogFile.h"
#include "Helper.h"
// #define DEBUG_DETAIL_ON
#define BUFFSIZE 1024
@@ -89,7 +93,7 @@ static bool ota_example_task(std::string fn)
int data_read;
FILE* f = fopen(fn.c_str(), "rb"); // vorher nur "r"
FILE* f = OpenFileAndWait(fn.c_str(), "rb"); // vorher nur "r"
data_read = fread(ota_write_data, 1, BUFFSIZE, f);
while (data_read > 0) {
@@ -301,6 +305,10 @@ void CheckOTAUpdate(void)
esp_err_t handler_ota_update(httpd_req_t *req)
{
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_ota_update - Start");
#endif
LogFile.WriteToFile("handler_ota_update");
char _query[200];
char _filename[30];
@@ -377,6 +385,10 @@ esp_err_t handler_ota_update(httpd_req_t *req)
httpd_resp_send(req, resp_str, strlen(resp_str));
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_ota_update - Done");
#endif
return ESP_OK;
};
@@ -412,6 +424,10 @@ void doReboot(){
esp_err_t handler_reboot(httpd_req_t *req)
{
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_reboot - Start");
#endif
LogFile.WriteToFile("handler_reboot");
ESP_LOGI(TAGPARTOTA, "!!! System will restart within 5 sec!!!");
const char* resp_str = "!!! System will restart within 5 sec!!!";
@@ -419,6 +435,10 @@ esp_err_t handler_reboot(httpd_req_t *req)
doReboot();
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_reboot - Done");
#endif
return ESP_OK;
}

View File

@@ -9,3 +9,4 @@ static const char *TAGPARTOTA = "server_ota";
void register_server_ota_sdcard_uri(httpd_handle_t server);
void CheckOTAUpdate();
void doReboot();

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_fileserver_ota)
REQUIRES jomjol_tfliteclass jomjol_helper jomjol_controlcamera jomjol_mqtt jomjol_fileserver_ota jomjol_image_proc connect_wlan)

View File

@@ -9,9 +9,12 @@
void ClassFlow::SetInitialParameter(void)
{
ListFlowControll = NULL;
previousElement = NULL;
disabled = false;
}
//std::vector<string> ClassFlow::ZerlegeZeile(std::string input, std::string delimiter);
std::vector<string> ClassFlow::ZerlegeZeile(std::string input, std::string delimiter)
{
@@ -37,16 +40,18 @@ std::vector<string> ClassFlow::ZerlegeZeile(std::string input, std::string delim
bool ClassFlow::isNewParagraph(string input)
{
if (input[0] == '[')
if ((input[0] == '[') || ((input[0] == ';') && (input[1] == '[')))
{
return true;
}
return false;
}
bool ClassFlow::GetNextParagraph(FILE* pfile, string& aktparamgraph)
{
while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph));
while (getNextLine(pfile, &aktparamgraph) && !isNewParagraph(aktparamgraph));
if (this->isNewParagraph(aktparamgraph))
if (isNewParagraph(aktparamgraph))
return true;
return false;
}
@@ -55,7 +60,6 @@ bool ClassFlow::GetNextParagraph(FILE* pfile, string& aktparamgraph)
ClassFlow::ClassFlow(void)
{
SetInitialParameter();
ListFlowControll = NULL;
}
ClassFlow::ClassFlow(std::vector<ClassFlow*> * lfc)
@@ -64,6 +68,13 @@ ClassFlow::ClassFlow(std::vector<ClassFlow*> * lfc)
ListFlowControll = lfc;
}
ClassFlow::ClassFlow(std::vector<ClassFlow*> * lfc, ClassFlow *_prev)
{
SetInitialParameter();
ListFlowControll = lfc;
previousElement = _prev;
}
bool ClassFlow::ReadParameter(FILE* pfile, string &aktparamgraph)
{
return false;
@@ -100,7 +111,7 @@ bool ClassFlow::getNextLine(FILE* pfile, string *rt)
}
*rt = zw;
*rt = trim(*rt);
while (zw[0] == '#' || (rt->size() == 0)) // Kommentarzeilen und Leerzeilen überspringen
while ((zw[0] == ';' || zw[0] == '#' || (rt->size() == 0)) && !(zw[1] == '[')) // Kommentarzeilen (; oder #) und Leerzeilen überspringen, es sei denn es ist ein neuer auskommentierter Paragraph
{
fgets(zw, 1024, pfile);
printf("%s", zw);

View File

@@ -5,7 +5,7 @@
#include <vector>
#include "Helper.h"
#include "CFindTemplate.h"
#include "CImageBasis.h"
using namespace std;
@@ -16,7 +16,10 @@ using namespace std;
struct HTMLInfo
{
float val;
CImageBasis *image = NULL;
CImageBasis *image_org = NULL;
std::string filename;
std::string filename_org;
};
@@ -24,18 +27,23 @@ class ClassFlow
{
protected:
// std::vector<string> ZerlegeZeile(string input);
std::vector<string> ZerlegeZeile(string input, string delimiter = " =, ");
std::vector<string> ZerlegeZeile(string input, string delimiter = " =, \t");
bool isNewParagraph(string input);
bool GetNextParagraph(FILE* pfile, string& aktparamgraph);
bool getNextLine(FILE* pfile, string* rt);
std::vector<ClassFlow*>* ListFlowControll;
ClassFlow *previousElement;
virtual void SetInitialParameter(void);
bool disabled;
public:
ClassFlow(void);
ClassFlow(std::vector<ClassFlow*> * lfc);
ClassFlow(std::vector<ClassFlow*> * lfc, ClassFlow *_prev);
virtual bool ReadParameter(FILE* pfile, string &aktparamgraph);
virtual bool doFlow(string time);
virtual string getHTMLSingleStep(string host);

View File

@@ -1,32 +1,64 @@
#include "ClassFlowAlignment.h"
#include "ClassFlowMakeImage.h"
#include "ClassFlow.h"
#include "CRotateImage.h"
#include "ClassLogFile.h"
ClassFlowAlignment::ClassFlowAlignment()
bool AlignmentExtendedDebugging = true;
// #define DEBUG_DETAIL_ON
void ClassFlowAlignment::SetInitialParameter(void)
{
initalrotate = 0;
anz_ref = 0;
suchex = 40;
suchey = 40;
initialmirror = false;
SaveAllFiles = false;
namerawimage = "/sdcard/img_tmp/raw.jpg";
FileStoreRefAlignment = "/sdcard/config/align.txt";
ListFlowControll = NULL;
AlignAndCutImage = NULL;
ImageBasis = NULL;
ImageTMP = NULL;
previousElement = NULL;
disabled = false;
SAD_criteria = 0.05;
}
ClassFlowAlignment::ClassFlowAlignment(std::vector<ClassFlow*>* lfc)
{
initalrotate = 0;
anz_ref = 0;
suchex = 40;
suchey = 40;
initialmirror = false;
namerawimage = "/sdcard/img_tmp/raw.jpg";
SetInitialParameter();
ListFlowControll = lfc;
for (int i = 0; i < ListFlowControll->size(); ++i)
{
if (((*ListFlowControll)[i])->name().compare("ClassFlowMakeImage") == 0)
{
ImageBasis = ((ClassFlowMakeImage*) (*ListFlowControll)[i])->rawImage;
}
}
if (!ImageBasis) // die Funktion Bilder aufnehmen existiert nicht --> muss erst erzeugt werden NUR ZU TESTZWECKEN
{
if (AlignmentExtendedDebugging) printf("CImageBasis musste erzeugt werden\n");
ImageBasis = new CImageBasis(namerawimage);
}
}
bool ClassFlowAlignment::ReadParameter(FILE* pfile, string& aktparamgraph)
{
std::vector<string> zerlegt;
int suchex = 40;
int suchey = 40;
int alg_algo = 0;
aktparamgraph = trim(aktparamgraph);
@@ -39,32 +71,64 @@ bool ClassFlowAlignment::ReadParameter(FILE* pfile, string& aktparamgraph)
while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph))
{
zerlegt = this->ZerlegeZeile(aktparamgraph);
if ((zerlegt[0] == "InitialMirror") && (zerlegt.size() > 1))
zerlegt = ZerlegeZeile(aktparamgraph);
if ((toUpper(zerlegt[0]) == "INITIALMIRROR") && (zerlegt.size() > 1))
{
if (toUpper(zerlegt[1]) == "TRUE")
initialmirror = true;
}
if (((zerlegt[0] == "InitalRotate") || (zerlegt[0] == "InitialRotate")) && (zerlegt.size() > 1))
if (((toUpper(zerlegt[0]) == "INITALROTATE") || (toUpper(zerlegt[0]) == "INITIALROTATE")) && (zerlegt.size() > 1))
{
this->initalrotate = std::stod(zerlegt[1]);
}
if ((zerlegt[0] == "SearchFieldX") && (zerlegt.size() > 1))
if ((toUpper(zerlegt[0]) == "SEARCHFIELDX") && (zerlegt.size() > 1))
{
this->suchex = std::stod(zerlegt[1]);
suchex = std::stod(zerlegt[1]);
}
if ((zerlegt[0] == "SearchFieldY") && (zerlegt.size() > 1))
if ((toUpper(zerlegt[0]) == "SEARCHFIELDY") && (zerlegt.size() > 1))
{
this->suchey = std::stod(zerlegt[1]);
suchey = std::stod(zerlegt[1]);
}
if ((zerlegt.size() == 3) && (anz_ref < 2))
{
this->reffilename[anz_ref] = FormatFileName("/sdcard" + zerlegt[0]);
this->ref_x[anz_ref] = std::stod(zerlegt[1]);
this->ref_y[anz_ref] = std::stod(zerlegt[2]);
References[anz_ref].image_file = FormatFileName("/sdcard" + zerlegt[0]);
References[anz_ref].target_x = std::stod(zerlegt[1]);
References[anz_ref].target_y = std::stod(zerlegt[2]);
anz_ref++;
}
if ((toUpper(zerlegt[0]) == "SAVEALLFILES") && (zerlegt.size() > 1))
{
if (toUpper(zerlegt[1]) == "TRUE")
SaveAllFiles = true;
}
if ((toUpper(zerlegt[0]) == "ALIGNMENTALGO") && (zerlegt.size() > 1))
{
#ifdef DEBUG_DETAIL_ON
std::string zw2 = "Alignmentmodus gewählt: " + zerlegt[1];
LogFile.WriteToFile(zw2);
#endif
if (toUpper(zerlegt[1]) == "HIGHACCURACY")
alg_algo = 1;
if (toUpper(zerlegt[1]) == "FAST")
alg_algo = 2;
}
}
for (int i = 0; i < anz_ref; ++i)
{
References[i].search_x = suchex;
References[i].search_y = suchey;
References[i].fastalg_SAD_criteria = SAD_criteria;
References[i].alignment_algo = alg_algo;
#ifdef DEBUG_DETAIL_ON
std::string zw2 = "Alignmentmodus geschrieben: " + std::to_string(alg_algo);
LogFile.WriteToFile(zw2);
#endif
}
LoadReferenceAlignmentValues();
return true;
}
@@ -82,70 +146,178 @@ string ClassFlowAlignment::getHTMLSingleStep(string host)
bool ClassFlowAlignment::doFlow(string time)
{
string input = namerawimage;
string output = "/sdcard/img_tmp/rot.jpg";
string output3 = "/sdcard/img_tmp/rot_roi.jpg";
string output2 = "/sdcard/img_tmp/alg.jpg";
string output4 = "/sdcard/img_tmp/alg_roi.jpg";
string output1 = "/sdcard/img_tmp/mirror.jpg";
if (!ImageTMP)
ImageTMP = new CImageBasis(ImageBasis, 5);
input = FormatFileName(input);
output = FormatFileName(output);
output2 = FormatFileName(output2);
if (AlignAndCutImage)
delete AlignAndCutImage;
AlignAndCutImage = new CAlignAndCutImage(ImageBasis, ImageTMP);
CRotateImage rt(AlignAndCutImage, ImageTMP);
if (initialmirror){
CRotate *rt;
rt = new CRotate(input);
if (!rt->ImageOkay()){
LogFile.WriteToFile("ClassFlowAlignment::doFlow CRotate Inital Mirror raw.jpg not okay!");
delete rt;
return false;
}
printf("do mirror\n");
rt->Mirror();
rt->SaveToFile(output1);
input = output1;
delete rt;
rt.Mirror();
if (SaveAllFiles) AlignAndCutImage->SaveToFile(FormatFileName("/sdcard/img_tmp/mirror.jpg"));
}
if (initalrotate != 0)
{
CRotate *rt = NULL;
printf("Load rotationfile: %s\n", input.c_str());
rt = new CRotate(input);
if (!rt->ImageOkay()){
LogFile.WriteToFile("ClassFlowAlignment::doFlow CRotate raw.jpg not okay!");
delete rt;
return false;
}
rt->Rotate(this->initalrotate);
rt->SaveToFile(output);
delete rt;
rt.Rotate(initalrotate);
if (SaveAllFiles) AlignAndCutImage->SaveToFile(FormatFileName("/sdcard/img_tmp/rot.jpg"));
}
else
if (!AlignAndCutImage->Align(&References[0], &References[1]))
{
CopyFile(input, output);
SaveReferenceAlignmentValues();
}
CAlignAndCutImage *caic;
caic = new CAlignAndCutImage(output);
caic->Align(this->reffilename[0], this->ref_x[0], this->ref_y[0], this->reffilename[1], this->ref_x[1], this->ref_y[1], suchex, suchey, output3);
caic->SaveToFile(output2);
if (SaveAllFiles) AlignAndCutImage->SaveToFile(FormatFileName("/sdcard/img_tmp/alg.jpg"));
printf("Startwriting Output4:%s\n", output4.c_str());
if (output4.length() > 0)
if (SaveAllFiles)
{
caic->drawRect(ref_x[0], ref_y[0], caic->t0_dx, caic->t0_dy, 255, 0, 0, 2);
caic->drawRect(ref_x[1], ref_y[1], caic->t1_dx, caic->t1_dy, 255, 0, 0, 2);
caic->SaveToFile(output4);
printf("Write output4: %s\n", output4.c_str());
DrawRef(ImageTMP);
ImageTMP->SaveToFile(FormatFileName("/sdcard/img_tmp/alg_roi.jpg"));
}
delete caic;
if (ImageTMP) // nuss gelöscht werden, um Speicherplatz für das Laden von tflite zu haben
{
delete ImageTMP;
ImageTMP = NULL;
}
LoadReferenceAlignmentValues();
// Align mit Templates
return true;
}
void ClassFlowAlignment::SaveReferenceAlignmentValues()
{
FILE* pFile;
std::string zwtime, zwvalue;
pFile = fopen(FileStoreRefAlignment.c_str(), "w");
if (strlen(zwtime.c_str()) == 0)
{
time_t rawtime;
struct tm* timeinfo;
char buffer[80];
time(&rawtime);
timeinfo = localtime(&rawtime);
strftime(buffer, 80, "%Y-%m-%d_%H-%M-%S", timeinfo);
zwtime = std::string(buffer);
}
fputs(zwtime.c_str(), pFile);
fputs("\n", pFile);
zwvalue = std::to_string(References[0].fastalg_x) + "\t" + std::to_string(References[0].fastalg_y);
zwvalue = zwvalue + "\t" +std::to_string(References[0].fastalg_SAD)+ "\t" +std::to_string(References[0].fastalg_min);
zwvalue = zwvalue + "\t" +std::to_string(References[0].fastalg_max)+ "\t" +std::to_string(References[0].fastalg_avg);
fputs(zwvalue.c_str(), pFile);
fputs("\n", pFile);
zwvalue = std::to_string(References[1].fastalg_x) + "\t" + std::to_string(References[1].fastalg_y);
zwvalue = zwvalue + "\t" +std::to_string(References[1].fastalg_SAD)+ "\t" +std::to_string(References[1].fastalg_min);
zwvalue = zwvalue + "\t" +std::to_string(References[1].fastalg_max)+ "\t" +std::to_string(References[1].fastalg_avg);
fputs(zwvalue.c_str(), pFile);
fputs("\n", pFile);
fclose(pFile);
}
bool ClassFlowAlignment::LoadReferenceAlignmentValues(void)
{
FILE* pFile;
char zw[1024];
string zwvalue;
std::vector<string> zerlegt;
// LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", "LoadReferenceAlignmentValues01");
pFile = fopen(FileStoreRefAlignment.c_str(), "r");
if (pFile == NULL)
return false;
// LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", "LoadReferenceAlignmentValues01");
fgets(zw, 1024, pFile);
printf("%s", zw);
// zwvalue = "LoadReferenceAlignmentValues Time: " + std::string(zw);
// LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", zwvalue);
// LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", "LoadReferenceAlignmentValues02");
fgets(zw, 1024, pFile);
zerlegt = ZerlegeZeile(std::string(zw), " \t");
if (zerlegt.size() < 6)
{
// LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", "Exit 01");
fclose(pFile);
return false;
}
// LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", "LoadReferenceAlignmentValues03");
References[0].fastalg_x = stoi(zerlegt[0]);
References[0].fastalg_y = stoi(zerlegt[1]);
References[0].fastalg_SAD = stof(zerlegt[2]);
References[0].fastalg_min = stoi(zerlegt[3]);
References[0].fastalg_max = stoi(zerlegt[4]);
References[0].fastalg_avg = stof(zerlegt[5]);
fgets(zw, 1024, pFile);
zerlegt = ZerlegeZeile(std::string(zw));
if (zerlegt.size() < 6)
{
// LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", "Exit 02");
fclose(pFile);
return false;
}
// LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", "LoadReferenceAlignmentValues03");
References[1].fastalg_x = stoi(zerlegt[0]);
References[1].fastalg_y = stoi(zerlegt[1]);
References[1].fastalg_SAD = stof(zerlegt[2]);
References[1].fastalg_min = stoi(zerlegt[3]);
References[1].fastalg_max = stoi(zerlegt[4]);
References[1].fastalg_avg = stof(zerlegt[5]);
fclose(pFile);
#ifdef DEBUG_DETAIL_ON
std::string _zw = "\tLoadReferences[0]\tx,y:\t" + std::to_string(References[0].fastalg_x) + "\t" + std::to_string(References[0].fastalg_x);
_zw = _zw + "\tSAD, min, max, avg:\t" + std::to_string(References[0].fastalg_SAD) + "\t" + std::to_string(References[0].fastalg_min);
_zw = _zw + "\t" + std::to_string(References[0].fastalg_max) + "\t" + std::to_string(References[0].fastalg_avg);
LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", _zw);
_zw = "\tLoadReferences[1]\tx,y:\t" + std::to_string(References[1].fastalg_x) + "\t" + std::to_string(References[1].fastalg_x);
_zw = _zw + "\tSAD, min, max, avg:\t" + std::to_string(References[1].fastalg_SAD) + "\t" + std::to_string(References[1].fastalg_min);
_zw = _zw + "\t" + std::to_string(References[1].fastalg_max) + "\t" + std::to_string(References[1].fastalg_avg);
LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", _zw);
#endif
return true;
}
void ClassFlowAlignment::DrawRef(CImageBasis *_zw)
{
_zw->drawRect(References[0].target_x, References[0].target_y, References[0].width, References[0].height, 255, 0, 0, 2);
_zw->drawRect(References[1].target_x, References[1].target_y, References[1].width, References[1].height, 255, 0, 0, 2);
}

View File

@@ -2,6 +2,8 @@
#include "ClassFlow.h"
#include "Helper.h"
#include "CAlignAndCutImage.h"
#include "CFindTemplate.h"
#include <string>
@@ -13,15 +15,27 @@ class ClassFlowAlignment :
protected:
float initalrotate;
bool initialmirror;
string reffilename[2];
int ref_x[2], ref_y[2];
RefInfo References[2];
int anz_ref;
int suchex, suchey;
string namerawimage;
bool SaveAllFiles;
CAlignAndCutImage *AlignAndCutImage;
std::string FileStoreRefAlignment;
float SAD_criteria;
void SetInitialParameter(void);
bool LoadReferenceAlignmentValues(void);
void SaveReferenceAlignmentValues();
public:
ClassFlowAlignment();
CImageBasis *ImageBasis, *ImageTMP;
ClassFlowAlignment(std::vector<ClassFlow*>* lfc);
CAlignAndCutImage* GetAlignAndCutImage(){return AlignAndCutImage;};
void DrawRef(CImageBasis *_zw);
bool ReadParameter(FILE* pfile, string& aktparamgraph);
bool doFlow(string time);
string getHTMLSingleStep(string host);

View File

@@ -16,32 +16,68 @@ static const char* TAG = "flow_analog";
bool debugdetailanalog = false;
ClassFlowAnalog::ClassFlowAnalog() : ClassFlowImage(TAG)
void ClassFlowAnalog::SetInitialParameter(void)
{
string cnnmodelfile = "";
modelxsize = 1;
modelysize = 1;
ListFlowControll = NULL;
previousElement = NULL;
SaveAllFiles = false;
disabled = false;
extendedResolution = false;
}
ClassFlowAnalog::ClassFlowAnalog(std::vector<ClassFlow*>* lfc) : ClassFlowImage(lfc, TAG)
{
string cnnmodelfile = "";
modelxsize = 1;
modelysize = 1;
SetInitialParameter();
ListFlowControll = lfc;
for (int i = 0; i < ListFlowControll->size(); ++i)
{
if (((*ListFlowControll)[i])->name().compare("ClassFlowAlignment") == 0)
{
flowpostalignment = (ClassFlowAlignment*) (*ListFlowControll)[i];
}
}
}
int ClassFlowAnalog::AnzahlROIs()
{
int zw = ROI.size();
if (extendedResolution)
zw++;
return zw;
}
string ClassFlowAnalog::getReadout()
{
int prev = -1;
string result = "";
for (int i = ROI.size() - 1; i >= 0; --i)
if (ROI.size() == 0)
return result;
float zahl = ROI[ROI.size() - 1]->result;
int ergebnis_nachkomma = ((int) floor(zahl * 10)) % 10;
int prev = -1;
prev = ZeigerEval(ROI[ROI.size() - 1]->result, prev);
result = std::to_string(prev);
if (extendedResolution)
result = result + std::to_string(ergebnis_nachkomma);
for (int i = ROI.size() - 2; i >= 0; --i)
{
prev = ZeigerEval(ROI[i]->result, prev);
result = std::to_string(prev) + result;
}
return result;
}
@@ -80,9 +116,18 @@ bool ClassFlowAnalog::ReadParameter(FILE* pfile, string& aktparamgraph)
return false;
if (aktparamgraph.compare("[Analog]") != 0) // Paragraph passt nich zu MakeImage
if ((aktparamgraph.compare("[Analog]") != 0) && (aktparamgraph.compare(";[Analog]") != 0)) // Paragraph passt nich zu MakeImage
return false;
if (aktparamgraph[0] == ';')
{
disabled = true;
while (getNextLine(pfile, &aktparamgraph) && !isNewParagraph(aktparamgraph));
printf("[Analog] is disabled !!!\n");
return true;
}
while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph))
{
zerlegt = this->ZerlegeZeile(aktparamgraph);
@@ -113,9 +158,30 @@ bool ClassFlowAnalog::ReadParameter(FILE* pfile, string& aktparamgraph)
neuroi->deltax = std::stoi(zerlegt[3]);
neuroi->deltay = std::stoi(zerlegt[4]);
neuroi->result = -1;
neuroi->image = NULL;
neuroi->image_org = NULL;
ROI.push_back(neuroi);
}
if ((toUpper(zerlegt[0]) == "SAVEALLFILES") && (zerlegt.size() > 1))
{
if (toUpper(zerlegt[1]) == "TRUE")
SaveAllFiles = true;
}
if ((toUpper(zerlegt[0]) == "EXTENDEDRESOLUTION") && (zerlegt.size() > 1))
{
if (toUpper(zerlegt[1]) == "TRUE")
extendedResolution = true;
}
}
for (int i = 0; i < ROI.size(); ++i)
{
ROI[i]->image = new CImageBasis(modelxsize, modelysize, 3);
ROI[i]->image_org = new CImageBasis(ROI[i]->deltax, ROI[i]->deltay, 3);
}
return true;
}
@@ -147,6 +213,9 @@ string ClassFlowAnalog::getHTMLSingleStep(string host)
bool ClassFlowAnalog::doFlow(string time)
{
if (disabled)
return true;
if (!doAlignAndCut(time)){
return false;
};
@@ -162,81 +231,45 @@ bool ClassFlowAnalog::doFlow(string time)
bool ClassFlowAnalog::doAlignAndCut(string time)
{
string input = "/sdcard/img_tmp/alg.jpg";
string input_roi = "/sdcard/img_tmp/alg_roi.jpg";
string ioresize = "/sdcard/img_tmp/resize.bmp";
string output;
string nm;
input = FormatFileName(input);
input_roi = FormatFileName(input_roi);
if (disabled)
return true;
CResizeImage *rs;
CImageBasis *img_roi = NULL;
CAlignAndCutImage *caic = new CAlignAndCutImage(input);
if (!caic->ImageOkay()){
if (debugdetailanalog) LogFile.WriteToFile("ClassFlowAnalog::doAlignAndCut not okay!");
delete caic;
return false;
}
if (input_roi.length() > 0){
img_roi = new CImageBasis(input_roi);
if (!img_roi->ImageOkay()){
if (debugdetailanalog) LogFile.WriteToFile("ClassFlowAnalog::doAlignAndCut ImageRoi not okay!");
delete caic;
delete img_roi;
return false;
}
}
CAlignAndCutImage *caic = flowpostalignment->GetAlignAndCutImage();
for (int i = 0; i < ROI.size(); ++i)
{
printf("Analog %d - Align&Cut\n", i);
output = "/sdcard/img_tmp/" + ROI[i]->name + ".jpg";
output = FormatFileName(output);
caic->CutAndSave(output, ROI[i]->posx, ROI[i]->posy, ROI[i]->deltax, ROI[i]->deltay);
rs = new CResizeImage(output);
if (!rs->ImageOkay()){
if (debugdetailanalog) LogFile.WriteToFile("ClassFlowAnalog::doAlignAndCut CResizeImage(output);!");
delete caic;
delete rs;
return false;
}
caic->CutAndSave(ROI[i]->posx, ROI[i]->posy, ROI[i]->deltax, ROI[i]->deltay, ROI[i]->image_org);
if (SaveAllFiles) ROI[i]->image_org->SaveToFile(FormatFileName("/sdcard/img_tmp/" + ROI[i]->name + ".jpg"));
rs->Resize(modelxsize, modelysize);
ioresize = "/sdcard/img_tmp/ra" + std::to_string(i) + ".bmp";
ioresize = FormatFileName(ioresize);
rs->SaveToFile(ioresize);
delete rs;
if (img_roi)
{
int r = 0;
int g = 255;
int b = 0;
img_roi->drawRect(ROI[i]->posx, ROI[i]->posy, ROI[i]->deltax, ROI[i]->deltay, r, g, b, 1);
img_roi->drawCircle((int) (ROI[i]->posx + ROI[i]->deltax/2), (int) (ROI[i]->posy + ROI[i]->deltay/2), (int) (ROI[i]->deltax/2), r, g, b, 2);
img_roi->drawLine((int) (ROI[i]->posx + ROI[i]->deltax/2), (int) ROI[i]->posy, (int) (ROI[i]->posx + ROI[i]->deltax/2), (int) (ROI[i]->posy + ROI[i]->deltay), r, g, b, 2);
img_roi->drawLine((int) ROI[i]->posx, (int) (ROI[i]->posy + ROI[i]->deltay/2), (int) ROI[i]->posx + ROI[i]->deltax, (int) (ROI[i]->posy + ROI[i]->deltay/2), r, g, b, 2);
}
ROI[i]->image_org->Resize(modelxsize, modelysize, ROI[i]->image);
if (SaveAllFiles) ROI[i]->image->SaveToFile(FormatFileName("/sdcard/img_tmp/" + ROI[i]->name + ".bmp"));
}
delete caic;
if (img_roi)
{
img_roi->SaveToFile(input_roi);
delete img_roi;
}
return true;
}
void ClassFlowAnalog::DrawROI(CImageBasis *_zw)
{
int r = 0;
int g = 255;
int b = 0;
for (int i = 0; i < ROI.size(); ++i)
{
_zw->drawRect(ROI[i]->posx, ROI[i]->posy, ROI[i]->deltax, ROI[i]->deltay, r, g, b, 1);
_zw->drawCircle((int) (ROI[i]->posx + ROI[i]->deltax/2), (int) (ROI[i]->posy + ROI[i]->deltay/2), (int) (ROI[i]->deltax/2), r, g, b, 2);
_zw->drawLine((int) (ROI[i]->posx + ROI[i]->deltax/2), (int) ROI[i]->posy, (int) (ROI[i]->posx + ROI[i]->deltax/2), (int) (ROI[i]->posy + ROI[i]->deltay), r, g, b, 2);
_zw->drawLine((int) ROI[i]->posx, (int) (ROI[i]->posy + ROI[i]->deltay/2), (int) ROI[i]->posx + ROI[i]->deltax, (int) (ROI[i]->posy + ROI[i]->deltay/2), r, g, b, 2);
}
}
bool ClassFlowAnalog::doNeuralNetwork(string time)
{
if (disabled)
return true;
string logPath = CreateLogFolder(time);
string input = "/sdcard/img_tmp/alg.jpg";
@@ -265,7 +298,8 @@ bool ClassFlowAnalog::doNeuralNetwork(string time)
#ifndef OHNETFLITE
// LogFile.WriteToFile("ClassFlowAnalog::doNeuralNetwork vor CNN tflite->LoadInputImage(ioresize)");
tflite->LoadInputImage(ioresize);
// tflite->LoadInputImage(ioresize);
tflite->LoadInputImageBasis(ROI[i]->image);
tflite->Invoke();
if (debugdetailanalog) LogFile.WriteToFile("Nach Invoke");
@@ -280,7 +314,10 @@ bool ClassFlowAnalog::doNeuralNetwork(string time)
printf("Result Analog%i: %f\n", i, ROI[i]->result);
LogImage(logPath, ROI[i]->name, &ROI[i]->result, NULL, time);
if (isLogImage)
{
LogImage(logPath, ROI[i]->name, &ROI[i]->result, NULL, time, ROI[i]->image_org);
}
}
#ifndef OHNETFLITE
delete tflite;
@@ -297,8 +334,11 @@ std::vector<HTMLInfo*> ClassFlowAnalog::GetHTMLInfo()
for (int i = 0; i < ROI.size(); ++i)
{
HTMLInfo *zw = new HTMLInfo;
zw->filename = ROI[i]->name + ".jpg";
zw->filename = ROI[i]->name + ".bmp";
zw->filename_org = ROI[i]->name + ".jpg";
zw->val = ROI[i]->result;
zw->image = ROI[i]->image;
zw->image_org = ROI[i]->image_org;
result.push_back(zw);
}

View File

@@ -1,10 +1,12 @@
#pragma once
#include "ClassFlowImage.h"
#include "ClassFlowAlignment.h"
// #include "CTfLiteClass.h"
struct roianalog {
int posx, posy, deltax, deltay;
float result;
CImageBasis *image, *image_org;
string name;
};
@@ -17,19 +19,29 @@ protected:
string cnnmodelfile;
int modelxsize, modelysize;
int ZeigerEval(float zahl, int ziffer_vorgaenger);
bool SaveAllFiles;
ClassFlowAlignment* flowpostalignment;
void SetInitialParameter(void);
public:
ClassFlowAnalog();
bool extendedResolution;
ClassFlowAnalog(std::vector<ClassFlow*>* lfc);
bool ReadParameter(FILE* pfile, string& aktparamgraph);
bool doFlow(string time);
string getHTMLSingleStep(string host);
string getReadout();
void DrawROI(CImageBasis *_zw);
bool doNeuralNetwork(string time);
bool doAlignAndCut(string time);
std::vector<HTMLInfo*> GetHTMLInfo();
int AnzahlROIs(){return ROI.size();};
int AnzahlROIs();
string name(){return "ClassFlowAnalog";};
};

View File

@@ -1,5 +1,7 @@
#include "ClassFlowControll.h"
#include "connect_wlan.h"
#include "freertos/task.h"
#include <sys/stat.h>
@@ -9,33 +11,35 @@
#include "Helper.h"
#include "server_ota.h"
#include "server_help.h"
//#define DEBUG_DETAIL_ON
static const char* TAG = "flow_controll";
std::string ClassFlowControll::doSingleStep(std::string _stepname, std::string _host){
std::string _classname = "";
std::string result = "";
if (_stepname.compare("[MakeImage]") == 0){
if ((_stepname.compare("[MakeImage]") == 0) || (_stepname.compare(";[MakeImage]") == 0)){
_classname = "ClassFlowMakeImage";
}
if (_stepname.compare("[Alignment]") == 0){
if ((_stepname.compare("[Alignment]") == 0) || (_stepname.compare(";[Alignment]") == 0)){
_classname = "ClassFlowAlignment";
}
if (_stepname.compare("[Digits]") == 0){
if ((_stepname.compare("[Digits]") == 0) || (_stepname.compare(";[Digits]") == 0)){
_classname = "ClassFlowDigit";
}
if (_stepname.compare("[Analog]") == 0){
if ((_stepname.compare("[Analog]") == 0) || (_stepname.compare(";[Analog]") == 0)){
_classname = "ClassFlowAnalog";
}
if (_stepname.compare("[MQTT]") == 0){
if ((_stepname.compare("[MQTT]") == 0) || (_stepname.compare(";[MQTT]") == 0)){
_classname = "ClassFlowMQTT";
}
// std::string zw = "Classname: " + _classname + "\n";
// printf(zw.c_str());
for (int i = 0; i < FlowControll.size(); ++i)
if (FlowControll[i]->name().compare(_classname) == 0){
// printf(FlowControll[i]->name().c_str()); printf("\n");
FlowControll[i]->doFlow("");
FlowControll[i]->doFlow("");
result = FlowControll[i]->getHTMLSingleStep(_host);
}
@@ -66,7 +70,15 @@ std::vector<HTMLInfo*> ClassFlowControll::GetAllAnalog()
void ClassFlowControll::SetInitialParameter(void)
{
AutoStart = false;
SetupModeActive = false;
AutoIntervall = 10;
flowdigit = NULL;
flowanalog = NULL;
flowpostprocessing = NULL;
disabled = false;
aktRunNr = 0;
aktstatus = "Startup";
}
bool ClassFlowControll::isAutoStart(long &_intervall)
@@ -82,13 +94,25 @@ ClassFlow* ClassFlowControll::CreateClassFlow(std::string _type)
_type = trim(_type);
if (toUpper(_type).compare("[MAKEIMAGE]") == 0)
{
cfc = new ClassFlowMakeImage(&FlowControll);
flowmakeimage = (ClassFlowMakeImage*) cfc;
}
if (toUpper(_type).compare("[ALIGNMENT]") == 0)
{
cfc = new ClassFlowAlignment(&FlowControll);
flowalignment = (ClassFlowAlignment*) cfc;
}
if (toUpper(_type).compare("[ANALOG]") == 0)
{
cfc = new ClassFlowAnalog(&FlowControll);
flowanalog = (ClassFlowAnalog*) cfc;
}
if (toUpper(_type).compare("[DIGITS]") == 0)
{
cfc = new ClassFlowDigit(&FlowControll);
flowdigit = (ClassFlowDigit*) cfc;
}
if (toUpper(_type).compare("[MQTT]") == 0)
cfc = new ClassFlowMQTT(&FlowControll);
if (toUpper(_type).compare("[POSTPROCESSING]") == 0)
@@ -121,7 +145,7 @@ void ClassFlowControll::InitFlow(std::string config)
ClassFlow* cfc;
FILE* pFile;
config = FormatFileName(config);
pFile = fopen(config.c_str(), "r");
pFile = OpenFileAndWait(config.c_str(), "r");
line = "";
@@ -138,6 +162,7 @@ void ClassFlowControll::InitFlow(std::string config)
cfc = CreateClassFlow(line);
if (cfc)
{
printf("Start ReadParameter\n");
cfc->ReadParameter(pFile, line);
}
else
@@ -156,6 +181,20 @@ std::string ClassFlowControll::getActStatus(){
return aktstatus;
}
void ClassFlowControll::doFlowMakeImageOnly(string time){
std::string zw_time;
for (int i = 0; i < FlowControll.size(); ++i)
{
if (FlowControll[i]->name() == "ClassFlowMakeImage") {
zw_time = gettimestring("%Y%m%d-%H%M%S");
aktstatus = zw_time + ": " + FlowControll[i]->name();
string zw = "FlowControll.doFlowMakeImageOnly - " + FlowControll[i]->name();
FlowControll[i]->doFlow(time);
}
}
}
bool ClassFlowControll::doFlow(string time)
{
// CleanTempFolder(); // dazu muss man noch eine Rolling einführen
@@ -164,12 +203,19 @@ bool ClassFlowControll::doFlow(string time)
std::string zw_time;
int repeat = 0;
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("ClassFlowAnalog::doFlow - Start");
#endif
for (int i = 0; i < FlowControll.size(); ++i)
{
zw_time = gettimestring("%Y%m%d-%H%M%S");
aktstatus = zw_time + ": " + FlowControll[i]->name();
string zw = "FlowControll.doFlow - " + FlowControll[i]->name();
LogFile.WriteToFile(zw);
LogFile.WriteHeapInfo(zw);
if (!FlowControll[i]->doFlow(time)){
repeat++;
LogFile.WriteToFile("Fehler im vorheriger Schritt - wird zum " + to_string(repeat) + ". Mal wiederholt");
@@ -185,12 +231,32 @@ bool ClassFlowControll::doFlow(string time)
{
result = true;
}
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("ClassFlowAnalog::doFlow");
#endif
}
zw_time = gettimestring("%Y%m%d-%H%M%S");
aktstatus = zw_time + ": Flow is done";
return result;
}
void ClassFlowControll::UpdateAktStatus(std::string _flow)
{
aktstatus = gettimestring("%Y%m%d-%H%M%S");
aktstatus = aktstatus + "\t" + std::to_string(aktRunNr) + "\t";
if (_flow == "ClassFlowMakeImage")
aktstatus = aktstatus + "Taking Raw Image";
else
if (_flow == "ClassFlowAlignment")
aktstatus = aktstatus + "Aligning Image";
}
string ClassFlowControll::getReadout(bool _rawvalue = false, bool _noerror = false)
{
if (flowpostprocessing)
@@ -303,12 +369,34 @@ bool ClassFlowControll::ReadParameter(FILE* pfile, string& aktparamgraph)
setTimeZone(zerlegt[1]);
}
if ((toUpper(zerlegt[0]) == "TIMEUPDATEINTERVALL") && (zerlegt.size() > 1))
if ((toUpper(zerlegt[0]) == "TIMESERVER") && (zerlegt.size() > 1))
{
TimeUpdateIntervall = stof(zerlegt[1]);
xTaskCreate(&task_doTimeSync, "update_time", configMINIMAL_STACK_SIZE * 16, &TimeUpdateIntervall, tskIDLE_PRIORITY, NULL);
string zw = "Set TimeZone: " + zerlegt[1];
reset_servername(zerlegt[1]);
}
if ((toUpper(zerlegt[0]) == "HOSTNAME") && (zerlegt.size() > 1))
{
if (ChangeHostName("/sdcard/wlan.ini", zerlegt[1]))
{
// reboot notwendig damit die neue wlan.ini auch benutzt wird !!!
fclose(pfile);
doReboot();
}
}
if ((toUpper(zerlegt[0]) == "SETUPMODE") && (zerlegt.size() > 1))
{
if (toUpper(zerlegt[1]) == "TRUE")
{
SetupModeActive = true;
}
}
if ((toUpper(zerlegt[0]) == "LOGLEVEL") && (zerlegt.size() > 1))
{
LogFile.setLogLevel(stoi(zerlegt[1]));
}
}
return true;
}
@@ -342,3 +430,84 @@ int ClassFlowControll::CleanTempFolder() {
return 0;
}
esp_err_t ClassFlowControll::SendRawJPG(httpd_req_t *req)
{
return flowmakeimage->SendRawJPG(req);
}
esp_err_t ClassFlowControll::GetJPGStream(std::string _fn, httpd_req_t *req)
{
printf("ClassFlowControll::GetJPGStream %s\n", _fn.c_str());
CImageBasis *_send = NULL;
esp_err_t result = ESP_FAIL;
bool Dodelete = false;
if (_fn == "alg.jpg")
{
_send = flowalignment->ImageBasis;
}
if (_fn == "alg_roi.jpg")
{
CImageBasis* _imgzw = new CImageBasis(flowalignment->ImageBasis);
flowalignment->DrawRef(_imgzw);
if (flowdigit) flowdigit->DrawROI(_imgzw);
if (flowanalog) flowanalog->DrawROI(_imgzw);
_send = _imgzw;
Dodelete = true;
}
std::vector<HTMLInfo*> htmlinfo;
htmlinfo = GetAllDigital();
for (int i = 0; i < htmlinfo.size(); ++i)
{
if (_fn == htmlinfo[i]->filename)
{
if (htmlinfo[i]->image)
_send = htmlinfo[i]->image;
}
if (_fn == htmlinfo[i]->filename_org)
{
if (htmlinfo[i]->image_org)
_send = htmlinfo[i]->image_org;
}
}
htmlinfo = GetAllAnalog();
for (int i = 0; i < htmlinfo.size(); ++i)
{
if (_fn == htmlinfo[i]->filename)
{
if (htmlinfo[i]->image)
_send = htmlinfo[i]->image;
}
if (_fn == htmlinfo[i]->filename_org)
{
if (htmlinfo[i]->image_org)
_send = htmlinfo[i]->image_org;
}
}
if (_send)
{
ESP_LOGI(TAG, "Sending file : %s ...", _fn.c_str());
set_content_type_from_file(req, _fn.c_str());
result = _send->SendJPGtoHTTP(req);
ESP_LOGI(TAG, "File sending complete");
/* Respond with an empty chunk to signal HTTP response completion */
httpd_resp_send_chunk(req, NULL, 0);
}
if (Dodelete)
{
delete _send;
}
return result;
}

View File

@@ -17,23 +17,34 @@ class ClassFlowControll :
protected:
std::vector<ClassFlow*> FlowControll;
ClassFlowPostProcessing* flowpostprocessing;
ClassFlowAlignment* flowalignment;
ClassFlowAnalog* flowanalog;
ClassFlowDigit* flowdigit;
ClassFlowMakeImage* flowmakeimage;
ClassFlow* CreateClassFlow(std::string _type);
bool AutoStart;
float AutoIntervall;
bool SetupModeActive;
void SetInitialParameter(void);
std::string aktstatus;
int TimeUpdateIntervall;
int aktRunNr;
void UpdateAktStatus(std::string _flow);
public:
void InitFlow(std::string config);
bool doFlow(string time);
void doFlowMakeImageOnly(string time);
bool getStatusSetupModus(){return SetupModeActive;};
string getReadout(bool _rawvalue, bool _noerror);
string UpdatePrevalue(std::string _newvalue);
string GetPrevalue();
bool ReadParameter(FILE* pfile, string& aktparamgraph);
esp_err_t GetJPGStream(std::string _fn, httpd_req_t *req);
esp_err_t SendRawJPG(httpd_req_t *req);
std::string doSingleStep(std::string _stepname, std::string _host);
bool isAutoStart(long &_intervall);
@@ -48,3 +59,4 @@ public:
string name(){return "ClassFlowControll";};
};

View File

@@ -1,5 +1,6 @@
#include "ClassFlowDigit.h"
//#include "CFindTemplate.h"
//#include "CTfLiteClass.h"
@@ -15,19 +16,51 @@
static const char* TAG = "flow_digital";
ClassFlowDigit::ClassFlowDigit() : ClassFlowImage(TAG)
void ClassFlowDigit::SetInitialParameter(void)
{
string cnnmodelfile = "";
modelxsize = 1;
modelysize = 1;
ListFlowControll = NULL;
previousElement = NULL;
SaveAllFiles = false;
disabled = false;
}
ClassFlowDigit::ClassFlowDigit() : ClassFlowImage(TAG)
{
SetInitialParameter();
}
ClassFlowDigit::ClassFlowDigit(std::vector<ClassFlow*>* lfc) : ClassFlowImage(lfc, TAG)
{
string cnnmodelfile = "";
modelxsize = 1;
modelysize = 1;
SetInitialParameter();
ListFlowControll = lfc;
for (int i = 0; i < ListFlowControll->size(); ++i)
{
if (((*ListFlowControll)[i])->name().compare("ClassFlowAlignment") == 0)
{
flowpostalignment = (ClassFlowAlignment*) (*ListFlowControll)[i];
}
}
}
ClassFlowDigit::ClassFlowDigit(std::vector<ClassFlow*>* lfc, ClassFlow *_prev) : ClassFlowImage(lfc, _prev, TAG)
{
SetInitialParameter();
ListFlowControll = lfc;
previousElement = _prev;
for (int i = 0; i < ListFlowControll->size(); ++i)
{
if (((*ListFlowControll)[i])->name().compare("ClassFlowAlignment") == 0)
{
flowpostalignment = (ClassFlowAlignment*) (*ListFlowControll)[i];
}
}
}
string ClassFlowDigit::getReadout()
@@ -55,11 +88,19 @@ bool ClassFlowDigit::ReadParameter(FILE* pfile, string& aktparamgraph)
if (!this->GetNextParagraph(pfile, aktparamgraph))
return false;
if (aktparamgraph.compare("[Digits]") != 0) // Paragraph passt nich zu MakeImage
if ((aktparamgraph.compare("[Digits]") != 0) && (aktparamgraph.compare(";[Digits]") != 0)) // Paragraph passt nich zu MakeImage
return false;
while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph))
if (aktparamgraph[0] == ';')
{
disabled = true;
while (getNextLine(pfile, &aktparamgraph) && !isNewParagraph(aktparamgraph));
printf("[Digits] is disabled !!!\n");
return true;
}
while (getNextLine(pfile, &aktparamgraph) && !isNewParagraph(aktparamgraph))
{
zerlegt = this->ZerlegeZeile(aktparamgraph);
if ((zerlegt[0] == "LogImageLocation") && (zerlegt.size() > 1))
@@ -85,9 +126,25 @@ bool ClassFlowDigit::ReadParameter(FILE* pfile, string& aktparamgraph)
neuroi->deltax = std::stoi(zerlegt[3]);
neuroi->deltay = std::stoi(zerlegt[4]);
neuroi->resultklasse = -1;
neuroi->image = NULL;
neuroi->image_org = NULL;
ROI.push_back(neuroi);
}
if ((toUpper(zerlegt[0]) == "SAVEALLFILES") && (zerlegt.size() > 1))
{
if (toUpper(zerlegt[1]) == "TRUE")
SaveAllFiles = true;
}
}
for (int i = 0; i < ROI.size(); ++i)
{
ROI[i]->image = new CImageBasis(modelxsize, modelysize, 3);
ROI[i]->image_org = new CImageBasis(ROI[i]->deltax, ROI[i]->deltay, 3);
}
return true;
}
@@ -120,6 +177,9 @@ string ClassFlowDigit::getHTMLSingleStep(string host)
bool ClassFlowDigit::doFlow(string time)
{
if (disabled)
return true;
if (!doAlignAndCut(time)){
return false;
};
@@ -133,60 +193,20 @@ bool ClassFlowDigit::doFlow(string time)
bool ClassFlowDigit::doAlignAndCut(string time)
{
string input = "/sdcard/img_tmp/alg.jpg";
string input_roi = "/sdcard/img_tmp/alg_roi.jpg";
string ioresize = "/sdcard/img_tmp/resize.bmp";
string output;
string nm;
input = FormatFileName(input);
input_roi = FormatFileName(input_roi);
CResizeImage *rs;
CImageBasis *img_roi = NULL;
CAlignAndCutImage *caic = new CAlignAndCutImage(input);
if (!caic->ImageOkay()){
LogFile.WriteToFile("ClassFlowDigit::doAlignAndCut not okay!");
delete caic;
return false;
}
if (input_roi.length() > 0){
img_roi = new CImageBasis(input_roi);
if (!img_roi->ImageOkay()){
LogFile.WriteToFile("ClassFlowDigit::doAlignAndCut ImageRoi not okay!");
delete caic;
delete img_roi;
return false;
}
}
if (disabled)
return true;
CAlignAndCutImage *caic = flowpostalignment->GetAlignAndCutImage();
for (int i = 0; i < ROI.size(); ++i)
{
printf("DigitalDigit %d - Align&Cut\n", i);
output = "/sdcard/img_tmp/" + ROI[i]->name + ".jpg";
output = FormatFileName(output);
caic->CutAndSave(output, ROI[i]->posx, ROI[i]->posy, ROI[i]->deltax, ROI[i]->deltay);
rs = new CResizeImage(output);
rs->Resize(modelxsize, modelysize);
ioresize = "/sdcard/img_tmp/rd" + std::to_string(i) + ".bmp";
ioresize = FormatFileName(ioresize);
rs->SaveToFile(ioresize);
delete rs;
caic->CutAndSave(ROI[i]->posx, ROI[i]->posy, ROI[i]->deltax, ROI[i]->deltay, ROI[i]->image_org);
if (SaveAllFiles) ROI[i]->image_org->SaveToFile(FormatFileName("/sdcard/img_tmp/" + ROI[i]->name + ".jpg"));
if (img_roi)
{
img_roi->drawRect(ROI[i]->posx, ROI[i]->posy, ROI[i]->deltax, ROI[i]->deltay, 0, 0, 255, 2);
}
}
delete caic;
if (img_roi)
{
img_roi->SaveToFile(input_roi);
delete img_roi;
ROI[i]->image_org->Resize(modelxsize, modelysize, ROI[i]->image);
if (SaveAllFiles) ROI[i]->image->SaveToFile(FormatFileName("/sdcard/img_tmp/" + ROI[i]->name + ".bmp"));
}
return true;
@@ -194,19 +214,14 @@ bool ClassFlowDigit::doAlignAndCut(string time)
bool ClassFlowDigit::doNeuralNetwork(string time)
{
if (disabled)
return true;
string logPath = CreateLogFolder(time);
string input = "/sdcard/img_tmp/alg.jpg";
string ioresize = "/sdcard/img_tmp/resize.bmp";
string output;
string nm;
input = FormatFileName(input);
#ifndef OHNETFLITE
CTfLiteClass *tflite = new CTfLiteClass;
string zwcnn = "/sdcard" + cnnmodelfile;
zwcnn = FormatFileName(zwcnn);
string zwcnn = FormatFileName("/sdcard" + cnnmodelfile);
printf(zwcnn.c_str());printf("\n");
tflite->LoadModel(zwcnn);
tflite->MakeAllocate();
@@ -215,17 +230,18 @@ bool ClassFlowDigit::doNeuralNetwork(string time)
for (int i = 0; i < ROI.size(); ++i)
{
printf("DigitalDigit %d - TfLite\n", i);
ioresize = "/sdcard/img_tmp/rd" + std::to_string(i) + ".bmp";
ioresize = FormatFileName(ioresize);
// printf("output: %s, ioresize: %s\n", output.c_str(), ioresize.c_str());
ROI[i]->resultklasse = 0;
#ifndef OHNETFLITE
ROI[i]->resultklasse = tflite->GetClassFromImage(ioresize);
ROI[i]->resultklasse = tflite->GetClassFromImageBasis(ROI[i]->image);
#endif
printf("Result Digit%i: %d\n", i, ROI[i]->resultklasse);
LogImage(logPath, ROI[i]->name, NULL, &ROI[i]->resultklasse, time);
if (isLogImage)
{
LogImage(logPath, ROI[i]->name, NULL, &ROI[i]->resultklasse, time, ROI[i]->image_org);
}
}
#ifndef OHNETFLITE
delete tflite;
@@ -233,6 +249,11 @@ bool ClassFlowDigit::doNeuralNetwork(string time)
return true;
}
void ClassFlowDigit::DrawROI(CImageBasis *_zw)
{
for (int i = 0; i < ROI.size(); ++i)
_zw->drawRect(ROI[i]->posx, ROI[i]->posy, ROI[i]->deltax, ROI[i]->deltay, 0, 0, 255, 2);
}
std::vector<HTMLInfo*> ClassFlowDigit::GetHTMLInfo()
{
@@ -241,10 +262,14 @@ std::vector<HTMLInfo*> ClassFlowDigit::GetHTMLInfo()
for (int i = 0; i < ROI.size(); ++i)
{
HTMLInfo *zw = new HTMLInfo;
zw->filename = ROI[i]->name + ".jpg";
zw->filename = ROI[i]->name + ".bmp";
zw->filename_org = ROI[i]->name + ".jpg";
zw->val = ROI[i]->resultklasse;
zw->image = ROI[i]->image;
zw->image_org = ROI[i]->image_org;
result.push_back(zw);
}
return result;
}

View File

@@ -1,5 +1,6 @@
#pragma once
#include "ClassFlowImage.h"
#include "ClassFlowAlignment.h"
#include "Helper.h"
#include <string>
@@ -8,6 +9,7 @@ struct roi {
int posx, posy, deltax, deltay;
int resultklasse;
string name;
CImageBasis *image, *image_org;
roi* next;
};
@@ -18,19 +20,27 @@ protected:
std::vector<roi*> ROI;
string cnnmodelfile;
int modelxsize, modelysize;
bool SaveAllFiles;
ClassFlowAlignment* flowpostalignment;
bool doNeuralNetwork(string time);
bool doAlignAndCut(string time);
void SetInitialParameter(void);
public:
ClassFlowDigit();
ClassFlowDigit(std::vector<ClassFlow*>* lfc);
ClassFlowDigit(std::vector<ClassFlow*>* lfc, ClassFlow *_prev);
bool ReadParameter(FILE* pfile, string& aktparamgraph);
bool doFlow(string time);
string getHTMLSingleStep(string host);
string getReadout();
std::vector<HTMLInfo*> GetHTMLInfo();
void DrawROI(CImageBasis *_zw);
string name(){return "ClassFlowDigit";};
};

View File

@@ -5,19 +5,31 @@
#include <dirent.h>
#include "time_sntp.h"
#include "ClassLogFile.h"
#include "CImageBasis.h"
ClassFlowImage::ClassFlowImage(const char* logTag)
{
this->logTag = logTag;
isLogImage = false;
disabled = false;
}
ClassFlowImage::ClassFlowImage(std::vector<ClassFlow*> * lfc, const char* logTag) : ClassFlow((std::vector<ClassFlow*>*)lfc)
ClassFlowImage::ClassFlowImage(std::vector<ClassFlow*> * lfc, const char* logTag) : ClassFlow(lfc)
{
this->logTag = logTag;
isLogImage = false;
disabled = false;
}
ClassFlowImage::ClassFlowImage(std::vector<ClassFlow*> * lfc, ClassFlow *_prev, const char* logTag) : ClassFlow(lfc, _prev)
{
this->logTag = logTag;
isLogImage = false;
disabled = false;
}
string ClassFlowImage::CreateLogFolder(string time) {
if (!isLogImage)
return "";
@@ -32,7 +44,7 @@ string ClassFlowImage::CreateLogFolder(string time) {
return logPath;
}
void ClassFlowImage::LogImage(string logPath, string name, float *resultFloat, int *resultInt, string time) {
void ClassFlowImage::LogImage(string logPath, string name, float *resultFloat, int *resultInt, string time, CImageBasis *_img) {
if (!isLogImage)
return;
@@ -50,7 +62,8 @@ void ClassFlowImage::LogImage(string logPath, string name, float *resultFloat, i
string output = "/sdcard/img_tmp/" + name + ".jpg";
output = FormatFileName(output);
printf("save to file: %s\n", nm.c_str());
CopyFile(output, nm);
_img->SaveToFile(nm);
// CopyFile(output, nm);
}
void ClassFlowImage::RemoveOldLogs()

View File

@@ -12,11 +12,13 @@ protected:
const char* logTag;
string CreateLogFolder(string time);
void LogImage(string logPath, string name, float *resultFloat, int *resultInt, string time);
void LogImage(string logPath, string name, float *resultFloat, int *resultInt, string time, CImageBasis *_img);
public:
ClassFlowImage(const char* logTag);
ClassFlowImage(std::vector<ClassFlow*> * lfc, const char* logTag);
ClassFlowImage(std::vector<ClassFlow*> * lfc, ClassFlow *_prev, const char* logTag);
void RemoveOldLogs();
};

View File

@@ -6,7 +6,7 @@
#include <time.h>
ClassFlowMQTT::ClassFlowMQTT()
void ClassFlowMQTT::SetInitialParameter(void)
{
uri = "";
topic = "";
@@ -16,19 +16,36 @@ ClassFlowMQTT::ClassFlowMQTT()
flowpostprocessing = NULL;
user = "";
password = "";
previousElement = NULL;
ListFlowControll = NULL;
disabled = false;
}
ClassFlowMQTT::ClassFlowMQTT()
{
SetInitialParameter();
}
ClassFlowMQTT::ClassFlowMQTT(std::vector<ClassFlow*>* lfc)
{
uri = "";
topic = "";
topicError = "";
clientname = "watermeter";
OldValue = "";
flowpostprocessing = NULL;
user = "";
password = "";
SetInitialParameter();
ListFlowControll = lfc;
for (int i = 0; i < ListFlowControll->size(); ++i)
{
if (((*ListFlowControll)[i])->name().compare("ClassFlowPostProcessing") == 0)
{
flowpostprocessing = (ClassFlowPostProcessing*) (*ListFlowControll)[i];
}
}
}
ClassFlowMQTT::ClassFlowMQTT(std::vector<ClassFlow*>* lfc, ClassFlow *_prev)
{
SetInitialParameter();
previousElement = _prev;
ListFlowControll = lfc;
for (int i = 0; i < ListFlowControll->size(); ++i)
@@ -38,9 +55,9 @@ ClassFlowMQTT::ClassFlowMQTT(std::vector<ClassFlow*>* lfc)
flowpostprocessing = (ClassFlowPostProcessing*) (*ListFlowControll)[i];
}
}
}
bool ClassFlowMQTT::ReadParameter(FILE* pfile, string& aktparamgraph)
{
std::vector<string> zerlegt;
@@ -86,7 +103,7 @@ bool ClassFlowMQTT::ReadParameter(FILE* pfile, string& aktparamgraph)
if ((uri.length() > 0) && (topic.length() > 0))
{
MQTTInit(uri, clientname, user, password);
MQTTInit(uri, clientname, user, password, topicError, 60);
}
return true;

View File

@@ -13,11 +13,13 @@ protected:
std::string OldValue;
ClassFlowPostProcessing* flowpostprocessing;
std::string user, password;
void SetInitialParameter(void);
public:
ClassFlowMQTT();
ClassFlowMQTT(std::vector<ClassFlow*>* lfc);
ClassFlowMQTT(std::vector<ClassFlow*>* lfc, ClassFlow *_prev);
bool ReadParameter(FILE* pfile, string& aktparamgraph);
bool doFlow(string time);
string name(){return "ClassFlowMQTT";};

View File

@@ -1,11 +1,14 @@
#include "ClassFlowMakeImage.h"
#include "Helper.h"
#include "ClassLogFile.h"
#include "CFindTemplate.h"
#include "CImageBasis.h"
#include "ClassControllCamera.h"
#include <time.h>
// #define DEBUG_DETAIL_ON
static const char* TAG = "flow_make_image";
esp_err_t ClassFlowMakeImage::camera_capture(){
@@ -16,30 +19,28 @@ esp_err_t ClassFlowMakeImage::camera_capture(){
void ClassFlowMakeImage::takePictureWithFlash(int flashdauer)
{
string nm = namerawimage;
if (isImageSize && (ImageQuality > 0))
Camera.SetQualitySize(ImageQuality, ImageSize);
printf("Start CaptureFile\n");
Camera.CaptureToFile(nm, flashdauer);
Camera.CaptureToBasisImage(rawImage, flashdauer);
if (SaveAllFiles) rawImage->SaveToFile(namerawimage);
}
ClassFlowMakeImage::ClassFlowMakeImage() : ClassFlowImage(TAG)
void ClassFlowMakeImage::SetInitialParameter(void)
{
waitbeforepicture = 5;
isImageSize = false;
ImageQuality = -1;
TimeImageTaken = 0;
ImageQuality = 5;
rawImage = NULL;
ImageSize = FRAMESIZE_VGA;
SaveAllFiles = false;
disabled = false;
namerawimage = "/sdcard/img_tmp/raw.jpg";
}
ClassFlowMakeImage::ClassFlowMakeImage(std::vector<ClassFlow*>* lfc) : ClassFlowImage(lfc, TAG)
{
waitbeforepicture = 5;
isImageSize = false;
ImageQuality = -1;
TimeImageTaken = 0;
namerawimage = "/sdcard/img_tmp/raw.jpg";
SetInitialParameter();
}
bool ClassFlowMakeImage::ReadParameter(FILE* pfile, string& aktparamgraph)
@@ -64,14 +65,28 @@ bool ClassFlowMakeImage::ReadParameter(FILE* pfile, string& aktparamgraph)
isLogImage = true;
}
if ((zerlegt[0] == "ImageQuality") && (zerlegt.size() > 1))
this->ImageQuality = std::stod(zerlegt[1]);
ImageQuality = std::stod(zerlegt[1]);
if ((zerlegt[0] == "ImageSize") && (zerlegt.size() > 1))
{
ImageSize = Camera.TextToFramesize(zerlegt[1].c_str());
isImageSize = true;
}
if ((toUpper(zerlegt[0]) == "SAVEALLFILES") && (zerlegt.size() > 1))
{
if (toUpper(zerlegt[1]) == "TRUE")
SaveAllFiles = true;
}
}
Camera.SetQualitySize(ImageQuality, ImageSize);
image_width = Camera.image_width;
image_height = Camera.image_height;
rawImage = new CImageBasis();
rawImage->CreateEmptyImage(image_width, image_height, 3);
return true;
}
@@ -84,27 +99,56 @@ string ClassFlowMakeImage::getHTMLSingleStep(string host)
bool ClassFlowMakeImage::doFlow(string zwtime)
{
////////////////////////////////////////////////////////////////////
// TakeImage and Store into /image_tmp/raw.jpg TO BE DONE
////////////////////////////////////////////////////////////////////
string logPath = CreateLogFolder(zwtime);
int flashdauer = (int) waitbeforepicture * 1000;
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("ClassFlowMakeImage::doFlow - Before takePictureWithFlash");
#endif
takePictureWithFlash(flashdauer);
time(&TimeImageTaken);
localtime(&TimeImageTaken);
LogImage(logPath, "raw", NULL, NULL, zwtime);
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("ClassFlowMakeImage::doFlow - After takePictureWithFlash");
#endif
LogImage(logPath, "raw", NULL, NULL, zwtime, rawImage);
RemoveOldLogs();
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("ClassFlowMakeImage::doFlow - After RemoveOldLogs");
#endif
return true;
}
esp_err_t ClassFlowMakeImage::SendRawJPG(httpd_req_t *req)
{
int flashdauer = (int) waitbeforepicture * 1000;
return Camera.CaptureToHTTP(req, flashdauer);
}
ImageData* ClassFlowMakeImage::SendRawImage()
{
CImageBasis *zw = new CImageBasis(rawImage);
ImageData *id;
int flashdauer = (int) waitbeforepicture * 1000;
Camera.CaptureToBasisImage(zw, flashdauer);
id = zw->writeToMemoryAsJPG();
delete zw;
return id;
}
time_t ClassFlowMakeImage::getTimeImageTaken()
{
return TimeImageTaken;
}
ClassFlowMakeImage::~ClassFlowMakeImage(void)
{
delete rawImage;
}

View File

@@ -20,19 +20,32 @@ protected:
int ImageQuality;
time_t TimeImageTaken;
string namerawimage;
int image_height, image_width;
bool SaveAllFiles;
void CopyFile(string input, string output);
esp_err_t camera_capture();
void takePictureWithFlash(int flashdauer);
void SetInitialParameter(void);
public:
ClassFlowMakeImage();
CImageBasis *rawImage;
ClassFlowMakeImage(std::vector<ClassFlow*>* lfc);
bool ReadParameter(FILE* pfile, string& aktparamgraph);
bool doFlow(string time);
string getHTMLSingleStep(string host);
time_t getTimeImageTaken();
string name(){return "ClassFlowMakeImage";};
ImageData* SendRawImage();
esp_err_t SendRawJPG(httpd_req_t *req);
~ClassFlowMakeImage(void);
};

View File

@@ -14,17 +14,28 @@
string ClassFlowPostProcessing::GetPreValue()
{
std::string result;
bool isAnalog = false;
bool isDigit = false;
int AnzahlAnalog = 0;
result = RundeOutput(PreValue, -DecimalShift);
for (int i = 0; i < ListFlowControll->size(); ++i)
{
if (((*ListFlowControll)[i])->name().compare("ClassFlowAnalog") == 0)
{
int AnzahlAnalog = ((ClassFlowAnalog*)(*ListFlowControll)[i])->AnzahlROIs();
result = RundeOutput(PreValue, AnzahlAnalog - DecimalShift);
isAnalog = true;
AnzahlAnalog = ((ClassFlowAnalog*)(*ListFlowControll)[i])->AnzahlROIs();
}
if (((*ListFlowControll)[i])->name().compare("ClassFlowDigit") == 0)
{
isDigit = true;
}
}
if (isDigit && isAnalog)
result = RundeOutput(PreValue, AnzahlAnalog - DecimalShift);
return result;
}
@@ -75,15 +86,22 @@ bool ClassFlowPostProcessing::LoadPreValue(void)
ReturnValue = to_string(Value);
ReturnValueNoError = ReturnValue;
// falls es Analog gibt, dann die Anzahl der Nachkommastellen feststellen und entsprechend runden:
bool isAnalog = false;
bool isDigit = false;
int AnzahlAnalog = 0;
for (int i = 0; i < ListFlowControll->size(); ++i)
{
if (((*ListFlowControll)[i])->name().compare("ClassFlowAnalog") == 0)
{
int AnzahlAnalog = ((ClassFlowAnalog*)(*ListFlowControll)[i])->AnzahlROIs();
ReturnValue = RundeOutput(Value, AnzahlAnalog - DecimalShift);
ReturnValueNoError = ReturnValue;
}
isAnalog = true;
if (((*ListFlowControll)[i])->name().compare("ClassFlowDigit") == 0)
isDigit = true;
}
if (isDigit || isAnalog)
{
ReturnValue = RundeOutput(Value, AnzahlAnalog - DecimalShift);
ReturnValueNoError = ReturnValue;
}
return true;
@@ -108,6 +126,8 @@ void ClassFlowPostProcessing::SavePreValue(float value, string zwtime)
zwtime = std::string(buffer);
}
PreValue = value;
fputs(zwtime.c_str(), pFile);
fputs("\n", pFile);
fputs(to_string(value).c_str(), pFile);
@@ -117,23 +137,6 @@ void ClassFlowPostProcessing::SavePreValue(float value, string zwtime)
}
ClassFlowPostProcessing::ClassFlowPostProcessing()
{
PreValueUse = false;
PreValueAgeStartup = 30;
AllowNegativeRates = false;
MaxRateValue = 0.1;
ErrorMessage = false;
ListFlowControll = NULL;
PreValueOkay = false;
useMaxRateValue = false;
checkDigitIncreaseConsistency = false;
DecimalShift = 0;
ErrorMessageText = "";
FilePreValue = FormatFileName("/sdcard/config/prevalue.ini");
}
ClassFlowPostProcessing::ClassFlowPostProcessing(std::vector<ClassFlow*>* lfc)
{
PreValueUse = false;
@@ -266,6 +269,7 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
int AnzahlAnalog = 0;
string zw;
time_t imagetime = 0;
string rohwert;
ErrorMessageText = "";
@@ -304,6 +308,8 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
// isdigit = true; digit = "12N";
// isanalog = true; analog = "456";
ReturnRawValue = "";
if (isdigit)
ReturnRawValue = digit;
if (isdigit && isanalog)
@@ -311,8 +317,15 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
if (isanalog)
ReturnRawValue = ReturnRawValue + analog;
if (!isdigit)
{
AnzahlAnalog = 0;
}
ReturnRawValue = ShiftDecimal(ReturnRawValue, DecimalShift);
rohwert = ReturnRawValue;
if (!PreValueUse || !PreValueOkay)
{
@@ -348,7 +361,7 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
if ((!AllowNegativeRates) && (Value < PreValue))
{
ErrorMessageText = ErrorMessageText + "Negative Rate - Returned old value - read value: " + zwvalue + " ";
ErrorMessageText = ErrorMessageText + "Negative Rate - Returned old value - read value: " + zwvalue + " - raw value: " + ReturnRawValue;
Value = PreValue;
zwvalue = RundeOutput(Value, AnzahlAnalog - DecimalShift);
}
@@ -391,7 +404,24 @@ string ClassFlowPostProcessing::getReadoutParam(bool _rawValue, bool _noerror)
string ClassFlowPostProcessing::RundeOutput(float _in, int _anzNachkomma){
std::stringstream stream;
stream << std::fixed << std::setprecision(_anzNachkomma) << _in;
int _zw = _in;
// printf("AnzNachkomma: %d\n", _anzNachkomma);
if (_anzNachkomma < 0) {
_anzNachkomma = 0;
}
if (_anzNachkomma > 0)
{
stream << std::fixed << std::setprecision(_anzNachkomma) << _in;
return stream.str();
}
else
{
stream << _zw;
}
return stream.str();
}

View File

@@ -34,7 +34,6 @@ protected:
string RundeOutput(float _in, int _anzNachkomma);
public:
ClassFlowPostProcessing();
ClassFlowPostProcessing(std::vector<ClassFlow*>* lfc);
bool ReadParameter(FILE* pfile, string& aktparamgraph);
bool doFlow(string time);

View File

@@ -2,6 +2,6 @@ FILE(GLOB_RECURSE app_sources ${CMAKE_CURRENT_SOURCE_DIR}/*.*)
idf_component_register(SRCS ${app_sources}
INCLUDE_DIRS "."
REQUIRES tfmicro)
REQUIRES tfmicro jomjol_logfile)

View File

@@ -1,5 +1,8 @@
//#pragma warning(disable : 4996)
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "Helper.h"
#include <sys/types.h>
#include <sys/stat.h>
@@ -7,11 +10,91 @@
#include <string.h>
#include <esp_log.h>
#include "ClassLogFile.h"
//#include "ClassLogFile.h"
//#define ISWINDOWS_TRUE
#define PATH_MAX_STRING_SIZE 256
using namespace std;
/////////////////////////////////////////////////////////////////////////////////////////////
string getESPHeapInfo(){
string espInfoResultStr = "";
char aMsgBuf[80];
multi_heap_info_t aMultiHead_info ;
heap_caps_get_info (&aMultiHead_info,MALLOC_CAP_8BIT);
size_t aFreeHeapSize = heap_caps_get_free_size(MALLOC_CAP_8BIT);
size_t aMinFreeHeadSize = heap_caps_get_minimum_free_size(MALLOC_CAP_8BIT);
size_t aMinFreeHeapSize = heap_caps_get_minimum_free_size(MALLOC_CAP_8BIT);
size_t aHeapLargestFreeBlockSize = heap_caps_get_largest_free_block(MALLOC_CAP_8BIT);
sprintf(aMsgBuf," Free Heap Size: %ld", (long) aFreeHeapSize);
size_t aFreeSPIHeapSize = heap_caps_get_free_size(MALLOC_CAP_8BIT| MALLOC_CAP_SPIRAM);
size_t aFreeInternalHeapSize = heap_caps_get_free_size(MALLOC_CAP_8BIT| MALLOC_CAP_INTERNAL);
size_t aMinFreeInternalHeapSize = heap_caps_get_minimum_free_size(MALLOC_CAP_8BIT| MALLOC_CAP_INTERNAL);
sprintf(aMsgBuf," Heap: %ld", (long) aFreeHeapSize);
espInfoResultStr += string(aMsgBuf);
sprintf(aMsgBuf," Min Free: %ld", (long) aMinFreeHeapSize);
espInfoResultStr += string(aMsgBuf);
sprintf(aMsgBuf," larg. Block: %ld", (long) aHeapLargestFreeBlockSize);
espInfoResultStr += string(aMsgBuf);
sprintf(aMsgBuf," SPI Heap: %ld", (long) aFreeSPIHeapSize);
espInfoResultStr += string(aMsgBuf);
sprintf(aMsgBuf," Min Free Heap Size: %ld", (long) aMinFreeHeadSize);
sprintf(aMsgBuf," NOT_SPI Heap: %ld", (long) (aFreeHeapSize - aFreeSPIHeapSize));
espInfoResultStr += string(aMsgBuf);
sprintf(aMsgBuf," largest Block Size: %ld", (long) aHeapLargestFreeBlockSize);
sprintf(aMsgBuf," Internal Heap: %ld", (long) (aFreeInternalHeapSize));
espInfoResultStr += string(aMsgBuf);
sprintf(aMsgBuf," Internal Min Heap free: %ld", (long) (aMinFreeInternalHeapSize));
espInfoResultStr += string(aMsgBuf);
return espInfoResultStr;
}
size_t getESPHeapSize(){
size_t aFreeHeapSize = heap_caps_get_free_size(MALLOC_CAP_8BIT);
return aFreeHeapSize;
}
size_t getInternalESPHeapSize() {
size_t aFreeInternalHeapSize = heap_caps_get_free_size(MALLOC_CAP_8BIT| MALLOC_CAP_INTERNAL);
return aFreeInternalHeapSize;
}
///////////////////////////////////////////////////////////////////////////////////////////////
void memCopyGen(uint8_t* _source, uint8_t* _target, int _size)
{
for (int i = 0; i < _size; ++i)
*(_target + i) = *(_source + i);
}
FILE* OpenFileAndWait(const char* nm, char* _mode, int _waitsec)
{
FILE *pfile = fopen(nm, _mode);
if (pfile == NULL)
{
TickType_t xDelay;
xDelay = _waitsec * 1000 / portTICK_PERIOD_MS;
std::string zw = "File is locked: " + std::string(nm) + " - wait for " + std::to_string(_waitsec);
printf(zw.c_str());
printf("\n");
LogFile.WriteToFile(zw);
vTaskDelay( xDelay );
pfile = fopen(nm, _mode);
}
return pfile;
}
std::string FormatFileName(std::string input)
{
#ifdef ISWINDOWS_TRUE
@@ -126,14 +209,14 @@ void CopyFile(string input, string output)
}
char cTemp;
FILE* fpSourceFile = fopen(input.c_str(), "rb");
FILE* fpSourceFile = OpenFileAndWait(input.c_str(), "rb");
if (!fpSourceFile) // Sourcefile existiert nicht sonst gibt es einen Fehler beim Kopierversuch!
{
printf("File %s existiert nicht!\n", input.c_str());
return;
}
FILE* fpTargetFile = fopen(output.c_str(), "wb");
FILE* fpTargetFile = OpenFileAndWait(output.c_str(), "wb");
// Code Section

View File

@@ -10,6 +10,8 @@ void FindReplace(std::string& line, std::string& oldString, std::string& newStri
void CopyFile(string input, string output);
FILE* OpenFileAndWait(const char* nm, char* _mode, int _waitsec = 1);
size_t findDelimiterPos(string input, string delimiter);
//string trim(string istring);
string trim(string istring, string adddelimiter = "");
@@ -25,3 +27,12 @@ string toUpper(string in);
float temperatureRead();
time_t addDays(time_t startTime, int days);
void memCopyGen(uint8_t* _source, uint8_t* _target, int _size);
///////////////////////////
size_t getInternalESPHeapSize();
size_t getESPHeapSize();
string getESPHeapInfo();
/////////////////////////////

View File

@@ -0,0 +1,207 @@
#include "CAlignAndCutImage.h"
#include "CRotateImage.h"
#include "ClassLogFile.h"
#define _USE_MATH_DEFINES
#include <math.h>
#include <algorithm>
//#define GET_MEMORY malloc
#define GET_MEMORY(X) heap_caps_malloc(X, MALLOC_CAP_SPIRAM)
CAlignAndCutImage::CAlignAndCutImage(CImageBasis *_org, CImageBasis *_temp)
{
rgb_image = _org->rgb_image;
channels = _org->channels;
width = _org->width;
height = _org->height;
bpp = _org->bpp;
externalImage = true;
islocked = false;
ImageTMP = _temp;
}
void CAlignAndCutImage::GetRefSize(int *ref_dx, int *ref_dy)
{
ref_dx[0] = t0_dx;
ref_dy[0] = t0_dy;
ref_dx[1] = t1_dx;
ref_dy[1] = t1_dy;
}
bool CAlignAndCutImage::Align(RefInfo *_temp1, RefInfo *_temp2)
{
int dx, dy;
int r0_x, r0_y, r1_x, r1_y;
bool isSimilar1, isSimilar2;
CFindTemplate* ft = new CFindTemplate(rgb_image, channels, width, height, bpp);
r0_x = _temp1->target_x;
r0_y = _temp1->target_y;
printf("Vor ft->FindTemplate(_temp1); %s\n", _temp1->image_file.c_str());
isSimilar1 = ft->FindTemplate(_temp1);
_temp1->width = ft->tpl_width;
_temp1->height = ft->tpl_height;
r1_x = _temp2->target_x;
r1_y = _temp2->target_y;
printf("Vor ft->FindTemplate(_temp2); %s\n", _temp2->image_file.c_str());
isSimilar2 = ft->FindTemplate(_temp2);
_temp2->width = ft->tpl_width;
_temp2->height = ft->tpl_height;
delete ft;
dx = _temp1->target_x - _temp1->found_x;
dy = _temp1->target_y - _temp1->found_y;
r0_x += dx;
r0_y += dy;
r1_x += dx;
r1_y += dy;
float w_org, w_ist, d_winkel;
w_org = atan2(_temp2->found_y - _temp1->found_y, _temp2->found_x - _temp1->found_x);
w_ist = atan2(r1_y - r0_y, r1_x - r0_x);
d_winkel = (w_ist - w_org) * 180 / M_PI;
#ifdef DEBUG_DETAIL_ON
std::string zw = "\tdx:\t" + std::to_string(dx) + "\tdy:\t" + std::to_string(dy) + "\td_winkel:\t" + std::to_string(d_winkel);
zw = zw + "\tt1_x_y:\t" + std::to_string(_temp1->found_x) + "\t" + std::to_string(_temp1->found_y);
zw = zw + "\tpara1_found_min_avg_max_SAD:\t" + std::to_string(_temp1->fastalg_min) + "\t" + std::to_string(_temp1->fastalg_avg) + "\t" + std::to_string(_temp1->fastalg_max) + "\t"+ std::to_string(_temp1->fastalg_SAD);
zw = zw + "\tt2_x_y:\t" + std::to_string(_temp2->found_x) + "\t" + std::to_string(_temp2->found_y);
zw = zw + "\tpara2_found_min_avg_max:\t" + std::to_string(_temp2->fastalg_min) + "\t" + std::to_string(_temp2->fastalg_avg) + "\t" + std::to_string(_temp2->fastalg_max) + "\t"+ std::to_string(_temp2->fastalg_SAD);
LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", zw);
#endif
CRotateImage rt(this, ImageTMP);
rt.Translate(dx, dy);
rt.Rotate(d_winkel, _temp1->target_x, _temp1->target_y);
printf("Alignment: dx %d - dy %d - rot %f\n", dx, dy, d_winkel);
return (isSimilar1 && isSimilar2);
}
void CAlignAndCutImage::CutAndSave(std::string _template1, int x1, int y1, int dx, int dy)
{
int x2, y2;
x2 = x1 + dx;
y2 = y1 + dy;
x2 = std::min(x2, width - 1);
y2 = std::min(y2, height - 1);
dx = x2 - x1;
dy = y2 - y1;
int memsize = dx * dy * channels;
uint8_t* odata = (unsigned char*) GET_MEMORY(memsize);
stbi_uc* p_target;
stbi_uc* p_source;
RGBImageLock();
for (int x = x1; x < x2; ++x)
for (int y = y1; y < y2; ++y)
{
p_target = odata + (channels * ((y - y1) * dx + (x - x1)));
p_source = rgb_image + (channels * (y * width + x));
for (int _channels = 0; _channels < channels; ++_channels)
p_target[_channels] = p_source[_channels];
}
// stbi_write_jpg(_template1.c_str(), dx, dy, channels, odata, 0);
stbi_write_bmp(_template1.c_str(), dx, dy, channels, odata);
RGBImageRelease();
stbi_image_free(odata);
}
void CAlignAndCutImage::CutAndSave(int x1, int y1, int dx, int dy, CImageBasis *_target)
{
int x2, y2;
x2 = x1 + dx;
y2 = y1 + dy;
x2 = std::min(x2, width - 1);
y2 = std::min(y2, height - 1);
dx = x2 - x1;
dy = y2 - y1;
if ((_target->height != dy) || (_target->width != dx) || (_target->channels != channels))
{
printf("CAlignAndCutImage::CutAndSave - Bildgröße passt nicht !!!!!!!!!");
return;
}
uint8_t* odata = _target->RGBImageLock();
RGBImageLock();
stbi_uc* p_target;
stbi_uc* p_source;
for (int x = x1; x < x2; ++x)
for (int y = y1; y < y2; ++y)
{
p_target = odata + (channels * ((y - y1) * dx + (x - x1)));
p_source = rgb_image + (channels * (y * width + x));
for (int _channels = 0; _channels < channels; ++_channels)
p_target[_channels] = p_source[_channels];
}
RGBImageRelease();
_target->RGBImageRelease();
}
CImageBasis* CAlignAndCutImage::CutAndSave(int x1, int y1, int dx, int dy)
{
int x2, y2;
x2 = x1 + dx;
y2 = y1 + dy;
x2 = std::min(x2, width - 1);
y2 = std::min(y2, height - 1);
dx = x2 - x1;
dy = y2 - y1;
int memsize = dx * dy * channels;
uint8_t* odata = (unsigned char*)GET_MEMORY(memsize);
stbi_uc* p_target;
stbi_uc* p_source;
RGBImageLock();
for (int x = x1; x < x2; ++x)
for (int y = y1; y < y2; ++y)
{
p_target = odata + (channels * ((y - y1) * dx + (x - x1)));
p_source = rgb_image + (channels * (y * width + x));
for (int _channels = 0; _channels < channels; ++_channels)
p_target[_channels] = p_source[_channels];
}
CImageBasis* rs = new CImageBasis(odata, channels, dx, dy, bpp);
RGBImageRelease();
rs->SetIndepended();
return rs;
}

View File

@@ -0,0 +1,21 @@
#include "CImageBasis.h"
#include "CFindTemplate.h"
class CAlignAndCutImage : public CImageBasis
{
public:
int t0_dx, t0_dy, t1_dx, t1_dy;
CImageBasis *ImageTMP;
CAlignAndCutImage(std::string _image) : CImageBasis(_image) {ImageTMP = NULL;};
CAlignAndCutImage(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp) : CImageBasis(_rgb_image, _channels, _width, _height, _bpp) {ImageTMP = NULL;};
CAlignAndCutImage(CImageBasis *_org, CImageBasis *_temp);
bool Align(RefInfo *_temp1, RefInfo *_temp2);
// void Align(std::string _template1, int x1, int y1, std::string _template2, int x2, int y2, int deltax = 40, int deltay = 40, std::string imageROI = "");
void CutAndSave(std::string _template1, int x1, int y1, int dx, int dy);
CImageBasis* CutAndSave(int x1, int y1, int dx, int dy);
void CutAndSave(int x1, int y1, int dx, int dy, CImageBasis *_target);
void GetRefSize(int *ref_dx, int *ref_dy);
};

View File

@@ -1,547 +1,185 @@
#include "CFindTemplate.h"
#include "Helper.h"
#include "ClassLogFile.h"
#include "esp_system.h"
// #define DEBUG_DETAIL_ON
#define _USE_MATH_DEFINES
#include <math.h>
#include <algorithm>
#define _ESP32_PSRAM
using namespace std;
#define GET_MEMORY malloc
/*
CResizeImage::CResizeImage(std::string _image, int _new_dx, int _new_dy)
bool CFindTemplate::FindTemplate(RefInfo *_ref)
{
CImageBasis::CImageBasis(_image);
}
*/
uint8_t* rgb_template = stbi_load(_ref->image_file.c_str(), &tpl_width, &tpl_height, &tpl_bpp, channels);
uint8_t CImageBasis::GetPixelColor(int x, int y, int ch)
{
stbi_uc* p_source;
p_source = this->rgb_image + (this->channels * (y * this->width + x));
return p_source[ch];
}
void CResizeImage::Resize(int _new_dx, int _new_dy)
{
int memsize = _new_dx * _new_dy * this->channels;
uint8_t* odata = (unsigned char*)GET_MEMORY(memsize);
stbir_resize_uint8(this->rgb_image, this->width, this->height, 0, odata, _new_dx, _new_dy, 0, this->channels);
stbi_image_free(this->rgb_image);
this->rgb_image = (unsigned char*)GET_MEMORY(memsize);
this->memCopy(odata, this->rgb_image, memsize);
this->width = _new_dx;
this->height = _new_dy;
stbi_image_free(odata);
}
void CRotate::Mirror(){
int memsize = this->width * this->height * this->channels;
uint8_t* odata = (unsigned char*)GET_MEMORY(memsize);
int x_source, y_source;
stbi_uc* p_target;
stbi_uc* p_source;
for (int x = 0; x < this->width; ++x)
for (int y = 0; y < this->height; ++y)
{
p_target = odata + (this->channels * (y * this->width + x));
x_source = this->width - x;
y_source = y;
p_source = this->rgb_image + (this->channels * (y_source * this->width + x_source));
for (int channels = 0; channels < this->channels; ++channels)
p_target[channels] = p_source[channels];
}
// memcpy(this->rgb_image, odata, memsize);
this->memCopy(odata, this->rgb_image, memsize);
stbi_image_free(odata);
}
void CRotate::Rotate(float _angle, int _centerx, int _centery)
{
float m[2][3];
float x_center = _centerx;
float y_center = _centery;
_angle = _angle / 180 * M_PI;
m[0][0] = cos(_angle);
m[0][1] = sin(_angle);
m[0][2] = (1 - m[0][0]) * x_center - m[0][1] * y_center;
m[1][0] = -m[0][1];
m[1][1] = m[0][0];
m[1][2] = m[0][1] * x_center + (1 - m[0][0]) * y_center;
int memsize = this->width * this->height * this->channels;
uint8_t* odata = (unsigned char*)GET_MEMORY(memsize);
int x_source, y_source;
stbi_uc* p_target;
stbi_uc* p_source;
for (int x = 0; x < this->width; ++x)
for (int y = 0; y < this->height; ++y)
{
p_target = odata + (this->channels * (y * this->width + x));
x_source = int(m[0][0] * x + m[0][1] * y);
y_source = int(m[1][0] * x + m[1][1] * y);
x_source += int(m[0][2]);
y_source += int(m[1][2]);
if ((x_source >= 0) && (x_source < this->width) && (y_source >= 0) && (y_source < this->height))
{
p_source = this->rgb_image + (this->channels * (y_source * this->width + x_source));
for (int channels = 0; channels < this->channels; ++channels)
p_target[channels] = p_source[channels];
}
else
{
for (int channels = 0; channels < this->channels; ++channels)
p_target[channels] = 255;
}
}
// memcpy(this->rgb_image, odata, memsize);
this->memCopy(odata, this->rgb_image, memsize);
stbi_image_free(odata);
}
void CRotate::Rotate(float _angle)
{
this->Rotate(_angle, this->width / 2, this->height / 2);
}
void CRotate::Translate(int _dx, int _dy)
{
int memsize = this->width * this->height * this->channels;
uint8_t* odata = (unsigned char*)GET_MEMORY(memsize);
int x_source, y_source;
stbi_uc* p_target;
stbi_uc* p_source;
for (int x = 0; x < this->width; ++x)
for (int y = 0; y < this->height; ++y)
{
p_target = odata + (this->channels * (y * this->width + x));
x_source = x - _dx;
y_source = y - _dy;
if ((x_source >= 0) && (x_source < this->width) && (y_source >= 0) && (y_source < this->height))
{
p_source = this->rgb_image + (this->channels * (y_source * this->width + x_source));
for (int channels = 0; channels < this->channels; ++channels)
p_target[channels] = p_source[channels];
}
else
{
for (int channels = 0; channels < this->channels; ++channels)
p_target[channels] = 255;
}
}
// memcpy(this->rgb_image, odata, memsize);
this->memCopy(odata, this->rgb_image, memsize);
stbi_image_free(odata);
}
CFindTemplate::CFindTemplate(std::string _image)
{
this->channels = 1;
this->rgb_image = stbi_load(_image.c_str(), &(this->width), &(this->height), &(this->bpp), this->channels);
}
void CFindTemplate::FindTemplate(std::string _template, int* found_x, int* found_y)
{
this->FindTemplate(_template, found_x, found_y, 0, 0);
}
void CFindTemplate::FindTemplate(std::string _template, int* found_x, int* found_y, int _dx, int _dy)
{
uint8_t* rgb_template = stbi_load(_template.c_str(), &tpl_width, &tpl_height, &tpl_bpp, this->channels);
// printf("FindTemplate 01\n");
int ow, ow_start, ow_stop;
int oh, oh_start, oh_stop;
if (_dx == 0)
if (_ref->search_x == 0)
{
_dx = this->width;
*found_x = 0;
_ref->search_x = width;
_ref->found_x = 0;
}
if (_dy == 0)
if (_ref->search_y == 0)
{
_dy = this->height;
*found_y = 0;
_ref->search_y = height;
_ref->found_y = 0;
}
ow_start = *found_x - _dx;
ow_start = _ref->target_x - _ref->search_x;
ow_start = std::max(ow_start, 0);
ow_stop = *found_x + _dx;
if ((ow_stop + tpl_width) > this->width)
ow_stop = this->width - tpl_width;
ow_stop = _ref->target_x + _ref->search_x;
if ((ow_stop + tpl_width) > width)
ow_stop = width - tpl_width;
ow = ow_stop - ow_start + 1;
oh_start = *found_y - _dy;
oh_start = _ref->target_y - _ref->search_y;
oh_start = std::max(oh_start, 0);
oh_stop = *found_y + _dy;
if ((oh_stop + tpl_height) > this->height)
oh_stop = this->height - tpl_height;
oh_stop = _ref->target_y + _ref->search_y;
if ((oh_stop + tpl_height) > height)
oh_stop = height - tpl_height;
oh = oh_stop - oh_start + 1;
uint8_t* odata = (unsigned char*)GET_MEMORY(ow * oh * this->channels);
float avg, SAD;
int min, max;
bool isSimilar = false;
// printf("FindTemplate 02\n");
if ((_ref->alignment_algo == 2) && (_ref->fastalg_x > -1) && (_ref->fastalg_y > -1)) // für Testzwecke immer Berechnen
{
isSimilar = CalculateSimularities(rgb_template, _ref->fastalg_x, _ref->fastalg_y, ow, oh, min, avg, max, SAD, _ref->fastalg_SAD, _ref->fastalg_SAD_criteria);
#ifdef DEBUG_DETAIL_ON
std::string zw = "\t" + _ref->image_file + "\tt1_x_y:\t" + std::to_string(_ref->fastalg_x) + "\t" + std::to_string(_ref->fastalg_y);
zw = zw + "\tpara1_found_min_avg_max_SAD:\t" + std::to_string(min) + "\t" + std::to_string(avg) + "\t" + std::to_string(max) + "\t"+ std::to_string(SAD);
LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", zw);
#endif
}
// printf("FindTemplate 03\n");
if (isSimilar)
{
#ifdef DEBUG_DETAIL_ON
LogFile.WriteToFile("Use FastAlignment sucessfull");
#endif
_ref->found_x = _ref->fastalg_x;
_ref->found_y = _ref->fastalg_y;
return true;
}
// printf("FindTemplate 04\n");
double aktSAD;
double minSAD = pow(tpl_width * tpl_height * 255, 2);
for (int xouter = ow_start; xouter <= ow_stop; xouter++)
for (int youter = oh_start; youter <= oh_stop; ++youter)
RGBImageLock();
// printf("FindTemplate 05\n");
int xouter, youter, tpl_x, tpl_y, _ch;
int _anzchannels = channels;
if (_ref->alignment_algo == 0) // 0 = "Default" (nur R-Kanal)
_anzchannels = 1;
for (xouter = ow_start; xouter <= ow_stop; xouter++)
for (youter = oh_start; youter <= oh_stop; ++youter)
{
aktSAD = 0;
for (int tpl_x = 0; tpl_x < tpl_width; tpl_x++)
for (int tpl_y = 0; tpl_y < tpl_height; tpl_y++)
for (tpl_x = 0; tpl_x < tpl_width; tpl_x++)
for (tpl_y = 0; tpl_y < tpl_height; tpl_y++)
{
stbi_uc* p_org = this->rgb_image + (this->channels * ((youter + tpl_y) * this->width + (xouter + tpl_x)));
stbi_uc* p_tpl = rgb_template + (this->channels * (tpl_y * tpl_width + tpl_x));
aktSAD += pow(p_tpl[0] - p_org[0], 2);
stbi_uc* p_org = rgb_image + (channels * ((youter + tpl_y) * width + (xouter + tpl_x)));
stbi_uc* p_tpl = rgb_template + (channels * (tpl_y * tpl_width + tpl_x));
for (_ch = 0; _ch < _anzchannels; ++_ch)
{
aktSAD += pow(p_tpl[_ch] - p_org[_ch], 2);
}
}
stbi_uc* p_out = odata + (this->channels * ((youter - oh_start) * ow + (xouter - ow_start)));
p_out[0] = int(sqrt(aktSAD / (tpl_width * tpl_height)));
if (aktSAD < minSAD)
{
minSAD = aktSAD;
*found_x = xouter;
*found_y = youter;
_ref->found_x = xouter;
_ref->found_y = youter;
}
}
stbi_write_bmp("sdcard\\find.bmp", ow, oh, this->channels, odata);
stbi_image_free(odata);
stbi_image_free(rgb_template);
}
void CFindTemplate::FindTemplate(std::string _template, int* found_x, int* found_y, std::string _imageout)
{
this->FindTemplate(_template, found_x, found_y);
this->SaveToFile(_imageout);
}
void CFindTemplate::FindTemplate(std::string _template, int* found_x, int* found_y, int _dx, int _dy, std::string _imageout)
{
this->FindTemplate(_template, found_x, found_y, _dx, _dy);
this->SaveToFile(_imageout);
}
// printf("FindTemplate 06\n");
void CImageBasis::memCopy(uint8_t* _source, uint8_t* _target, int _size)
{
#ifdef _ESP32_PSRAM
for (int i = 0; i < _size; ++i)
*(_target + i) = *(_source + i);
#else
memcpy(_target, _source, _size);
#endif
}
bool CImageBasis::isInImage(int x, int y)
{
if ((x < 0) || (x > this->width - 1))
return false;
if ((y < 0) || (y > this->height- 1))
return false;
return true;
}
void CImageBasis::setPixelColor(int x, int y, int r, int g, int b)
{
stbi_uc* p_source;
p_source = this->rgb_image + (this->channels * (y * this->width + x));
p_source[0] = r;
if (this-> channels > 2)
{
p_source[1] = g;
p_source[2] = b;
}
}
void CImageBasis::drawRect(int x, int y, int dx, int dy, int r, int g, int b, int thickness)
{
int zwx1, zwx2, zwy1, zwy2;
int _x, _y, _thick;
zwx1 = x - thickness + 1;
zwx2 = x + dx + thickness - 1;
zwy1 = y;
zwy2 = y;
for (_thick = 0; _thick < thickness; _thick++)
for (_x = zwx1; _x <= zwx2; ++_x)
for (_y = zwy1; _y <= zwy2; _y++)
if (isInImage(_x, _y))
setPixelColor(_x, _y - _thick, r, g, b);
zwx1 = x - thickness + 1;
zwx2 = x + dx + thickness - 1;
zwy1 = y + dy;
zwy2 = y + dy;
for (_thick = 0; _thick < thickness; _thick++)
for (_x = zwx1; _x <= zwx2; ++_x)
for (_y = zwy1; _y <= zwy2; _y++)
if (isInImage(_x, _y))
setPixelColor(_x, _y + _thick, r, g, b);
zwx1 = x;
zwx2 = x;
zwy1 = y;
zwy2 = y + dy;
for (_thick = 0; _thick < thickness; _thick++)
for (_x = zwx1; _x <= zwx2; ++_x)
for (_y = zwy1; _y <= zwy2; _y++)
if (isInImage(_x, _y))
setPixelColor(_x - _thick, _y, r, g, b);
zwx1 = x + dx;
zwx2 = x + dx;
zwy1 = y;
zwy2 = y + dy;
for (_thick = 0; _thick < thickness; _thick++)
for (_x = zwx1; _x <= zwx2; ++_x)
for (_y = zwy1; _y <= zwy2; _y++)
if (isInImage(_x, _y))
setPixelColor(_x + _thick, _y, r, g, b);
}
void CImageBasis::drawLine(int x1, int y1, int x2, int y2, int r, int g, int b, int thickness)
{
int _x, _y, _thick;
int _zwy1, _zwy2;
thickness = (thickness-1) / 2;
for (_thick = 0; _thick <= thickness; ++_thick)
for (_x = x1 - _thick; _x <= x2 + _thick; ++_x)
{
if (x2 == x1)
{
_zwy1 = y1;
_zwy2 = y2;
}
else
{
_zwy1 = (y2 - y1) * (float)(_x - x1) / (float)(x2 - x1) + y1;
_zwy2 = (y2 - y1) * (float)(_x + 1 - x1) / (float)(x2 - x1) + y1;
}
for (_y = _zwy1 - _thick; _y <= _zwy2 + _thick; _y++)
if (isInImage(_x, _y))
setPixelColor(_x, _y, r, g, b);
}
}
void CImageBasis::drawCircle(int x1, int y1, int rad, int r, int g, int b, int thickness)
{
float deltarad, aktrad;
int _thick, _x, _y;
deltarad = 1 / (4 * M_PI * (rad + thickness - 1));
for (aktrad = 0; aktrad <= (2 * M_PI); aktrad += deltarad)
for (_thick = 0; _thick < thickness; ++_thick)
{
_x = sin(aktrad) * (rad + _thick) + x1;
_y = cos(aktrad) * (rad + _thick) + y1;
if (isInImage(_x, _y))
setPixelColor(_x, _y, r, g, b);
}
}
CImageBasis::CImageBasis()
{
this->externalImage = false;
}
CImageBasis::CImageBasis(std::string _image)
{
channels = 3;
externalImage = false;
filename = _image;
// long freebefore = esp_get_free_heap_size();
rgb_image = stbi_load(_image.c_str(), &width, &height, &bpp, channels);
// if (rgb_image == NULL)
// LogFile.WriteToFile("Image Load failed:" + _image + " FreeHeapSize before: " + to_string(freebefore) + " after: " + to_string(esp_get_free_heap_size()));
// printf("CImageBasis after load\n");
// printf("w %d, h %d, b %d, c %d", this->width, this->height, this->bpp, this->channels);
}
bool CImageBasis::ImageOkay(){
return rgb_image != NULL;
}
CImageBasis::CImageBasis(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp)
{
this->rgb_image = _rgb_image;
this->channels = _channels;
this->width = _width;
this->height = _height;
this->bpp = _bpp;
this->externalImage = true;
}
void CImageBasis::Contrast(float _contrast) //input range [-100..100]
{
stbi_uc* p_source;
float contrast = (_contrast/100) + 1; //convert to decimal & shift range: [0..2]
float intercept = 128 * (1 - contrast);
for (int x = 0; x < width; ++x)
for (int y = 0; y < height; ++y)
{
p_source = this->rgb_image + (this->channels * (y * this->width + x));
for (int channels = 0; channels < this->channels; ++channels)
p_source[channels] = (uint8_t) std::min(255, std::max(0, (int) (p_source[channels] * contrast + intercept)));
}
}
CImageBasis::~CImageBasis()
{
if (!this->externalImage)
stbi_image_free(this->rgb_image);
}
void CImageBasis::SaveToFile(std::string _imageout)
{
string typ = getFileType(_imageout);
if ((typ == "jpg") || (typ == "JPG")) // ACHTUNG PROBLEMATISCH IM ESP32
{
stbi_write_jpg(_imageout.c_str(), this->width, this->height, this->channels, this->rgb_image, 0);
}
if ((typ == "bmp") || (typ == "BMP"))
{
stbi_write_bmp(_imageout.c_str(), this->width, this->height, this->channels, this->rgb_image);
}
// stbi_write_jpg(_imageout.c_str(), this->width, this->height, this->channels, this->rgb_image, 0);
// stbi_write_bmp(_imageout.c_str(), this->width, this->height, this->channels, this->rgb_image);
}
if (_ref->alignment_algo == 2)
CalculateSimularities(rgb_template, _ref->found_x, _ref->found_y, ow, oh, min, avg, max, SAD, _ref->fastalg_SAD, _ref->fastalg_SAD_criteria);
// printf("FindTemplate 07\n");
void CAlignAndCutImage::Align(std::string _template0, int ref0_x, int ref0_y, std::string _template1, int ref1_x, int ref1_y, int deltax, int deltay, std::string imageROI)
{
int dx, dy;
int r0_x, r0_y, r1_x, r1_y;
CFindTemplate* ft = new CFindTemplate(this->filename);
r0_x = ref0_x;
r0_y = ref0_y;
ft->FindTemplate(_template0, &r0_x, &r0_y, deltax, deltay);
t0_dx = ft->tpl_width;
t0_dy = ft->tpl_height;
r1_x = ref1_x;
r1_y = ref1_y;
ft->FindTemplate(_template1, &r1_x, &r1_y, deltax, deltay);
t1_dx = ft->tpl_width;
t1_dy = ft->tpl_height;
delete ft;
_ref->fastalg_x = _ref->found_x;
_ref->fastalg_y = _ref->found_y;
_ref->fastalg_min = min;
_ref->fastalg_avg = avg;
_ref->fastalg_max = max;
_ref->fastalg_SAD = SAD;
dx = ref0_x - r0_x;
dy = ref0_y - r0_y;
r0_x += dx;
r0_y += dy;
r1_x += dx;
r1_y += dy;
float w_org, w_ist, d_winkel;
w_org = atan2(ref1_y - ref0_y, ref1_x - ref0_x);
w_ist = atan2(r1_y - r0_y, r1_x - r0_x);
d_winkel = (w_org - w_ist) * 180 / M_PI;
if (imageROI.length() > 0)
{
CImageBasis* imgzw = new CImageBasis(this->filename);
imgzw->drawRect(r0_x, r0_y, t0_dx, t0_dy, 255, 0, 0, 2);
imgzw->drawRect(r1_x, r1_y, t1_dx, t1_dy, 255, 0, 0, 2);
imgzw->SaveToFile(imageROI);
printf("Alignment: alignment ROI created: %s\n", imageROI.c_str());
delete imgzw;
}
string zw = "\tdx:\t" + to_string(dx) + "\tdy:\t" + to_string(dy) + "\td_winkel:\t" + to_string(d_winkel);
#ifdef DEBUG_DETAIL_ON
std::string zw = "\t" + _ref->image_file + "\tt1_x_y:\t" + std::to_string(_ref->fastalg_x) + "\t" + std::to_string(_ref->fastalg_y);
zw = zw + "\tpara1_found_min_avg_max_SAD:\t" + std::to_string(min) + "\t" + std::to_string(avg) + "\t" + std::to_string(max) + "\t"+ std::to_string(SAD);
LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", zw);
#endif
CRotate rt(this->rgb_image, this->channels, this->width, this->height, this->bpp);
rt.Translate(dx, dy);
rt.Rotate(d_winkel, ref0_x, ref0_y);
printf("Alignment: dx %d - dy %d - rot %f\n", dx, dy, d_winkel);
RGBImageRelease();
stbi_image_free(rgb_template);
// printf("FindTemplate 08\n");
return false;
}
void CAlignAndCutImage::CutAndSave(std::string _template1, int x1, int y1, int dx, int dy)
bool CFindTemplate::CalculateSimularities(uint8_t* _rgb_tmpl, int _startx, int _starty, int _sizex, int _sizey, int &min, float &avg, int &max, float &SAD, float _SADold, float _SADcrit)
{
int dif;
int minDif = 255;
int maxDif = -255;
double avgDifSum = 0;
long int anz = 0;
double aktSAD = 0;
int x2, y2;
int xouter, youter, _ch;
x2 = x1 + dx;
y2 = y1 + dy;
x2 = min(x2, this->width - 1);
y2 = min(y2, this->height - 1);
dx = x2 - x1;
dy = y2 - y1;
int memsize = dx * dy * this->channels;
uint8_t* odata = (unsigned char*)GET_MEMORY(memsize);
stbi_uc* p_target;
stbi_uc* p_source;
for (int x = x1; x < x2; ++x)
for (int y = y1; y < y2; ++y)
for (xouter = 0; xouter <= _sizex; xouter++)
for (youter = 0; youter <= _sizey; ++youter)
{
p_target = odata + (this->channels * ((y - y1) * dx + (x - x1)));
p_source = this->rgb_image + (this->channels * (y * this->width + x));
for (int channels = 0; channels < this->channels; ++channels)
p_target[channels] = p_source[channels];
stbi_uc* p_org = rgb_image + (channels * ((youter + _starty) * width + (xouter + _startx)));
stbi_uc* p_tpl = _rgb_tmpl + (channels * (youter * tpl_width + xouter));
for (_ch = 0; _ch < channels; ++_ch)
{
dif = p_tpl[_ch] - p_org[_ch];
aktSAD += pow(p_tpl[_ch] - p_org[_ch], 2);
if (dif < minDif) minDif = dif;
if (dif > maxDif) maxDif = dif;
avgDifSum += dif;
anz++;
}
}
// stbi_write_jpg(_template1.c_str(), dx, dy, this->channels, odata, 0);
stbi_write_bmp(_template1.c_str(), dx, dy, this->channels, odata);
avg = avgDifSum / anz;
min = minDif;
max = maxDif;
SAD = sqrt(aktSAD) / anz;
stbi_image_free(odata);
float _SADdif = abs(SAD - _SADold);
printf("Anzahl %ld, avgDifSum %fd, avg %f, SAD_neu: %fd, _SAD_old: %f, _SAD_crit:%f\n", anz, avgDifSum, avg, SAD, _SADold, _SADdif);
if (_SADdif <= _SADcrit)
return true;
return false;
}

View File

@@ -1,98 +1,40 @@
#pragma once
#ifndef __CFINDTEMPLATE_CLASS
#define __CFINDTEMPLATE_CLASS
#include "CImageBasis.h"
#ifndef __CFINDTEMPLATE
#define __CFINGTEMPLATE
#include <stdint.h>
#include <string>
#define _USE_MATH_DEFINES
#include <math.h>
#include "stb_image.h"
#include "stb_image_write.h"
#include "stb_image_resize.h"
class CImageBasis
{
protected:
uint8_t* rgb_image;
int channels;
int width, height, bpp;
bool externalImage;
std::string filename;
void memCopy(uint8_t* _source, uint8_t* _target, int _size);
bool isInImage(int x, int y);
public:
int getWidth(){return this->width;};
int getHeight(){return this->height;};
int getChannels(){return this->channels;};
void drawRect(int x, int y, int dx, int dy, int r = 255, int g = 255, int b = 255, int thickness = 1);
void drawLine(int x1, int y1, int x2, int y2, int r, int g, int b, int thickness = 1);
void drawCircle(int x1, int y1, int rad, int r, int g, int b, int thickness = 1);
void setPixelColor(int x, int y, int r, int g, int b);
void Contrast(float _contrast);
bool ImageOkay();
CImageBasis();
CImageBasis(std::string _image);
CImageBasis(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp);
uint8_t GetPixelColor(int x, int y, int ch);
~CImageBasis();
void SaveToFile(std::string _imageout);
struct RefInfo {
std::string image_file;
int target_x = 0;
int target_y = 0;
int width = 0;
int height = 0;
int found_x;
int found_y;
int search_x;
int search_y;
int fastalg_x = -1;
int fastalg_y = -1;
int fastalg_min = -256;
float fastalg_avg = -1;
int fastalg_max = -1;
float fastalg_SAD = -1;
float fastalg_SAD_criteria = -1;
int alignment_algo = 0; // 0 = "Default" (nur R-Kanal), 1 = "HighAccurity" (RGB-Kanal), 2 = "Fast" (1.x RGB, dann isSimilar)
};
class CFindTemplate : public CImageBasis
{
public:
int tpl_width, tpl_height, tpl_bpp;
CFindTemplate(std::string _image);
CFindTemplate(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp) : CImageBasis(_rgb_image, _channels, _width, _height, _bpp) {};
void FindTemplate(std::string _template, int* found_x, int* found_y, std::string _imageout);
void FindTemplate(std::string _template, int* found_x, int* found_y, int _dx, int _dy, std::string _imageout);
void FindTemplate(std::string _template, int* found_x, int* found_y);
void FindTemplate(std::string _template, int* found_x, int* found_y, int _dx, int _dy);
bool FindTemplate(RefInfo *_ref);
bool CalculateSimularities(uint8_t* _rgb_tmpl, int _startx, int _starty, int _sizex, int _sizey, int &min, float &avg, int &max, float &SAD, float _SADold, float _SADcrit);
};
class CRotate: public CImageBasis
{
public:
CRotate(std::string _image) : CImageBasis(_image) {};
CRotate(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp) : CImageBasis(_rgb_image, _channels, _width, _height, _bpp) {};
void Rotate(float _angle);
void Rotate(float _angle, int _centerx, int _centery);
void Translate(int _dx, int _dy);
void Mirror();
};
class CAlignAndCutImage : public CImageBasis
{
public:
int t0_dx, t0_dy, t1_dx, t1_dy;
CAlignAndCutImage(std::string _image) : CImageBasis(_image) {};
void Align(std::string _template1, int x1, int y1, std::string _template2, int x2, int y2, int deltax = 40, int deltay = 40, std::string imageROI = "");
void CutAndSave(std::string _template1, int x1, int y1, int dx, int dy);
};
class CResizeImage : public CImageBasis
{
public:
CResizeImage(std::string _image) : CImageBasis(_image) {};
// CResizeImage(std::string _image, int _new_dx, int _new_dy);
void Resize(int _new_dx, int _new_dy);
};
#endif

View File

@@ -0,0 +1,523 @@
#include "CImageBasis.h"
#include "Helper.h"
#include "ClassLogFile.h"
#include <esp_log.h>
#include "esp_system.h"
#include <cstring>
#define _USE_MATH_DEFINES
#include <math.h>
#include <algorithm>
#define _ESP32_PSRAM
using namespace std;
static const char *TAG = "CImageBasis";
//#define DEBUG_DETAIL_ON
uint8_t * CImageBasis::RGBImageLock(int _waitmaxsec)
{
if (islocked)
{
#ifdef DEBUG_DETAIL_ON
printf("Image is locked: sleep for : %ds\n", _waitmaxsec);
#endif
TickType_t xDelay;
xDelay = 1000 / portTICK_PERIOD_MS;
for (int i = 0; i <= _waitmaxsec; ++i)
{
vTaskDelay( xDelay );
if (!islocked)
break;
}
}
if (islocked)
return NULL;
return rgb_image;
}
void CImageBasis::RGBImageRelease()
{
islocked = false;
}
uint8_t * CImageBasis::RGBImageGet()
{
return rgb_image;
}
void writejpghelp(void *context, void *data, int size)
{
// printf("Size all: %d, size %d\n", ((ImageData*)context)->size, size);
ImageData* _zw = (ImageData*) context;
uint8_t *voidstart = _zw->data;
uint8_t *datastart = (uint8_t*) data;
voidstart += _zw->size;
for (int i = 0; i < size; ++i)
*(voidstart + i) = *(datastart + i);
_zw->size += size;
}
ImageData* CImageBasis::writeToMemoryAsJPG(const int quality)
{
ImageData* ii = new ImageData;
RGBImageLock();
stbi_write_jpg_to_func(writejpghelp, ii, width, height, channels, rgb_image, quality);
RGBImageRelease();
return ii;
}
#define HTTP_BUFFER_SENT 1024
struct SendJPGHTTP
{
httpd_req_t *req;
esp_err_t res;
char buf[HTTP_BUFFER_SENT];
int size = 0;
};
inline void writejpgtohttphelp(void *context, void *data, int size)
{
SendJPGHTTP* _send = (SendJPGHTTP*) context;
if ((_send->size + size) >= HTTP_BUFFER_SENT) // data passt nich mehr in buffer
{
httpd_req_t *_req = _send->req;
if (httpd_resp_send_chunk(_req, _send->buf, _send->size) != ESP_OK)
{
ESP_LOGE(TAG, "File sending failed!");
_send->res = ESP_FAIL;
}
_send->size = 0;
}
std::memcpy((void*) (&(_send->buf[0]) + _send->size), data, size);
_send->size+= size;
}
esp_err_t CImageBasis::SendJPGtoHTTP(httpd_req_t *_req, const int quality)
{
SendJPGHTTP ii;
ii.req = _req;
ii.res = ESP_OK;
ii.size = 0;
RGBImageLock();
stbi_write_jpg_to_func(writejpgtohttphelp, &ii, width, height, channels, rgb_image, quality);
RGBImageRelease();
if (ii.size > 0)
{
if (httpd_resp_send_chunk(_req, (char*) ii.buf, ii.size) != ESP_OK) // verschicke noch den Rest
{
ESP_LOGE(TAG, "File sending failed!");
ii.res = ESP_FAIL;
}
}
return ii.res;
}
bool CImageBasis::CopyFromMemory(uint8_t* _source, int _size)
{
int gr = height * width * channels;
if (gr != _size) // Größe passt nicht
{
printf("Kann Bild nicht von Speicher kopierte - Größen passen nicht zusammen: soll %d, ist %d\n", _size, gr);
return false;
}
RGBImageLock();
memCopy(_source, rgb_image, _size);
RGBImageRelease();
return true;
}
uint8_t CImageBasis::GetPixelColor(int x, int y, int ch)
{
stbi_uc* p_source;
p_source = rgb_image + (channels * (y * width + x));
return p_source[ch];
}
void CImageBasis::memCopy(uint8_t* _source, uint8_t* _target, int _size)
{
#ifdef _ESP32_PSRAM
for (int i = 0; i < _size; ++i)
*(_target + i) = *(_source + i);
#else
memcpy(_target, _source, _size);
#endif
}
bool CImageBasis::isInImage(int x, int y)
{
if ((x < 0) || (x > width - 1))
return false;
if ((y < 0) || (y > height- 1))
return false;
return true;
}
void CImageBasis::setPixelColor(int x, int y, int r, int g, int b)
{
stbi_uc* p_source;
RGBImageLock();
p_source = rgb_image + (channels * (y * width + x));
p_source[0] = r;
if ( channels > 2)
{
p_source[1] = g;
p_source[2] = b;
}
RGBImageRelease();
}
void CImageBasis::drawRect(int x, int y, int dx, int dy, int r, int g, int b, int thickness)
{
int zwx1, zwx2, zwy1, zwy2;
int _x, _y, _thick;
zwx1 = x - thickness + 1;
zwx2 = x + dx + thickness - 1;
zwy1 = y;
zwy2 = y;
for (_thick = 0; _thick < thickness; _thick++)
for (_x = zwx1; _x <= zwx2; ++_x)
for (_y = zwy1; _y <= zwy2; _y++)
if (isInImage(_x, _y))
setPixelColor(_x, _y - _thick, r, g, b);
zwx1 = x - thickness + 1;
zwx2 = x + dx + thickness - 1;
zwy1 = y + dy;
zwy2 = y + dy;
for (_thick = 0; _thick < thickness; _thick++)
for (_x = zwx1; _x <= zwx2; ++_x)
for (_y = zwy1; _y <= zwy2; _y++)
if (isInImage(_x, _y))
setPixelColor(_x, _y + _thick, r, g, b);
zwx1 = x;
zwx2 = x;
zwy1 = y;
zwy2 = y + dy;
for (_thick = 0; _thick < thickness; _thick++)
for (_x = zwx1; _x <= zwx2; ++_x)
for (_y = zwy1; _y <= zwy2; _y++)
if (isInImage(_x, _y))
setPixelColor(_x - _thick, _y, r, g, b);
zwx1 = x + dx;
zwx2 = x + dx;
zwy1 = y;
zwy2 = y + dy;
for (_thick = 0; _thick < thickness; _thick++)
for (_x = zwx1; _x <= zwx2; ++_x)
for (_y = zwy1; _y <= zwy2; _y++)
if (isInImage(_x, _y))
setPixelColor(_x + _thick, _y, r, g, b);
}
void CImageBasis::drawLine(int x1, int y1, int x2, int y2, int r, int g, int b, int thickness)
{
int _x, _y, _thick;
int _zwy1, _zwy2;
thickness = (thickness-1) / 2;
for (_thick = 0; _thick <= thickness; ++_thick)
for (_x = x1 - _thick; _x <= x2 + _thick; ++_x)
{
if (x2 == x1)
{
_zwy1 = y1;
_zwy2 = y2;
}
else
{
_zwy1 = (y2 - y1) * (float)(_x - x1) / (float)(x2 - x1) + y1;
_zwy2 = (y2 - y1) * (float)(_x + 1 - x1) / (float)(x2 - x1) + y1;
}
for (_y = _zwy1 - _thick; _y <= _zwy2 + _thick; _y++)
if (isInImage(_x, _y))
setPixelColor(_x, _y, r, g, b);
}
}
void CImageBasis::drawCircle(int x1, int y1, int rad, int r, int g, int b, int thickness)
{
float deltarad, aktrad;
int _thick, _x, _y;
deltarad = 1 / (4 * M_PI * (rad + thickness - 1));
for (aktrad = 0; aktrad <= (2 * M_PI); aktrad += deltarad)
for (_thick = 0; _thick < thickness; ++_thick)
{
_x = sin(aktrad) * (rad + _thick) + x1;
_y = cos(aktrad) * (rad + _thick) + y1;
if (isInImage(_x, _y))
setPixelColor(_x, _y, r, g, b);
}
}
CImageBasis::CImageBasis()
{
externalImage = false;
rgb_image = NULL;
width = 0;
height = 0;
channels = 0;
islocked = false;
}
void CImageBasis::CreateEmptyImage(int _width, int _height, int _channels)
{
bpp = _channels;
width = _width;
height = _height;
channels = _channels;
RGBImageLock();
int memsize = width * height * channels;
rgb_image = (unsigned char*)GET_MEMORY(memsize);
stbi_uc* p_source;
for (int x = 0; x < width; ++x)
for (int y = 0; y < height; ++y)
{
p_source = rgb_image + (channels * (y * width + x));
for (int _channels = 0; _channels < channels; ++_channels)
p_source[_channels] = (uint8_t) 0;
}
RGBImageRelease();
}
void CImageBasis::LoadFromMemory(stbi_uc *_buffer, int len)
{
RGBImageLock();
if (rgb_image)
stbi_image_free(rgb_image);
rgb_image = stbi_load_from_memory(_buffer, len, &width, &height, &channels, 3);
bpp = channels;
printf("Image loaded from memory: %d, %d, %d\n", width, height, channels);
RGBImageRelease();
}
CImageBasis::CImageBasis(CImageBasis *_copyfrom, int _anzrepeat)
{
islocked = false;
externalImage = false;
channels = _copyfrom->channels;
width = _copyfrom->width;
height = _copyfrom->height;
bpp = _copyfrom->bpp;
RGBImageLock();
int memsize = width * height * channels;
rgb_image = (unsigned char*)GET_MEMORY(memsize);
TickType_t xDelay;
int anz = 1;
while (!rgb_image && (anz < _anzrepeat))
{
printf("Create Image from Copy - Speicher ist voll - Versuche es erneut: %d.\n", anz);
xDelay = 1000 / portTICK_PERIOD_MS;
rgb_image = (unsigned char*) malloc(memsize);
anz++;
}
if (!rgb_image)
{
printf(getESPHeapInfo().c_str());
printf("\nKein freier Speicher mehr!!!! Benötigt: %d %d %d %d\n", width, height, channels, memsize);
RGBImageRelease();
return;
}
memCopy(_copyfrom->rgb_image, rgb_image, memsize);
RGBImageRelease();
}
CImageBasis::CImageBasis(int _width, int _height, int _channels)
{
islocked = false;
externalImage = false;
channels = _channels;
width = _width;
height = _height;
bpp = _channels;
int memsize = width * height * channels;
rgb_image = (unsigned char*)GET_MEMORY(memsize);
if (!rgb_image)
{
printf(getESPHeapInfo().c_str());
printf("\nKein freier Speicher mehr!!!! Benötigt: %d %d %d %d\n", width, height, channels, memsize);
return;
}
}
CImageBasis::CImageBasis(std::string _image)
{
islocked = false;
channels = 3;
externalImage = false;
filename = _image;
long zwld = esp_get_free_heap_size();
printf("freeheapsize before: %ld\n", zwld);
RGBImageLock();
rgb_image = stbi_load(_image.c_str(), &width, &height, &bpp, channels);
RGBImageRelease();
zwld = esp_get_free_heap_size();
printf("freeheapsize after : %ld\n", zwld);
std::string zw = "Image Load failed:" + _image + "\n";
if (rgb_image == NULL)
printf(zw.c_str());
zw = "CImageBasis after load " + _image + "\n";
printf(zw.c_str());
printf("w %d, h %d, b %d, c %d\n", width, height, bpp, channels);
}
bool CImageBasis::ImageOkay(){
return rgb_image != NULL;
}
CImageBasis::CImageBasis(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp)
{
islocked = false;
rgb_image = _rgb_image;
channels = _channels;
width = _width;
height = _height;
bpp = _bpp;
externalImage = true;
}
void CImageBasis::Contrast(float _contrast) //input range [-100..100]
{
stbi_uc* p_source;
float contrast = (_contrast/100) + 1; //convert to decimal & shift range: [0..2]
float intercept = 128 * (1 - contrast);
RGBImageLock();
for (int x = 0; x < width; ++x)
for (int y = 0; y < height; ++y)
{
p_source = rgb_image + (channels * (y * width + x));
for (int _channels = 0; _channels < channels; ++_channels)
p_source[_channels] = (uint8_t) std::min(255, std::max(0, (int) (p_source[_channels] * contrast + intercept)));
}
RGBImageRelease();
}
CImageBasis::~CImageBasis()
{
RGBImageLock();
if (!externalImage)
stbi_image_free(rgb_image);
}
void CImageBasis::SaveToFile(std::string _imageout)
{
string typ = getFileType(_imageout);
RGBImageLock();
if ((typ == "jpg") || (typ == "JPG")) // ACHTUNG PROBLEMATISCH IM ESP32
{
stbi_write_jpg(_imageout.c_str(), width, height, channels, rgb_image, 0);
}
if ((typ == "bmp") || (typ == "BMP"))
{
stbi_write_bmp(_imageout.c_str(), width, height, channels, rgb_image);
}
RGBImageRelease();
}
void CImageBasis::Resize(int _new_dx, int _new_dy)
{
int memsize = _new_dx * _new_dy * channels;
uint8_t* odata = (unsigned char*)GET_MEMORY(memsize);
RGBImageLock();
stbir_resize_uint8(rgb_image, width, height, 0, odata, _new_dx, _new_dy, 0, channels);
stbi_image_free(rgb_image);
rgb_image = (unsigned char*)GET_MEMORY(memsize);
memCopy(odata, rgb_image, memsize);
RGBImageRelease();
width = _new_dx;
height = _new_dy;
stbi_image_free(odata);
}
void CImageBasis::Resize(int _new_dx, int _new_dy, CImageBasis *_target)
{
if ((_target->height != _new_dy) || (_target->width != _new_dx) || (_target->channels != channels))
{
printf("CImageBasis::Resize - Targetbildgröße passt nicht !!!!!!!!!");
return;
}
RGBImageLock();
uint8_t* odata = _target->rgb_image;
stbir_resize_uint8(rgb_image, width, height, 0, odata, _new_dx, _new_dy, 0, channels);
RGBImageRelease();
}

View File

@@ -0,0 +1,94 @@
#pragma once
#ifndef __CIMAGEBASIS
#define __CIMAGEBASIS
#include <stdint.h>
#include <string>
#include <esp_http_server.h>
#define _USE_MATH_DEFINES
#include <math.h>
#include "stb_image.h"
#include "stb_image_write.h"
#include "stb_image_resize.h"
#include "esp_heap_caps.h"
//#define GET_MEMORY malloc
#define GET_MEMORY(X) heap_caps_malloc(X, MALLOC_CAP_SPIRAM)
#define MAX_JPG_SIZE 128000
struct ImageData
{
uint8_t data[MAX_JPG_SIZE];
size_t size = 0;
};
class CImageBasis
{
protected:
bool externalImage;
std::string filename;
void memCopy(uint8_t* _source, uint8_t* _target, int _size);
bool isInImage(int x, int y);
bool islocked;
public:
uint8_t* rgb_image;
int channels;
int width, height, bpp;
uint8_t * RGBImageLock(int _waitmaxsec = 60);
void RGBImageRelease();
uint8_t * RGBImageGet();
int getWidth(){return this->width;};
int getHeight(){return this->height;};
int getChannels(){return this->channels;};
void drawRect(int x, int y, int dx, int dy, int r = 255, int g = 255, int b = 255, int thickness = 1);
void drawLine(int x1, int y1, int x2, int y2, int r, int g, int b, int thickness = 1);
void drawCircle(int x1, int y1, int rad, int r, int g, int b, int thickness = 1);
void setPixelColor(int x, int y, int r, int g, int b);
void Contrast(float _contrast);
bool ImageOkay();
bool CopyFromMemory(uint8_t* _source, int _size);
void SetIndepended(){externalImage = false;};
void CreateEmptyImage(int _width, int _height, int _channels);
CImageBasis();
CImageBasis(std::string _image);
CImageBasis(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp);
CImageBasis(int _width, int _height, int _channels);
CImageBasis(CImageBasis *_copyfrom, int _anzrepeat = 0);
void Resize(int _new_dx, int _new_dy);
void Resize(int _new_dx, int _new_dy, CImageBasis *_target);
void LoadFromMemory(stbi_uc *_buffer, int len);
ImageData* writeToMemoryAsJPG(const int quality = 90);
esp_err_t SendJPGtoHTTP(httpd_req_t *req, const int quality = 90);
uint8_t GetPixelColor(int x, int y, int ch);
~CImageBasis();
void SaveToFile(std::string _imageout);
};
#endif

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_helper jomjol_logfile)
REQUIRES jomjol_helper jomjol_logfile esp_http_server)

View File

@@ -0,0 +1,192 @@
#include "CRotateImage.h"
CRotateImage::CRotateImage(CImageBasis *_org, CImageBasis *_temp)
{
rgb_image = _org->rgb_image;
channels = _org->channels;
width = _org->width;
height = _org->height;
bpp = _org->bpp;
externalImage = true;
ImageTMP = _temp;
islocked = false;
}
void CRotateImage::Mirror(){
int memsize = width * height * channels;
uint8_t* odata;
if (ImageTMP)
{
odata = ImageTMP->RGBImageLock();
}
else
{
odata = (unsigned char*)GET_MEMORY(memsize);
}
int x_source, y_source;
stbi_uc* p_target;
stbi_uc* p_source;
RGBImageLock();
for (int x = 0; x < width; ++x)
for (int y = 0; y < height; ++y)
{
p_target = odata + (channels * (y * width + x));
x_source = width - x;
y_source = y;
p_source = rgb_image + (channels * (y_source * width + x_source));
for (int _channels = 0; _channels < channels; ++_channels)
p_target[_channels] = p_source[_channels];
}
// memcpy(rgb_image, odata, memsize);
memCopy(odata, rgb_image, memsize);
if (!ImageTMP)
stbi_image_free(odata);
if (ImageTMP)
ImageTMP->RGBImageRelease();
RGBImageRelease();
}
void CRotateImage::Rotate(float _angle, int _centerx, int _centery)
{
float m[2][3];
float x_center = _centerx;
float y_center = _centery;
_angle = _angle / 180 * M_PI;
m[0][0] = cos(_angle);
m[0][1] = sin(_angle);
m[0][2] = (1 - m[0][0]) * x_center - m[0][1] * y_center;
m[1][0] = -m[0][1];
m[1][1] = m[0][0];
m[1][2] = m[0][1] * x_center + (1 - m[0][0]) * y_center;
int memsize = width * height * channels;
uint8_t* odata;
if (ImageTMP)
{
odata = ImageTMP->RGBImageLock();
}
else
{
odata = (unsigned char*)GET_MEMORY(memsize);
}
int x_source, y_source;
stbi_uc* p_target;
stbi_uc* p_source;
RGBImageLock();
for (int x = 0; x < width; ++x)
for (int y = 0; y < height; ++y)
{
p_target = odata + (channels * (y * width + x));
x_source = int(m[0][0] * x + m[0][1] * y);
y_source = int(m[1][0] * x + m[1][1] * y);
x_source += int(m[0][2]);
y_source += int(m[1][2]);
if ((x_source >= 0) && (x_source < width) && (y_source >= 0) && (y_source < height))
{
p_source = rgb_image + (channels * (y_source * width + x_source));
for (int _channels = 0; _channels < channels; ++_channels)
p_target[_channels] = p_source[_channels];
}
else
{
for (int _channels = 0; _channels < channels; ++_channels)
p_target[_channels] = 255;
}
}
// memcpy(rgb_image, odata, memsize);
memCopy(odata, rgb_image, memsize);
if (!ImageTMP)
{
stbi_image_free(odata);
}
if (ImageTMP)
ImageTMP->RGBImageRelease();
RGBImageRelease();
}
void CRotateImage::Rotate(float _angle)
{
// printf("width %d, height %d\n", width, height);
Rotate(_angle, width / 2, height / 2);
}
void CRotateImage::Translate(int _dx, int _dy)
{
int memsize = width * height * channels;
uint8_t* odata;
if (ImageTMP)
{
odata = ImageTMP->RGBImageLock();
}
else
{
odata = (unsigned char*)GET_MEMORY(memsize);
}
int x_source, y_source;
stbi_uc* p_target;
stbi_uc* p_source;
RGBImageLock();
for (int x = 0; x < width; ++x)
for (int y = 0; y < height; ++y)
{
p_target = odata + (channels * (y * width + x));
x_source = x - _dx;
y_source = y - _dy;
if ((x_source >= 0) && (x_source < width) && (y_source >= 0) && (y_source < height))
{
p_source = rgb_image + (channels * (y_source * width + x_source));
for (int _channels = 0; _channels < channels; ++_channels)
p_target[_channels] = p_source[_channels];
}
else
{
for (int _channels = 0; _channels < channels; ++_channels)
p_target[_channels] = 255;
}
}
// memcpy(rgb_image, odata, memsize);
memCopy(odata, rgb_image, memsize);
if (!ImageTMP)
{
stbi_image_free(odata);
}
if (ImageTMP)
{
ImageTMP->RGBImageRelease();
}
RGBImageRelease();
}

View File

@@ -0,0 +1,16 @@
#include "CImageBasis.h"
class CRotateImage: public CImageBasis
{
public:
CImageBasis *ImageTMP;
CRotateImage(std::string _image) : CImageBasis(_image) {ImageTMP = NULL;};
CRotateImage(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp) : CImageBasis(_rgb_image, _channels, _width, _height, _bpp) {ImageTMP = NULL;};
CRotateImage(CImageBasis *_org, CImageBasis *_temp);
void Rotate(float _angle);
void Rotate(float _angle, int _centerx, int _centery);
void Translate(int _dx, int _dy);
void Mirror();
};

View File

@@ -10,6 +10,50 @@ static const char *TAG = "log";
ClassLogFile LogFile("/sdcard/log/message", "log_%Y-%m-%d.txt");
void ClassLogFile::WriteHeapInfo(std::string _id)
{
std::string _zw = "\t" + _id;
if (loglevel > 0)
_zw = _zw + "\t" + getESPHeapInfo();
WriteToFile(_zw);
}
std::string ClassLogFile::getESPHeapInfo(){
string espInfoResultStr = "";
char aMsgBuf[80];
multi_heap_info_t aMultiHead_info ;
heap_caps_get_info (&aMultiHead_info,MALLOC_CAP_8BIT);
size_t aFreeHeapSize = heap_caps_get_free_size(MALLOC_CAP_8BIT);
size_t aMinFreeHeadSize = heap_caps_get_minimum_free_size(MALLOC_CAP_8BIT);
size_t aMinFreeHeapSize = heap_caps_get_minimum_free_size(MALLOC_CAP_8BIT);
size_t aHeapLargestFreeBlockSize = heap_caps_get_largest_free_block(MALLOC_CAP_8BIT);
sprintf(aMsgBuf,"Free Heap Size: \t%ld", (long) aFreeHeapSize);
size_t aFreeSPIHeapSize = heap_caps_get_free_size(MALLOC_CAP_8BIT| MALLOC_CAP_SPIRAM);
size_t aFreeInternalHeapSize = heap_caps_get_free_size(MALLOC_CAP_8BIT| MALLOC_CAP_INTERNAL);
size_t aMinFreeInternalHeapSize = heap_caps_get_minimum_free_size(MALLOC_CAP_8BIT| MALLOC_CAP_INTERNAL);
sprintf(aMsgBuf,"\tHeap:\t%ld", (long) aFreeHeapSize);
espInfoResultStr += string(aMsgBuf);
sprintf(aMsgBuf,"\tMin Free:\t%ld", (long) aMinFreeHeapSize);
espInfoResultStr += string(aMsgBuf);
sprintf(aMsgBuf,"\tlarg. Block: \t%ld", (long) aHeapLargestFreeBlockSize);
espInfoResultStr += string(aMsgBuf);
sprintf(aMsgBuf,"\tSPI Heap:\t%ld", (long) aFreeSPIHeapSize);
espInfoResultStr += string(aMsgBuf);
sprintf(aMsgBuf,"\tMin Free Heap Size:\t%ld", (long) aMinFreeHeadSize);
sprintf(aMsgBuf,"\tNOT_SPI Heap:\t%ld", (long) (aFreeHeapSize - aFreeSPIHeapSize));
espInfoResultStr += string(aMsgBuf);
sprintf(aMsgBuf,"\tlargest Block Size: \t%ld", (long) aHeapLargestFreeBlockSize);
sprintf(aMsgBuf,"\tInternal Heap:\t%ld", (long) (aFreeInternalHeapSize));
espInfoResultStr += string(aMsgBuf);
sprintf(aMsgBuf,"\tInternal Min Heap free:\t%ld", (long) (aMinFreeInternalHeapSize));
espInfoResultStr += string(aMsgBuf);
return espInfoResultStr;
}
void ClassLogFile::WriteToDedicatedFile(std::string _fn, std::string info, bool _time)
{
FILE* pFile;
@@ -19,7 +63,10 @@ void ClassLogFile::WriteToDedicatedFile(std::string _fn, std::string info, bool
return;
}
// pFile = OpenFileAndWait(_fn.c_str(), "a");
pFile = fopen(_fn.c_str(), "a+");
printf("Logfile opened: %s\n", _fn.c_str());
if (pFile!=NULL) {
if (_time)
{
@@ -54,6 +101,7 @@ void ClassLogFile::SetRetention(unsigned short _retentionInDays){
void ClassLogFile::WriteToFile(std::string info, bool _time)
{
/*
struct stat path_stat;
if (stat(logroot.c_str(), &path_stat) != 0) {
ESP_LOGI(TAG, "Create log folder: %s", logroot.c_str());
@@ -61,7 +109,7 @@ void ClassLogFile::WriteToFile(std::string info, bool _time)
ESP_LOGI(TAG, "Can't create log foolder");
}
}
*/
time_t rawtime;
struct tm* timeinfo;
char buffer[30];
@@ -79,12 +127,12 @@ std::string ClassLogFile::GetCurrentFileName()
{
time_t rawtime;
struct tm* timeinfo;
char buffer[30];
char buffer[60];
time(&rawtime);
timeinfo = localtime(&rawtime);
strftime(buffer, 30, logfile.c_str(), timeinfo);
strftime(buffer, 60, logfile.c_str(), timeinfo);
std::string logpath = logroot + "/" + buffer;
return logpath;
@@ -142,4 +190,5 @@ ClassLogFile::ClassLogFile(std::string _logroot, std::string _logfile)
logfile = _logfile;
doLogFile = true;
retentionInDays = 10;
loglevel = 0;
}

View File

@@ -9,9 +9,16 @@ private:
std::string logfile;
bool doLogFile;
unsigned short retentionInDays;
int loglevel;
public:
ClassLogFile(std::string _logpath, std::string _logfile);
std::string getESPHeapInfo();
void setLogLevel(int i){loglevel = i;};
void WriteHeapInfo(std::string _id);
void SwitchOnOff(bool _doLogFile);
void SetRetention(unsigned short _retentionInDays);

View File

@@ -64,10 +64,18 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_
mqtt_event_handler_cb((esp_mqtt_event_handle_t) event_data);
}
void MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user, std::string _password){
void MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user, std::string _password, std::string _LWTContext, int _keepalive){
std::string _zwmessage = "connection lost";
int _lzw = _zwmessage.length();
esp_mqtt_client_config_t mqtt_cfg = {
.uri = _mqttURI.c_str(),
.client_id = _clientid.c_str(),
.lwt_topic = _LWTContext.c_str(),
.lwt_msg = _zwmessage.c_str(),
.lwt_msg_len = _lzw,
.keepalive = _keepalive
};
if (_user.length() && _password.length()){
@@ -79,4 +87,6 @@ void MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user, st
client = esp_mqtt_client_init(&mqtt_cfg);
esp_mqtt_client_register_event(client, esp_mmqtt_ID, mqtt_event_handler, client);
esp_mqtt_client_start(client);
MQTTPublish(_LWTContext, "");
}

View File

@@ -1,4 +1,7 @@
#include <string>
void MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user = "", std::string _password = "");
void MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user, std::string _password, std::string _LWTContext, int _keepalive);
//void MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user = "", std::string _password = "");
void MQTTPublish(std::string _key, std::string _content);

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-master jomjol_controlcamera jomjol_flowcontroll)
REQUIRES jomjol_image_proc jomjol_logfile esp_http_server esp32-camera-master jomjol_controlcamera jomjol_flowcontroll jomjol_helper)

View File

@@ -1,12 +1,10 @@
#include "CTfLiteClass.h"
#include "bitmap_image.hpp"
#include "ClassLogFile.h"
#include "Helper.h"
#include <sys/stat.h>
bool debugdetailtflite = false;
// #define DEBUG_DETAIL_ON
float CTfLiteClass::GetOutputValue(int nr)
{
@@ -19,19 +17,14 @@ float CTfLiteClass::GetOutputValue(int nr)
return output2->data.f[nr];
}
int CTfLiteClass::GetClassFromImage(std::string _fn)
int CTfLiteClass::GetClassFromImageBasis(CImageBasis *rs)
{
// printf("Before Load image %s\n", _fn.c_str());
if (!LoadInputImage(_fn))
if (!LoadInputImageBasis(rs))
return -1000;
// printf("After Load image %s\n", _fn.c_str());
Invoke();
printf("After Invoke %s\n", _fn.c_str());
return GetOutClassification();
// return 0;
}
int CTfLiteClass::GetOutClassification()
@@ -55,7 +48,6 @@ int CTfLiteClass::GetOutClassification()
zw_class = i;
}
}
// printf("Result Ziffer: %d\n", zw_class);
return zw_class;
}
@@ -107,21 +99,17 @@ void CTfLiteClass::GetOutPut()
void CTfLiteClass::Invoke()
{
interpreter->Invoke();
// printf("Invoke Done.\n");
}
bool CTfLiteClass::LoadInputImage(std::string _fn)
bool CTfLiteClass::LoadInputImageBasis(CImageBasis *rs)
{
std::string zw = "ClassFlowAnalog::doNeuralNetwork nach Load Image: " + _fn;
// LogFile.WriteToFile(zw);
bitmap_image image(_fn);
if (debugdetailtflite) LogFile.WriteToFile(zw);
std::string zw = "ClassFlowAnalog::doNeuralNetwork nach LoadInputResizeImage: ";
unsigned int w = image.width();
unsigned int h = image.height();
unsigned int w = rs->width;
unsigned int h = rs->height;
unsigned char red, green, blue;
// printf("Image: %s size: %d x %d\n", _fn.c_str(), w, h);
input_i = 0;
@@ -130,21 +118,20 @@ bool CTfLiteClass::LoadInputImage(std::string _fn)
for (int y = 0; y < h; ++y)
for (int x = 0; x < w; ++x)
{
red = image.red_channel(x, y);
green = image.green_channel(x, y);
blue = image.blue_channel(x, y);
red = rs->GetPixelColor(x, y, 0);
green = rs->GetPixelColor(x, y, 1);
blue = rs->GetPixelColor(x, y, 2);
*(input_data_ptr) = (float) red;
input_data_ptr++;
*(input_data_ptr) = (float) green;
input_data_ptr++;
*(input_data_ptr) = (float) blue;
input_data_ptr++;
// printf("BMP: %f %f %f\n", (float) red, (float) green, (float) blue);
}
if (debugdetailtflite) LogFile.WriteToFile("Nach dem Laden in input");
#ifdef DEBUG_DETAIL_ON
LogFile.WriteToFile("Nach dem Laden in input");
#endif
return true;
}
@@ -152,7 +139,6 @@ bool CTfLiteClass::LoadInputImage(std::string _fn)
void CTfLiteClass::MakeAllocate()
{
// static tflite::ops::micro::AllOpsResolver resolver;
static tflite::AllOpsResolver resolver;
this->interpreter = new tflite::MicroInterpreter(this->model, resolver, this->tensor_arena, this->kTensorArenaSize, this->error_reporter);
@@ -162,16 +148,15 @@ void CTfLiteClass::MakeAllocate()
this->GetInputDimension();
return;
}
// printf("Allocate Done.\n");
}
void CTfLiteClass::GetInputTensorSize(){
float *zw = this->input;
int test = sizeof(zw);
#ifdef DEBUG_DETAIL_ON
printf("Input Tensor Dimension: %d\n", test);
printf("Input Tensor Dimension: %d\n", test);
#endif
}
long CTfLiteClass::GetFileSize(std::string filename)
@@ -186,24 +171,34 @@ unsigned char* CTfLiteClass::ReadFileToCharArray(std::string _fn)
{
long size;
size = this->GetFileSize(_fn);
size = GetFileSize(_fn);
if (size == -1)
{
printf("\nFile existiert nicht.\n");
return NULL;
printf("\nFile existiert nicht.\n");
return NULL;
}
unsigned char *result = (unsigned char*) malloc(size);
int anz = 1;
TickType_t xDelay;
while (!result && (anz < 6)) // maximal 5x versuchen (= 5s)
{
#ifdef DEBUG_DETAIL_ON
printf("Speicher ist voll - Versuche es erneut: %d.\n", anz);
#endif
xDelay = 1000 / portTICK_PERIOD_MS;
result = (unsigned char*) malloc(size);
anz++;
}
unsigned char *result = (unsigned char*) malloc(size);
if(result != NULL) {
// printf("\nSpeicher ist reserviert\n");
FILE* f = fopen(_fn.c_str(), "rb"); // vorher nur "r"
if(result != NULL) {
FILE* f = OpenFileAndWait(_fn.c_str(), "rb"); // vorher nur "r"
fread(result, 1, size, f);
fclose(f);
}else {
printf("\nKein freier Speicher vorhanden.\n");
}else {
printf("\nKein freier Speicher vorhanden.\n");
}
@@ -219,14 +214,11 @@ void CTfLiteClass::LoadModel(std::string _fn){
#endif
unsigned char *rd;
rd = this->ReadFileToCharArray(_fn.c_str());
// printf("loadedfile: %d", (int) rd);
rd = ReadFileToCharArray(_fn.c_str());
this->model = tflite::GetModel(rd);
free(rd);
TFLITE_MINIMAL_CHECK(model != nullptr);
// printf("tfile Loaded.\n");
}
@@ -237,7 +229,7 @@ CTfLiteClass::CTfLiteClass()
this->interpreter = nullptr;
this->input = nullptr;
this->output = nullptr;
this->kTensorArenaSize = 600 * 1024;
this->kTensorArenaSize = 150 * 1024; /// laut testfile: 108000 - bisher 600
this->tensor_arena = new uint8_t[kTensorArenaSize];
}
@@ -255,6 +247,6 @@ namespace tflite {
return 0;
}
} // namespace tflite
}

View File

@@ -14,6 +14,8 @@
#include "esp_err.h"
#include "esp_log.h"
#include "CImageBasis.h"
#define SUPRESS_TFLITE_ERRORS // use, to avoid error messages from TFLITE
@@ -39,7 +41,6 @@ class CTfLiteClass
const tflite::Model* model;
tflite::MicroInterpreter* interpreter;
TfLiteTensor* output = nullptr;
// static tflite::ops::micro::AllOpsResolver *resolver;
static tflite::AllOpsResolver resolver;
int kTensorArenaSize;
@@ -58,11 +59,11 @@ class CTfLiteClass
void LoadModel(std::string _fn);
void MakeAllocate();
void GetInputTensorSize();
bool LoadInputImage(std::string _fn);
bool LoadInputImageBasis(CImageBasis *rs);
void Invoke();
void GetOutPut();
int GetOutClassification();
int GetClassFromImage(std::string _fn);
int GetClassFromImageBasis(CImageBasis *rs);
float GetOutputValue(int nr);
void GetInputDimension(bool silent);

View File

@@ -18,31 +18,69 @@
#include "ClassLogFile.h"
//#define DEBUG_DETAIL_ON
ClassFlowControll tfliteflow;
TaskHandle_t xHandleblink_task_doFlow = NULL;
TaskHandle_t xHandletask_autodoFlow = NULL;
bool flowisrunning = false;
long auto_intervall = 0;
bool auto_isrunning = false;
int countRounds = 0;
int getCountFlowRounds() {
return countRounds;
}
esp_err_t GetJPG(std::string _filename, httpd_req_t *req)
{
return tfliteflow.GetJPGStream(_filename, req);
}
esp_err_t GetRawJPG(httpd_req_t *req)
{
return tfliteflow.SendRawJPG(req);
}
bool isSetupModusActive() {
return tfliteflow.getStatusSetupModus();
return false;
}
void KillTFliteTasks()
{
#ifdef DEBUG_DETAIL_ON
printf("Handle: xHandleblink_task_doFlow: %ld\n", (long) xHandleblink_task_doFlow);
#endif
if (xHandleblink_task_doFlow)
{
vTaskDelete(xHandleblink_task_doFlow);
#ifdef DEBUG_DETAIL_ON
printf("Killed: xHandleblink_task_doFlow\n");
#endif
}
#ifdef DEBUG_DETAIL_ON
printf("Handle: xHandletask_autodoFlow: %ld\n", (long) xHandletask_autodoFlow);
#endif
if (xHandletask_autodoFlow)
{
vTaskDelete(xHandletask_autodoFlow);
#ifdef DEBUG_DETAIL_ON
printf("Killed: xHandletask_autodoFlow\n");
#endif
}
}
@@ -50,9 +88,13 @@ void KillTFliteTasks()
void doInit(void)
{
string config = "/sdcard/config/config.ini";
#ifdef DEBUG_DETAIL_ON
printf("Start tfliteflow.InitFlow(config);\n");
#endif
tfliteflow.InitFlow(config);
#ifdef DEBUG_DETAIL_ON
printf("Finished tfliteflow.InitFlow(config);\n");
#endif
}
@@ -65,13 +107,17 @@ bool doflow(void)
tfliteflow.doFlow(zw_time);
flowisrunning = false;
#ifdef DEBUG_DETAIL_ON
printf("doflow - end %s\n", zw_time.c_str());
#endif
return true;
}
void blink_task_doFlow(void *pvParameter)
{
#ifdef DEBUG_DETAIL_ON
printf("blink_task_doFlow\n");
#endif
if (!flowisrunning)
{
flowisrunning = true;
@@ -85,8 +131,10 @@ void blink_task_doFlow(void *pvParameter)
esp_err_t handler_init(httpd_req_t *req)
{
LogFile.WriteToFile("handler_init");
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_init - Start");
printf("handler_doinit uri:\n"); printf(req->uri); printf("\n");
#endif
char* resp_str = "Init started<br>";
httpd_resp_send(req, resp_str, strlen(resp_str));
@@ -98,12 +146,19 @@ esp_err_t handler_init(httpd_req_t *req)
/* Respond with an empty chunk to signal HTTP response completion */
httpd_resp_send_chunk(req, NULL, 0);
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_init - Done");
#endif
return ESP_OK;
};
esp_err_t handler_doflow(httpd_req_t *req)
{
LogFile.WriteToFile("handler_doflow");
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_doflow - Start");
#endif
char* resp_str;
printf("handler_doFlow uri: "); printf(req->uri); printf("\n");
@@ -122,6 +177,11 @@ esp_err_t handler_doflow(httpd_req_t *req)
httpd_resp_send(req, resp_str, strlen(resp_str));
/* Respond with an empty chunk to signal HTTP response completion */
httpd_resp_send_chunk(req, NULL, 0);
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_doflow - Done");
#endif
return ESP_OK;
};
@@ -130,7 +190,10 @@ esp_err_t handler_doflow(httpd_req_t *req)
esp_err_t handler_wasserzaehler(httpd_req_t *req)
{
LogFile.WriteToFile("handler_wasserzaehler");
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_wasserzaehler - Start");
#endif
bool _rawValue = false;
bool _noerror = false;
string zw;
@@ -145,12 +208,16 @@ esp_err_t handler_wasserzaehler(httpd_req_t *req)
// printf("Query: "); printf(_query); printf("\n");
if (httpd_query_key_value(_query, "rawvalue", _size, 10) == ESP_OK)
{
#ifdef DEBUG_DETAIL_ON
printf("rawvalue is found"); printf(_size); printf("\n");
#endif
_rawValue = true;
}
if (httpd_query_key_value(_query, "noerror", _size, 10) == ESP_OK)
{
#ifdef DEBUG_DETAIL_ON
printf("noerror is found"); printf(_size); printf("\n");
#endif
_noerror = true;
}
}
@@ -165,7 +232,7 @@ esp_err_t handler_wasserzaehler(httpd_req_t *req)
{
string txt, zw;
txt = "<p>Aligned Image: <p><img src=\"/img_tmp/alg.jpg\"> <p>\n";
txt = "<p>Aligned Image: <p><img src=\"/img_tmp/alg_roi.jpg\"> <p>\n";
txt = txt + "Digital Counter: <p> ";
httpd_resp_sendstr_chunk(req, txt.c_str());
@@ -211,13 +278,18 @@ esp_err_t handler_wasserzaehler(httpd_req_t *req)
/* Respond with an empty chunk to signal HTTP response completion */
httpd_resp_sendstr_chunk(req, NULL);
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_wasserzaehler - Done");
#endif
return ESP_OK;
};
esp_err_t handler_editflow(httpd_req_t *req)
{
LogFile.WriteToFile("handler_editflow");
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_editflow - Start");
#endif
printf("handler_editflow uri: "); printf(req->uri); printf("\n");
@@ -229,7 +301,9 @@ esp_err_t handler_editflow(httpd_req_t *req)
{
if (httpd_query_key_value(_query, "task", _valuechar, 30) == ESP_OK)
{
#ifdef DEBUG_DETAIL_ON
printf("task is found: %s\n", _valuechar);
#endif
_task = string(_valuechar);
}
}
@@ -240,11 +314,13 @@ esp_err_t handler_editflow(httpd_req_t *req)
httpd_query_key_value(_query, "in", _valuechar, 30);
in = string(_valuechar);
printf("in: "); printf(in.c_str()); printf("\n");
httpd_query_key_value(_query, "out", _valuechar, 30);
out = string(_valuechar);
#ifdef DEBUG_DETAIL_ON
printf("in: "); printf(in.c_str()); printf("\n");
printf("out: "); printf(out.c_str()); printf("\n");
#endif
in = "/sdcard" + in;
out = "/sdcard" + out;
@@ -263,31 +339,34 @@ esp_err_t handler_editflow(httpd_req_t *req)
httpd_query_key_value(_query, "in", _valuechar, 30);
in = string(_valuechar);
printf("in: "); printf(in.c_str()); printf("\n");
httpd_query_key_value(_query, "out", _valuechar, 30);
out = string(_valuechar);
printf("out: "); printf(out.c_str()); printf("\n");
httpd_query_key_value(_query, "x", _valuechar, 30);
zw = string(_valuechar);
x = stoi(zw);
printf("x: "); printf(zw.c_str()); printf("\n");
httpd_query_key_value(_query, "y", _valuechar, 30);
zw = string(_valuechar);
y = stoi(zw);
printf("y: "); printf(zw.c_str()); printf("\n");
httpd_query_key_value(_query, "dx", _valuechar, 30);
zw = string(_valuechar);
dx = stoi(zw);
printf("dx: "); printf(zw.c_str()); printf("\n");
httpd_query_key_value(_query, "dy", _valuechar, 30);
zw = string(_valuechar);
dy = stoi(zw);
#ifdef DEBUG_DETAIL_ON
printf("in: "); printf(in.c_str()); printf("\n");
printf("out: "); printf(out.c_str()); printf("\n");
printf("x: "); printf(zw.c_str()); printf("\n");
printf("y: "); printf(zw.c_str()); printf("\n");
printf("dx: "); printf(zw.c_str()); printf("\n");
printf("dy: "); printf(zw.c_str()); printf("\n");
#endif
if (httpd_query_key_value(_query, "enhance", _valuechar, 10) == ESP_OK)
{
@@ -318,6 +397,7 @@ esp_err_t handler_editflow(httpd_req_t *req)
zw = "CutImage Done";
httpd_resp_sendstr_chunk(req, zw.c_str());
}
if (_task.compare("test_take") == 0)
@@ -373,27 +453,41 @@ esp_err_t handler_editflow(httpd_req_t *req)
/* Respond with an empty chunk to signal HTTP response completion */
httpd_resp_sendstr_chunk(req, NULL);
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_editflow - Done");
#endif
return ESP_OK;
};
esp_err_t handler_prevalue(httpd_req_t *req)
{
LogFile.WriteToFile("handler_prevalue");
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_prevalue - Start");
#endif
const char* resp_str;
string zw;
// printf("handler_prevalue:\n"); printf(req->uri); printf("\n");
#ifdef DEBUG_DETAIL_ON
printf("handler_prevalue:\n"); printf(req->uri); printf("\n");
#endif
char _query[100];
char _size[10] = "";
if (httpd_req_get_url_query_str(req, _query, 100) == ESP_OK)
{
// printf("Query: "); printf(_query); printf("\n");
#ifdef DEBUG_DETAIL_ON
printf("Query: "); printf(_query); printf("\n");
#endif
if (httpd_query_key_value(_query, "value", _size, 10) == ESP_OK)
{
#ifdef DEBUG_DETAIL_ON
printf("Value: "); printf(_size); printf("\n");
#endif
}
}
@@ -408,6 +502,10 @@ esp_err_t handler_prevalue(httpd_req_t *req)
/* Respond with an empty chunk to signal HTTP response completion */
httpd_resp_send_chunk(req, NULL, 0);
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_prevalue - Start");
#endif
return ESP_OK;
};
@@ -419,22 +517,36 @@ void task_autodoFlow(void *pvParameter)
auto_isrunning = tfliteflow.isAutoStart(auto_intervall);
if (isSetupModusActive()) {
auto_isrunning = false;
std::string zw_time = gettimestring(LOGFILE_TIME_FORMAT);
tfliteflow.doFlowMakeImageOnly(zw_time);
}
while (auto_isrunning)
{
LogFile.WriteToFile("task_autodoFlow - next round");
std::string _zw = "task_autodoFlow - next round - Round #" + std::to_string(++countRounds);
LogFile.WriteToFile(_zw);
printf("Autoflow: start\n");
fr_start = esp_timer_get_time();
if (flowisrunning)
{
#ifdef DEBUG_DETAIL_ON
printf("Autoflow: doFLow laeuft bereits!\n");
#endif
}
else
{
#ifdef DEBUG_DETAIL_ON
printf("Autoflow: doFLow wird gestartet\n");
#endif
flowisrunning = true;
doflow();
#ifdef DEBUG_DETAIL_ON
printf("Remove older log files\n");
#endif
LogFile.RemoveOld();
}
@@ -494,5 +606,4 @@ void register_server_tflite_uri(httpd_handle_t server)
camuri.handler = handler_wasserzaehler;
camuri.user_ctx = (void*) "Wasserzaehler";
httpd_register_uri_handler(server, &camuri);
}

View File

@@ -1,6 +1,7 @@
#include <esp_log.h>
#include <esp_http_server.h>
#include "CImageBasis.h"
//#include "ClassControllCamera.h"
@@ -11,3 +12,9 @@ void register_server_tflite_uri(httpd_handle_t server);
void KillTFliteTasks();
void TFliteDoAutoStart();
bool isSetupModusActive();
esp_err_t GetJPG(std::string _filename, httpd_req_t *req);
esp_err_t GetRawJPG(httpd_req_t *req);

View File

@@ -1,11 +1,5 @@
#include "time_sntp.h"
/* LwIP SNTP example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <string>
#include <time.h>
#include <sys/time.h>
@@ -17,27 +11,17 @@
#include "esp_log.h"
#include "esp_attr.h"
#include "esp_sleep.h"
// #include "nvs_flash.h"
// #include "protocol_examples_common.h"
#include "esp_sntp.h"
#include "ClassLogFile.h"
static const char *TAG = "sntp";
RTC_DATA_ATTR int boot_count = 0;
bool setTimeAlwaysOnReboot = true;
/* Variable holding number of times ESP32 restarted since first boot.
* It is placed into RTC memory using RTC_DATA_ATTR and
* maintains its value when ESP32 wakes from deep sleep.
*/
static void obtain_time(void);
static void initialize_sntp(void);
void time_sync_notification_cb(struct timeval *tv)
{
ESP_LOGI(TAG, "Notification of a time synchronization event");
@@ -58,9 +42,6 @@ std::string gettimestring(const char * frm)
void setup_time()
{
++boot_count;
ESP_LOGI(TAG, "Boot count: %d", boot_count);
time_t now;
struct tm timeinfo;
time(&now);
@@ -76,8 +57,6 @@ void setup_time()
char strftime_buf[64];
setTimeZone("CET-1CEST,M3.5.0,M10.5.0/3");
// setTimeZone("Europe/Berlin");
// setTimeZone("Asia/Tokyo");
localtime_r(&now, &timeinfo);
strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo);
@@ -101,9 +80,6 @@ void setTimeZone(std::string _tzstring)
static void obtain_time(void)
{
// initialize_sntp();
// wait for time to be set
time_t now = 0;
struct tm timeinfo = {};
int retry = 0;
@@ -114,52 +90,28 @@ static void obtain_time(void)
ESP_LOGI(TAG, "Waiting for system time to be set... (%d/%d)", retry, retry_count);
vTaskDelay(2000 / portTICK_PERIOD_MS);
}
if (retry == retry_count) {
LogFile.WriteToFile("Time Synchzronisation nicht erfolgreich ...");
}
else
{
LogFile.WriteToFile("Time erfolgreich ...");
}
time(&now);
localtime_r(&now, &timeinfo);
}
void reset_servername(std::string _servername)
{
printf("Set SNTP-Server: %s\n", _servername.c_str());
sntp_stop();
sntp_setoperatingmode(SNTP_OPMODE_POLL);
sntp_setservername(0, _servername.c_str());
sntp_init();
obtain_time();
std::string zw = gettimestring("%Y%m%d-%H%M%S");
printf("Time ist %s\n", zw.c_str());
}
static void initialize_sntp(void)
{
ESP_LOGI(TAG, "Initializing SNTP");
sntp_setoperatingmode(SNTP_OPMODE_POLL);
sntp_setservername(0, "pool.ntp.org");
sntp_set_time_sync_notification_cb(time_sync_notification_cb);
// sntp_set_time_sync_notification_cb(time_sync_notification_cb);
sntp_init();
}
void task_doTimeSync(void *pvParameter)
{
time_t now;
struct tm timeinfo;
char strftime_buf[64];
int *zw_int = (int*) pvParameter;
printf("Start Autoupdate Time every: %d Stunden\n", *zw_int );
TickType_t xDelay = ((*zw_int) * 60 * 60 * 1000) / portTICK_PERIOD_MS;
while (1)
{
obtain_time();
localtime_r(&now, &timeinfo);
strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo);
ESP_LOGI(TAG, "The current date/time in Berlin is: %s", strftime_buf);
strftime(strftime_buf, sizeof(strftime_buf), "%Y-%m-%d_%H:%M", &timeinfo);
ESP_LOGI(TAG, "The current date/time in Berlin is: %s", strftime_buf);
std::string zw = gettimestring("%Y%m%d-%H%M%S");
printf("time %s\n", zw.c_str());
vTaskDelay( xDelay );
}
vTaskDelete(NULL); //Delete this task if it exits from the loop above
}

View File

@@ -12,11 +12,8 @@
// #include "nvs_flash.h"
#include "esp_sntp.h"
extern int boot_count;
void setup_time(void);
std::string gettimestring(const char * frm);
void task_doTimeSync(void *pvParameter);
void setTimeZone(std::string _tzstring);
void reset_servername(std::string _servername);

View File

@@ -53,7 +53,7 @@ endif()
#######################################################################
FILE(GLOB_RECURSE app_sources ${CMAKE_SOURCE_DIR}/src/*.*)
FILE(GLOB_RECURSE app_sources ${CMAKE_SOURCE_DIR}/main/*.*)
# idf_component_register(SRCS ${app_sources})

View File

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

@@ -25,7 +25,7 @@
#include "ClassControllCamera.h"
#include "server_main.h"
#include "server_camera.h"
#include "server_GPIO.h"
static const char *TAGMAIN = "connect_wlan_main";
#define FLASH_GPIO GPIO_NUM_4
@@ -44,10 +44,15 @@ void Init_NVS_SDCard()
// sdmmc_host_t host = SDMMC_HOST_SLOT_1();
// host.flags = SDMMC_HOST_FLAG_1BIT;
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
slot_config.width = 1; // 1 line SD mode
esp_vfs_fat_sdmmc_mount_config_t mount_config = { };
mount_config.format_if_mount_failed = false;
mount_config.max_files = 5;
gpio_set_pull_mode((gpio_num_t) 15, GPIO_PULLUP_ONLY); // CMD, needed in 4- and 1- line modes
gpio_set_pull_mode((gpio_num_t) 2, GPIO_PULLUP_ONLY); // D0, needed in 4- and 1-line modes
sdmmc_card_t* card;
ret = esp_vfs_fat_sdmmc_mount("/sdcard", &host, &slot_config, &mount_config, &card);
if (ret != ESP_OK) {
@@ -81,13 +86,32 @@ extern "C" void app_main(void)
std::string ssid = "";
std::string password = "";
std::string hostname = "";
std::string ip = "";
std::string gw = "";
std::string netmask = "";
std::string dns = "";
// LoadWlanFromFile("/sdcard/wlan.ini", ssid, password, hostname, ip, gw, netmask, dns);
LoadWlanFromFile("/sdcard/wlan.ini", ssid, password, hostname);
LoadNetConfigFromFile("/sdcard/wlan.ini", ip, gw, netmask, dns);
// LogFile.WriteToFile("Startsequence 04");
printf("To use WLan: %s, %s\n", ssid.c_str(), password.c_str());
printf("To set Hostename: %s\n", hostname.c_str());
printf("Fixed IP: %s, Gateway %s, Netmask %s, DNS %s\n", ip.c_str(), gw.c_str(), netmask.c_str(), dns.c_str());
if (ip.length() == 0 || gw.length() == 0 || netmask.length() == 0)
{
initialise_wifi(ssid, password, hostname);
}
else
{
initialise_wifi_fixed_ip(ip, gw, netmask, ssid, password, hostname, dns);
}
printf("Netparameter: IP: %s - GW: %s - NetMask %s\n", getIPAddress().c_str(), getGW().c_str(), getNetMask().c_str());
initialise_wifi(ssid, password, hostname);
// LogFile.WriteToFile("Startsequence 05");
TickType_t xDelay;
@@ -97,7 +121,9 @@ extern "C" void app_main(void)
vTaskDelay( xDelay );
// LogFile.WriteToFile("Startsequence 07");
setup_time();
LogFile.WriteToFile("============================== Main Started =======================================");
LogFile.WriteToFile("=============================================================================================");
LogFile.WriteToFile("=================================== Main Started ============================================");
LogFile.WriteToFile("=============================================================================================");
LogFile.SwitchOnOff(false);
std::string zw = gettimestring("%Y%m%d-%H%M%S");
@@ -114,6 +140,7 @@ extern "C" void app_main(void)
register_server_tflite_uri(server);
register_server_file_uri(server, "/sdcard");
register_server_ota_sdcard_uri(server);
register_server_GPIO_uri(server);
register_server_main_uri(server, "/sdcard");
TFliteDoAutoStart();

View File

@@ -13,16 +13,24 @@
#include "esp_wifi.h"
#include "server_tflite.h"
//#define DEBUG_DETAIL_ON
httpd_handle_t server = NULL;
std::string starttime = "";
/* An HTTP GET handler */
esp_err_t info_get_handler(httpd_req_t *req)
{
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("info_get_handler - Start");
#endif
LogFile.WriteToFile("info_get_handler");
char _query[200];
char _valuechar[30];
@@ -123,25 +131,40 @@ esp_err_t info_get_handler(httpd_req_t *req)
return ESP_OK;
}
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("info_get_handler - Done");
#endif
return ESP_OK;
}
esp_err_t starttime_get_handler(httpd_req_t *req)
{
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("starttime_get_handler - Start");
#endif
httpd_resp_send(req, starttime.c_str(), strlen(starttime.c_str()));
/* Respond with an empty chunk to signal HTTP response completion */
httpd_resp_send_chunk(req, NULL, 0);
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("starttime_get_handler - Done");
#endif
return ESP_OK;
}
esp_err_t hello_main_handler(httpd_req_t *req)
{
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("hello_main_handler - Start");
#endif
char filepath[50];
struct stat file_stat;
printf("uri: %s\n", req->uri);
int _pos;
esp_err_t res;
char *base_path = (char*) req->user_ctx;
std::string filetosend(base_path);
@@ -152,7 +175,9 @@ esp_err_t hello_main_handler(httpd_req_t *req)
if ((strcmp(req->uri, "/") == 0))
{
filetosend = filetosend + "/html/index.html";
{
filetosend = filetosend + "/html/index.html";
}
}
else
{
@@ -163,6 +188,11 @@ esp_err_t hello_main_handler(httpd_req_t *req)
}
}
if (filetosend == "/sdcard/html/index.html" && isSetupModusActive()) {
printf("System ist im Setupmodus --> index.html --> setup.html");
filetosend = "/sdcard/html/setup.html";
}
printf("Filename: %s\n", filename);
printf("File requested: %s\n", filetosend.c_str());
@@ -173,60 +203,37 @@ esp_err_t hello_main_handler(httpd_req_t *req)
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Filename too long");
return ESP_FAIL;
}
if (stat(filetosend.c_str(), &file_stat) == -1) {
/* If file not present on SPIFFS check if URI
* corresponds to one of the hardcoded paths */
ESP_LOGE(TAG, "Failed to stat file : %s", filetosend.c_str());
/* Respond with 404 Not Found */
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "File does not exist");
return ESP_FAIL;
}
esp_err_t res;
res = httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
if (res != ESP_OK)
return res;
res = send_file(req, filetosend, &file_stat);
res = send_file(req, filetosend);
if (res != ESP_OK)
return res;
/* Respond with an empty chunk to signal HTTP response completion */
httpd_resp_send_chunk(req, NULL, 0);
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("hello_main_handler - Stop");
#endif
return ESP_OK;
}
esp_err_t img_tmp_handler(httpd_req_t *req)
{
char filepath[50];
struct stat file_stat;
printf("uri: %s\n", req->uri);
char *base_path = (char*) req->user_ctx;
std::string filetosend(base_path);
const char *filename = get_path_from_uri(filepath, base_path,
req->uri + sizeof("/img_tmp") - 1, sizeof(filepath));
req->uri + sizeof("/img_tmp/") - 1, sizeof(filepath));
printf("1 uri: %s, filename: %s, filepath: %s\n", req->uri, filename, filepath);
filetosend = filetosend + "/img_tmp/" + std::string(filename);
printf("File to upload: %s\n", filetosend.c_str());
if (!filename) {
ESP_LOGE(TAG, "Filename is too long");
/* Respond with 500 Internal Server Error */
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Filename too long");
return ESP_FAIL;
}
if (stat(filetosend.c_str(), &file_stat) == -1) {
/* If file not present on SPIFFS check if URI
* corresponds to one of the hardcoded paths */
ESP_LOGE(TAG, "Failed to stat file : %s", filetosend.c_str());
/* Respond with 404 Not Found */
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "File does not exist");
return ESP_FAIL;
}
esp_err_t res = send_file(req, filetosend, &file_stat);
esp_err_t res = send_file(req, filetosend);
if (res != ESP_OK)
return res;
@@ -235,8 +242,54 @@ esp_err_t img_tmp_handler(httpd_req_t *req)
return ESP_OK;
}
esp_err_t img_tmp_virtual_handler(httpd_req_t *req)
{
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("img_tmp_virtual_handler - Start");
#endif
char filepath[50];
printf("uri: %s\n", req->uri);
char *base_path = (char*) req->user_ctx;
std::string filetosend(base_path);
const char *filename = get_path_from_uri(filepath, base_path,
req->uri + sizeof("/img_tmp/") - 1, sizeof(filepath));
printf("1 uri: %s, filename: %s, filepath: %s\n", req->uri, filename, filepath);
filetosend = std::string(filename);
printf("File to upload: %s\n", filetosend.c_str());
if (filetosend == "raw.jpg")
{
return GetRawJPG(req);
}
esp_err_t zw = GetJPG(filetosend, req);
if (zw == ESP_OK)
return ESP_OK;
// File wird nicht intern bereit gestellt --> klassischer weg:
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("img_tmp_virtual_handler - Done");
#endif
return img_tmp_handler(req);
}
esp_err_t sysinfo_handler(httpd_req_t *req)
{
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("sysinfo_handler - Start");
#endif
const char* resp_str;
std::string zw;
std::string cputemp = std::to_string(temperatureRead());
@@ -272,6 +325,10 @@ esp_err_t sysinfo_handler(httpd_req_t *req)
/* Respond with an empty chunk to signal HTTP response completion */
httpd_resp_send_chunk(req, NULL, 0);
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("sysinfo_handler - Done");
#endif
return ESP_OK;
}
@@ -305,7 +362,7 @@ void register_server_main_uri(httpd_handle_t server, const char *base_path)
httpd_uri_t img_tmp_handle = {
.uri = "/img_tmp/*", // Match all URIs of type /path/to/file
.method = HTTP_GET,
.handler = img_tmp_handler,
.handler = img_tmp_virtual_handler,
.user_ctx = (void*) base_path // Pass server data as context
};
httpd_register_uri_handler(server, &img_tmp_handle);

View File

@@ -22,9 +22,4 @@ httpd_handle_t start_webserver(void);
void register_server_main_uri(httpd_handle_t server, const char *base_path);
//void disconnect_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data);
//void connect_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data);
#endif

4
code/main/version.cpp Normal file
View File

@@ -0,0 +1,4 @@
const char* GIT_REV="46cfe45";
const char* GIT_TAG="";
const char* GIT_BRANCH="master";
const char* BUILD_TIME="2021-01-20 19:47";

View File

@@ -13,7 +13,7 @@ extern "C"
#include "Helper.h"
#include <fstream>
const char* GIT_BASE_BRANCH = "master - v4.1.0 - 2020-11-30";
const char* GIT_BASE_BRANCH = "master - v6.1.0 - 2020-01-20";
const char* git_base_branch(void)

View File

@@ -9,20 +9,20 @@
; https://docs.platformio.org/page/projectconf.html
[platformio]
src_dir = main
[env:esp32cam]
platform = espressif32
platform = espressif32@2.1.0
board = esp32cam
framework = espidf
board_build.embed_files =
src/favicon.ico
;board_build.partitions = partitions_singleapp.csv
board_build.partitions = partitions.csv
lib_deps =
jomjol_helper
connect_wlan
@@ -35,6 +35,7 @@ lib_deps =
jomjol_time_sntp
jomjol_logfile
jomjol_mqtt
jomjol_controlGPIO
monitor_speed = 115200

View File

@@ -83,11 +83,11 @@ CONFIG_ESPTOOLPY_FLASHFREQ_40M=y
# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set
CONFIG_ESPTOOLPY_FLASHFREQ="40m"
# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set
CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y
# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set
# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set
# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set
CONFIG_ESPTOOLPY_FLASHSIZE="2MB"
CONFIG_ESPTOOLPY_FLASHSIZE="4MB"
CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y
CONFIG_ESPTOOLPY_BEFORE_RESET=y
# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set
@@ -109,11 +109,11 @@ CONFIG_ESPTOOLPY_MONITOR_BAUD=115200
#
# Partition Table
#
CONFIG_PARTITION_TABLE_SINGLE_APP=y
# CONFIG_PARTITION_TABLE_SINGLE_APP is not set
# CONFIG_PARTITION_TABLE_TWO_OTA is not set
# CONFIG_PARTITION_TABLE_CUSTOM is not set
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv"
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
CONFIG_PARTITION_TABLE_OFFSET=0x8000
CONFIG_PARTITION_TABLE_MD5=y
# end of Partition Table
@@ -173,7 +173,95 @@ CONFIG_BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF=1
CONFIG_BT_RESERVE_DRAM=0
# end of Bluetooth
# CONFIG_BLE_MESH is not set
CONFIG_BLE_MESH=y
CONFIG_BLE_MESH_HCI_5_0=y
# CONFIG_BLE_MESH_ALLOC_FROM_PSRAM_FIRST is not set
# CONFIG_BLE_MESH_FAST_PROV is not set
# CONFIG_BLE_MESH_NODE is not set
# CONFIG_BLE_MESH_PROVISIONER is not set
CONFIG_BLE_MESH_PROV=y
CONFIG_BLE_MESH_PB_ADV=y
# CONFIG_BLE_MESH_PB_GATT is not set
CONFIG_BLE_MESH_PROXY=y
# CONFIG_BLE_MESH_GATT_PROXY_CLIENT is not set
CONFIG_BLE_MESH_NET_BUF_POOL_USAGE=y
# CONFIG_BLE_MESH_SETTINGS is not set
CONFIG_BLE_MESH_SUBNET_COUNT=3
CONFIG_BLE_MESH_APP_KEY_COUNT=3
CONFIG_BLE_MESH_MODEL_KEY_COUNT=3
CONFIG_BLE_MESH_MODEL_GROUP_COUNT=3
CONFIG_BLE_MESH_LABEL_COUNT=3
CONFIG_BLE_MESH_CRPL=10
CONFIG_BLE_MESH_MSG_CACHE_SIZE=10
CONFIG_BLE_MESH_ADV_BUF_COUNT=60
# CONFIG_BLE_MESH_SUPPORT_BLE_ADV is not set
CONFIG_BLE_MESH_IVU_DIVIDER=4
CONFIG_BLE_MESH_TX_SEG_MSG_COUNT=1
CONFIG_BLE_MESH_RX_SEG_MSG_COUNT=1
CONFIG_BLE_MESH_RX_SDU_MAX=384
CONFIG_BLE_MESH_TX_SEG_MAX=32
# CONFIG_BLE_MESH_FRIEND is not set
# CONFIG_BLE_MESH_NO_LOG is not set
#
# BLE Mesh STACK DEBUG LOG LEVEL
#
# CONFIG_BLE_MESH_TRACE_LEVEL_NONE is not set
# CONFIG_BLE_MESH_TRACE_LEVEL_ERROR is not set
CONFIG_BLE_MESH_TRACE_LEVEL_WARNING=y
# CONFIG_BLE_MESH_TRACE_LEVEL_INFO is not set
# CONFIG_BLE_MESH_TRACE_LEVEL_DEBUG is not set
# CONFIG_BLE_MESH_TRACE_LEVEL_VERBOSE is not set
CONFIG_BLE_MESH_STACK_TRACE_LEVEL=2
# end of BLE Mesh STACK DEBUG LOG LEVEL
#
# BLE Mesh NET BUF DEBUG LOG LEVEL
#
# CONFIG_BLE_MESH_NET_BUF_TRACE_LEVEL_NONE is not set
# CONFIG_BLE_MESH_NET_BUF_TRACE_LEVEL_ERROR is not set
CONFIG_BLE_MESH_NET_BUF_TRACE_LEVEL_WARNING=y
# CONFIG_BLE_MESH_NET_BUF_TRACE_LEVEL_INFO is not set
# CONFIG_BLE_MESH_NET_BUF_TRACE_LEVEL_DEBUG is not set
# CONFIG_BLE_MESH_NET_BUF_TRACE_LEVEL_VERBOSE is not set
CONFIG_BLE_MESH_NET_BUF_TRACE_LEVEL=2
# end of BLE Mesh NET BUF DEBUG LOG LEVEL
CONFIG_BLE_MESH_CLIENT_MSG_TIMEOUT=4000
#
# Support for BLE Mesh Client Models
#
# CONFIG_BLE_MESH_CFG_CLI is not set
# CONFIG_BLE_MESH_HEALTH_CLI is not set
# CONFIG_BLE_MESH_GENERIC_ONOFF_CLI is not set
# CONFIG_BLE_MESH_GENERIC_LEVEL_CLI is not set
# CONFIG_BLE_MESH_GENERIC_DEF_TRANS_TIME_CLI is not set
# CONFIG_BLE_MESH_GENERIC_POWER_ONOFF_CLI is not set
# CONFIG_BLE_MESH_GENERIC_POWER_LEVEL_CLI is not set
# CONFIG_BLE_MESH_GENERIC_BATTERY_CLI is not set
# CONFIG_BLE_MESH_GENERIC_LOCATION_CLI is not set
# CONFIG_BLE_MESH_GENERIC_PROPERTY_CLI is not set
# CONFIG_BLE_MESH_SENSOR_CLI is not set
# CONFIG_BLE_MESH_TIME_CLI is not set
# CONFIG_BLE_MESH_SCENE_CLI is not set
# CONFIG_BLE_MESH_SCHEDULER_CLI is not set
# CONFIG_BLE_MESH_LIGHT_LIGHTNESS_CLI is not set
# CONFIG_BLE_MESH_LIGHT_CTL_CLI is not set
# CONFIG_BLE_MESH_LIGHT_HSL_CLI is not set
# CONFIG_BLE_MESH_LIGHT_XYL_CLI is not set
# CONFIG_BLE_MESH_LIGHT_LC_CLI is not set
# end of Support for BLE Mesh Client Models
# CONFIG_BLE_MESH_IV_UPDATE_TEST is not set
#
# BLE Mesh specific test option
#
# CONFIG_BLE_MESH_SELF_TEST is not set
# CONFIG_BLE_MESH_SHELL is not set
# CONFIG_BLE_MESH_DEBUG is not set
# end of BLE Mesh specific test option
#
# CoAP Configuration
@@ -537,8 +625,8 @@ CONFIG_FATFS_MAX_LFN=255
CONFIG_FATFS_API_ENCODING_ANSI_OEM=y
# CONFIG_FATFS_API_ENCODING_UTF_16 is not set
# CONFIG_FATFS_API_ENCODING_UTF_8 is not set
CONFIG_FATFS_FS_LOCK=5
CONFIG_FATFS_TIMEOUT_MS=10000
CONFIG_FATFS_FS_LOCK=10
CONFIG_FATFS_TIMEOUT_MS=5000
CONFIG_FATFS_PER_FILE_CACHE=y
CONFIG_FATFS_ALLOC_PREFER_EXTRAM=y
# end of FAT Filesystem support
@@ -965,7 +1053,7 @@ CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y
#
# Virtual file system
#
CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y
# CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT is not set
CONFIG_VFS_SUPPORT_TERMIOS=y
#
@@ -1166,6 +1254,6 @@ CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread"
CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y
# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set
# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set
CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y
# CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT is not set
CONFIG_SUPPORT_TERMIOS=y
# End of deprecated options

View File

@@ -83,11 +83,11 @@ CONFIG_ESPTOOLPY_FLASHFREQ_40M=y
# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set
CONFIG_ESPTOOLPY_FLASHFREQ="40m"
# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set
CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y
# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set
# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set
# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set
CONFIG_ESPTOOLPY_FLASHSIZE="2MB"
CONFIG_ESPTOOLPY_FLASHSIZE="4MB"
CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y
CONFIG_ESPTOOLPY_BEFORE_RESET=y
# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set
@@ -109,11 +109,11 @@ CONFIG_ESPTOOLPY_MONITOR_BAUD=115200
#
# Partition Table
#
CONFIG_PARTITION_TABLE_SINGLE_APP=y
# CONFIG_PARTITION_TABLE_SINGLE_APP is not set
# CONFIG_PARTITION_TABLE_TWO_OTA is not set
# CONFIG_PARTITION_TABLE_CUSTOM is not set
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv"
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
CONFIG_PARTITION_TABLE_OFFSET=0x8000
CONFIG_PARTITION_TABLE_MD5=y
# end of Partition Table
@@ -315,8 +315,8 @@ CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR=y
CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES=4
# CONFIG_ESP32_ULP_COPROC_ENABLED is not set
CONFIG_ESP32_ULP_COPROC_RESERVE_MEM=0
# CONFIG_ESP32_PANIC_PRINT_HALT is not set
CONFIG_ESP32_PANIC_PRINT_REBOOT=y
CONFIG_ESP32_PANIC_PRINT_HALT=y
# CONFIG_ESP32_PANIC_PRINT_REBOOT is not set
# CONFIG_ESP32_PANIC_SILENT_REBOOT is not set
# CONFIG_ESP32_PANIC_GDBSTUB is not set
CONFIG_ESP32_DEBUG_OCDAWARE=y
@@ -537,8 +537,8 @@ CONFIG_FATFS_MAX_LFN=255
CONFIG_FATFS_API_ENCODING_ANSI_OEM=y
# CONFIG_FATFS_API_ENCODING_UTF_16 is not set
# CONFIG_FATFS_API_ENCODING_UTF_8 is not set
CONFIG_FATFS_FS_LOCK=2
CONFIG_FATFS_TIMEOUT_MS=10000
CONFIG_FATFS_FS_LOCK=10
CONFIG_FATFS_TIMEOUT_MS=5000
CONFIG_FATFS_PER_FILE_CACHE=y
CONFIG_FATFS_ALLOC_PREFER_EXTRAM=y
# end of FAT Filesystem support
@@ -965,7 +965,7 @@ CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y
#
# Virtual file system
#
CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y
# CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT is not set
CONFIG_VFS_SUPPORT_TERMIOS=y
#
@@ -1166,6 +1166,6 @@ CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread"
CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y
# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set
# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set
CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y
# CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT is not set
CONFIG_SUPPORT_TERMIOS=y
# End of deprecated options

View File

@@ -1,4 +0,0 @@
const char* GIT_REV="ffc15aa";
const char* GIT_TAG="";
const char* GIT_BRANCH="master";
const char* BUILD_TIME="2020-12-02 21:56";

View File

@@ -1,4 +1,4 @@
const char* GIT_REV="ffc15aa";
const char* GIT_REV="46cfe45";
const char* GIT_TAG="";
const char* GIT_BRANCH="master";
const char* BUILD_TIME="2020-12-02 21:55";
const char* BUILD_TIME="2021-01-20 19:47";

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -11,10 +11,11 @@ InitalRotate=180
/config/ref1.jpg 456 138
SearchFieldX = 20
SearchFieldY = 20
AlignmentAlgo = Default
[Digits]
Model = /config/dig0720s1.tflite
Model = /config/dig0721s1.tflite
;LogImageLocation = /log/digit
;LogfileRetentionInDays = 3
ModelInputSize = 20 32
@@ -31,6 +32,7 @@ analog1 444 225 92 92
analog2 391 329 92 92
analog3 294 369 92 92
analog4 168 326 92 92
ExtendedResolution = false
[PostProcessing]
DecimalShift = 0
@@ -39,13 +41,13 @@ PreValueAgeStartup = 720
AllowNegativeRates = false
MaxRateValue = 0.1
ErrorMessage = true
CheckDigitIncreaseConsistency = true
CheckDigitIncreaseConsistency = false
[MQTT]
Uri = mqtt://IP-ADRESS:1883
Topic = wasserzaehler/zaehlerstand
TopicError = wasserzaehler/error
ClientID = wasser
;Uri = mqtt://IP-ADRESS:1883
;Topic = wasserzaehler/zaehlerstand
;TopicError = wasserzaehler/error
;ClientID = wasser
;user = USERNAME
;password = PASSWORD
@@ -59,5 +61,8 @@ LogfileRetentionInDays = 3
[System]
TimeZone = CET-1CEST,M3.5.0,M10.5.0/3
;TimeServer = fritz.box
;hostname = watermeter
SetupMode = true
[Ende]

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
sd-card/html/cnn_images.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

3
sd-card/html/debug.log Normal file
View File

@@ -0,0 +1,3 @@
[1204/185120.033:ERROR:directory_reader_win.cc(43)] FindFirstFile: Das System kann den angegebenen Pfad nicht finden. (0x3)
[0102/122131.430:ERROR:directory_reader_win.cc(43)] FindFirstFile: Das System kann den angegebenen Pfad nicht finden. (0x3)
[0118/210038.095:ERROR:directory_reader_win.cc(43)] FindFirstFile: Das System kann den angegebenen Pfad nicht finden. (0x3)

View File

@@ -91,6 +91,7 @@ select {
<script type="text/javascript" src="./gethost.js"></script>
<script type="text/javascript" src="./readconfig.js"></script>
<script type="text/javascript" src="./readconfigcommon.js"></script>
<script language="JavaScript">
var canvas = document.getElementById('canvas'),

View File

@@ -49,13 +49,26 @@ select {
th, td {
padding: 5px 5px 5px 0px;
}
#div2{
background-color:#777;
margin-bottom:20px;
}
.disabledDiv {
pointer-events: none;
opacity: 0.4;
}
</style>
</head>
<body style="font-family: arial; padding: 0px 10px;">
<h2>Edit Analog</h2>
<h2><input type="checkbox" id="Category_Analog_enabled" value="1" onclick = 'EnDisableAnalog()' checked >
Edit Analog</h2>
<div id="div1">
<table>
<tr>
@@ -78,8 +91,8 @@ th, td {
</td>
<td>Name: <input type="text" name="name" id="name" onchange="onNameChange()" size="13"></td>
<td>
<input class="move" type="submit" id="moveNext" onclick="moveNext()" value="move Next">
<input class="move" type="submit" id="movePrevious" onclick="movePrevious()" value="move Previous">
<input class="button" type="submit" id="moveNext" onclick="moveNext()" value="move Next">
<input class="button" type="submit" id="movePrevious" onclick="movePrevious()" value="move Previous">
</td>
</tr>
<tr>
@@ -92,15 +105,19 @@ th, td {
<td>dy: <input type="number" name="refdy" id="refdy" step=1 onchange="valuemanualchanged()"></td>
</tr>
</table>
</div>
<table>
<tr>
<td><input class="button" type="submit" id="saveroi" name="saveroi" onclick="SaveToConfig()" value="Save all to Config.ini"></td>
</tr>
</table>
</table>
<script type="text/javascript" src="./gethost.js"></script>
<script type="text/javascript" src="./readconfigcommon.js"></script>
<script type="text/javascript" src="./readconfig.js"></script>
<script type="text/javascript" src="./jquery-3.5.1.min.js"></script>
<script language="JavaScript">
var canvas = document.getElementById('canvas'),
@@ -114,6 +131,40 @@ th, td {
lockAR = true;
basepath = "http://192.168.178.26";
function EnDisableAnalog() {
isEnabled = document.getElementById("Category_Analog_enabled").checked;
$("#div2").attr("disabled", "disabled").off('click');
var x1=$("#div2").hasClass("disabledDiv");
if (isEnabled)
{
$("#div2").removeClass("disabledDiv");
}
else
{
$("#div2").addClass("disabledDiv");
}
sah1(document.getElementById("div1"), !isEnabled);
if (isEnabled)
{
UpdateROIs();
}
}
function sah1(el, _target) {
try {
el.disabled = _target;
} catch (E) {}
if (el.childNodes && el.childNodes.length > 0) {
for (var x = 0; x < el.childNodes.length; x++) {
sah1(el.childNodes[x], _target);
}
}
}
function onNameChange(){
ROIInfo[aktindex]["name"] = document.getElementById("name").value;
UpdateROIs();
@@ -172,7 +223,8 @@ function ChangeSelection(){
}
function SaveToConfig(){
SaveROIToConfig(ROIInfo, "[Analog]", basepath);
_enabled = document.getElementById("Category_Analog_enabled").checked;
SaveROIToConfig(ROIInfo, "[Analog]", basepath, _enabled);
UpdatePage();
}
@@ -230,8 +282,18 @@ function UpdateROIs(){
function ParseIni(_basepath) {
loadConfig(_basepath);
ParseConfig();
document.getElementById("Category_Analog_enabled").checked = true;
ROIInfo = getROIInfo("[Analog]");
if (!GetAnalogEnabled())
{
document.getElementById("Category_Analog_enabled").checked = false;
EnDisableAnalog();
alert("Analog ROIs are disabled - please enable (Check box top left).\n");
return;
}
UpdateROIs();
}
@@ -288,22 +350,25 @@ function ParseIni(_basepath) {
}
function draw() {
function draw() {
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
context.drawImage(imageObj, 0, 0);
lw = 4
context.lineWidth = lw;
context.strokeStyle = "#FF0000";
var x0 = parseInt(rect.startX) - parseInt(lw/2);
var y0 = parseInt(rect.startY) - parseInt(lw/2);
var dx = parseInt(rect.w) + parseInt(lw);
var dy = parseInt(rect.h) + parseInt(lw);
context.strokeRect(x0, y0, dx, dy);
ROIInfo[aktindex]["x"] = rect.startX;
ROIInfo[aktindex]["y"] = rect.startY;
ROIInfo[aktindex]["dx"] = rect.w;
ROIInfo[aktindex]["dy"] = rect.h;
if (document.getElementById("Category_Analog_enabled").checked)
{
lw = 4
context.lineWidth = lw;
context.strokeStyle = "#FF0000";
var x0 = parseInt(rect.startX) - parseInt(lw/2);
var y0 = parseInt(rect.startY) - parseInt(lw/2);
var dx = parseInt(rect.w) + parseInt(lw);
var dy = parseInt(rect.h) + parseInt(lw);
context.strokeRect(x0, y0, dx, dy);
ROIInfo[aktindex]["x"] = rect.startX;
ROIInfo[aktindex]["y"] = rect.startY;
ROIInfo[aktindex]["dx"] = rect.w;
ROIInfo[aktindex]["dy"] = rect.h;
}
}
function getCoords(elem) { // crossbrowser version

View File

@@ -42,6 +42,7 @@ textarea {
<script type="text/javascript" src="./gethost.js"></script>
<script type="text/javascript" src="./readconfig.js"></script>
<script type="text/javascript" src="./readconfigcommon.js"></script>
<script type="text/javascript">
var canvas = document.getElementById('canvas'),

View File

@@ -61,7 +61,7 @@ textarea {
</tr>
<tr>
<td width="20px" style="padding-left: 40px;">
<input type="checkbox" id="MakeImage_LogImageLocation_enabled" value="1" onclick = 'document.getElementById("MakeImage_LogImageLocation_value").disabled = !document.getElementById("MakeImage_LogImageLocation_value1").disabled' unchecked >
<input type="checkbox" id="MakeImage_LogImageLocation_enabled" value="1" onclick = 'document.getElementById("MakeImage_LogImageLocation_value1").disabled = !document.getElementById("MakeImage_LogImageLocation_value1").disabled' unchecked >
</td>
<td width="200px">
<class id="MakeImage_LogImageLocation_text" style="color:black;">LogImageLocation</class>
@@ -75,7 +75,7 @@ textarea {
</tr>
<tr>
<td width="20px" style="padding-left: 40px;">
<td"><input type="checkbox" id="MakeImage_LogfileRetentionInDays_enabled" value="1" onclick = 'document.getElementById("MakeImage_LogfileRetentionInDays_value").disabled = !document.getElementById("MakeImage_LogfileRetentionInDays_value1").disabled' unchecked ></td>
<td"><input type="checkbox" id="MakeImage_LogfileRetentionInDays_enabled" value="1" onclick = 'document.getElementById("MakeImage_LogfileRetentionInDays_value1").disabled = !document.getElementById("MakeImage_LogfileRetentionInDays_value1").disabled' unchecked ></td>
</td>
<td>
<class id="MakeImage_LogfileRetentionInDays_text" style="color:black;">LogfileRetentionInDays</class>
@@ -123,7 +123,7 @@ textarea {
<td>
<select id="MakeImage_ImageSize_value1">
<option value="0" selected>VGA</option>
<option value="1" >SVGA</option>
<option value="1" >QVGA</option>
</select>
</td>
<td style="font-size: 80%;">
@@ -160,9 +160,29 @@ textarea {
y size (height) in which the reference is searched (default = "20")
</td>
</tr>
<tr class="expert" id="AlignmentAlgo_ex8">
<td width="20px" style="padding-left: 40px;">
<input type="checkbox" id="Alignment_AlignmentAlgo_enabled" value="1" onclick = 'document.getElementById("Alignment_AlignmentAlgo_value1").disabled = !document.getElementById("Alignment_AlignmentAlgo_value1").disabled' unchecked >
</td>
<td>
<class id="Alignment_AlignmentAlgo_text" style="color:black;">AlignmentAlgo</class>
</td>
<td>
<select id="Alignment_AlignmentAlgo_value1">
<option value="0" selected>Default</option>
<option value="1" >HighAccurity</option>
<option value="2" >Fast</option>
</select>
</td>
<td style="font-size: 80%;">
"Default" = use only R-Channel, "HighAccurity" = use all Channels (RGB, 3x slower), <br> "Fast" (First time RGB, then only check if image is shifted)
</td>
</tr>
<tr class="expert" id="ex4">
<td colspan="4" style="padding-left: 20px;"><h4>Digits</h4></td>
<tr id="Category_Digits_ex4">
<td colspan="4" style="padding-left: 20px;">
<h4><input type="checkbox" id="Category_Digits_enabled" value="1" onclick = 'UpdateAfterCategoryCheck()' unchecked >Digits</h4></td>
</tr>
<tr>
<td width="20px" style="padding-left: 40px;">
@@ -174,7 +194,7 @@ textarea {
<input type="text" id="Digits_Model_value1">
</td>
<td style="font-size: 80%;">
path to CNN model file for image recognition (in seconds)
path to CNN model file for image recognition
</td>
</tr>
<tr>
@@ -221,62 +241,61 @@ textarea {
</tr>
<tr class="expert" id="ex4">
<td colspan="4" style="padding-left: 20px;"><h4>Analog</h4></td>
<td colspan="4" style="padding-left: 20px;">
<h4><input type="checkbox" id="Category_Analog_enabled" value="1" onclick = 'UpdateAfterCategoryCheck()' unchecked > Analog</h4></td>
</tr>
<tr>
<td width="20px" style="padding-left: 40px;">
</td>
<td width="200px">
<class id="Analog_Model_text" style="color:black;">Model</class>
</td>
<td>
<input type="text" id="Analog_Model_value1">
</td>
<td style="font-size: 80%;">
path to CNN model file for image recognition (in seconds)
</td>
<td width="20px" style="padding-left: 40px;"> </td>
<td width="200px"> <class id="Analog_Model_text" style="color:black;">Model</class> </td>
<td> <input type="text" id="Analog_Model_value1"> </td>
<td style="font-size: 80%;"> path to CNN model file for image recognition</td>
</tr>
<tr>
<td width="20px" style="padding-left: 40px;">
<input type="checkbox" id="Analog_LogImageLocation_enabled" value="1" onclick = 'document.getElementById("Analog_LogImageLocation_value1").disabled = !document.getElementById("Analog_LogImageLocation_value1").disabled' unchecked >
</td>
<td>
<class id="Analog_LogImageLocation_text" style="color:black;">LogImageLocation</class>
</td>
<td>
<input type="text" name="name" id="Analog_LogImageLocation_value1">
</td>
<td style="font-size: 80%;">
Location to store separated digits for logging
</td>
<td> <class id="Analog_LogImageLocation_text" style="color:black;">LogImageLocation</class> </td>
<td> <input type="text" name="name" id="Analog_LogImageLocation_value1"> </td>
<td style="font-size: 80%;"> Location to store separated digits for logging </td>
</tr>
<tr>
<td width="20px" style="padding-left: 40px;">
<td"><input type="checkbox" id="Analog_LogfileRetentionInDays_enabled" value="1" onclick = 'document.getElementById("Analog_LogfileRetentionInDays_value1").disabled = !document.getElementById("Analog_LogfileRetentionInDays_value1").disabled' unchecked ></td>
</td>
<td>
<class id="Analog_LogfileRetentionInDays_text" style="color:black;">LogfileRetentionInDays</class>
<td> <class id="Analog_LogfileRetentionInDays_text" style="color:black;">LogfileRetentionInDays</class> </td>
<td> <input type="number" id="Analog_LogfileRetentionInDays_value1" min="0" step="1"> </td>
<td style="font-size: 80%;"> Time to keep the separated digit images (in days -"0" = forever) </td>
</tr>
<tr class="expert" id="Analog_ExtendedResolution_ex10">
<td width="20px" style="padding-left: 40px;">
<input type="checkbox" id="Analog_ExtendedResolution_enabled" value="1" onclick = 'document.getElementById("Analog_ExtendedResolution_value1").disabled = !document.getElementById("Analog_ExtendedResolution_value1").disabled' unchecked >
</td>
<td width="200px">
<class id="Analog_ExtendedResolution_text" style="color:black;">ExtendedResolution</class>
</td>
<td>
<input type="number" id="Analog_LogfileRetentionInDays_value1" min="0" step="1">
<select id="Analog_ExtendedResolution_value1">
<option value="0" selected>true</option>
<option value="1" >false</option>
</select>
</td>
<td style="font-size: 80%;">
Time to keep the separated digit images (in days -"0" = forever)
Enable to use the after point resolution for the last analog counter
</td>
</tr>
ExtendedResolution
<tr class="expert" id="ex10">
<td width="20px" style="padding-left: 40px;">
</td>
<td>
<class id="Analog_ModelInputSize_text" style="color:black;">ModelInputSize</class>
</td>
<td width="20px" style="padding-left: 40px;"> </td>
<td> <class id="Analog_ModelInputSize_text" style="color:black;">ModelInputSize</class> </td>
<td>
x: <input type="number" id="Analog_ModelInputSize_value1" style="width: 30px;" min="1" step="1">
y: <input type="number" id="Analog_ModelInputSize_value2" style="width: 30px;" min="1" step="1">
</td>
<td style="font-size: 80%;">
Size of the input image for the CNN model
</td>
<td style="font-size: 80%;"> Size of the input image for the CNN model </td>
</tr>
<tr>
@@ -394,7 +413,7 @@ textarea {
</tr>
<tr>
<td colspan="4" style="padding-left: 20px;"><h4>MQTT</h4></td>
<td colspan="4" style="padding-left: 20px;"><h4><input type="checkbox" id="Category_MQTT_enabled" value="1" onclick = 'UpdateAfterCategoryCheck()' unchecked > MQTT</h4></td>
</tr>
<tr>
<td width="20px" style="padding-left: 40px;">
@@ -468,7 +487,7 @@ textarea {
</tr>
<tr>
<td width="20px" style="padding-left: 40px;">
<input type="checkbox" id="MQTT_password_enabled" value="1" onclick = 'document.getElementById("MQTT_password_value1").disabled = !document.getElementById("MQTT_password_value1").disabled' checked >
<input type="checkbox" id="MQTT_password_enabled" value="1" onclick = 'document.getElementById("MQTT_password_value1").disabled = !document.getElementById("MQTT_password_value1").disabled' unchecked >
</td>
<td width="200px">
<class id="MQTT_password_text" style="color:black;">password</class>
@@ -538,7 +557,7 @@ textarea {
</tr>
<tr>
<td width="20px" style="padding-left: 40px;">
<td"><input type="checkbox" id="Debug_LogfileRetentionInDays_enabled" value="1" onclick = 'document.getElementById("Debug_LogfileRetentionInDays_value").disabled = !document.getElementById("Debug_LogfileRetentionInDays_value1").disabled' unchecked ></td>
<td"><input type="checkbox" id="Debug_LogfileRetentionInDays_enabled" value="1" onclick = 'document.getElementById("Debug_LogfileRetentionInDays_value1").disabled = !document.getElementById("Debug_LogfileRetentionInDays_value1").disabled' unchecked ></td>
</td>
<td>
<class id="Debug_LogfileRetentionInDays_text" style="color:black;">LogfileRetentionInDays</class>
@@ -556,7 +575,7 @@ textarea {
</tr>
<tr>
<td width="20px" style="padding-left: 40px;">
<td"><input type="checkbox" id="System_TimeZone_enabled" value="1" onclick = 'document.getElementById("System_TimeZone_value").disabled = !document.getElementById("System_TimeZone_value1").disabled' unchecked ></td>
<td"><input type="checkbox" id="System_TimeZone_enabled" value="1" onclick = 'document.getElementById("System_TimeZone_value1").disabled = !document.getElementById("System_TimeZone_value1").disabled' unchecked ></td>
</td>
<td>
<class id="System_TimeZone_text" style="color:black;">TimeZone</class>
@@ -570,18 +589,33 @@ textarea {
</tr>
<tr class="expert" id="ex16">
<td width="20px" style="padding-left: 40px;">
<input type="checkbox" id="System_TimeUpdateIntervall_enabled" value="1" onclick = 'document.getElementById("System_TimeUpdateIntervall_value1").disabled = !document.getElementById("System_TimeUpdateIntervall_value1").disabled' unchecked >
</td>
<td width="200px">
<class id="System_TimeUpdateIntervall_text" style="color:black;">TimeUpdateIntervall</class>
<td"><input type="checkbox" id="System_TimeServer_enabled" value="1" onclick = 'document.getElementById("System_TimeServer_value1").disabled = !document.getElementById("System_TimeServer_value1").disabled' unchecked ></td>
</td>
<td>
<input type="number" id="System_TimeUpdateIntervall_value1" size="13" min="0" step="1">
<class id="System_TimeServer_text" style="color:black;">TimeServer</class>
</td>
<td>
<input type="text" id="System_TimeServer_value1">
</td>
<td style="font-size: 80%;">
Intervall for synchronizing the time with the time server (in hours)
Time server to synchronize system time (default: "pool.ntp.org" - used if nothing is specified)
</td>
</tr>
<tr class="expert" id="System_Hostname">
<td width="20px" style="padding-left: 40px;">
<td"><input type="checkbox" id="System_Hostname_enabled" value="1" onclick = 'document.getElementById("System_Hostname_value1").disabled = !document.getElementById("System_Hostname_value1").disabled' unchecked ></td>
</td>
<td>
<class id="System_Hostname_text" style="color:black;">Hostname</class>
</td>
<td>
<input type="text" id="System_Hostname_value1">
</td>
<td style="font-size: 80%;">
Hostname for server - will be transfered to wlan.ini at next startup)
</td>
</tr>
</table>
<p>
@@ -597,12 +631,14 @@ textarea {
</div>
<script type="text/javascript" src="./gethost.js"></script>
<script type="text/javascript" src="./readconfigcommon.js"></script>
<script type="text/javascript" src="./readconfigparam.js"></script>
<script type="text/javascript">
var canvas = document.getElementById('canvas'),
basepath = "http://192.168.178.22";
param;
category;
function LoadConfigNeu() {
@@ -613,12 +649,14 @@ function LoadConfigNeu() {
}
loadConfig(basepath);
ParseConfig();
param = getConfigParameters();
category = getConfigCategory();
UpdateInput();
UpdateExpertModus();
document.getElementById("divall").style.display = '';
}
function WriteParameter(_param, _cat, _name, _optional, _select = false, _anzpara = 1){
function WriteParameter(_param, _category, _cat, _name, _optional, _select = false, _anzpara = 1){
if (_param[_cat][_name]["found"]){
if (_optional) {
document.getElementById(_cat+"_"+_name+"_enabled").checked = _param[_cat][_name]["enabled"];
@@ -654,6 +692,52 @@ function WriteParameter(_param, _cat, _name, _optional, _select = false, _anzpar
document.getElementById(_cat+"_"+_name+"_text").style="color:lightgrey;"
}
///////////////// am Ende, falls Kategorie als gesamtes nicht ausgewählt --> deaktivieren
if (_category[_cat]["enabled"] == false)
{
if (_optional) {
document.getElementById(_cat+"_"+_name+"_enabled").disabled = true;
for (var j = 1; j <= _anzpara; ++j) {
document.getElementById(_cat+"_"+_name+"_value"+j).disabled = true;
}
}
document.getElementById(_cat+"_"+_name+"_text").style="color:lightgrey;"
}
EnDisableItem(_category[_cat]["enabled"], _param, _category, _cat, _name, _optional);
}
function EnDisableItem(_status, _param, _category, _cat, _name, _optional)
{
_status = _param[_cat][_name]["found"] && _category[_cat]["enabled"];
_color = "color:lightgrey;";
if (_status) {
_color = "color:black;";
}
if (_optional) {
document.getElementById(_cat+"_"+_name+"_enabled").disabled = !_status;
document.getElementById(_cat+"_"+_name+"_enabled").style=_color;
}
if (!_param[_cat][_name]["enabled"]) {
_status = false;
_color = "color:lightgrey;";
}
document.getElementById(_cat+"_"+_name+"_text").disabled = !_status;
document.getElementById(_cat+"_"+_name+"_text").style = _color;
if (_param[_cat][_name]["anzParam"] == 2) {
_color = "width: 30px;" + _color;
}
for (var j = 1; j <= _param[_cat][_name]["anzParam"]; ++j) {
document.getElementById(_cat+"_"+_name+"_value"+j).disabled = !_status;
document.getElementById(_cat+"_"+_name+"_value"+j).style=_color;
}
}
@@ -667,7 +751,7 @@ function ReadParameter(_param, _cat, _name, _optional, _select = false){
_param[_cat][_name]["value1"] = sel.options[sel.selectedIndex].text;
}
else {
for (var j = 1; j <= _param[_cat][_name]["anzpara"]; ++j) {
for (var j = 1; j <= _param[_cat][_name]["anzParam"]; ++j) {
_param[_cat][_name]["value"+j] = document.getElementById(_cat+"_"+_name+"_value"+j).value;
}
}
@@ -675,52 +759,63 @@ function ReadParameter(_param, _cat, _name, _optional, _select = false){
}
function UpdateInput() {
param = getConfigParameters();
WriteParameter(param, "MakeImage", "LogImageLocation", true);
WriteParameter(param, "MakeImage", "LogfileRetentionInDays", true);
WriteParameter(param, "MakeImage", "WaitBeforeTakingPicture", false);
WriteParameter(param, "MakeImage", "ImageQuality", false);
WriteParameter(param, "MakeImage", "ImageSize", false, true, true);
document.getElementById("Category_Analog_enabled").checked = category["Analog"]["enabled"];
document.getElementById("Category_Digits_enabled").checked = category["Digits"]["enabled"];
document.getElementById("Category_MQTT_enabled").checked = category["MQTT"]["enabled"];
WriteParameter(param, "Alignment", "SearchFieldX", false);
WriteParameter(param, "Alignment", "SearchFieldY", false);
WriteParameter(param, category, "MakeImage", "LogImageLocation", true);
WriteParameter(param, category, "MakeImage", "LogfileRetentionInDays", true);
WriteParameter(param, category, "MakeImage", "WaitBeforeTakingPicture", false);
WriteParameter(param, category, "MakeImage", "ImageQuality", false);
WriteParameter(param, category, "MakeImage", "ImageSize", false, true, true);
WriteParameter(param, "Digits", "Model", false);
WriteParameter(param, "Digits", "LogImageLocation", false);
WriteParameter(param, "Digits", "LogfileRetentionInDays", false);
WriteParameter(param, "Digits", "ModelInputSize", false, false, 2);
WriteParameter(param, category, "Alignment", "SearchFieldX", false);
WriteParameter(param, category, "Alignment", "SearchFieldY", false);
WriteParameter(param, category, "Alignment", "AlignmentAlgo", true, true, true);
WriteParameter(param, "Analog", "Model", false);
WriteParameter(param, "Analog", "LogImageLocation", false);
WriteParameter(param, "Analog", "LogfileRetentionInDays", false);
WriteParameter(param, "Analog", "ModelInputSize", false, false, 2);
WriteParameter(param, category, "Digits", "Model", false);
WriteParameter(param, category, "Digits", "LogImageLocation", true);
WriteParameter(param, category, "Digits", "LogfileRetentionInDays", true);
WriteParameter(param, category, "Digits", "ModelInputSize", false, false, 2);
WriteParameter(param, "PostProcessing", "DecimalShift", true);
WriteParameter(param, "PostProcessing", "PreValueUse", true, true);
WriteParameter(param, "PostProcessing", "PreValueAgeStartup", true);
WriteParameter(param, "PostProcessing", "AllowNegativeRates", true, true);
WriteParameter(param, "PostProcessing", "MaxRateValue", true);
WriteParameter(param, "PostProcessing", "ErrorMessage", true, true);
WriteParameter(param, "PostProcessing", "CheckDigitIncreaseConsistency", true, true);
WriteParameter(param, category, "Analog", "Model", false);
WriteParameter(param, category, "Analog", "LogImageLocation", true);
WriteParameter(param, category, "Analog", "LogfileRetentionInDays", true);
WriteParameter(param, category, "Analog", "ExtendedResolution", true, true);
WriteParameter(param, category, "Analog", "ModelInputSize", false, false, 2);
WriteParameter(param, "MQTT", "Uri", true);
WriteParameter(param, "MQTT", "Topic", true);
WriteParameter(param, "MQTT", "TopicError", true);
WriteParameter(param, "MQTT", "ClientID", true);
WriteParameter(param, "MQTT", "user", true);
WriteParameter(param, "MQTT", "password", true);
WriteParameter(param, category, "PostProcessing", "DecimalShift", true);
WriteParameter(param, category, "PostProcessing", "PreValueUse", true, true);
WriteParameter(param, category, "PostProcessing", "PreValueAgeStartup", true);
WriteParameter(param, category, "PostProcessing", "AllowNegativeRates", true, true);
WriteParameter(param, category, "PostProcessing", "MaxRateValue", true);
WriteParameter(param, category, "PostProcessing", "ErrorMessage", true, true);
WriteParameter(param, category, "PostProcessing", "CheckDigitIncreaseConsistency", true, true);
WriteParameter(param, "AutoTimer", "AutoStart", true, true);
WriteParameter(param, "AutoTimer", "Intervall", true);
WriteParameter(param, category, "MQTT", "Uri", true);
WriteParameter(param, category, "MQTT", "Topic", true);
WriteParameter(param, category, "MQTT", "TopicError", true);
WriteParameter(param, category, "MQTT", "ClientID", true);
WriteParameter(param, category, "MQTT", "user", true);
WriteParameter(param, category, "MQTT", "password", true);
WriteParameter(param, "Debug", "Logfile", true, true);
WriteParameter(param, "Debug", "LogfileRetentionInDays", true);
WriteParameter(param, category, "AutoTimer", "AutoStart", true, true);
WriteParameter(param, category, "AutoTimer", "Intervall", true);
WriteParameter(param, "System", "TimeZone", true);
WriteParameter(param, "System", "TimeUpdateIntervall", true);
WriteParameter(param, category, "Debug", "Logfile", true, true);
WriteParameter(param, category, "Debug", "LogfileRetentionInDays", true);
WriteParameter(param, category, "System", "TimeZone", true);
WriteParameter(param, category, "System", "Hostname", true);
WriteParameter(param, category, "System", "TimeServer", true);
}
function WriteConfig(){
function ReadParameterAll()
{
category["Analog"]["enabled"] = document.getElementById("Category_Analog_enabled").checked;
category["Digits"]["enabled"] = document.getElementById("Category_Digits_enabled").checked;
category["MQTT"]["enabled"] = document.getElementById("Category_MQTT_enabled").checked;
ReadParameter(param, "MakeImage", "LogImageLocation", true);
ReadParameter(param, "MakeImage", "LogfileRetentionInDays", true);
ReadParameter(param, "MakeImage", "WaitBeforeTakingPicture", false);
@@ -729,15 +824,17 @@ function WriteConfig(){
ReadParameter(param, "Alignment", "SearchFieldX", false);
ReadParameter(param, "Alignment", "SearchFieldY", false);
ReadParameter(param, "Alignment", "AlignmentAlgo", true, true);
ReadParameter(param, "Digits", "Model", false);
ReadParameter(param, "Digits", "LogImageLocation", false);
ReadParameter(param, "Digits", "LogfileRetentionInDays", false);
ReadParameter(param, "Digits", "LogImageLocation", true);
ReadParameter(param, "Digits", "LogfileRetentionInDays", true);
ReadParameter(param, "Digits", "ModelInputSize", false, false, 2);
ReadParameter(param, "Analog", "Model", false);
ReadParameter(param, "Analog", "LogImageLocation", false);
ReadParameter(param, "Analog", "LogfileRetentionInDays", false);
ReadParameter(param, "Analog", "LogImageLocation", true);
ReadParameter(param, "Analog", "LogfileRetentionInDays", true);
ReadParameter(param, "Analog", "ExtendedResolution", true, true);
ReadParameter(param, "Analog", "ModelInputSize", false, false, 2);
ReadParameter(param, "PostProcessing", "DecimalShift", true);
@@ -762,21 +859,32 @@ function WriteConfig(){
ReadParameter(param, "Debug", "LogfileRetentionInDays", true);
ReadParameter(param, "System", "TimeZone", true);
ReadParameter(param, "System", "TimeUpdateIntervall", true);
ReadParameter(param, "System", "Hostname", true);
ReadParameter(param, "System", "TimeServer", true);
FormatDecimalValue(param, "PostProcessing", "MaxRateValue");
}
return setConfigParameters(param);
function WriteConfig(){
ReadParameterAll();
return setConfigParameters(param, category);
}
function FormatDecimalValue(_param, _cat, _name) {
for (var j = 1; j <= _param[_cat][_name]["anzpara"]; ++j) {
for (var j = 1; j <= _param[_cat][_name]["anzParam"]; ++j) {
var _val = _param[_cat][_name]["value"+j];
_val = _val.replace(",", ".");
_param[_cat][_name]["value"+j] = _val;
}
}
function UpdateAfterCategoryCheck() {
ReadParameterAll();
category["Analog"]["enabled"] = document.getElementById("Category_Analog_enabled").checked;
category["Digits"]["enabled"] = document.getElementById("Category_Digits_enabled").checked;
UpdateInput();
}
function UpdateExpertModus()
{
var _style = 'display:none;';

View File

@@ -55,7 +55,10 @@ th, td {
<body style="font-family: arial; padding: 0px 10px;">
<h2>Edit Digits</h2>
<h2><input type="checkbox" id="Category_Digits_enabled" value="1" onclick = 'EnDisableDigits()' checked >
Edit Digits</h2>
<div id="div1">
<table>
<tr>
@@ -91,7 +94,9 @@ th, td {
<td>y: <input type="number" name="refy" id="refy" step=1 onchange="valuemanualchanged()"></td>
<td>dy: <input type="number" name="refdy" id="refdy" step=1 onchange="valuemanualchanged()"></td>
</tr>
</table>
</table>
</div>
<table>
<tr>
@@ -101,6 +106,8 @@ th, td {
<script type="text/javascript" src="./gethost.js"></script>
<script type="text/javascript" src="./readconfig.js"></script>
<script type="text/javascript" src="./readconfigcommon.js"></script>
<script type="text/javascript" src="./jquery-3.5.1.min.js"></script>
<script language="JavaScript">
var canvas = document.getElementById('canvas'),
@@ -114,6 +121,41 @@ th, td {
lockAR = true;
basepath = "http://192.168.178.26";
function EnDisableDigits() {
isEnabled = document.getElementById("Category_Digits_enabled").checked;
$("#div2").attr("disabled", "disabled").off('click');
var x1=$("#div2").hasClass("disabledDiv");
if (isEnabled)
{
$("#div2").removeClass("disabledDiv");
}
else
{
$("#div2").addClass("disabledDiv");
}
sah1(document.getElementById("div1"), !isEnabled);
if (isEnabled)
{
UpdateROIs();
}
}
function sah1(el, _target) {
try {
el.disabled = _target;
} catch (E) {}
if (el.childNodes && el.childNodes.length > 0) {
for (var x = 0; x < el.childNodes.length; x++) {
sah1(el.childNodes[x], _target);
}
}
}
function onNameChange(){
ROIInfo[aktindex]["name"] = document.getElementById("name").value;
UpdateROIs();
@@ -172,7 +214,8 @@ function ChangeSelection(){
}
function SaveToConfig(){
SaveROIToConfig(ROIInfo, "[Digits]", basepath);
_enabled = document.getElementById("Category_Digits_enabled").checked;
SaveROIToConfig(ROIInfo, "[Digits]", basepath, _enabled);
UpdatePage();
}
@@ -230,8 +273,19 @@ function UpdateROIs(){
function ParseIni(_basepath) {
loadConfig(_basepath);
ParseConfig();
document.getElementById("Category_Digits_enabled").checked = true;
ROIInfo = getROIInfo("[Digits]");
if (!GetDigitsEnabled())
{
document.getElementById("Category_Digits_enabled").checked = false;
EnDisableDigits();
alert("Digital ROIs are disabled - please enable (Check box top left).\n");
return;
}
UpdateROIs();
}
@@ -287,22 +341,25 @@ function ParseIni(_basepath) {
}
function draw() {
function draw() {
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
context.drawImage(imageObj, 0, 0);
lw = 4
context.lineWidth = lw;
context.strokeStyle = "#FF0000";
var x0 = parseInt(rect.startX) - parseInt(lw/2);
var y0 = parseInt(rect.startY) - parseInt(lw/2);
var dx = parseInt(rect.w) + parseInt(lw);
var dy = parseInt(rect.h) + parseInt(lw);
context.strokeRect(x0, y0, dx, dy);
ROIInfo[aktindex]["x"] = rect.startX;
ROIInfo[aktindex]["y"] = rect.startY;
ROIInfo[aktindex]["dx"] = rect.w;
ROIInfo[aktindex]["dy"] = rect.h;
if (document.getElementById("Category_Digits_enabled").checked)
{
lw = 4
context.lineWidth = lw;
context.strokeStyle = "#FF0000";
var x0 = parseInt(rect.startX) - parseInt(lw/2);
var y0 = parseInt(rect.startY) - parseInt(lw/2);
var dx = parseInt(rect.w) + parseInt(lw);
var dy = parseInt(rect.h) + parseInt(lw);
context.strokeRect(x0, y0, dx, dy);
ROIInfo[aktindex]["x"] = rect.startX;
ROIInfo[aktindex]["y"] = rect.startY;
ROIInfo[aktindex]["dx"] = rect.w;
ROIInfo[aktindex]["dy"] = rect.h;
}
}
function getCoords(elem) { // crossbrowser version

View File

@@ -0,0 +1,66 @@
<!DOCTYPE html>
<html style="width: fit-content">
<head>
<title>jomjol - AI on the edge</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.h_iframe iframe {width:995px;height:605px;}
.h_iframe {width:995px;height:605px;}
h1 {font-size: 2em; margin-block-end: 0.3em;}
h2 {font-size: 1.5em;margin-block-start: 0.3em;}
h3 {font-size: 1.2em;}
p {font-size: 1em;}
</style>
</head>
<body style="font-family: arial">
<h2>Welcome to the Setup of the Digitizer</h2>
<p>
<img src="flow_overview.jpg" alt=""><img src="cnn_images.jpg" alt="">
</p>
<p>
This is the first time you the digitizer. You have been automatically routed to the <b>initial setup procedure</b>.
This procedure should adjust the setting to your local counter. Basically you can customize your settings in five steps.
<br>
In the final step the inital setup will be disabled and it will restart to the normal mode.
<br>
<br>
Just use the buttons "Next" and "Previous" to nagivate through the process.
<br>
</p>
<p>
Follow the instructions:
</p>
<p>
<ol>
<li>Create reference image <br>
Basis for the position references and the marking of the digits and counters.</li>
<li>Define two unique references <br>
Used to align the individual camera shot and identify the absolut positions</li>
<li>Define the digits <br>
Digital digits to be recognized</li>
<li>Define the analog counters <br>
Analog counters to be identified</li>
<li>General settings <br>
Most can stay to the default value - also MQTT connection can be specified here</li>
</ol>
<p>
After step 5 you switch of the setup mode, reboot and start in normal mode!
<h4>Have fun with the digitizer!</h4>
</body>
</html>

View File

@@ -0,0 +1,82 @@
<!DOCTYPE html>
<html style="width: fit-content">
<head>
<title>jomjol - AI on the edge</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.h_iframe iframe {width:995px;height:605px;}
.h_iframe {width:995px;height:605px;}
h1 {font-size: 2em; margin-block-end: 0.3em;}
h2 {font-size: 1.5em;margin-block-start: 0.3em;}
h3 {font-size: 1.2em;}
p {font-size: 1em;}
.button {
padding: 5px 20px;
width: 211px;
font-size: 16px;
}
</style>
</head>
<body style="font-family: arial">
<h4>Finished!</h4>
<p>
Now you are finished with the setup and ready to reboot to the normal mode.
<br>
Once you have pushed below button, the setup modus will be left and the digitizer start to normal operation mode.
<br>
After a view seconds you can reload this page again and will go to normal operation mode.
<br>
All settings can be changed later on as well in the configuration menue.
</p>
<p>
<button class="button" onclick="reboot()">Leave Setup Modus and Reboot to Normal</button>
</p>
<script type="text/javascript" src="./gethost.js"></script>
<script type="text/javascript" src="./readconfigparam.js"></script>
<script type="text/javascript" src="./readconfigcommon.js"></script>
<script type="text/javascript">
var canvas = document.getElementById('canvas'),
basepath = "http://192.168.178.22";
aktstatu = 0;
function reboot() {
if (confirm("Do you want to leave the configuration mode and restart the ESP32?\n\nPlease reload the page in about 30s.")) {
basepath = getbasepath();
if (!loadConfig(basepath)) {
alert("Setup Modus could not be deactivated!\Please retry.");
return;
}
ParseConfig();
param = getConfigParameters();
param["System"]["SetupMode"]["enabled"] = false;
param["System"]["SetupMode"]["value1"] = "false";
setConfigParameters(param);
var textToSave = setConfigParameters(param);
FileDeleteOnServer("/config/config.ini", basepath);
FileSendContent(textToSave, "/config/config.ini", basepath);
var stringota = "/reboot";
window.location = stringota;
window.location.href = stringota;
window.location.assign(stringota);
window.location.replace(stringota);
}
}
</script>
</body>
</html>

View File

@@ -39,7 +39,7 @@ table {
<tr>
<td><input class="button" type="button" value="Show Actual Reference" onclick="showReference()"></td>
<td><input class="button" type="button" value="Create New Reference" onclick="loadRawImage()"></td>
<td><input class="button" type="submit" id="take" onclick="doTake()" value="New Raw Image (raw.jpg)"></td>
<td><input class="button" type="submit" id="take" onclick="doTake()" value="Take Image"></td>
</tr>
<tr>
<td style="padding-top: 10px"><label for="mirror">Mirror Image:</label></td>
@@ -67,6 +67,7 @@ table {
<script type="text/javascript" src="./gethost.js"></script>
<script type="text/javascript" src="./readconfig.js"></script>
<script type="text/javascript" src="./readconfigcommon.js"></script>
<script language="JavaScript">
var canvas = document.getElementById('canvas'),
@@ -87,7 +88,7 @@ table {
}
function loadRawImage(){
url = basepath + "/fileserver/img_tmp/raw.jpg" + "?session=" + Math.floor((Math.random() * 1000000) + 1);
url = basepath + "/img_tmp/raw.jpg" + "?session=" + Math.floor((Math.random() * 1000000) + 1);
document.getElementById("finerotate").value = 0;
document.getElementById("prerotateangle").value = getPreRotate();
document.getElementById("mirror").checked = getMirror();

View File

@@ -0,0 +1,29 @@
<!DOCTYPE html>
<html style="width: fit-content">
<head>
<title>jomjol - AI on the edge</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.h_iframe iframe {width:995px;height:605px;}
.h_iframe {width:995px;height:605px;}
h1 {font-size: 2em; margin-block-end: 0.3em;}
h2 {font-size: 1.5em;margin-block-start: 0.3em;}
h3 {font-size: 1.2em;}
p {font-size: 1em;}
</style>
</head>
<body style="font-family: arial">
<h4>Introduction</h4>
<p>
Read below!
</body>
</html>

View File

@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html style="width: fit-content">
<head>
<title>jomjol - AI on the edge</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.h_iframe iframe {width:995px;height:605px;}
.h_iframe {width:995px;height:605px;}
h1 {font-size: 2em; margin-block-end: 0.3em;}
h2 {font-size: 1.5em;margin-block-start: 0.3em;}
h3 {font-size: 1.2em;}
p {font-size: 1em;}
</style>
</head>
<body style="font-family: arial">
<h4>Reference Image</h4>
The reference image is needed to define the digits, counters and references for alignment.
<p>
The last taken raw image from the camera is taken. Use the Button "Create New Reference" to make your own reference.<br>
Most important feature is a straight alignment of the image. Use the Pre roate Angle and the fine alignment to fine tune the rotation of the image<br>
Finish the step by pushing <b>"Update Reference Image"</b>.
</p>
</body>
</html>

View File

@@ -0,0 +1,36 @@
<!DOCTYPE html>
<html style="width: fit-content">
<head>
<title>jomjol - AI on the edge</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.h_iframe iframe {width:995px;height:605px;}
.h_iframe {width:995px;height:605px;}
h1 {font-size: 2em; margin-block-end: 0.3em;}
h2 {font-size: 1.5em;margin-block-start: 0.3em;}
h3 {font-size: 1.2em;}
p {font-size: 1em;}
</style>
</head>
<body style="font-family: arial">
<h4>Alignment References</h4>
Two opposite alignment references are needed to identify unique fix points on the image.
<p>
Mark the reference by drag and dop with the mouse or with the coordinates and push <b>"Update Reference"</b>.
<br>
You can switch between the two reference with <b>"Select Reference"</b>.
</p>
<p>
Don't forget to save your changes with <b>"Save to Config.ini"</b>!.
</p>
</body>
</html>

View File

@@ -0,0 +1,37 @@
<!DOCTYPE html>
<html style="width: fit-content">
<head>
<title>jomjol - AI on the edge</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.h_iframe iframe {width:995px;height:605px;}
.h_iframe {width:995px;height:605px;}
h1 {font-size: 2em; margin-block-end: 0.3em;}
h2 {font-size: 1.5em;margin-block-start: 0.3em;}
h3 {font-size: 1.2em;}
p {font-size: 1em;}
</style>
</head>
<body style="font-family: arial">
<h4>Define Digits</h4>
Here you define your digits you want to read.
<p>
With the drop down menue <b>"ROI x"</b> you can change between the different digits. Mark them with the mouse or the coordinates.
<br>
To create new ROIs use <b>"New ROIs"</b>. The order of the ROIs defines the positon within the reading. <br>
You can change it with <b>"move Next" / "move Previous"</b>.
</p>
<p>
Don't forget to save your changes with <b>"Save all to Config.ini"</b>!.
</p>
</body>
</html>

View File

@@ -0,0 +1,37 @@
<!DOCTYPE html>
<html style="width: fit-content">
<head>
<title>jomjol - AI on the edge</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.h_iframe iframe {width:995px;height:605px;}
.h_iframe {width:995px;height:605px;}
h1 {font-size: 2em; margin-block-end: 0.3em;}
h2 {font-size: 1.5em;margin-block-start: 0.3em;}
h3 {font-size: 1.2em;}
p {font-size: 1em;}
</style>
</head>
<body style="font-family: arial">
<h4>Define Digits</h4>
Here you define your analog counters you want to read. If you do not have analog counters delete all ROIs.
<p>
With the drop down menue <b>"ROI x"</b> you can change between the different counters. Mark them with the mouse or the coordinates.
<br>
To create new ROIs use <b>"New ROIs"</b>. The order of the ROIs defines the positon within the reading. <br>
You can change it with <b>"move Next" / "move Previous"</b>.
</p>
<p>
Don't forget to save your changes with <b>"Save all to Config.ini"</b>!.
</p>
</body>
</html>

View File

@@ -0,0 +1,35 @@
<!DOCTYPE html>
<html style="width: fit-content">
<head>
<title>jomjol - AI on the edge</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.h_iframe iframe {width:995px;height:605px;}
.h_iframe {width:995px;height:605px;}
h1 {font-size: 2em; margin-block-end: 0.3em;}
h2 {font-size: 1.5em;margin-block-start: 0.3em;}
h3 {font-size: 1.2em;}
p {font-size: 1em;}
</style>
</head>
<body style="font-family: arial">
<h4>General configuration parameters</h4>
Here you define additional setting. The settings should fit for a normal setup. </p>
<p>
Only if you want to connect to a MQTT-broker you need to adjust the corresponding parameters.
</p>
<p>
Don't forget to save your changes with <b>"Update Config.ini"</b>!.
<br>You should not reboot here, but leave the setup modus on the next page.
</p>
</body>
</html>

View File

@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html style="width: fit-content">
<head>
<title>jomjol - AI on the edge</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.h_iframe iframe {width:995px;height:605px;}
.h_iframe {width:995px;height:605px;}
h1 {font-size: 2em; margin-block-end: 0.3em;}
h2 {font-size: 1.5em;margin-block-start: 0.3em;}
h3 {font-size: 1.2em;}
p {font-size: 1em;}
</style>
</head>
<body style="font-family: arial">
<h4>Finished!</h4>
Read below!
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

View File

@@ -7,9 +7,11 @@ function getbasepath(){
var host = window.location.hostname;
if ((host == "127.0.0.1") || (host == "localhost"))
{
// host = "http://192.168.178.26"; // jomjol interner test
host = "http://192.168.178.22"; // jomjol interner Real
// host = "http://192.168.2.118"; // jomjol interner test
host = "http://192.168.178.26"; // jomjol interner test
// host = "http://192.168.178.22"; // jomjol interner Real
// host = "."; // jomjol interner localhost
}
else
{

View File

@@ -97,6 +97,7 @@ li.dropdown {
</div>
</ul>
<p>
<div class="h_iframe">
<iframe name="maincontent" id ="maincontent" src="/wasserzaehler_roi.html" title="fileserver" allowfullscreen></iframe>
</div>

View File

@@ -8,6 +8,10 @@ var ref = new Array(2);
var digit = new Array(0);
var analog = new Array(0);
var initalrotate = new Object();
var analogEnabled = false;
var posAnalogHeader;
var digitsEnabled = false;
var posDigitsHeader;
function MakeRefZW(zw, _basepath){
url = _basepath + "/editflow.html?task=cutref&in=/config/reference.jpg&out=/img_tmp/ref_zw_org.jpg&x=" + zw["x"] + "&y=" + zw["y"] + "&dx=" + zw["dx"] + "&dy=" + zw["dy"];
@@ -36,7 +40,9 @@ function ParseConfigAlignment(_aktline){
var akt_ref = 0;
++_aktline;
while ((akt_ref < 2) && (_aktline < config_split.length) && (config_split[_aktline][0] != "[")) {
while ((_aktline < config_split.length)
&& !(config_split[_aktline][0] == "[")
&& !((config_split[_aktline][0] == ";") && (config_split[_aktline][1] == "["))) {
var linesplit = ZerlegeZeile(config_split[_aktline]);
if ((linesplit[0].toUpperCase() == "INITIALMIRROR") && (linesplit.length > 1))
{
@@ -67,7 +73,9 @@ function ParseConfigDigit(_aktline){
++_aktline;
digit.length = 0;
while ((_aktline < config_split.length) && (config_split[_aktline][0] != "[")) {
while ((_aktline < config_split.length)
&& !(config_split[_aktline][0] == "[")
&& !((config_split[_aktline][0] == ";") && (config_split[_aktline][1] == "["))) {
var linesplit = ZerlegeZeile(config_split[_aktline]);
if (linesplit.length >= 5)
{
@@ -86,12 +94,23 @@ function ParseConfigDigit(_aktline){
return _aktline;
}
function GetAnalogEnabled() {
return analogEnabled;
}
function GetDigitsEnabled() {
return digitsEnabled;
}
function ParseConfigAnalog(_aktline){
++_aktline;
analog.length = 0;
while ((_aktline < config_split.length) && (config_split[_aktline][0] != "[")) {
while ((_aktline < config_split.length)
&& !(config_split[_aktline][0] == "[")
&& !((config_split[_aktline][0] == ";") && (config_split[_aktline][1] == "["))) {
var linesplit = ZerlegeZeile(config_split[_aktline]);
if (linesplit.length >= 5)
{
@@ -121,11 +140,21 @@ function getROIInfo(_typeROI){
return targetROI.slice(); // Kopie senden, nicht orginal!!!
}
function SaveROIToConfig(_ROIInfo, _typeROI, _basepath){
function SaveROIToConfig(_ROIInfo, _typeROI, _basepath, _enabled){
if (_enabled) {
text = _typeROI;
}
else {
text = ";" + _typeROI;
}
if (_typeROI == "[Digits]"){
config_split[posDigitsHeader] = text;
targetROI = digit;
}
if (_typeROI == "[Analog]"){
config_split[posAnalogHeader] = text;
targetROI = analog;
}
@@ -165,16 +194,24 @@ function ParseConfig() {
var aktline = 0;
while (aktline < config_split.length){
if (config_split[aktline].trim().toUpperCase() == "[ALIGNMENT]") {
if ((config_split[aktline].trim().toUpperCase() == "[ALIGNMENT]") || (config_split[aktline].trim().toUpperCase() == ";[ALIGNMENT]")){
aktline = ParseConfigAlignment(aktline);
continue;
}
if (config_split[aktline].trim().toUpperCase() == "[DIGITS]") {
if ((config_split[aktline].trim().toUpperCase() == "[DIGITS]") || (config_split[aktline].trim().toUpperCase() == ";[DIGITS]")){
posDigitsHeader = aktline;
if (config_split[aktline][0] == "[") {
digitsEnabled = true;
}
aktline = ParseConfigDigit(aktline);
continue;
}
if (config_split[aktline].trim().toUpperCase() == "[ANALOG]") {
if ((config_split[aktline].trim().toUpperCase() == "[ANALOG]") || (config_split[aktline].trim().toUpperCase() == ";[ANALOG]")) {
posAnalogHeader = aktline;
if (config_split[aktline][0] == "[") {
analogEnabled = true;
}
aktline = ParseConfigAnalog(aktline);
continue;
}
@@ -313,19 +350,6 @@ function MakeContrastImageZW(zw, _enhance, _basepath){
}
}
function createReader(file) {
var image = new Image();
reader.onload = function(evt) {
var image = new Image();
image.onload = function(evt) {
var width = this.width;
var height = this.height;
alert (width); // will produce something like 198
};
image.src = evt.target.result;
};
reader.readAsDataURL(file);
}
function GetReferenceSize(name){
img = new Image();
@@ -347,83 +371,6 @@ function GetReferenceSize(name){
}
function ZerlegeZeile(input)
{
var Output = Array(0);
delimiter = " =,";
input = trim(input, delimiter);
var pos = findDelimiterPos(input, delimiter);
var token;
while (pos > -1) {
token = input.substr(0, pos);
token = trim(token, delimiter);
Output.push(token);
input = input.substr(pos+1, input.length);
input = trim(input, delimiter);
pos = findDelimiterPos(input, delimiter);
}
Output.push(input);
return Output;
}
function findDelimiterPos(input, delimiter)
{
var pos = -1;
var zw;
var akt_del;
for (var anz = 0; anz < delimiter.length; ++anz)
{
akt_del = delimiter[anz];
zw = input.indexOf(akt_del);
if (zw > -1)
{
if (pos > -1)
{
if (zw < pos)
pos = zw;
}
else
pos = zw;
}
}
return pos;
}
function trim(istring, adddelimiter)
{
while ((istring.length > 0) && (adddelimiter.indexOf(istring[0]) >= 0)){
istring = istring.substr(1, istring.length-1);
}
while ((istring.length > 0) && (adddelimiter.indexOf(istring[istring.length-1]) >= 0)){
istring = istring.substr(0, istring.length-1);
}
return istring;
}
function loadConfig(_basepath) {
var xhttp = new XMLHttpRequest();
try {
url = _basepath + '/fileserver/config/config.ini';
xhttp.open("GET", url, false);
xhttp.send();
config_gesamt = xhttp.responseText;
}
catch (error)
{
// alert("Deleting Config.ini failed");
}
}
function getConfig() {
return config_gesamt;
}
@@ -439,75 +386,6 @@ function dataURLtoBlob(dataurl) {
return new Blob([u8arr], {type:mime});
}
function FileCopyOnServer(_source, _target, _basepath = ""){
url = _basepath + "/editflow.html?task=copy&in=" + _source + "&out=" + _target;
var xhttp = new XMLHttpRequest();
try {
xhttp.open("GET", url, false);
xhttp.send(); }
catch (error)
{
// alert("Deleting Config.ini failed");
}
}
function FileDeleteOnServer(_filename, _basepath = ""){
var xhttp = new XMLHttpRequest();
var okay = false;
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4) {
if (xhttp.status == 200) {
okay = true;
} else if (xhttp.status == 0) {
// alert("Server closed the connection on delete abruptly!");
// location.reload()
} else {
// alert(xhttp.status + " Error!\n" + xhttp.responseText);
// location.reload()
}
}
};
try {
var url = _basepath + "/delete" + _filename;
xhttp.open("POST", url, false);
xhttp.send();
}
catch (error)
{
// alert("Deleting Config.ini failed");
}
return okay;
}
function FileSendContent(_content, _filename, _basepath = ""){
var xhttp = new XMLHttpRequest();
var okay = false;
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4) {
if (xhttp.status == 200) {
okay = true;
} else if (xhttp.status == 0) {
alert("Server closed the connection abruptly!");
} else {
alert(xhttp.status + " Error!\n" + xhttp.responseText);
}
}
};
try {
upload_path = _basepath + "/upload" + _filename;
xhttp.open("POST", upload_path, false);
xhttp.send(_content);
}
catch (error)
{
// alert("Deleting Config.ini failed");
}
return okay;
}
function SaveReferenceImage(_id_canvas, _filename, _doDelete, _basepath = ""){
if (_doDelete){

View File

@@ -0,0 +1,263 @@
function readconfig_Version(){
return "1.0.0 - 20200910";
}
function SaveConfigToServer(_basepath){
// leere Zeilen am Ende löschen
var zw = config_split.length - 1;
while (config_split[zw] == "") {
config_split.pop();
}
var config_gesamt = "";
for (var i = 0; i < config_split.length; ++i)
{
config_gesamt = config_gesamt + config_split[i] + "\n";
}
FileDeleteOnServer("/config/config.ini", _basepath);
FileSendContent(config_gesamt, "/config/config.ini", _basepath);
}
function UpdateConfigFileReferenceChange(_basepath){
for (var _index = 0; _index < ref.length; ++_index){
var zeile = ref[_index]["name"] + " " + ref[_index]["x"] + " " + ref[_index]["y"];
var _pos = ref[_index]["pos_ref"];
config_split[_pos] = zeile;
}
zeile = "InitialRotate = " + initalrotate["angle"];
var _pos = initalrotate["pos_config"];
config_split[_pos] = zeile;
var mirror = false;
if (initalrotate.hasOwnProperty("mirror")) {
mirror = initalrotate["mirror"];
}
var mirror_pos = -1;
if (initalrotate.hasOwnProperty("pos_config_mirror")) {
mirror_pos = initalrotate["pos_config_mirror"];
}
if (mirror_pos > -1) {
if (mirror) {
config_split[mirror_pos] = "InitialMirror = true";
}
else {
config_split[mirror_pos] = "InitialMirror = false";
}
}
else {
if (mirror) { // neue Zeile muss an der richtigen Stelle eingefügt werden - hier direct nach [Alignment]
var aktline = 0;
while (aktline < config_split.length){
if (config_split[aktline].trim() == "[Alignment]") {
break;
}
aktline++
}
// fuege neue Zeile in config_split ein
var zw = config_split[config_split.length-1];
config_split.push(zw);
for (var j = config_split.length-2; j > aktline + 1; --j){
config_split[j] = config_split[j-1];
}
config_split[aktline + 1] = "InitialMirror = True"
}
}
SaveConfigToServer(_basepath);
}
function UpdateConfig(zw, _index, _enhance, _basepath){
var zeile = zw["name"] + " " + zw["x"] + " " + zw["y"];
var _pos = ref[_index]["pos_ref"];
config_split[_pos] = zeile;
SaveConfigToServer(_basepath);
var namezw = zw["name"];
FileCopyOnServer("/img_tmp/ref_zw.jpg", namezw, _basepath);
var namezw = zw["name"].replace(".jpg", "_org.jpg");
FileCopyOnServer("/img_tmp/ref_zw_org.jpg", namezw, _basepath);
}
function createReader(file) {
var image = new Image();
reader.onload = function(evt) {
var image = new Image();
image.onload = function(evt) {
var width = this.width;
var height = this.height;
alert (width); // will produce something like 198
};
image.src = evt.target.result;
};
reader.readAsDataURL(file);
}
function ZerlegeZeile(input)
{
var Output = Array(0);
delimiter = " =,\r";
input = trim(input, delimiter);
var pos = findDelimiterPos(input, delimiter);
var token;
while (pos > -1) {
token = input.substr(0, pos);
token = trim(token, delimiter);
Output.push(token);
input = input.substr(pos+1, input.length);
input = trim(input, delimiter);
pos = findDelimiterPos(input, delimiter);
}
Output.push(input);
return Output;
}
function findDelimiterPos(input, delimiter)
{
var pos = -1;
var zw;
var akt_del;
for (var anz = 0; anz < delimiter.length; ++anz)
{
akt_del = delimiter[anz];
zw = input.indexOf(akt_del);
if (zw > -1)
{
if (pos > -1)
{
if (zw < pos)
pos = zw;
}
else
pos = zw;
}
}
return pos;
}
function trim(istring, adddelimiter)
{
while ((istring.length > 0) && (adddelimiter.indexOf(istring[0]) >= 0)){
istring = istring.substr(1, istring.length-1);
}
while ((istring.length > 0) && (adddelimiter.indexOf(istring[istring.length-1]) >= 0)){
istring = istring.substr(0, istring.length-1);
}
return istring;
}
function loadConfig(_basepath) {
var xhttp = new XMLHttpRequest();
try {
url = _basepath + '/fileserver/config/config.ini';
xhttp.open("GET", url, false);
xhttp.send();
config_gesamt = xhttp.responseText;
}
catch (error)
{
// alert("Deleting Config.ini failed");
}
return true;
}
function dataURLtoBlob(dataurl) {
var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while(n--){
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], {type:mime});
}
function FileCopyOnServer(_source, _target, _basepath = ""){
url = _basepath + "/editflow.html?task=copy&in=" + _source + "&out=" + _target;
var xhttp = new XMLHttpRequest();
try {
xhttp.open("GET", url, false);
xhttp.send(); }
catch (error)
{
// alert("Deleting Config.ini failed");
}
}
function FileDeleteOnServer(_filename, _basepath = ""){
var xhttp = new XMLHttpRequest();
var okay = false;
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4) {
if (xhttp.status == 200) {
okay = true;
} else if (xhttp.status == 0) {
// alert("Server closed the connection on delete abruptly!");
// location.reload()
} else {
// alert(xhttp.status + " Error!\n" + xhttp.responseText);
// location.reload()
}
}
};
try {
var url = _basepath + "/delete" + _filename;
xhttp.open("POST", url, false);
xhttp.send();
}
catch (error)
{
// alert("Deleting Config.ini failed");
}
return okay;
}
function FileSendContent(_content, _filename, _basepath = ""){
var xhttp = new XMLHttpRequest();
var okay = false;
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4) {
if (xhttp.status == 200) {
okay = true;
} else if (xhttp.status == 0) {
alert("Server closed the connection abruptly!");
} else {
alert(xhttp.status + " Error!\n" + xhttp.responseText);
}
}
};
try {
upload_path = _basepath + "/upload" + _filename;
xhttp.open("POST", upload_path, false);
xhttp.send(_content);
}
catch (error)
{
// alert("Deleting Config.ini failed");
}
return okay;
}

View File

@@ -5,6 +5,7 @@ function readconfig_Version(){
var config_gesamt;
var config_split;
var param;
var category;
var ref = new Array(2);
function ParseConfig() {
@@ -12,8 +13,12 @@ function ParseConfig() {
var aktline = 0;
param = new Object();
category = new Object();
var catname = "MakeImage";
category[catname] = new Object();
category[catname]["enabled"] = false;
category[catname]["found"] = false;
param[catname] = new Object();
ParamAddValue(param, catname, "LogImageLocation");
ParamAddValue(param, catname, "WaitBeforeTakingPicture");
@@ -22,25 +27,39 @@ function ParseConfig() {
ParamAddValue(param, catname, "ImageSize");
var catname = "Alignment";
category[catname] = new Object();
category[catname]["enabled"] = false;
category[catname]["found"] = false;
param[catname] = new Object();
ParamAddValue(param, catname, "SearchFieldX");
ParamAddValue(param, catname, "SearchFieldY");
ParamAddValue(param, catname, "AlignmentAlgo");
var catname = "Digits";
category[catname] = new Object();
category[catname]["enabled"] = false;
category[catname]["found"] = false;
param[catname] = new Object();
ParamAddValue(param, catname, "Model");
ParamAddValue(param, catname, "LogImageLocation");
ParamAddValue(param, catname, "LogfileRetentionInDays");
ParamAddValue(param, catname, "ModelInputSize");
ParamAddValue(param, catname, "ModelInputSize", 2);
var catname = "Analog";
category[catname] = new Object();
category[catname]["enabled"] = false;
category[catname]["found"] = false;
param[catname] = new Object();
ParamAddValue(param, catname, "Model");
ParamAddValue(param, catname, "LogImageLocation");
ParamAddValue(param, catname, "LogfileRetentionInDays");
ParamAddValue(param, catname, "ModelInputSize");
ParamAddValue(param, catname, "ModelInputSize", 2);
ParamAddValue(param, catname, "ExtendedResolution");
var catname = "PostProcessing";
category[catname] = new Object();
category[catname]["enabled"] = false;
category[catname]["found"] = false;
param[catname] = new Object();
ParamAddValue(param, catname, "DecimalShift");
ParamAddValue(param, catname, "PreValueUse");
@@ -51,6 +70,9 @@ function ParseConfig() {
ParamAddValue(param, catname, "CheckDigitIncreaseConsistency");
var catname = "MQTT";
category[catname] = new Object();
category[catname]["enabled"] = false;
category[catname]["found"] = false;
param[catname] = new Object();
ParamAddValue(param, catname, "Uri");
ParamAddValue(param, catname, "Topic");
@@ -60,224 +82,77 @@ function ParseConfig() {
ParamAddValue(param, catname, "password");
var catname = "AutoTimer";
category[catname] = new Object();
category[catname]["enabled"] = false;
category[catname]["found"] = false;
param[catname] = new Object();
ParamAddValue(param, catname, "AutoStart");
ParamAddValue(param, catname, "Intervall");
var catname = "Debug";
category[catname] = new Object();
category[catname]["enabled"] = false;
category[catname]["found"] = false;
param[catname] = new Object();
ParamAddValue(param, catname, "Logfile");
ParamAddValue(param, catname, "LogfileRetentionInDays");
var catname = "System";
category[catname] = new Object();
category[catname]["enabled"] = false;
category[catname]["found"] = false;
param[catname] = new Object();
ParamAddValue(param, catname, "TimeZone");
ParamAddValue(param, catname, "TimeServer");
ParamAddValue(param, catname, "AutoAdjustSummertime");
ParamAddValue(param, catname, "TimeUpdateIntervall");
ParamAddValue(param, catname, "Hostname");
ParamAddValue(param, catname, "SetupMode");
while (aktline < config_split.length){
if (config_split[aktline].trim().toUpperCase() == "[MAKEIMAGE]") {
aktline = ParseConfigParamMakeImage(aktline);
continue;
for (var cat in category) {
zw = cat.toUpperCase();
zw1 = "[" + zw + "]";
zw2 = ";[" + zw + "]";
if ((config_split[aktline].trim().toUpperCase() == zw1) || (config_split[aktline].trim().toUpperCase() == zw2)) {
if (config_split[aktline].trim().toUpperCase() == zw1) {
category[cat]["enabled"] = true;
}
category[cat]["found"] = true;
category[cat]["line"] = aktline;
aktline = ParseConfigParamAll(aktline, cat);
continue;
}
}
if (config_split[aktline].trim().toUpperCase() == "[ALIGNMENT]") {
aktline = ParseConfigParamAlignment(aktline);
continue;
}
if (config_split[aktline].trim().toUpperCase() == "[DIGITS]") {
aktline = ParseConfigParamDigit(aktline);
continue;
}
if (config_split[aktline].trim().toUpperCase() == "[ANALOG]") {
aktline = ParseConfigParamAnalog(aktline);
continue;
}
if (config_split[aktline].trim().toUpperCase() == "[POSTPROCESSING]") {
aktline = ParseConfigParamPostProcessing(aktline);
continue;
}
if (config_split[aktline].trim().toUpperCase() == "[MQTT]") {
aktline = ParseConfigParamMQTT(aktline);
continue;
}
if (config_split[aktline].trim().toUpperCase() == "[AUTOTIMER]") {
aktline = ParseConfigParamAutoTimer(aktline);
continue;
}
if (config_split[aktline].trim().toUpperCase() == "[DEBUG]") {
aktline = ParseConfigParamDebug(aktline);
continue;
}
if (config_split[aktline].trim().toUpperCase() == "[SYSTEM]") {
aktline = ParseConfigParamSystem(aktline);
continue;
}
aktline++;
}
}
function ParamAddValue(param, _cat, _param){
function ParamAddValue(param, _cat, _param, _anzParam = 1){
param[_cat][_param] = new Object();
param[_cat][_param]["found"] = false;
param[_cat][_param]["enabled"] = false;
param[_cat][_param]["line"] = -1;
param[_cat][_param]["anzParam"] = _anzParam;
};
function ParseConfigParamSystem(_aktline){
var akt_ref = 0;
function ParseConfigParamAll(_aktline, _catname){
++_aktline;
var catname = "System";
while ((akt_ref < 2) && (_aktline < config_split.length) && (config_split[_aktline][0] != "[")) {
var _input = config_split[_aktline];
let [isCom, input] = isCommented(_input);
var linesplit = ZerlegeZeile(input, " =");
ParamExtractValue(param, linesplit, catname, "TimeZone", _aktline, isCom);
ParamExtractValue(param, linesplit, catname, "AutoAdjustSummertime", _aktline, isCom);
ParamExtractValue(param, linesplit, catname, "TimeUpdateIntervall", _aktline, isCom);
++_aktline;
}
return _aktline;
}
function ParseConfigParamDebug(_aktline){
var akt_ref = 0;
++_aktline;
var catname = "Debug";
while ((akt_ref < 2) && (_aktline < config_split.length) && (config_split[_aktline][0] != "[")) {
while ((_aktline < config_split.length)
&& !(config_split[_aktline][0] == "[")
&& !((config_split[_aktline][0] == ";") && (config_split[_aktline][1] == "["))) {
var _input = config_split[_aktline];
let [isCom, input] = isCommented(_input);
var linesplit = ZerlegeZeile(input);
ParamExtractValue(param, linesplit, catname, "Logfile", _aktline, isCom);
ParamExtractValue(param, linesplit, catname, "LogfileRetentionInDays", _aktline, isCom);
ParamExtractValueAll(param, linesplit, _catname, _aktline, isCom);
++_aktline;
}
return _aktline;
}
function ParseConfigParamAutoTimer(_aktline){
var akt_ref = 0;
++_aktline;
var catname = "AutoTimer";
while ((akt_ref < 2) && (_aktline < config_split.length) && (config_split[_aktline][0] != "[")) {
var _input = config_split[_aktline];
let [isCom, input] = isCommented(_input);
var linesplit = ZerlegeZeile(input);
ParamExtractValue(param, linesplit, catname, "AutoStart", _aktline, isCom);
ParamExtractValue(param, linesplit, catname, "Intervall", _aktline, isCom);
++_aktline;
}
return _aktline;
}
function ParseConfigParamMQTT(_aktline){
var akt_ref = 0;
++_aktline;
var catname = "MQTT";
while ((akt_ref < 2) && (_aktline < config_split.length) && (config_split[_aktline][0] != "[")) {
var _input = config_split[_aktline];
let [isCom, input] = isCommented(_input);
var linesplit = ZerlegeZeile(input);
ParamExtractValue(param, linesplit, catname, "Uri", _aktline, isCom);
ParamExtractValue(param, linesplit, catname, "Topic", _aktline, isCom);
ParamExtractValue(param, linesplit, catname, "TopicError", _aktline, isCom);
ParamExtractValue(param, linesplit, catname, "ClientID", _aktline, isCom);
ParamExtractValue(param, linesplit, catname, "user", _aktline, isCom);
ParamExtractValue(param, linesplit, catname, "password", _aktline, isCom);
++_aktline;
}
return _aktline;
}
function ParseConfigParamPostProcessing(_aktline){
var akt_ref = 0;
++_aktline;
var catname = "PostProcessing";
while ((akt_ref < 2) && (_aktline < config_split.length) && (config_split[_aktline][0] != "[")) {
var _input = config_split[_aktline];
let [isCom, input] = isCommented(_input);
var linesplit = ZerlegeZeile(input);
ParamExtractValue(param, linesplit, catname, "DecimalShift", _aktline, isCom);
ParamExtractValue(param, linesplit, catname, "PreValueUse", _aktline, isCom);
ParamExtractValue(param, linesplit, catname, "PreValueAgeStartup", _aktline, isCom);
ParamExtractValue(param, linesplit, catname, "AllowNegativeRates", _aktline, isCom);
ParamExtractValue(param, linesplit, catname, "MaxRateValue", _aktline, isCom);
ParamExtractValue(param, linesplit, catname, "ErrorMessage", _aktline, isCom);
ParamExtractValue(param, linesplit, catname, "CheckDigitIncreaseConsistency", _aktline, isCom);
++_aktline;
}
return _aktline;
}
function ParseConfigParamAnalog(_aktline){
var akt_ref = 0;
++_aktline;
var catname = "Analog";
while ((akt_ref < 2) && (_aktline < config_split.length) && (config_split[_aktline][0] != "[")) {
var _input = config_split[_aktline];
let [isCom, input] = isCommented(_input);
var linesplit = ZerlegeZeile(input);
ParamExtractValue(param, linesplit, catname, "Model", _aktline, isCom);
ParamExtractValue(param, linesplit, catname, "LogImageLocation", _aktline, isCom);
ParamExtractValue(param, linesplit, catname, "LogfileRetentionInDays", _aktline, isCom);
ParamExtractValue(param, linesplit, catname, "ModelInputSize", _aktline, isCom, 2);
++_aktline;
}
return _aktline;
}
function ParseConfigParamDigit(_aktline){
var akt_ref = 0;
++_aktline;
var catname = "Digits";
while ((akt_ref < 2) && (_aktline < config_split.length) && (config_split[_aktline][0] != "[")) {
var _input = config_split[_aktline];
let [isCom, input] = isCommented(_input);
var linesplit = ZerlegeZeile(input);
ParamExtractValue(param, linesplit, catname, "Model", _aktline, isCom);
ParamExtractValue(param, linesplit, catname, "LogImageLocation", _aktline, isCom);
ParamExtractValue(param, linesplit, catname, "LogfileRetentionInDays", _aktline, isCom);
ParamExtractValue(param, linesplit, catname, "ModelInputSize", _aktline, isCom, 2);
++_aktline;
}
return _aktline;
}
function ParamExtractValue(_param, _linesplit, _catname, _paramname, _aktline, _iscom, _anzvalue = 1){
if ((_linesplit[0].toUpperCase() == _paramname.toUpperCase()) && (_linesplit.length > _anzvalue))
{
@@ -291,66 +166,40 @@ function ParamExtractValue(_param, _linesplit, _catname, _paramname, _aktline, _
}
}
function ParseConfigParamAlignment(_aktline){
var akt_ref = 0;
++_aktline;
var catname = "Alignment";
while ((akt_ref < 2) && (_aktline < config_split.length) && (config_split[_aktline][0] != "[")) {
var _input = config_split[_aktline];
let [isCom, input] = isCommented(_input);
var linesplit = ZerlegeZeile(input);
ParamExtractValue(param, linesplit, catname, "SearchFieldX", _aktline, isCom);
ParamExtractValue(param, linesplit, catname, "SearchFieldY", _aktline, isCom);
++_aktline;
function ParamExtractValueAll(_param, _linesplit, _catname, _aktline, _iscom){
for (var paramname in _param[_catname]) {
if ((_linesplit[0].toUpperCase() == paramname.toUpperCase()) && (_linesplit.length > _param[_catname][paramname]["anzParam"]))
{
_param[_catname][paramname]["found"] = true;
_param[_catname][paramname]["enabled"] = !_iscom;
_param[_catname][paramname]["line"] = _aktline;
for (var j = 1; j <= _param[_catname][paramname]["anzParam"]; ++j) {
_param[_catname][paramname]["value"+j] = _linesplit[j];
}
}
}
return _aktline;
}
function ParseConfigParamMakeImage(_aktline){
var akt_ref = 0;
++_aktline;
var catname = "MakeImage";
while ((akt_ref < 2) && (_aktline < config_split.length) && (config_split[_aktline][0] != "[")) {
var _input = config_split[_aktline];
let [isCom, input] = isCommented(_input);
var linesplit = ZerlegeZeile(input);
ParamExtractValue(param, linesplit, catname, "LogImageLocation", _aktline, isCom);
ParamExtractValue(param, linesplit, catname, "WaitBeforeTakingPicture", _aktline, isCom);
ParamExtractValue(param, linesplit, catname, "LogfileRetentionInDays", _aktline, isCom);
ParamExtractValue(param, linesplit, catname, "ImageQuality", _aktline, isCom);
ParamExtractValue(param, linesplit, catname, "ImageSize", _aktline, isCom);
++_aktline;
}
return _aktline;
}
function getConfigParameters() {
return param;
}
function setConfigParameters(_param) {
function setConfigParameters(_param, _category) {
for (var cat in _param) {
for (var name in _param[cat]) {
param[cat][name]["found"] = _param[cat][name]["found"];
param[cat][name]["enabled"] = _param[cat][name]["enabled"];
param[cat][name]["line"] = _param[cat][name]["line"];
param[cat][name]["anzpara"] = _param[cat][name]["anzpara"];
for (var j = 1; j <= _param[cat][name]["anzpara"]; ++j) {
param[cat][name]["anzParam"] = _param[cat][name]["anzParam"];
for (var j = 1; j <= _param[cat][name]["anzParam"]; ++j) {
param[cat][name]["value"+j] = _param[cat][name]["value"+j];
}
if (param[cat][name]["found"]) {
var text = name + " ="
for (var j = 1; j <= _param[cat][name]["anzpara"]; ++j) {
for (var j = 1; j <= _param[cat][name]["anzParam"]; ++j) {
text = text + " " + param[cat][name]["value"+j];
}
if (!param[cat][name]["enabled"]) {
@@ -361,6 +210,19 @@ function setConfigParameters(_param) {
}
}
for (var cat in _category) {
if (category[cat]["found"])
{
category[cat]["enabled"] = _category[cat]["enabled"];
text = "[" + cat + "]";
if (!category[cat]["enabled"]) {
text = ";" + text;
}
config_split[category[cat]["line"]] = text;
}
}
config_gesamt = config_split[0];
for (var i = 1; i < config_split.length; ++i){
config_gesamt = config_gesamt + "\n" + config_split[i];
@@ -394,171 +256,16 @@ function SaveConfigToServer(_basepath){
}
FileDeleteOnServer("/config/config.ini", _basepath);
FileSendContent(config_gesamt, "/config/config.ini", _basepath);
}
function createReader(file) {
var image = new Image();
reader.onload = function(evt) {
var image = new Image();
image.onload = function(evt) {
var width = this.width;
var height = this.height;
alert (width); // will produce something like 198
};
image.src = evt.target.result;
};
reader.readAsDataURL(file);
}
function ZerlegeZeile(input, delimiter = " =,")
{
var Output = Array(0);
// delimiter = " =,";
input = trim(input, delimiter);
var pos = findDelimiterPos(input, delimiter);
var token;
while (pos > -1) {
token = input.substr(0, pos);
token = trim(token, delimiter);
Output.push(token);
input = input.substr(pos+1, input.length);
input = trim(input, delimiter);
pos = findDelimiterPos(input, delimiter);
}
Output.push(input);
return Output;
}
function findDelimiterPos(input, delimiter)
{
var pos = -1;
var zw;
var akt_del;
for (var anz = 0; anz < delimiter.length; ++anz)
{
akt_del = delimiter[anz];
zw = input.indexOf(akt_del);
if (zw > -1)
{
if (pos > -1)
{
if (zw < pos)
pos = zw;
}
else
pos = zw;
}
}
return pos;
}
function trim(istring, adddelimiter)
{
while ((istring.length > 0) && (adddelimiter.indexOf(istring[0]) >= 0)){
istring = istring.substr(1, istring.length-1);
}
while ((istring.length > 0) && (adddelimiter.indexOf(istring[istring.length-1]) >= 0)){
istring = istring.substr(0, istring.length-1);
}
return istring;
}
function loadConfig(_basepath) {
var xhttp = new XMLHttpRequest();
config_gesamt = "";
try {
url = _basepath + '/fileserver/config/config.ini';
xhttp.open("GET", url, false);
xhttp.send();
config_gesamt = xhttp.responseText;
return true;
}
catch (error)
{
// alert("Deleting Config.ini failed");
}
return false;
}
function getConfig() {
return config_gesamt;
}
function FileCopyOnServer(_source, _target, _basepath = ""){
url = _basepath + "/editflow.html?task=copy&in=" + _source + "&out=" + _target;
var xhttp = new XMLHttpRequest();
try {
xhttp.open("GET", url, false);
xhttp.send(); }
catch (error)
{
// alert("Deleting Config.ini failed");
}
function getConfigCategory() {
return category;
}
function FileDeleteOnServer(_filename, _basepath = ""){
var xhttp = new XMLHttpRequest();
var okay = false;
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4) {
if (xhttp.status == 200) {
okay = true;
} else if (xhttp.status == 0) {
// alert("Server closed the connection on delete abruptly!");
// location.reload()
} else {
// alert(xhttp.status + " Error!\n" + xhttp.responseText);
// location.reload()
}
}
};
try {
var url = _basepath + "/delete" + _filename;
xhttp.open("POST", url, false);
xhttp.send();
}
catch (error)
{
// alert("Deleting Config.ini failed");
}
return okay;
}
function FileSendContent(_content, _filename, _basepath = ""){
var xhttp = new XMLHttpRequest();
var okay = false;
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4) {
if (xhttp.status == 200) {
okay = true;
} else if (xhttp.status == 0) {
alert("Server closed the connection abruptly!");
} else {
alert(xhttp.status + " Error!\n" + xhttp.responseText);
}
}
};
try {
upload_path = _basepath + "/upload" + _filename;
xhttp.open("POST", upload_path, false);
xhttp.send(_content);
}
catch (error)
{
// alert("Deleting Config.ini failed");
}
return okay;
}

Some files were not shown because too many files have changed in this diff Show More