Compare commits

..

56 Commits

Author SHA1 Message Date
jomjol
a91f99faab update 2021-08-01 21:49:29 +02:00
jomjol
17a87b23a1 v8.0.5 2021-08-01 21:46:17 +02:00
jomjol
d4b5ec2ae2 v8.0.4 2021-07-29 20:18:53 +02:00
jomjol
1bcaf09855 v8.0.4 2021-07-29 20:14:36 +02:00
jomjol
fa3842b2b4 v8.0.3 2021-07-25 18:15:35 +02:00
jomjol
ea72256e56 Merge branch 'rolling' 2021-07-25 18:08:43 +02:00
jomjol
be5828cb3e v8.0.3 2021-07-25 18:07:50 +02:00
jomjol
104b72505c Rolling - 20210725 2021-07-25 13:44:22 +02:00
jomjol
23728a0686 Update README.md 2021-07-23 21:02:19 +02:00
jomjol
eaaa856b13 Update README.md 2021-07-23 21:01:50 +02:00
jomjol
01e81d02b5 v8.0.2 2021-07-23 20:57:42 +02:00
jomjol
9ae8d0a512 Merge branch 'rolling' 2021-07-23 20:48:28 +02:00
jomjol
da16322fb8 v8.0.2 2021-07-23 20:47:23 +02:00
jomjol
a6d39afc26 rolling 20210723 2021-07-23 07:44:59 +02:00
jomjol
1b6a124f54 Update FeatureRequest.md 2021-07-21 07:00:12 +02:00
jomjol
8aff6bf8f3 Rolling 20210719 2021-07-19 21:54:14 +02:00
jomjol
21115752aa Merge pull request #280 from jomjol/rolling
v8.0.1
2021-07-18 16:58:23 +02:00
jomjol
025c2b88b9 v8.0.1 2021-07-18 16:57:35 +02:00
jomjol
655f9d7c97 Update version 2021-07-14 20:00:06 +02:00
jomjol
03b5e36114 Merge branch 'rolling' 2021-07-14 19:52:11 +02:00
jomjol
9c78c1e9ca v8.0.0 2021-07-14 19:48:49 +02:00
jomjol
136186a526 rolling 20210713 BETA v8.0.0 2021-07-13 21:41:17 +02:00
jomjol
1f6b02a671 Rolling 20210712 2021-07-12 22:06:32 +02:00
jomjol
76a0518d52 Rolling 20210721 BugFix 2021-07-11 23:47:24 +02:00
jomjol
a688a69af6 Merge branch 'rolling' of https://github.com/jomjol/AI-on-the-edge-device into rolling 2021-07-11 18:28:00 +02:00
jomjol
b890ffc5f3 Rolling 20210711 2021-07-11 18:27:25 +02:00
jomjol
b98558107e Merge pull request #263 from Zwer2k/rolling
Rolling
2021-07-11 17:51:09 +02:00
Zwer2k
3e360ad0fb add log in gpio handler
add nullpint check in tfliteCass
2021-07-11 16:19:45 +02:00
Zwer2k
a7ced407f8 Update README.md
improve case if gpio is disabled
remove /test html route
2021-07-11 13:56:37 +02:00
Zwer2k
45a1e137d1 Merge branch 'rolling' of https://github.com/jomjol/AI-on-the-edge-device into rolling 2021-07-11 11:24:26 +02:00
Zwer2k
a44e0d81cc gpio handler work 2021-07-10 12:36:13 +02:00
Zwer2k
749fc6699c Merge remote-tracking branch 'origin/gpio-handler' into rolling 2021-07-08 21:54:44 +02:00
jomjol
d7bb147a23 Rolling 20210708 2021-07-08 21:45:33 +02:00
jomjol
08b0b254f2 rolling 20210707 2021-07-07 21:57:59 +02:00
Zwer2k
5414a4c3f1 Merge remote-tracking branch 'upstream/rolling' into rolling 2021-07-06 23:33:01 +02:00
Zwer2k
7944ab329d litle improvements on html and config.ini 2021-07-06 21:32:49 +02:00
Zwer2k
8ca14a434c gpio handler works again
remove memory leak in FlowDigit
2021-07-06 01:25:20 +02:00
jomjol
e24ba68fec rolling 20210705 2021-07-05 07:30:04 +02:00
Zwer2k
b205326782 gpio handler is working 2021-07-04 23:59:59 +02:00
jomjol
daa1960dff rolling 20210704 bug fix 2021-07-04 10:20:07 +02:00
jomjol
894c7f6972 Revert "Revert "rolling 20210704 bugfix""
This reverts commit 737dcc76b8.
2021-07-04 08:12:50 +02:00
jomjol
737dcc76b8 Revert "rolling 20210704 bugfix"
This reverts commit b42f17916b.
2021-07-04 08:12:36 +02:00
jomjol
b42f17916b rolling 20210704 bugfix 2021-07-04 08:06:04 +02:00
jomjol
2c6ce6fd07 rolling 20210705 2021-07-04 07:54:17 +02:00
jomjol
f243f4b8ea Rolling 20210701 2021-07-01 19:47:44 +02:00
jomjol
02e881ebc0 Add files via upload 2021-07-01 19:15:36 +02:00
Zwer2k
7b8f10a14e work on GPIO handler
bigfix: memory leak in GetJPGStream
2021-06-25 01:19:23 +02:00
Zwer2k
d995c31b7b work on GPIO handler
bigfix: memory leak in GetJPGStream
2021-06-18 01:29:59 +02:00
jomjol
45154cb55c 20210617 2021-06-17 20:28:24 +02:00
Zwer2k
f24c40d780 work on GPIO handling 2021-06-13 01:24:02 +02:00
jomjol
f4edd36744 Update README.md 2021-06-11 07:41:06 +02:00
jomjol
a202a6abdc Rolling 20210611 2021-06-11 07:31:06 +02:00
Zwer2k
c25adfe28a add interrupt to gpio config
bugfix in gpio config
2021-06-09 00:16:31 +02:00
Zwer2k
822c6cc45c complete extended config.ini handling for GPIO settings
added TopicUptime and MainTopicGPIO
2021-06-08 22:24:53 +02:00
Zwer2k
c48b44d06a extend config.ini handler for GPIO settings
add BootTime incode
2021-06-08 00:59:28 +02:00
jomjol
8308f159ad Merge pull request #237 from jomjol/master
Sync Rolling
2021-05-28 19:57:20 +02:00
86 changed files with 4588 additions and 1785 deletions

View File

@@ -11,13 +11,35 @@
____
#### #6 Check for double ROI names
#### #9 Basic auth for the UI
Check during configuration, that ROI names are unique.
* https://github.com/jomjol/AI-on-the-edge-device/issues/283
* Implementation of an authentication mechanism.
#### #8 MQTT configurable readout intervall
Make the readout intervall configurable via MQTT.
* Change the mqtt part to receive and process input and not only sending
#### #7 Extended Error Handling
Check different types of error (e.g. tflite not availabe) and generate an error on the html page.
To do:
* Implementation of ROI name checking in html code before saving analog or digital ROIs
* Make a list of "important" errors
* Implement a checking algo
* Extend the firmware and html page for the error handling
#### ~~#6 Check for double ROI names~~ - implemented v8.0.0
~~Check during configuration, that ROI names are unique.~~
~~To do:~~
* ~~Implementation of ROI name checking in html code before saving analog or digital ROIs~~
@@ -33,31 +55,31 @@ To do:
#### #4 Initial Shifting and Rotation
#### ~~#4 Initial Shifting and Rotation~~ - implemented v7.0.0
* https://github.com/jomjol/AI-on-the-edge-device/issues/123
* ~~https://github.com/jomjol/AI-on-the-edge-device/issues/123~~
Implementation of a shifting additional to the initial rotation of the raw camera input
~~Implementation of a shifting additional to the initial rotation of the raw camera input~~
To do:
~~To do:~~
* Implementation of shifting
* Extension of configuration
* Adaption of the html configuration to implement shifting
* ~~Implementation of shifting~~
* ~~Extension of configuration~~
* ~~Adaption of the html configuration to implement shifting~~
#### #3 Allow grouping of digits to multiple reading values
#### ~~#3 Allow grouping of digits to multiple reading values~~ - implemented v8.0.0
* https://github.com/jomjol/AI-on-the-edge-device/issues/123
* ~~https://github.com/jomjol/AI-on-the-edge-device/issues/123~~
Implementation of two different independent readouts in one setup
~~Implementation of two different independent readouts in one setup~~
To do:
~~To do:~~
* ~~Extend the configuration, setting and processing flow for two independend readouts~~
* Extend the configuration, setting and processing flow for two independend readouts
https://github.com/jomjol/AI-on-the-edge-device/issues/123
@@ -80,15 +102,16 @@ To do:
____
#### #1 Optional GPIO for external flash/lighting
#### ~~#1 Optional GPIO for external flash/lighting~~ - implemented (v8.0.0)
* https://github.com/jomjol/AI-on-the-edge-device/issues/133
* ~~https://github.com/jomjol/AI-on-the-edge-device/issues/133~~
Implementation of an an extrnal flash / lightning through GPIOs.
* available GPIOs: 12 & 13 (currently in use for html switching)
~~Implementation of an an extrnal flash / lightning through GPIOs.~~
To do:
* ~~available GPIOs: 12 & 13 (currently in use for html switching)~~
* Implementation of a software module for external light source (e.g. WS8132 LED controller, ...)
* Update of the camera module to use the external light instead of the internal flash light
* Adopt the configuration algorithm with a configurable light source
~~To do:~~
* ~~Implementation of a software module for external light source (e.g. WS8132 LED controller, ...)~~
* ~~Update of the camera module to use the external light instead of the internal flash light~~
* ~~Adopt the configuration algorithm with a configurable light source~~

View File

@@ -12,6 +12,8 @@ respectively ESP32-Cam housing only: https://www.thingiverse.com/thing:4571627
<img src="https://raw.githubusercontent.com/jomjol/AI-on-the-edge-device/master/images/watermeter.jpg" width="600">
<img src="https://raw.githubusercontent.com/jomjol/AI-on-the-edge-device/master/images/powermeter.jpg" width="600">
@@ -45,16 +47,32 @@ In other cases you can contact the developer via email: <img src="https://raw.gi
##### 8.0.5 - Multi Meter Support (2021-07-29)
* NEW 8.0.5: bug fix: saving prevalue
* NEW 8.0.4: bug fix: load config.ini after upgrade
* NEW 8.0.3: bug fix: reboot during `config.ini` handling, html error
* NEW 8.0.2: saving roundes prevalue, bug fix html server
* NEW 8.0.1: bug fix: html handling of parameter `FixedExposure` and `ImageSize`
* Dual / multi meter support (more than 1 number to be recognized)
This is implemented with the feature "number" on the ROI definition as well as selected options
* MQTT: standardization of the naming - including new topics (`json`, `freeMem `, `uptime`)c
* Preparation for extended GPIO support (thanks to Zwerk2k) - not tested and fully functional yet
* Bug fixing: html server, memory leak, MQTT connect, hostname, turn of flash LED
<span style="color: red;">**ATTENTION: the configuration and prevalue files are modified automatically and will not be backward compatible!**</span>
##### 7.1.2 MQTT-Update - (2021-06-17)
* NEW: 7.1.2: bug fix setting hostname, Flash-LED not off during reboot
* NEW: 7.1.1: bug fix wlan password with "=" (again)
* NEW: 7.1.2: bug fix setting hostname, Flash-LED not off during rebootNEW: 7.1.1: bug fix wlan password with "=" (again)
* MQTT error message: changes "no error", send retain flag
* Update wlan handling to esp-idf 4.1
* Upgrade digital CNN to v8.7.0 (added new images)
* Bug fix: MQTT, WLAN, LED-Controll, GPIO usage, fixed IP, calculation flow rate
##### 7.0.1 MQTT-Update - (2021-05-13)

View File

@@ -1,3 +1,3 @@
copy "C:\Users\Muell\Documents\Programmieren\GitHub\AI-on-the-edge-device\code\.pio\build\esp32cam\firmware.bin" "C:\Users\Muell\Documents\Programmieren\GitHub\AI-on-the-edge-device\firmware\firmware.bin"
copy "C:\Users\Muell\Documents\Programmieren\GitHub\AI-on-the-edge-device\code\.pio\build\esp32cam\bootloader.bin" "C:\Users\Muell\Documents\Programmieren\GitHub\AI-on-the-edge-device\firmware\bootloader.bin"
copy "C:\Users\Muell\Documents\Programmieren\GitHub\AI-on-the-edge-device\code\.pio\build\esp32cam\partitions.bin" "C:\Users\Muell\Documents\Programmieren\GitHub\AI-on-the-edge-device\firmware\partitions.bin"
copy "..\..\code\.pio\build\esp32cam\firmware.bin" "..\..\firmware\firmware.bin"
copy "..\..\code\.pio\build\esp32cam\bootloader.bin" "..\..\firmware\bootloader.bin"
copy "..\..\code\.pio\build\esp32cam\partitions.bin" "..\..\firmware\partitions.bin"

View File

@@ -1 +1 @@
powershell Compress-Archive "C:\Users\Muell\Documents\Programmieren\GitHub\AI-on-the-edge-device\sd-card\html\*.*" "C:\Users\Muell\Documents\Programmieren\GitHub\AI-on-the-edge-device\firmware\html.zip"
powershell Compress-Archive "..\..\sd-card\html\*.*" "..\..\firmware\html.zip"

Binary file not shown.

View File

@@ -29,7 +29,7 @@
// ================================ CODE ======================================
#include <esp_event_loop.h>
#include <esp_event.h>
#include <esp_log.h>
#include <esp_system.h>
#include <nvs_flash.h>

View File

@@ -0,0 +1,7 @@
FILE(GLOB_RECURSE app_sources ${CMAKE_CURRENT_SOURCE_DIR}/*.*)
idf_component_register(SRCS ${app_sources}
INCLUDE_DIRS "."
REQUIRES jomjol_logfile)

View File

@@ -0,0 +1,105 @@
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "Helper.h"
#include "configFile.h"
//static const char *TAGCONFIGFILE = "configFile";
ConfigFile::ConfigFile(std::string filePath)
{
std::string config = FormatFileName(filePath);
pFile = OpenFileAndWait(config.c_str(), "r");
}
ConfigFile::~ConfigFile()
{
fclose(pFile);
}
bool ConfigFile::isNewParagraph(std::string input)
{
if ((input[0] == '[') || ((input[0] == ';') && (input[1] == '[')))
{
return true;
}
return false;
}
bool ConfigFile::GetNextParagraph(std::string& aktparamgraph, bool &disabled, bool &eof)
{
while (getNextLine(&aktparamgraph, disabled, eof) && !isNewParagraph(aktparamgraph));
if (isNewParagraph(aktparamgraph))
return true;
return false;
}
bool ConfigFile::getNextLine(std::string *rt, bool &disabled, bool &eof)
{
eof = false;
char zw[1024] = "";
if (pFile == NULL)
{
*rt = "";
return false;
}
if (fgets(zw, 1024, pFile))
{
printf("%s", zw);
if ((strlen(zw) == 0) && feof(pFile))
{
*rt = "";
eof = true;
return false;
}
}
else
{
*rt = "";
eof = true;
return false;
}
*rt = zw;
*rt = trim(*rt);
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);
if (feof(pFile))
{
*rt = "";
eof = true;
return false;
}
*rt = zw;
*rt = trim(*rt);
}
disabled = ((*rt)[0] == ';');
return true;
}
std::vector<string> ConfigFile::ZerlegeZeile(std::string input, std::string delimiter)
{
std::vector<string> Output;
// std::string delimiter = " =,";
input = trim(input, delimiter);
size_t pos = findDelimiterPos(input, delimiter);
std::string token;
while (pos != std::string::npos) {
token = input.substr(0, pos);
token = trim(token, delimiter);
Output.push_back(token);
input.erase(0, pos + 1);
input = trim(input, delimiter);
pos = findDelimiterPos(input, delimiter);
}
Output.push_back(input);
return Output;
}

View File

@@ -0,0 +1,16 @@
#include <string>
#include <vector>
class ConfigFile {
public:
ConfigFile(std::string filePath);
~ConfigFile();
bool isNewParagraph(std::string input);
bool GetNextParagraph(std::string& aktparamgraph, bool &disabled, bool &eof);
bool getNextLine(std::string* rt, bool &disabled, bool &eof);
std::vector<std::string> ZerlegeZeile(std::string input, std::string delimiter = " =, \t");
private:
FILE* pFile;
};

View File

@@ -3,7 +3,7 @@ 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)
INCLUDE_DIRS "." "../../include"
REQUIRES esp_http_server jomjol_logfile jomjol_configfile jomjol_mqtt jomjol_flowcontroll)

View File

@@ -1,4 +1,5 @@
#include <string>
#include <functional>
#include "string.h"
#include <string.h>
@@ -6,22 +7,386 @@
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_event.h"
//#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
#include "esp_log.h"
#include "driver/gpio.h"
//#include "errno.h"
#include <sys/stat.h>
#include <vector>
//#include <regex>
#include "defines.h"
#include "server_GPIO.h"
#include "ClassLogFile.h"
#include "configFile.h"
#include "Helper.h"
#include "interface_mqtt.h"
// #define DEBUG_DETAIL_ON
static const char *TAG_SERVERGPIO = "server_GPIO";
QueueHandle_t gpio_queue_handle = NULL;
esp_err_t handler_switch_GPIO(httpd_req_t *req)
#define DEBUG_DETAIL_ON
GpioPin::GpioPin(gpio_num_t gpio, const char* name, gpio_pin_mode_t mode, gpio_int_type_t interruptType, uint8_t dutyResolution, std::string mqttTopic, bool httpEnable)
{
_gpio = gpio;
_name = name;
_mode = mode;
_interruptType = interruptType;
_mqttTopic = mqttTopic;
}
GpioPin::~GpioPin()
{
ESP_LOGD(TAG_SERVERGPIO,"reset GPIO pin %d", _gpio);
if (_interruptType != GPIO_INTR_DISABLE) {
//hook isr handler for specific gpio pin
gpio_isr_handler_remove(_gpio);
}
gpio_reset_pin(_gpio);
}
static void IRAM_ATTR gpio_isr_handler(void* arg)
{
GpioResult gpioResult;
gpioResult.gpio = *(gpio_num_t*) arg;
gpioResult.value = gpio_get_level(gpioResult.gpio);
BaseType_t ContextSwitchRequest = pdFALSE;
xQueueSendToBackFromISR(gpio_queue_handle,(void*)&gpioResult,&ContextSwitchRequest);
if(ContextSwitchRequest){
taskYIELD();
}
}
static void gpioHandlerTask(void *arg) {
ESP_LOGD(TAG_SERVERGPIO,"start interrupt task");
while(1){
if(uxQueueMessagesWaiting(gpio_queue_handle)){
while(uxQueueMessagesWaiting(gpio_queue_handle)){
GpioResult gpioResult;
xQueueReceive(gpio_queue_handle,(void*)&gpioResult,10);
ESP_LOGD(TAG_SERVERGPIO,"gpio: %d state: %d", gpioResult.gpio, gpioResult.value);
((GpioHandler*)arg)->gpioInterrupt(&gpioResult);
}
}
((GpioHandler*)arg)->taskHandler();
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
void GpioPin::gpioInterrupt(int value) {
if (_mqttTopic != "") {
ESP_LOGD(TAG_SERVERGPIO, "gpioInterrupt %s %d", _mqttTopic.c_str(), value);
MQTTPublish(_mqttTopic, value ? "true" : "false");
currentState = value;
}
}
void GpioPin::init()
{
gpio_config_t io_conf;
//set interrupt
io_conf.intr_type = _interruptType;
//set as output mode
io_conf.mode = (_mode == GPIO_PIN_MODE_OUTPUT) || (_mode == GPIO_PIN_MODE_BUILT_IN_FLASH_LED) ? gpio_mode_t::GPIO_MODE_OUTPUT : gpio_mode_t::GPIO_MODE_INPUT;
//bit mask of the pins that you want to set,e.g.GPIO18/19
io_conf.pin_bit_mask = (1ULL << _gpio);
//set pull-down mode
io_conf.pull_down_en = _mode == GPIO_PIN_MODE_INPUT_PULLDOWN ? gpio_pulldown_t::GPIO_PULLDOWN_ENABLE : gpio_pulldown_t::GPIO_PULLDOWN_DISABLE;
//set pull-up mode
io_conf.pull_up_en = _mode == GPIO_PIN_MODE_INPUT_PULLDOWN ? gpio_pullup_t::GPIO_PULLUP_ENABLE : gpio_pullup_t::GPIO_PULLUP_DISABLE;
//configure GPIO with the given settings
gpio_config(&io_conf);
if (_interruptType != GPIO_INTR_DISABLE) {
//hook isr handler for specific gpio pin
ESP_LOGD(TAG_SERVERGPIO, "GpioPin::init add isr handler for GPIO %d\r\n", _gpio);
gpio_isr_handler_add(_gpio, gpio_isr_handler, (void*)&_gpio);
}
if ((_mqttTopic != "") && ((_mode == GPIO_PIN_MODE_OUTPUT) || (_mode == GPIO_PIN_MODE_OUTPUT_PWM) || (_mode == GPIO_PIN_MODE_BUILT_IN_FLASH_LED))) {
std::function<bool(std::string, char*, int)> f = std::bind(&GpioPin::handleMQTT, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
MQTTregisterSubscribeFunction(_mqttTopic, f);
}
}
bool GpioPin::getValue(std::string* errorText)
{
if ((_mode != GPIO_PIN_MODE_INPUT) && (_mode != GPIO_PIN_MODE_INPUT_PULLUP) && (_mode != GPIO_PIN_MODE_INPUT_PULLDOWN)) {
(*errorText) = "GPIO is not in input mode";
}
return gpio_get_level(_gpio) == 1;
}
void GpioPin::setValue(bool value, gpio_set_source setSource, std::string* errorText)
{
ESP_LOGD(TAG_SERVERGPIO, "GpioPin::setValue %d\r\n", value);
if ((_mode != GPIO_PIN_MODE_OUTPUT) && (_mode != GPIO_PIN_MODE_OUTPUT_PWM) && (_mode != GPIO_PIN_MODE_BUILT_IN_FLASH_LED)) {
(*errorText) = "GPIO is not in output mode";
} else {
gpio_set_level(_gpio, value);
if ((_mqttTopic != "") && (setSource != GPIO_SET_SOURCE_MQTT)) {
MQTTPublish(_mqttTopic, value ? "true" : "false");
}
}
}
void GpioPin::publishState() {
int newState = gpio_get_level(_gpio);
if (newState != currentState) {
ESP_LOGD(TAG_SERVERGPIO,"publish state of GPIO %d new state %d", _gpio, newState);
MQTTPublish(_mqttTopic, newState ? "true" : "false");
currentState = newState;
}
}
bool GpioPin::handleMQTT(std::string, char* data, int data_len) {
ESP_LOGD(TAG_SERVERGPIO, "GpioPin::handleMQTT data %.*s\r\n", data_len, data);
std::string dataStr(data, data_len);
dataStr = toLower(dataStr);
std::string errorText = "";
if ((dataStr == "true") || (dataStr == "1")) {
setValue(true, GPIO_SET_SOURCE_MQTT, &errorText);
} else if ((dataStr == "false") || (dataStr == "0")) {
setValue(false, GPIO_SET_SOURCE_MQTT, &errorText);
} else {
errorText = "wrong value ";
errorText.append(data, data_len);
}
if (errorText != "") {
ESP_LOGE(TAG_SERVERGPIO, "%s", errorText.c_str());
}
return (errorText == "");
}
esp_err_t callHandleHttpRequest(httpd_req_t *req)
{
ESP_LOGD(TAG_SERVERGPIO,"callHandleHttpRequest");
GpioHandler *gpioHandler = (GpioHandler*)req->user_ctx;
return gpioHandler->handleHttpRequest(req);
}
void taskGpioHandler(void *pvParameter)
{
ESP_LOGD(TAG_SERVERGPIO,"taskGpioHandler");
((GpioHandler*)pvParameter)->init();
}
GpioHandler::GpioHandler(std::string configFile, httpd_handle_t httpServer)
{
ESP_LOGI(TAG_SERVERGPIO,"start GpioHandler");
_configFile = configFile;
_httpServer = httpServer;
ESP_LOGI(TAG_SERVERGPIO, "register GPIO Uri");
registerGpioUri();
}
GpioHandler::~GpioHandler() {
if (gpioMap != NULL) {
clear();
delete gpioMap;
}
}
void GpioHandler::init()
{
// TickType_t xDelay = 60000 / portTICK_PERIOD_MS;
// printf("wait before start %ldms\r\n", (long) xDelay);
// vTaskDelay( xDelay );
if (gpioMap == NULL) {
gpioMap = new std::map<gpio_num_t, GpioPin*>();
} else {
clear();
}
ESP_LOGI(TAG_SERVERGPIO, "read GPIO config and init GPIO");
if (!readConfig()) {
clear();
delete gpioMap;
gpioMap = NULL;
ESP_LOGI(TAG_SERVERGPIO, "GPIO init comleted, handler is disabled");
return;
}
for(std::map<gpio_num_t, GpioPin*>::iterator it = gpioMap->begin(); it != gpioMap->end(); ++it) {
it->second->init();
}
std::function<void()> f = std::bind(&GpioHandler::handleMQTTconnect, this);
MQTTregisterConnectFunction("gpio-handler", f);
if (xHandleTaskGpio == NULL) {
gpio_queue_handle = xQueueCreate(10,sizeof(GpioResult));
BaseType_t xReturned = xTaskCreate(&gpioHandlerTask, "gpio_int", configMINIMAL_STACK_SIZE * 8, (void *)this, tskIDLE_PRIORITY + 2, &xHandleTaskGpio);
if(xReturned == pdPASS ) {
ESP_LOGD(TAG_SERVERGPIO, "xHandletaskGpioHandler started");
} else {
ESP_LOGD(TAG_SERVERGPIO, "xHandletaskGpioHandler not started %d ", (int)xHandleTaskGpio);
}
}
ESP_LOGI(TAG_SERVERGPIO, "GPIO init comleted, is enabled");
}
void GpioHandler::taskHandler() {
if (gpioMap != NULL) {
for(std::map<gpio_num_t, GpioPin*>::iterator it = gpioMap->begin(); it != gpioMap->end(); ++it) {
if ((it->second->getInterruptType() == GPIO_INTR_DISABLE))
it->second->publishState();
}
}
}
void GpioHandler::handleMQTTconnect()
{
if (gpioMap != NULL) {
for(std::map<gpio_num_t, GpioPin*>::iterator it = gpioMap->begin(); it != gpioMap->end(); ++it) {
if ((it->second->getMode() == GPIO_PIN_MODE_INPUT) || (it->second->getMode() == GPIO_PIN_MODE_INPUT_PULLDOWN) || (it->second->getMode() == GPIO_PIN_MODE_INPUT_PULLUP))
it->second->publishState();
}
}
}
void GpioHandler::deinit() {
MQTTunregisterConnectFunction("gpio-handler");
clear();
if (xHandleTaskGpio != NULL) {
vTaskDelete(xHandleTaskGpio);
xHandleTaskGpio = NULL;
}
}
void GpioHandler::gpioInterrupt(GpioResult* gpioResult) {
if ((gpioMap != NULL) && (gpioMap->find(gpioResult->gpio) != gpioMap->end())) {
(*gpioMap)[gpioResult->gpio]->gpioInterrupt(gpioResult->value);
}
}
bool GpioHandler::readConfig()
{
if (!gpioMap->empty())
clear();
ConfigFile configFile = ConfigFile(_configFile);
std::vector<std::string> zerlegt;
std::string line = "";
bool disabledLine = false;
bool eof = false;
while ((!configFile.GetNextParagraph(line, disabledLine, eof) || (line.compare("[GPIO]") != 0)) && !disabledLine && !eof) {}
if (eof)
return false;
_isEnabled = !disabledLine;
if (!_isEnabled)
return false;
std::string mainTopicMQTT = "";
bool registerISR = false;
while (configFile.getNextLine(&line, disabledLine, eof) && !configFile.isNewParagraph(line))
{
zerlegt = configFile.ZerlegeZeile(line);
// const std::regex pieces_regex("IO([0-9]{1,2})");
// std::smatch pieces_match;
// if (std::regex_match(zerlegt[0], pieces_match, pieces_regex) && (pieces_match.size() == 2))
// {
// std::string gpioStr = pieces_match[1];
ESP_LOGD(TAG_SERVERGPIO, "conf param %s\r\n", toUpper(zerlegt[0]).c_str());
if (toUpper(zerlegt[0]) == "MAINTOPICMQTT") {
ESP_LOGD(TAG_SERVERGPIO, "MAINTOPICMQTT found\r\n");
mainTopicMQTT = zerlegt[1];
} else if ((zerlegt[0].rfind("IO", 0) == 0) && (zerlegt.size() >= 6))
{
ESP_LOGI(TAG_SERVERGPIO,"Enable GP%s in %s mode", zerlegt[0].c_str(), zerlegt[1].c_str());
std::string gpioStr = zerlegt[0].substr(2, 2);
gpio_num_t gpioNr = (gpio_num_t)atoi(gpioStr.c_str());
gpio_pin_mode_t pinMode = resolvePinMode(toLower(zerlegt[1]));
gpio_int_type_t intType = resolveIntType(toLower(zerlegt[2]));
uint16_t dutyResolution = (uint8_t)atoi(zerlegt[3].c_str());
bool mqttEnabled = toLower(zerlegt[4]) == "true";
bool httpEnabled = toLower(zerlegt[5]) == "true";
char gpioName[100];
if (zerlegt.size() >= 7) {
strcpy(gpioName, trim(zerlegt[6]).c_str());
} else {
sprintf(gpioName, "GPIO%d", gpioNr);
}
std::string mqttTopic = mqttEnabled ? (mainTopicMQTT + "/" + gpioName) : "";
GpioPin* gpioPin = new GpioPin(gpioNr, gpioName, pinMode, intType,dutyResolution, mqttTopic, httpEnabled);
(*gpioMap)[gpioNr] = gpioPin;
if (intType != GPIO_INTR_DISABLE) {
registerISR = true;
}
}
}
if (registerISR) {
//install gpio isr service
gpio_install_isr_service(ESP_INTR_FLAG_LOWMED | ESP_INTR_FLAG_IRAM);
}
return true;
}
void GpioHandler::clear()
{
ESP_LOGD(TAG_SERVERGPIO, "GpioHandler::clear\r\n");
if (gpioMap != NULL) {
for(std::map<gpio_num_t, GpioPin*>::iterator it = gpioMap->begin(); it != gpioMap->end(); ++it) {
delete it->second;
}
gpioMap->clear();
}
// gpio_uninstall_isr_service(); can't uninstall, isr service is used by camera
}
void GpioHandler::registerGpioUri()
{
ESP_LOGI(TAG_SERVERGPIO, "server_GPIO - Registering URI handlers");
httpd_uri_t camuri = { };
camuri.method = HTTP_GET;
camuri.uri = "/GPIO";
camuri.handler = callHandleHttpRequest;
camuri.user_ctx = (void*)this;
httpd_register_uri_handler(_httpServer, &camuri);
}
esp_err_t GpioHandler::handleHttpRequest(httpd_req_t *req)
{
ESP_LOGD(TAG_SERVERGPIO, "handleHttpRequest");
if (gpioMap == NULL) {
std::string resp_str = "GPIO handler not initialized";
httpd_resp_send(req, resp_str.c_str(), resp_str.length());
return ESP_OK;
}
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("handler_switch_GPIO - Start");
#endif
@@ -30,95 +395,183 @@ esp_err_t handler_switch_GPIO(httpd_req_t *req)
char _query[200];
char _valueGPIO[30];
char _valueStatus[30];
std::string gpio, status, zw;
int gpionum = 0;
gpio_num_t gpio_num;
std::string gpio, status;
if (httpd_req_get_url_query_str(req, _query, 200) == ESP_OK)
{
printf("Query: "); printf(_query); printf("\n");
if (httpd_req_get_url_query_str(req, _query, 200) == ESP_OK) {
ESP_LOGD(TAG_SERVERGPIO, "Query: %s", _query);
if (httpd_query_key_value(_query, "GPIO", _valueGPIO, 30) == ESP_OK)
{
printf("GPIO is found"); printf(_valueGPIO); printf("\n");
ESP_LOGD(TAG_SERVERGPIO, "GPIO is found %s", _valueGPIO);
gpio = std::string(_valueGPIO);
} else {
std::string resp_str = "GPIO No is not defined";
httpd_resp_send(req, resp_str.c_str(), resp_str.length());
return ESP_OK;
}
if (httpd_query_key_value(_query, "Status", _valueStatus, 30) == ESP_OK)
{
printf("Status is found"); printf(_valueStatus); printf("\n");
ESP_LOGD(TAG_SERVERGPIO, "Status is found %s", _valueStatus);
status = std::string(_valueStatus);
}
};
} else {
const char* resp_str = "Error in call. Use /GPIO?GPIO=12&Status=high";
httpd_resp_send(req, resp_str, strlen(resp_str));
return ESP_OK;
}
status = toUpper(status);
if (!(status == "HIGH") && !(status == "LOW"))
if ((status != "HIGH") && (status != "LOW") && (status != "TRUE") && (status != "FALSE") && (status != "0") && (status != "1") && (status != ""))
{
zw = "Status not valid: " + status;;
std::string 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 ???
int gpionum = stoi(gpio);
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";
// frei: 16; 12-15; 2; 4 // nur 12 und 13 funktionieren 2: reboot, 4: BlitzLED, 15: PSRAM, 14/15: DMA für SDKarte ???
gpio_num_t gpio_num = resolvePinNr(gpionum);
if (gpio_num == GPIO_NUM_NC)
{
std::string 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;
return ESP_OK;
}
if (status == "HIGH")
gpio_set_level(gpio_num, 1);
if (gpioMap->count(gpio_num) == 0) {
char resp_str [30];
sprintf(resp_str, "GPIO%d is not registred", gpio_num);
httpd_resp_send(req, resp_str, strlen(resp_str));
return ESP_OK;
}
if (status == "")
{
std::string resp_str = "";
status = (*gpioMap)[gpio_num]->getValue(&resp_str) ? "HIGH" : "LOW";
if (resp_str == "") {
resp_str = status;
}
httpd_resp_sendstr_chunk(req, resp_str.c_str());
httpd_resp_sendstr_chunk(req, NULL);
}
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);
{
std::string resp_str = "";
(*gpioMap)[gpio_num]->setValue((status == "HIGH") || (status == "TRUE") || (status == "1"), GPIO_SET_SOURCE_HTTP, &resp_str);
if (resp_str == "") {
resp_str = "GPIO" + std::to_string(gpionum) + " switched to " + status;
}
httpd_resp_sendstr_chunk(req, resp_str.c_str());
httpd_resp_sendstr_chunk(req, NULL);
}
return ESP_OK;
};
void initGPIO()
void GpioHandler::flashLightEnable(bool value)
{
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);
ESP_LOGD(TAG_SERVERGPIO, "GpioHandler::flashLightEnable %s\r\n", value ? "true" : "false");
if (gpioMap != NULL) {
for(std::map<gpio_num_t, GpioPin*>::iterator it = gpioMap->begin(); it != gpioMap->end(); ++it)
{
if (it->second->getMode() == GPIO_PIN_MODE_BUILT_IN_FLASH_LED) //|| (it->second->getMode() == GPIO_PIN_MODE_EXTERNAL_FLASH_PWM) || (it->second->getMode() == GPIO_PIN_MODE_EXTERNAL_FLASH_WS281X))
{
std::string resp_str = "";
it->second->setValue(value, GPIO_SET_SOURCE_INTERNAL, &resp_str);
if (resp_str == "") {
ESP_LOGD(TAG_SERVERGPIO, "Flash light pin GPIO %d switched to %s\r\n", (int)it->first, (value ? "on" : "off"));
} else {
ESP_LOGE(TAG_SERVERGPIO, "Can't set flash light pin GPIO %d. Error: %s\r\n", (int)it->first, resp_str.c_str());
}
}
}
}
}
void register_server_GPIO_uri(httpd_handle_t server)
gpio_num_t GpioHandler::resolvePinNr(uint8_t pinNr)
{
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();
switch(pinNr) {
case 0:
return GPIO_NUM_0;
case 1:
return GPIO_NUM_1;
case 3:
return GPIO_NUM_3;
case 4:
return GPIO_NUM_4;
case 12:
return GPIO_NUM_12;
case 13:
return GPIO_NUM_13;
default:
return GPIO_NUM_NC;
}
}
gpio_pin_mode_t GpioHandler::resolvePinMode(std::string input)
{
if( input == "disabled" ) return GPIO_PIN_MODE_DISABLED;
if( input == "input" ) return GPIO_PIN_MODE_INPUT;
if( input == "input-pullup" ) return GPIO_PIN_MODE_INPUT_PULLUP;
if( input == "input-pulldown" ) return GPIO_PIN_MODE_INPUT_PULLDOWN;
if( input == "output" ) return GPIO_PIN_MODE_OUTPUT;
if( input == "built-in-led" ) return GPIO_PIN_MODE_BUILT_IN_FLASH_LED;
if( input == "output-pwm" ) return GPIO_PIN_MODE_OUTPUT_PWM;
if( input == "external-flash-pwm" ) return GPIO_PIN_MODE_EXTERNAL_FLASH_PWM;
if( input == "external-flash-ws281x" ) return GPIO_PIN_MODE_EXTERNAL_FLASH_WS281X;
return GPIO_PIN_MODE_DISABLED;
}
gpio_int_type_t GpioHandler::resolveIntType(std::string input)
{
if( input == "disabled" ) return GPIO_INTR_DISABLE;
if( input == "rising-edge" ) return GPIO_INTR_POSEDGE;
if( input == "falling-edge" ) return GPIO_INTR_NEGEDGE;
if( input == "rising-and-falling" ) return GPIO_INTR_ANYEDGE ;
if( input == "low-level-trigger" ) return GPIO_INTR_LOW_LEVEL;
if( input == "high-level-trigger" ) return GPIO_INTR_HIGH_LEVEL;
return GPIO_INTR_DISABLE;
}
static GpioHandler *gpioHandler = NULL;
void gpio_handler_create(httpd_handle_t server)
{
if (gpioHandler == NULL)
gpioHandler = new GpioHandler(CONFIG_FILE, server);
}
void gpio_handler_init()
{
if (gpioHandler != NULL) {
gpioHandler->init();
}
}
void gpio_handler_deinit() {
if (gpioHandler != NULL) {
gpioHandler->deinit();
}
}
void gpio_handler_destroy()
{
if (gpioHandler != NULL) {
delete gpioHandler;
gpioHandler = NULL;
}
}
GpioHandler* gpio_handler_get()
{
return gpioHandler;
}

View File

@@ -1,10 +1,99 @@
#ifndef SERVER_GPIO_H
#define SERVER_GPIO_H
#include <esp_log.h>
#include <esp_http_server.h>
#include <map>
#include "driver/gpio.h"
//#include "ClassControllCamera.h"
static const char *TAGPARTGPIO = "server_GPIO";
typedef enum {
GPIO_PIN_MODE_DISABLED = 0x0,
GPIO_PIN_MODE_INPUT = 0x1,
GPIO_PIN_MODE_INPUT_PULLUP = 0x2,
GPIO_PIN_MODE_INPUT_PULLDOWN = 0x3,
GPIO_PIN_MODE_OUTPUT = 0x4,
GPIO_PIN_MODE_BUILT_IN_FLASH_LED = 0x5,
GPIO_PIN_MODE_OUTPUT_PWM = 0x6,
GPIO_PIN_MODE_EXTERNAL_FLASH_PWM = 0x7,
GPIO_PIN_MODE_EXTERNAL_FLASH_WS281X = 0x8,
} gpio_pin_mode_t;
void register_server_GPIO_uri(httpd_handle_t server);
struct GpioResult {
gpio_num_t gpio;
int value;
};
typedef enum {
GPIO_SET_SOURCE_INTERNAL = 0,
GPIO_SET_SOURCE_MQTT = 1,
GPIO_SET_SOURCE_HTTP = 2,
} gpio_set_source;
class GpioPin {
public:
GpioPin(gpio_num_t gpio, const char* name, gpio_pin_mode_t mode, gpio_int_type_t interruptType, uint8_t dutyResolution, std::string mqttTopic, bool httpEnable);
~GpioPin();
void init();
bool getValue(std::string* errorText);
void setValue(bool value, gpio_set_source setSource, std::string* errorText);
bool handleMQTT(std::string, char* data, int data_len);
void publishState();
void gpioInterrupt(int value);
gpio_int_type_t getInterruptType() { return _interruptType; }
gpio_pin_mode_t getMode() { return _mode; }
private:
gpio_num_t _gpio;
const char* _name;
gpio_pin_mode_t _mode;
gpio_int_type_t _interruptType;
std::string _mqttTopic;
int currentState = -1;
};
esp_err_t callHandleHttpRequest(httpd_req_t *req);
void taskGpioHandler(void *pvParameter);
class GpioHandler {
public:
GpioHandler(std::string configFile, httpd_handle_t httpServer);
~GpioHandler();
void init();
void deinit();
void registerGpioUri();
esp_err_t handleHttpRequest(httpd_req_t *req);
void taskHandler();
void gpioInterrupt(GpioResult* gpioResult);
void flashLightEnable(bool value);
bool isEnabled() { return _isEnabled; }
void handleMQTTconnect();
private:
std::string _configFile;
httpd_handle_t _httpServer;
std::map<gpio_num_t, GpioPin*> *gpioMap = NULL;
TaskHandle_t xHandleTaskGpio = NULL;
bool _isEnabled = false;
bool readConfig();
void clear();
gpio_num_t resolvePinNr(uint8_t pinNr);
gpio_pin_mode_t resolvePinMode(std::string input);
gpio_int_type_t resolveIntType(std::string input);
};
void gpio_handler_create(httpd_handle_t server);
void gpio_handler_init();
void gpio_handler_deinit();
void gpio_handler_destroy();
GpioHandler* gpio_handler_get();
#endif //SERVER_GPIO_H

View File

@@ -4,6 +4,6 @@ list(APPEND EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/proto
idf_component_register(SRCS ${app_sources}
INCLUDE_DIRS "."
REQUIRES esp32-camera-master esp_http_server jomjol_logfile jomjol_image_proc nvs_flash jomjol_fileserver_ota)
REQUIRES esp32-camera-master esp_http_server jomjol_logfile jomjol_image_proc nvs_flash jomjol_fileserver_ota jomjol_controlGPIO)

View File

@@ -10,12 +10,13 @@
#include "CImageBasis.h"
#include "server_ota.h"
#include "server_GPIO.h"
#define BOARD_ESP32CAM_AITHINKER
#include <esp_event_loop.h>
#include <esp_event.h>
#include <esp_log.h>
#include <esp_system.h>
#include <nvs_flash.h>
@@ -50,7 +51,7 @@
#define CAM_PIN_HREF 23
#define CAM_PIN_PCLK 22
static const char *TAG = "example:take_picture";
static const char *TAGCAMERACLASS = "server_part_camera";
static camera_config_t camera_config = {
.pin_pwdn = CAM_PIN_PWDN,
@@ -275,7 +276,7 @@ esp_err_t CCamera::CaptureToBasisImage(CImageBasis *_Image, int delay)
camera_fb_t * fb = esp_camera_fb_get();
if (!fb) {
ESP_LOGE(TAGCAMERACLASS, "Camera Capture Failed");
ESP_LOGE(TAGCAMERACLASS, "CaptureToBasisImage: Camera Capture Failed");
LEDOnOff(false);
LightOnOff(false);
doReboot();
@@ -362,8 +363,7 @@ 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");
ESP_LOGE(TAGCAMERACLASS, "Reboot ?????");
ESP_LOGE(TAGCAMERACLASS, "CaptureToFile: Camera Capture Failed");
LEDOnOff(false);
LightOnOff(false);
doReboot();
@@ -497,15 +497,20 @@ esp_err_t CCamera::CaptureToHTTP(httpd_req_t *req, int delay)
void CCamera::LightOnOff(bool status)
{
// Init the GPIO
gpio_pad_select_gpio(FLASH_GPIO);
/* Set the GPIO as a push/pull output */
gpio_set_direction(FLASH_GPIO, GPIO_MODE_OUTPUT);
GpioHandler* gpioHandler = gpio_handler_get();
if ((gpioHandler != NULL) && (gpioHandler->isEnabled())) {
gpioHandler->flashLightEnable(status);
} else {
// Init the GPIO
gpio_pad_select_gpio(FLASH_GPIO);
/* Set the GPIO as a push/pull output */
gpio_set_direction(FLASH_GPIO, GPIO_MODE_OUTPUT);
if (status)
gpio_set_level(FLASH_GPIO, 1);
else
gpio_set_level(FLASH_GPIO, 0);
if (status)
gpio_set_level(FLASH_GPIO, 1);
else
gpio_set_level(FLASH_GPIO, 0);
}
}
void CCamera::LEDOnOff(bool status)

View File

@@ -16,9 +16,6 @@
#define CAMERA_MODEL_AI_THINKER
static const char *TAGCAMERACLASS = "server_part_camera";
class CCamera {
protected:
int ActualQuality;

View File

@@ -12,14 +12,17 @@
char scratch2[SCRATCH_BUFSIZE2];
//#define DEBUG_DETAIL_ON
static const char *TAGPARTCAMERA = "server_camera";
void PowerResetCamera(){
ESP_LOGD(TAGPARTCAMERA, "Resetting camera by power down line");
gpio_config_t conf = { 0 };
gpio_config_t conf;
conf.intr_type = GPIO_INTR_DISABLE;
conf.pin_bit_mask = 1LL << GPIO_NUM_32;
conf.mode = GPIO_MODE_OUTPUT;
conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
conf.pull_up_en = GPIO_PULLUP_DISABLE;
gpio_config(&conf);
// carefull, logic is inverted compared to reset pin

View File

@@ -7,8 +7,6 @@
//#include "ClassControllCamera.h"
static const char *TAGPARTCAMERA = "server_camera";
void register_server_camera_uri(httpd_handle_t server);
void PowerResetCamera();

View File

@@ -1,7 +1,7 @@
FILE(GLOB_RECURSE app_sources ${CMAKE_CURRENT_SOURCE_DIR}/*.*)
idf_component_register(SRCS ${app_sources}
INCLUDE_DIRS "."
REQUIRES tfmicro esp_http_server app_update esp_http_client nvs_flash jomjol_tfliteclass jomjol_flowcontroll spiffs jomjol_helper)
INCLUDE_DIRS "." "../../include"
REQUIRES tfmicro esp_http_server app_update esp_http_client nvs_flash jomjol_tfliteclass jomjol_flowcontroll spiffs jomjol_helper jomjol_controlGPIO)

View File

@@ -26,9 +26,12 @@
#include <esp_spiffs.h>
#include "esp_http_server.h"
#include "defines.h"
#include "ClassLogFile.h"
#include "server_help.h"
#include "interface_mqtt.h"
#include "server_GPIO.h"
#include "Helper.h"
#include "miniz.h"
@@ -53,17 +56,17 @@ struct file_server_data {
char scratch[SCRATCH_BUFSIZE];
};
static const char *TAG = "file_server";
static const char *TAG_FILESERVER = "file_server";
/* Handler to redirect incoming GET request for /index.html to /
* This can be overridden by uploading file with same name */
static esp_err_t index_html_get_handler(httpd_req_t *req)
{
httpd_resp_set_status(req, "307 Temporary Redirect");
httpd_resp_set_hdr(req, "Location", "/");
httpd_resp_send(req, NULL, 0); // Response body can be empty
return ESP_OK;
}
// static esp_err_t index_html_get_handler(httpd_req_t *req)
// {
// httpd_resp_set_status(req, "307 Temporary Redirect");
// httpd_resp_set_hdr(req, "Location", "/");
// httpd_resp_send(req, NULL, 0); // Response body can be empty
// 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.
@@ -95,7 +98,7 @@ static esp_err_t http_resp_dir_html(httpd_req_t *req, const char *dirpath, const
printf("entrypath: <%s>\n", entrypath);
if (!dir) {
ESP_LOGE(TAG, "Failed to stat dir : %s", dirpath);
ESP_LOGE(TAG_FILESERVER, "Failed to stat dir : %s", dirpath);
/* Respond with 404 Not Found */
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "Directory does not exist");
return ESP_FAIL;
@@ -115,7 +118,7 @@ static esp_err_t http_resp_dir_html(httpd_req_t *req, const char *dirpath, const
if (chunksize > 0){
if (httpd_resp_send_chunk(req, chunk, chunksize) != ESP_OK) {
fclose(fd);
ESP_LOGE(TAG, "File sending failed!");
ESP_LOGE(TAG_FILESERVER, "File sending failed!");
return ESP_FAIL;
}
}
@@ -154,11 +157,11 @@ static esp_err_t http_resp_dir_html(httpd_req_t *req, const char *dirpath, const
strlcpy(entrypath + dirpath_len, entry->d_name, sizeof(entrypath) - dirpath_len);
printf("Entrypath: %s\n", entrypath);
if (stat(entrypath, &entry_stat) == -1) {
ESP_LOGE(TAG, "Failed to stat %s : %s", entrytype, entry->d_name);
ESP_LOGE(TAG_FILESERVER, "Failed to stat %s : %s", entrytype, entry->d_name);
continue;
}
sprintf(entrysize, "%ld", entry_stat.st_size);
ESP_LOGI(TAG, "Found %s : %s (%s bytes)", entrytype, entry->d_name, entrysize);
ESP_LOGI(TAG_FILESERVER, "Found %s : %s (%s bytes)", entrytype, entry->d_name, entrysize);
/* Send chunk of HTML file containing table entries with file name and size */
httpd_resp_sendstr_chunk(req, "<tr><td><a href=\"");
@@ -206,19 +209,19 @@ static esp_err_t logfileact_get_handler(httpd_req_t *req)
LogFile.WriteToFile("logfileact_get_handler");
char filepath[FILE_PATH_MAX];
FILE *fd = NULL;
struct stat file_stat;
//struct stat file_stat;
printf("uri: %s\n", req->uri);
const char filename = 'log_current.txt';
const char* filename = "log_current.txt";
printf("uri: %s, filename: %s, filepath: %s\n", req->uri, &filename, filepath);
printf("uri: %s, filename: %s, filepath: %s\n", req->uri, filename, filepath);
std::string currentfilename = LogFile.GetCurrentFileName();
fd = OpenFileAndWait(currentfilename.c_str(), "r");
if (!fd) {
ESP_LOGE(TAG, "Failed to read existing file : %s", filepath);
ESP_LOGE(TAG_FILESERVER, "Failed to read existing file : %s", filepath);
/* Respond with 500 Internal Server Error */
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to read existing file");
return ESP_FAIL;
@@ -226,8 +229,8 @@ static esp_err_t logfileact_get_handler(httpd_req_t *req)
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
// ESP_LOGI(TAG, "Sending file : %s (%ld bytes)...", &filename, file_stat.st_size);
set_content_type_from_file(req, &filename);
// ESP_LOGI(TAG_FILESERVER, "Sending file : %s (%ld bytes)...", &filename, file_stat.st_size);
set_content_type_from_file(req, filename);
/* Retrieve the pointer to scratch buffer for temporary storage */
char *chunk = ((struct file_server_data *)req->user_ctx)->scratch;
@@ -239,7 +242,7 @@ static esp_err_t logfileact_get_handler(httpd_req_t *req)
/* Send the buffer contents as HTTP response chunk */
if (httpd_resp_send_chunk(req, chunk, chunksize) != ESP_OK) {
fclose(fd);
ESP_LOGE(TAG, "File sending failed!");
ESP_LOGE(TAG_FILESERVER, "File sending failed!");
/* Abort sending file */
httpd_resp_sendstr_chunk(req, NULL);
/* Respond with 500 Internal Server Error */
@@ -252,7 +255,7 @@ static esp_err_t logfileact_get_handler(httpd_req_t *req)
/* Close file after sending complete */
fclose(fd);
ESP_LOGI(TAG, "File sending complete");
ESP_LOGI(TAG_FILESERVER, "File sending complete");
/* Respond with an empty chunk to signal HTTP response completion */
httpd_resp_send_chunk(req, NULL, 0);
@@ -284,7 +287,7 @@ static esp_err_t download_get_handler(httpd_req_t *req)
if (!filename) {
ESP_LOGE(TAG, "Filename is too long");
ESP_LOGE(TAG_FILESERVER, "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;
@@ -297,11 +300,11 @@ static esp_err_t download_get_handler(httpd_req_t *req)
if (buf_len > 1) {
char buf[buf_len];
if (httpd_req_get_url_query_str(req, buf, buf_len) == ESP_OK) {
ESP_LOGI(TAG, "Found URL query => %s", buf);
ESP_LOGI(TAG_FILESERVER, "Found URL query => %s", buf);
char param[32];
/* Get value of expected key from query string */
if (httpd_query_key_value(buf, "readonly", param, sizeof(param)) == ESP_OK) {
ESP_LOGI(TAG, "Found URL query parameter => readonly=%s", param);
ESP_LOGI(TAG_FILESERVER, "Found URL query parameter => readonly=%s", param);
readonly = param && strcmp(param,"true")==0;
}
}
@@ -316,7 +319,7 @@ static esp_err_t download_get_handler(httpd_req_t *req)
/* If file not present on SPIFFS check if URI
* corresponds to one of the hardcoded paths */
ESP_LOGE(TAG, "Failed to stat file : %s", filepath);
ESP_LOGE(TAG_FILESERVER, "Failed to stat file : %s", filepath);
/* Respond with 404 Not Found */
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "File does not exist");
return ESP_FAIL;
@@ -324,7 +327,7 @@ static esp_err_t download_get_handler(httpd_req_t *req)
fd = OpenFileAndWait(filepath, "r");
if (!fd) {
ESP_LOGE(TAG, "Failed to read existing file : %s", filepath);
ESP_LOGE(TAG_FILESERVER, "Failed to read existing file : %s", filepath);
/* Respond with 500 Internal Server Error */
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to read existing file");
return ESP_FAIL;
@@ -332,7 +335,7 @@ static esp_err_t download_get_handler(httpd_req_t *req)
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
ESP_LOGI(TAG, "Sending file : %s (%ld bytes)...", filename, file_stat.st_size);
ESP_LOGI(TAG_FILESERVER, "Sending file : %s (%ld bytes)...", filename, file_stat.st_size);
set_content_type_from_file(req, filename);
/* Retrieve the pointer to scratch buffer for temporary storage */
@@ -345,7 +348,7 @@ static esp_err_t download_get_handler(httpd_req_t *req)
/* Send the buffer contents as HTTP response chunk */
if (httpd_resp_send_chunk(req, chunk, chunksize) != ESP_OK) {
fclose(fd);
ESP_LOGE(TAG, "File sending failed!");
ESP_LOGE(TAG_FILESERVER, "File sending failed!");
/* Abort sending file */
httpd_resp_sendstr_chunk(req, NULL);
/* Respond with 500 Internal Server Error */
@@ -358,7 +361,7 @@ static esp_err_t download_get_handler(httpd_req_t *req)
/* Close file after sending complete */
fclose(fd);
ESP_LOGI(TAG, "File sending complete");
ESP_LOGI(TAG_FILESERVER, "File sending complete");
/* Respond with an empty chunk to signal HTTP response completion */
httpd_resp_send_chunk(req, NULL, 0);
@@ -385,13 +388,13 @@ static esp_err_t upload_post_handler(httpd_req_t *req)
/* Filename cannot have a trailing '/' */
if (filename[strlen(filename) - 1] == '/') {
ESP_LOGE(TAG, "Invalid filename : %s", filename);
ESP_LOGE(TAG_FILESERVER, "Invalid filename : %s", filename);
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Invalid filename");
return ESP_FAIL;
}
if (stat(filepath, &file_stat) == 0) {
ESP_LOGE(TAG, "File already exists : %s", filepath);
ESP_LOGE(TAG_FILESERVER, "File already exists : %s", filepath);
/* Respond with 400 Bad Request */
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "File already exists");
return ESP_FAIL;
@@ -399,7 +402,7 @@ static esp_err_t upload_post_handler(httpd_req_t *req)
/* File cannot be larger than a limit */
if (req->content_len > MAX_FILE_SIZE) {
ESP_LOGE(TAG, "File too large : %d bytes", req->content_len);
ESP_LOGE(TAG_FILESERVER, "File too large : %d bytes", req->content_len);
/* Respond with 400 Bad Request */
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST,
"File size must be less than "
@@ -411,13 +414,13 @@ static esp_err_t upload_post_handler(httpd_req_t *req)
fd = OpenFileAndWait(filepath, "w");
if (!fd) {
ESP_LOGE(TAG, "Failed to create file : %s", filepath);
ESP_LOGE(TAG_FILESERVER, "Failed to create file : %s", filepath);
/* Respond with 500 Internal Server Error */
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to create file");
return ESP_FAIL;
}
ESP_LOGI(TAG, "Receiving file : %s...", filename);
ESP_LOGI(TAG_FILESERVER, "Receiving file : %s...", filename);
/* Retrieve the pointer to scratch buffer for temporary storage */
char *buf = ((struct file_server_data *)req->user_ctx)->scratch;
@@ -429,7 +432,7 @@ static esp_err_t upload_post_handler(httpd_req_t *req)
while (remaining > 0) {
ESP_LOGI(TAG, "Remaining size : %d", remaining);
ESP_LOGI(TAG_FILESERVER, "Remaining size : %d", remaining);
/* Receive the file part by part into a buffer */
if ((received = httpd_req_recv(req, buf, MIN(remaining, SCRATCH_BUFSIZE))) <= 0) {
if (received == HTTPD_SOCK_ERR_TIMEOUT) {
@@ -442,7 +445,7 @@ static esp_err_t upload_post_handler(httpd_req_t *req)
fclose(fd);
unlink(filepath);
ESP_LOGE(TAG, "File reception failed!");
ESP_LOGE(TAG_FILESERVER, "File reception failed!");
/* Respond with 500 Internal Server Error */
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to receive file");
return ESP_FAIL;
@@ -455,7 +458,7 @@ static esp_err_t upload_post_handler(httpd_req_t *req)
fclose(fd);
unlink(filepath);
ESP_LOGE(TAG, "File write failed!");
ESP_LOGE(TAG_FILESERVER, "File write failed!");
/* Respond with 500 Internal Server Error */
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to write file to storage");
return ESP_FAIL;
@@ -468,7 +471,7 @@ static esp_err_t upload_post_handler(httpd_req_t *req)
/* Close file upon upload completion */
fclose(fd);
ESP_LOGI(TAG, "File reception complete");
ESP_LOGI(TAG_FILESERVER, "File reception complete");
std::string directory = std::string(filepath);
size_t zw = directory.find("/");
@@ -483,10 +486,10 @@ static esp_err_t upload_post_handler(httpd_req_t *req)
int start_fn = strlen(((struct file_server_data *)req->user_ctx)->base_path);
printf("Directory: %s, start_fn: %d, found: %d\n", directory.c_str(), start_fn, found);
directory = directory.substr(start_fn, found - start_fn + 1);
printf("Directory danach: %s\n", directory.c_str());
printf("Directory danach 1: %s\n", directory.c_str());
directory = "/fileserver" + directory;
printf("Directory danach: %s\n", directory.c_str());
printf("Directory danach 2: %s\n", directory.c_str());
/* Redirect onto root to see the updated file list */
httpd_resp_set_status(req, "303 See Other");
@@ -496,6 +499,15 @@ static esp_err_t upload_post_handler(httpd_req_t *req)
httpd_resp_set_status(req, "303 See Other");
httpd_resp_set_hdr(req, "Location", directory.c_str());
httpd_resp_sendstr(req, "File uploaded successfully");
/*
if (strcmp(filepath, CONFIG_FILE) == 0) {
printf("New config found. Reload handler.");
gpio_handler_deinit();
MQTTdestroy();
}
*/
return ESP_OK;
}
@@ -567,19 +579,19 @@ static esp_err_t delete_post_handler(httpd_req_t *req)
/* Filename cannot have a trailing '/' */
if (filename[strlen(filename) - 1] == '/') {
ESP_LOGE(TAG, "Invalid filename : %s", filename);
ESP_LOGE(TAG_FILESERVER, "Invalid filename : %s", filename);
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Invalid filename");
return ESP_FAIL;
}
if (stat(filepath, &file_stat) == -1) {
ESP_LOGE(TAG, "File does not exist : %s", filename);
ESP_LOGE(TAG_FILESERVER, "File does not exist : %s", filename);
/* Respond with 400 Bad Request */
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "File does not exist");
return ESP_FAIL;
}
ESP_LOGI(TAG, "Deleting file : %s", filename);
ESP_LOGI(TAG_FILESERVER, "Deleting file : %s", filename);
/* Delete file */
unlink(filepath);
@@ -596,10 +608,10 @@ static esp_err_t delete_post_handler(httpd_req_t *req)
int start_fn = strlen(((struct file_server_data *)req->user_ctx)->base_path);
printf("Directory: %s, start_fn: %d, found: %d\n", directory.c_str(), start_fn, found);
directory = directory.substr(start_fn, found - start_fn + 1);
printf("Directory danach: %s\n", directory.c_str());
printf("Directory danach 3: %s\n", directory.c_str());
directory = "/fileserver" + directory;
printf("Directory danach: %s\n", directory.c_str());
printf("Directory danach 4: %s\n", directory.c_str());
}
@@ -623,7 +635,7 @@ void delete_all_in_directory(std::string _directory)
std::string filename;
if (!dir) {
ESP_LOGE(TAG, "Failed to stat dir : %s", _directory.c_str());
ESP_LOGE(TAG_FILESERVER, "Failed to stat dir : %s", _directory.c_str());
return;
}
@@ -632,7 +644,7 @@ void delete_all_in_directory(std::string _directory)
if (!(entry->d_type == DT_DIR)){
if (strcmp("wlan.ini", entry->d_name) != 0){ // auf wlan.ini soll nicht zugegriffen werden !!!
filename = _directory + "/" + std::string(entry->d_name);
ESP_LOGI(TAG, "Deleting file : %s", filename.c_str());
ESP_LOGI(TAG_FILESERVER, "Deleting file : %s", filename.c_str());
/* Delete file */
unlink(filename.c_str());
}
@@ -722,19 +734,19 @@ void register_server_file_uri(httpd_handle_t server, const char *base_path)
/* Validate file storage base path */
if (!base_path) {
// if (!base_path || strcmp(base_path, "/spiffs") != 0) {
ESP_LOGE(TAG, "File server base_path not set");
ESP_LOGE(TAG_FILESERVER, "File server base_path not set");
// return ESP_ERR_INVALID_ARG;
}
if (server_data) {
ESP_LOGE(TAG, "File server already started");
ESP_LOGE(TAG_FILESERVER, "File server already started");
// return ESP_ERR_INVALID_STATE;
}
/* Allocate memory for server data */
server_data = (file_server_data *) calloc(1, sizeof(struct file_server_data));
if (!server_data) {
ESP_LOGE(TAG, "Failed to allocate memory for server data");
ESP_LOGE(TAG_FILESERVER, "Failed to allocate memory for server data");
// return ESP_ERR_NO_MEM;
}
strlcpy(server_data->base_path, base_path,

View File

@@ -107,6 +107,8 @@ esp_err_t set_content_type_from_file(httpd_req_t *req, const char *filename)
return httpd_resp_set_type(req, "text/html");
} else if (IS_FILE_EXT(filename, ".jpeg")) {
return httpd_resp_set_type(req, "image/jpeg");
} else if (IS_FILE_EXT(filename, ".jpg")) {
return httpd_resp_set_type(req, "image/jpeg");
} else if (IS_FILE_EXT(filename, ".ico")) {
return httpd_resp_set_type(req, "image/x-icon");
}

View File

@@ -12,7 +12,7 @@
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_event.h"
#include "esp_event_loop.h"
#include "esp_event.h"
#include "esp_log.h"
#include <esp_ota_ops.h>
#include "esp_http_client.h"
@@ -28,6 +28,7 @@
#include "server_tflite.h"
#include "server_file.h"
#include "server_GPIO.h"
#include "ClassLogFile.h"
@@ -46,6 +47,7 @@ static char ota_write_data[BUFFSIZE + 1] = { 0 };
#define OTA_URL_SIZE 256
static const char *TAGPARTOTA = "server_ota";
static void infinite_loop(void)
@@ -60,14 +62,14 @@ static void infinite_loop(void)
static bool ota_example_task(std::string fn)
static bool ota_update_task(std::string fn)
{
esp_err_t err;
/* update handle : set by esp_ota_begin(), must be freed via esp_ota_end() */
esp_ota_handle_t update_handle = 0 ;
const esp_partition_t *update_partition = NULL;
ESP_LOGI(TAGPARTOTA, "Starting OTA example");
ESP_LOGI(TAGPARTOTA, "Starting OTA update");
const esp_partition_t *configured = esp_ota_get_boot_partition();
const esp_partition_t *running = esp_ota_get_running_partition();
@@ -374,7 +376,9 @@ esp_err_t handler_ota_update(httpd_req_t *req)
const char* resp_str;
if (ota_example_task(fn))
KillTFliteTasks();
gpio_handler_deinit();
if (ota_update_task(fn))
{
resp_str = "Firmware Update Successfull!<br><br>You can restart now.";
}
@@ -400,8 +404,6 @@ void hard_restart() {
void task_reboot(void *pvParameter)
{
while(1)
{
vTaskDelay(5000 / portTICK_PERIOD_MS);
@@ -413,12 +415,14 @@ void task_reboot(void *pvParameter)
}
void doReboot(){
LogFile.WriteToFile("Reboot - now");
KillTFliteTasks();
ESP_LOGI(TAGPARTOTA, "Reboot in 5sec");
LogFile.WriteToFile("Reboot in 5sec");
xTaskCreate(&task_reboot, "reboot", configMINIMAL_STACK_SIZE * 64, NULL, 10, NULL);
// KillTFliteTasks(); // kills itself
gpio_handler_destroy();
vTaskDelay(5000 / portTICK_PERIOD_MS);
esp_restart();
hard_restart();
hard_restart();
}

View File

@@ -4,8 +4,6 @@
//#include "ClassControllCamera.h"
static const char *TAGPARTOTA = "server_ota";
void register_server_ota_sdcard_uri(httpd_handle_t server);
void CheckOTAUpdate();
void doReboot();

View File

@@ -94,6 +94,23 @@ string ClassFlow::getReadout()
return string();
}
std::string ClassFlow::GetParameterName(std::string _input)
{
string _param;
int _pospunkt = _input.find_first_of(".");
if (_pospunkt > -1)
{
_param = _input.substr(_pospunkt+1, _input.length() - _pospunkt - 1);
}
else
{
_param = _input;
}
// printf("Parameter: %s, Pospunkt: %d\n", _param.c_str(), _pospunkt);
return _param;
}
bool ClassFlow::getNextLine(FILE* pfile, string *rt)
{
char zw[1024];
@@ -102,24 +119,21 @@ bool ClassFlow::getNextLine(FILE* pfile, string *rt)
*rt = "";
return false;
}
fgets(zw, 1024, pfile);
printf("%s", zw);
if ((strlen(zw) == 0) && feof(pfile))
if (!fgets(zw, 1024, pfile))
{
*rt = "";
printf("END OF FILE\n");
return false;
}
printf("%s", zw);
*rt = zw;
*rt = trim(*rt);
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);
if (feof(pfile))
{
*rt = "";
*rt = "";
if (!fgets(zw, 1024, pfile))
return false;
}
printf("%s", zw);
*rt = zw;
*rt = trim(*rt);
}

View File

@@ -37,6 +37,8 @@ protected:
virtual void SetInitialParameter(void);
std::string GetParameterName(std::string _input);
bool disabled;
public:

View File

@@ -1,7 +1,7 @@
#include "ClassFlowAnalog.h"
#include <math.h>
#include <iomanip>
#include <iomanip>
#include <sys/types.h>
#include <sstream> // std::stringstream
@@ -46,9 +46,9 @@ ClassFlowAnalog::ClassFlowAnalog(std::vector<ClassFlow*>* lfc) : ClassFlowImage(
}
int ClassFlowAnalog::AnzahlROIs()
int ClassFlowAnalog::AnzahlROIs(int _analog = 0)
{
int zw = ROI.size();
int zw = ANALOG[_analog]->ROI.size();
if (extendedResolution)
zw++;
@@ -56,27 +56,27 @@ int ClassFlowAnalog::AnzahlROIs()
}
string ClassFlowAnalog::getReadout()
string ClassFlowAnalog::getReadout(int _analog = 0)
{
string result = "";
if (ROI.size() == 0)
if (ANALOG[_analog]->ROI.size() == 0)
return result;
float zahl = ROI[ROI.size() - 1]->result;
float zahl = ANALOG[_analog]->ROI[ANALOG[_analog]->ROI.size() - 1]->result;
int ergebnis_nachkomma = ((int) floor(zahl * 10)) % 10;
int prev = -1;
prev = ZeigerEval(ROI[ROI.size() - 1]->result, prev);
prev = ZeigerEval(ANALOG[_analog]->ROI[ANALOG[_analog]->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)
for (int i = ANALOG[_analog]->ROI.size() - 2; i >= 0; --i)
{
prev = ZeigerEval(ROI[i]->result, prev);
prev = ZeigerEval(ANALOG[_analog]->ROI[i]->result, prev);
result = std::to_string(prev) + result;
}
@@ -153,8 +153,8 @@ bool ClassFlowAnalog::ReadParameter(FILE* pfile, string& aktparamgraph)
}
if (zerlegt.size() >= 5)
{
roianalog* neuroi = new roianalog;
neuroi->name = zerlegt[0];
analog* _analog = GetANALOG(zerlegt[0], true);
roianalog* neuroi = _analog->ROI[_analog->ROI.size()-1];
neuroi->posx = std::stoi(zerlegt[1]);
neuroi->posy = std::stoi(zerlegt[2]);
neuroi->deltax = std::stoi(zerlegt[3]);
@@ -162,7 +162,7 @@ bool ClassFlowAnalog::ReadParameter(FILE* pfile, string& aktparamgraph)
neuroi->result = -1;
neuroi->image = NULL;
neuroi->image_org = NULL;
ROI.push_back(neuroi);
// ROI.push_back(neuroi);
}
if ((toUpper(zerlegt[0]) == "SAVEALLFILES") && (zerlegt.size() > 1))
@@ -178,15 +178,75 @@ bool ClassFlowAnalog::ReadParameter(FILE* pfile, string& aktparamgraph)
}
}
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);
}
for (int _ana = 0; _ana < ANALOG.size(); ++_ana)
for (int i = 0; i < ANALOG[_ana]->ROI.size(); ++i)
{
ANALOG[_ana]->ROI[i]->image = new CImageBasis(modelxsize, modelysize, 3);
ANALOG[_ana]->ROI[i]->image_org = new CImageBasis(ANALOG[_ana]->ROI[i]->deltax, ANALOG[_ana]->ROI[i]->deltay, 3);
}
return true;
}
analog* ClassFlowAnalog::FindANALOG(string _name_number)
{
for (int i = 0; i < ANALOG.size(); ++i)
{
if (ANALOG[i]->name == _name_number)
return ANALOG[i];
}
return NULL;
}
analog* ClassFlowAnalog::GetANALOG(string _name, bool _create = true)
{
string _analog, _roi;
int _pospunkt = _name.find_first_of(".");
// printf("Name: %s, Pospunkt: %d\n", _name.c_str(), _pospunkt);
if (_pospunkt > -1)
{
_analog = _name.substr(0, _pospunkt);
_roi = _name.substr(_pospunkt+1, _name.length() - _pospunkt - 1);
}
else
{
_analog = "default";
_roi = _name;
}
analog *_ret = NULL;
for (int i = 0; i < ANALOG.size(); ++i)
{
if (ANALOG[i]->name == _analog)
_ret = ANALOG[i];
}
if (!_create) // nicht gefunden und soll auch nicht erzeugt werden
return _ret;
if (_ret == NULL)
{
_ret = new analog;
_ret->name = _analog;
ANALOG.push_back(_ret);
}
roianalog* neuroi = new roianalog;
neuroi->name = _roi;
_ret->ROI.push_back(neuroi);
printf("GetANALOG - ANALOG %s - roi %s\n", _analog.c_str(), _roi.c_str());
return _ret;
}
string ClassFlowAnalog::getHTMLSingleStep(string host)
{
@@ -238,16 +298,29 @@ bool ClassFlowAnalog::doAlignAndCut(string time)
CAlignAndCutImage *caic = flowpostalignment->GetAlignAndCutImage();
for (int i = 0; i < ROI.size(); ++i)
{
printf("Analog %d - Align&Cut\n", i);
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"));
for (int _ana = 0; _ana < ANALOG.size(); ++_ana)
for (int i = 0; i < ANALOG[_ana]->ROI.size(); ++i)
{
printf("Analog %d - Align&Cut\n", i);
caic->CutAndSave(ANALOG[_ana]->ROI[i]->posx, ANALOG[_ana]->ROI[i]->posy, ANALOG[_ana]->ROI[i]->deltax, ANALOG[_ana]->ROI[i]->deltay, ANALOG[_ana]->ROI[i]->image_org);
if (SaveAllFiles)
{
if (ANALOG[_ana]->name == "default")
ANALOG[_ana]->ROI[i]->image_org->SaveToFile(FormatFileName("/sdcard/img_tmp/" + ANALOG[_ana]->ROI[i]->name + ".jpg"));
else
ANALOG[_ana]->ROI[i]->image_org->SaveToFile(FormatFileName("/sdcard/img_tmp/" + ANALOG[_ana]->name + "_" + ANALOG[_ana]->ROI[i]->name + ".jpg"));
}
ROI[i]->image_org->Resize(modelxsize, modelysize, ROI[i]->image);
if (SaveAllFiles) ROI[i]->image->SaveToFile(FormatFileName("/sdcard/img_tmp/" + ROI[i]->name + ".bmp"));
}
ANALOG[_ana]->ROI[i]->image_org->Resize(modelxsize, modelysize, ANALOG[_ana]->ROI[i]->image);
if (SaveAllFiles)
{
if (ANALOG[_ana]->name == "default")
ANALOG[_ana]->ROI[i]->image->SaveToFile(FormatFileName("/sdcard/img_tmp/" + ANALOG[_ana]->ROI[i]->name + ".bmp"));
else
ANALOG[_ana]->ROI[i]->image->SaveToFile(FormatFileName("/sdcard/img_tmp/" + ANALOG[_ana]->name + "_" + ANALOG[_ana]->ROI[i]->name + ".bmp"));
}
}
return true;
}
@@ -258,13 +331,14 @@ void ClassFlowAnalog::DrawROI(CImageBasis *_zw)
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);
}
for (int _ana = 0; _ana < ANALOG.size(); ++_ana)
for (int i = 0; i < ANALOG[_ana]->ROI.size(); ++i)
{
_zw->drawRect(ANALOG[_ana]->ROI[i]->posx, ANALOG[_ana]->ROI[i]->posy, ANALOG[_ana]->ROI[i]->deltax, ANALOG[_ana]->ROI[i]->deltay, r, g, b, 1);
_zw->drawCircle((int) (ANALOG[_ana]->ROI[i]->posx + ANALOG[_ana]->ROI[i]->deltax/2), (int) (ANALOG[_ana]->ROI[i]->posy + ANALOG[_ana]->ROI[i]->deltay/2), (int) (ANALOG[_ana]->ROI[i]->deltax/2), r, g, b, 2);
_zw->drawLine((int) (ANALOG[_ana]->ROI[i]->posx + ANALOG[_ana]->ROI[i]->deltax/2), (int) ANALOG[_ana]->ROI[i]->posy, (int) (ANALOG[_ana]->ROI[i]->posx + ANALOG[_ana]->ROI[i]->deltax/2), (int) (ANALOG[_ana]->ROI[i]->posy + ANALOG[_ana]->ROI[i]->deltay), r, g, b, 2);
_zw->drawLine((int) ANALOG[_ana]->ROI[i]->posx, (int) (ANALOG[_ana]->ROI[i]->posy + ANALOG[_ana]->ROI[i]->deltay/2), (int) ANALOG[_ana]->ROI[i]->posx + ANALOG[_ana]->ROI[i]->deltax, (int) (ANALOG[_ana]->ROI[i]->posy + ANALOG[_ana]->ROI[i]->deltay/2), r, g, b, 2);
}
}
bool ClassFlowAnalog::doNeuralNetwork(string time)
@@ -284,43 +358,46 @@ bool ClassFlowAnalog::doNeuralNetwork(string time)
string zwcnn = "/sdcard" + cnnmodelfile;
zwcnn = FormatFileName(zwcnn);
printf(zwcnn.c_str());printf("\n");
tflite->LoadModel(zwcnn);
if (!tflite->LoadModel(zwcnn)) {
printf("Can't read model file /sdcard%s\n", cnnmodelfile.c_str());
delete tflite;
return false;
}
tflite->MakeAllocate();
#endif
for (int i = 0; i < ROI.size(); ++i)
for (int _ana = 0; _ana < ANALOG.size(); ++_ana)
{
printf("Analog %d - TfLite\n", i);
ioresize = "/sdcard/img_tmp/ra" + std::to_string(i) + ".bmp";
ioresize = FormatFileName(ioresize);
float f1, f2;
f1 = 0; f2 = 0;
#ifndef OHNETFLITE
// LogFile.WriteToFile("ClassFlowAnalog::doNeuralNetwork vor CNN tflite->LoadInputImage(ioresize)");
// tflite->LoadInputImage(ioresize);
tflite->LoadInputImageBasis(ROI[i]->image);
tflite->Invoke();
if (debugdetailanalog) LogFile.WriteToFile("Nach Invoke");
f1 = tflite->GetOutputValue(0);
f2 = tflite->GetOutputValue(1);
#endif
float result = fmod(atan2(f1, f2) / (M_PI * 2) + 2, 1);
// printf("Result sin, cos, ziffer: %f, %f, %f\n", f1, f2, result);
ROI[i]->result = result * 10;
printf("Result Analog%i: %f\n", i, ROI[i]->result);
if (isLogImage)
for (int i = 0; i < ANALOG[_ana]->ROI.size(); ++i)
{
LogImage(logPath, ROI[i]->name, &ROI[i]->result, NULL, time, ROI[i]->image_org);
printf("Analog %d - TfLite\n", i);
float f1, f2;
f1 = 0; f2 = 0;
#ifndef OHNETFLITE
tflite->LoadInputImageBasis(ANALOG[_ana]->ROI[i]->image);
tflite->Invoke();
if (debugdetailanalog) LogFile.WriteToFile("Nach Invoke");
f1 = tflite->GetOutputValue(0);
f2 = tflite->GetOutputValue(1);
#endif
float result = fmod(atan2(f1, f2) / (M_PI * 2) + 2, 1);
// printf("Result sin, cos, ziffer: %f, %f, %f\n", f1, f2, result);
ANALOG[_ana]->ROI[i]->result = result * 10;
printf("Result Analog%i: %f\n", i, ANALOG[_ana]->ROI[i]->result);
if (isLogImage)
{
LogImage(logPath, ANALOG[_ana]->ROI[i]->name, &ANALOG[_ana]->ROI[i]->result, NULL, time, ANALOG[_ana]->ROI[i]->image_org);
}
}
}
#ifndef OHNETFLITE
delete tflite;
#endif
@@ -333,18 +410,78 @@ std::vector<HTMLInfo*> ClassFlowAnalog::GetHTMLInfo()
{
std::vector<HTMLInfo*> result;
for (int i = 0; i < ROI.size(); ++i)
{
HTMLInfo *zw = new HTMLInfo;
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);
}
for (int _ana = 0; _ana < ANALOG.size(); ++_ana)
for (int i = 0; i < ANALOG[_ana]->ROI.size(); ++i)
{
if (ANALOG[_ana]->name == "default")
ANALOG[_ana]->ROI[i]->image->SaveToFile(FormatFileName("/sdcard/img_tmp/" + ANALOG[_ana]->ROI[i]->name + ".bmp"));
else
ANALOG[_ana]->ROI[i]->image->SaveToFile(FormatFileName("/sdcard/img_tmp/" + ANALOG[_ana]->name + "_" + ANALOG[_ana]->ROI[i]->name + ".bmp"));
HTMLInfo *zw = new HTMLInfo;
if (ANALOG[_ana]->name == "default")
{
zw->filename = ANALOG[_ana]->ROI[i]->name + ".bmp";
zw->filename_org = ANALOG[_ana]->ROI[i]->name + ".jpg";
}
else
{
zw->filename = ANALOG[_ana]->name + "_" + ANALOG[_ana]->ROI[i]->name + ".bmp";
zw->filename_org = ANALOG[_ana]->name + "_" + ANALOG[_ana]->ROI[i]->name + ".jpg";
}
zw->val = ANALOG[_ana]->ROI[i]->result;
zw->image = ANALOG[_ana]->ROI[i]->image;
zw->image_org = ANALOG[_ana]->ROI[i]->image_org;
result.push_back(zw);
}
return result;
}
int ClassFlowAnalog::getAnzahlANALOG()
{
return ANALOG.size();
}
string ClassFlowAnalog::getNameANALOG(int _analog)
{
if (_analog < ANALOG.size())
return ANALOG[_analog]->name;
return "ANALOG DOES NOT EXIST";
}
analog* ClassFlowAnalog::GetANALOG(int _analog)
{
if (_analog < ANALOG.size())
return ANALOG[_analog];
return NULL;
}
void ClassFlowAnalog::UpdateNameNumbers(std::vector<std::string> *_name_numbers)
{
for (int _dig = 0; _dig < ANALOG.size(); _dig++)
{
std::string _name = ANALOG[_dig]->name;
bool found = false;
for (int i = 0; i < (*_name_numbers).size(); ++i)
{
if ((*_name_numbers)[i] == _name)
found = true;
}
if (!found)
(*_name_numbers).push_back(_name);
}
}

View File

@@ -10,12 +10,19 @@ struct roianalog {
string name;
};
struct analog {
string name;
std::vector<roianalog*> ROI;
};
class ClassFlowAnalog :
public ClassFlowImage
{
protected:
std::vector<roianalog*> ROI;
// std::vector<roianalog*> ROI;
std::vector<analog*> ANALOG;
string cnnmodelfile;
int modelxsize, modelysize;
int ZeigerEval(float zahl, int ziffer_vorgaenger);
@@ -24,7 +31,8 @@ protected:
ClassFlowAlignment* flowpostalignment;
void SetInitialParameter(void);
void SetInitialParameter(void);
public:
bool extendedResolution;
@@ -34,14 +42,23 @@ public:
bool ReadParameter(FILE* pfile, string& aktparamgraph);
bool doFlow(string time);
string getHTMLSingleStep(string host);
string getReadout();
string getReadout(int _analog);
void DrawROI(CImageBasis *_zw);
bool doNeuralNetwork(string time);
bool doAlignAndCut(string time);
std::vector<HTMLInfo*> GetHTMLInfo();
int AnzahlROIs();
int AnzahlROIs(int _analog);
int getAnzahlANALOG();
analog* GetANALOG(int _analog);
analog* GetANALOG(string _name, bool _create);
analog* FindANALOG(string _name_number);
string getNameANALOG(int _analog);
void UpdateNameNumbers(std::vector<std::string> *_name_numbers);
string name(){return "ClassFlowAnalog";};
};

View File

@@ -120,6 +120,7 @@ ClassFlow* ClassFlowControll::CreateClassFlow(std::string _type)
}
if (toUpper(_type).compare("[MQTT]") == 0)
cfc = new ClassFlowMQTT(&FlowControll);
if (toUpper(_type).compare("[POSTPROCESSING]") == 0)
{
cfc = new ClassFlowPostProcessing(&FlowControll);
@@ -172,9 +173,12 @@ void ClassFlowControll::InitFlow(std::string config)
}
else
{
fgets(zw, 1024, pFile);
printf("%s", zw);
line = std::string(zw);
line = "";
if (fgets(zw, 1024, pFile) && !feof(pFile))
{
printf("Read: %s", zw);
line = std::string(zw);
}
}
}
@@ -209,7 +213,7 @@ bool ClassFlowControll::doFlow(string time)
int repeat = 0;
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("ClassFlowAnalog::doFlow - Start");
LogFile.WriteHeapInfo("ClassFlowControll::doFlow - Start");
#endif
for (int i = 0; i < FlowControll.size(); ++i)
@@ -238,7 +242,7 @@ bool ClassFlowControll::doFlow(string time)
}
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("ClassFlowAnalog::doFlow");
LogFile.WriteHeapInfo("ClassFlowControll::doFlow");
#endif
}
@@ -262,6 +266,38 @@ void ClassFlowControll::UpdateAktStatus(std::string _flow)
}
string ClassFlowControll::getReadoutAll(int _type)
{
std::vector<NumberPost*> numbers = flowpostprocessing->GetNumbers();
std::string out = "";
for (int i = 0; i < numbers.size(); ++i)
{
out = out + numbers[i]->name + "\t";
switch (_type) {
case READOUT_TYPE_VALUE:
out = out + numbers[i]->ReturnValue;
break;
case READOUT_TYPE_PREVALUE:
out = out + numbers[i]->ReturnPreValue;
break;
case READOUT_TYPE_RAWVALUE:
out = out + numbers[i]->ReturnRawValue;
break;
case READOUT_TYPE_ERROR:
out = out + numbers[i]->ErrorMessageText;
break;
}
if (i < numbers.size()-1)
out = out + "\r\n";
}
// printf("OUT: %s", out.c_str());
return out;
}
string ClassFlowControll::getReadout(bool _rawvalue = false, bool _noerror = false)
{
if (flowpostprocessing)
@@ -285,17 +321,17 @@ string ClassFlowControll::getReadout(bool _rawvalue = false, bool _noerror = fal
return result;
}
string ClassFlowControll::GetPrevalue()
string ClassFlowControll::GetPrevalue(std::string _number)
{
if (flowpostprocessing)
{
return flowpostprocessing->GetPreValue();
return flowpostprocessing->GetPreValue(_number);
}
return std::string();
}
std::string ClassFlowControll::UpdatePrevalue(std::string _newvalue)
std::string ClassFlowControll::UpdatePrevalue(std::string _newvalue, std::string _numbers, bool _extern)
{
float zw;
char* p;
@@ -317,7 +353,7 @@ std::string ClassFlowControll::UpdatePrevalue(std::string _newvalue)
if (flowpostprocessing)
{
flowpostprocessing->SavePreValue(zw);
flowpostprocessing->SetPreValue(zw, _numbers, _extern);
return _newvalue;
}
@@ -442,7 +478,7 @@ int ClassFlowControll::CleanTempFolder() {
esp_err_t ClassFlowControll::SendRawJPG(httpd_req_t *req)
{
return flowmakeimage->SendRawJPG(req);
return flowmakeimage != NULL ? flowmakeimage->SendRawJPG(req) : ESP_FAIL;
}
@@ -454,6 +490,12 @@ esp_err_t ClassFlowControll::GetJPGStream(std::string _fn, httpd_req_t *req)
esp_err_t result = ESP_FAIL;
bool Dodelete = false;
if (flowalignment == NULL)
{
printf("Can't continue, flowalignment is NULL\n");
return ESP_FAIL;
}
if (_fn == "alg.jpg")
{
_send = flowalignment->ImageBasis;
@@ -485,7 +527,9 @@ esp_err_t ClassFlowControll::GetJPGStream(std::string _fn, httpd_req_t *req)
if (htmlinfo[i]->image_org)
_send = htmlinfo[i]->image_org;
}
delete htmlinfo[i];
}
htmlinfo.clear();
htmlinfo = GetAllAnalog();
for (int i = 0; i < htmlinfo.size(); ++i)
@@ -500,7 +544,9 @@ esp_err_t ClassFlowControll::GetJPGStream(std::string _fn, httpd_req_t *req)
if (htmlinfo[i]->image_org)
_send = htmlinfo[i]->image_org;
}
delete htmlinfo[i];
}
htmlinfo.clear();
if (_send)
{

View File

@@ -11,6 +11,12 @@
#include "ClassFlowMQTT.h"
#define READOUT_TYPE_VALUE 0
#define READOUT_TYPE_PREVALUE 1
#define READOUT_TYPE_RAWVALUE 2
#define READOUT_TYPE_ERROR 3
class ClassFlowControll :
public ClassFlow
{
@@ -38,8 +44,9 @@ public:
void doFlowMakeImageOnly(string time);
bool getStatusSetupModus(){return SetupModeActive;};
string getReadout(bool _rawvalue, bool _noerror);
string UpdatePrevalue(std::string _newvalue);
string GetPrevalue();
string getReadoutAll(int _type);
string UpdatePrevalue(std::string _newvalue, std::string _numbers, bool _extern);
string GetPrevalue(std::string _number = "");
bool ReadParameter(FILE* pfile, string& aktparamgraph);
esp_err_t GetJPGStream(std::string _fn, httpd_req_t *req);

View File

@@ -64,16 +64,16 @@ ClassFlowDigit::ClassFlowDigit(std::vector<ClassFlow*>* lfc, ClassFlow *_prev) :
}
}
string ClassFlowDigit::getReadout()
string ClassFlowDigit::getReadout(int _digit = 0)
{
string rst = "";
for (int i = 0; i < ROI.size(); ++i)
for (int i = 0; i < DIGIT[_digit]->ROI.size(); ++i)
{
if (ROI[i]->resultklasse == 10)
if (DIGIT[_digit]->ROI[i]->resultklasse == 10)
rst = rst + "N";
else
rst = rst + std::to_string(ROI[i]->resultklasse);
rst = rst + std::to_string(DIGIT[_digit]->ROI[i]->resultklasse);
}
return rst;
@@ -91,18 +91,11 @@ bool ClassFlowDigit::ReadParameter(FILE* pfile, string& aktparamgraph)
printf("aktparamgraph: %s\n", aktparamgraph.c_str());
/*
if ((aktparamgraph.compare("[Digits]") != 0) && (aktparamgraph.compare(";[Digits]") != 0)) // Paragraph passt nich zu MakeImage
return false;
*/
if ((aktparamgraph.compare(0, 7, "[Digits") != 0) && (aktparamgraph.compare(0, 8, ";[Digits") != 0)) // Paragraph passt nich zu MakeImage
return false;
int _pospkt = aktparamgraph.find_first_of(".");
int _posklammerzu = aktparamgraph.find_first_of("]");
// printf("Pos: %d, %d\n", _pospkt, _posklammerzu);
if (_pospkt > -1)
NameDigit = aktparamgraph.substr(_pospkt+1, _posklammerzu - _pospkt-1);
else
@@ -137,8 +130,8 @@ bool ClassFlowDigit::ReadParameter(FILE* pfile, string& aktparamgraph)
}
if (zerlegt.size() >= 5)
{
roi* neuroi = new roi;
neuroi->name = zerlegt[0];
digit* _digit = GetDIGIT(zerlegt[0], true);
roi* neuroi = _digit->ROI[_digit->ROI.size()-1];
neuroi->posx = std::stoi(zerlegt[1]);
neuroi->posy = std::stoi(zerlegt[2]);
neuroi->deltax = std::stoi(zerlegt[3]);
@@ -146,7 +139,6 @@ bool ClassFlowDigit::ReadParameter(FILE* pfile, string& aktparamgraph)
neuroi->resultklasse = -1;
neuroi->image = NULL;
neuroi->image_org = NULL;
ROI.push_back(neuroi);
}
if ((toUpper(zerlegt[0]) == "SAVEALLFILES") && (zerlegt.size() > 1))
@@ -157,15 +149,72 @@ bool ClassFlowDigit::ReadParameter(FILE* pfile, string& aktparamgraph)
}
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);
}
for (int _dig = 0; _dig < DIGIT.size(); ++_dig)
for (int i = 0; i < DIGIT[_dig]->ROI.size(); ++i)
{
DIGIT[_dig]->ROI[i]->image = new CImageBasis(modelxsize, modelysize, 3);
DIGIT[_dig]->ROI[i]->image_org = new CImageBasis(DIGIT[_dig]->ROI[i]->deltax, DIGIT[_dig]->ROI[i]->deltay, 3);
}
return true;
}
digit* ClassFlowDigit::FindDIGIT(string _name_number)
{
for (int i = 0; i < DIGIT.size(); ++i)
{
if (DIGIT[i]->name == _name_number)
return DIGIT[i];
}
return NULL;
}
digit* ClassFlowDigit::GetDIGIT(string _name, bool _create = true)
{
string _digit, _roi;
int _pospunkt = _name.find_first_of(".");
// printf("Name: %s, Pospunkt: %d\n", _name.c_str(), _pospunkt);
if (_pospunkt > -1)
{
_digit = _name.substr(0, _pospunkt);
_roi = _name.substr(_pospunkt+1, _name.length() - _pospunkt - 1);
}
else
{
_digit = "default";
_roi = _name;
}
digit *_ret = NULL;
for (int i = 0; i < DIGIT.size(); ++i)
{
if (DIGIT[i]->name == _digit)
_ret = DIGIT[i];
}
if (!_create) // nicht gefunden und soll auch nicht erzeugt werden, ggf. geht eine NULL zurück
return _ret;
if (_ret == NULL)
{
_ret = new digit;
_ret->name = _digit;
DIGIT.push_back(_ret);
}
roi* neuroi = new roi;
neuroi->name = _roi;
_ret->ROI.push_back(neuroi);
printf("GetDIGIT - digit %s - roi %s\n", _digit.c_str(), _roi.c_str());
return _ret;
}
string ClassFlowDigit::getHTMLSingleStep(string host)
{
@@ -216,17 +265,32 @@ bool ClassFlowDigit::doAlignAndCut(string time)
CAlignAndCutImage *caic = flowpostalignment->GetAlignAndCutImage();
for (int i = 0; i < ROI.size(); ++i)
for (int _dig = 0; _dig < DIGIT.size(); ++_dig)
{
printf("DigitalDigit %d - Align&Cut\n", i);
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"));
printf("DIGIT[_dig]->ROI.size() %d\n", DIGIT[_dig]->ROI.size());
for (int i = 0; i < DIGIT[_dig]->ROI.size(); ++i)
{
printf("DigitalDigit %d - Align&Cut\n", i);
caic->CutAndSave(DIGIT[_dig]->ROI[i]->posx, DIGIT[_dig]->ROI[i]->posy, DIGIT[_dig]->ROI[i]->deltax, DIGIT[_dig]->ROI[i]->deltay, DIGIT[_dig]->ROI[i]->image_org);
if (SaveAllFiles)
{
if (DIGIT[_dig]->name == "default")
DIGIT[_dig]->ROI[i]->image_org->SaveToFile(FormatFileName("/sdcard/img_tmp/" + DIGIT[_dig]->ROI[i]->name + ".jpg"));
else
DIGIT[_dig]->ROI[i]->image_org->SaveToFile(FormatFileName("/sdcard/img_tmp/" + DIGIT[_dig]->name + "_" + DIGIT[_dig]->ROI[i]->name + ".jpg"));
}
ROI[i]->image_org->Resize(modelxsize, modelysize, ROI[i]->image);
if (SaveAllFiles) ROI[i]->image->SaveToFile(FormatFileName("/sdcard/img_tmp/" + ROI[i]->name + ".bmp"));
DIGIT[_dig]->ROI[i]->image_org->Resize(modelxsize, modelysize, DIGIT[_dig]->ROI[i]->image);
if (SaveAllFiles)
{
if (DIGIT[_dig]->name == "default")
DIGIT[_dig]->ROI[i]->image->SaveToFile(FormatFileName("/sdcard/img_tmp/" + DIGIT[_dig]->ROI[i]->name + ".bmp"));
else
DIGIT[_dig]->ROI[i]->image->SaveToFile(FormatFileName("/sdcard/img_tmp/" + DIGIT[_dig]->name + "_" + DIGIT[_dig]->ROI[i]->name + ".bmp"));
}
}
}
return true;
}
@@ -241,26 +305,32 @@ bool ClassFlowDigit::doNeuralNetwork(string time)
CTfLiteClass *tflite = new CTfLiteClass;
string zwcnn = FormatFileName("/sdcard" + cnnmodelfile);
printf(zwcnn.c_str());printf("\n");
tflite->LoadModel(zwcnn);
if (!tflite->LoadModel(zwcnn)) {
printf("Can't read model file /sdcard%s\n", cnnmodelfile.c_str());
delete tflite;
return false;
}
tflite->MakeAllocate();
#endif
for (int i = 0; i < ROI.size(); ++i)
{
printf("DigitalDigit %d - TfLite\n", i);
ROI[i]->resultklasse = 0;
#ifndef OHNETFLITE
ROI[i]->resultklasse = tflite->GetClassFromImageBasis(ROI[i]->image);
#endif
printf("Result Digit%i: %d\n", i, ROI[i]->resultklasse);
if (isLogImage)
for (int _dig = 0; _dig < DIGIT.size(); ++_dig)
for (int i = 0; i < DIGIT[_dig]->ROI.size(); ++i)
{
LogImage(logPath, ROI[i]->name, NULL, &ROI[i]->resultklasse, time, ROI[i]->image_org);
printf("DigitalDigit %d - TfLite\n", i);
DIGIT[_dig]->ROI[i]->resultklasse = 0;
#ifndef OHNETFLITE
DIGIT[_dig]->ROI[i]->resultklasse = tflite->GetClassFromImageBasis(DIGIT[_dig]->ROI[i]->image);
#endif
printf("Result Digit%i: %d\n", i, DIGIT[_dig]->ROI[i]->resultklasse);
if (isLogImage)
{
LogImage(logPath, DIGIT[_dig]->ROI[i]->name, NULL, &DIGIT[_dig]->ROI[i]->resultklasse, time, DIGIT[_dig]->ROI[i]->image_org);
}
}
}
#ifndef OHNETFLITE
delete tflite;
#endif
@@ -269,25 +339,82 @@ bool ClassFlowDigit::doNeuralNetwork(string time)
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);
for (int _dig = 0; _dig < DIGIT.size(); ++_dig)
for (int i = 0; i < DIGIT[_dig]->ROI.size(); ++i)
_zw->drawRect(DIGIT[_dig]->ROI[i]->posx, DIGIT[_dig]->ROI[i]->posy, DIGIT[_dig]->ROI[i]->deltax, DIGIT[_dig]->ROI[i]->deltay, 0, 0, (255 - _dig*100), 2);
}
std::vector<HTMLInfo*> ClassFlowDigit::GetHTMLInfo()
{
std::vector<HTMLInfo*> result;
for (int i = 0; i < ROI.size(); ++i)
{
HTMLInfo *zw = new HTMLInfo;
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);
}
for (int _dig = 0; _dig < DIGIT.size(); ++_dig)
for (int i = 0; i < DIGIT[_dig]->ROI.size(); ++i)
{
if (DIGIT[_dig]->name == "default")
DIGIT[_dig]->ROI[i]->image->SaveToFile(FormatFileName("/sdcard/img_tmp/" + DIGIT[_dig]->ROI[i]->name + ".bmp"));
else
DIGIT[_dig]->ROI[i]->image->SaveToFile(FormatFileName("/sdcard/img_tmp/" + DIGIT[_dig]->name + "_" + DIGIT[_dig]->ROI[i]->name + ".bmp"));
HTMLInfo *zw = new HTMLInfo;
if (DIGIT[_dig]->name == "default")
{
zw->filename = DIGIT[_dig]->ROI[i]->name + ".bmp";
zw->filename_org = DIGIT[_dig]->ROI[i]->name + ".jpg";
}
else
{
zw->filename = DIGIT[_dig]->name + "_" + DIGIT[_dig]->ROI[i]->name + ".bmp";
zw->filename_org = DIGIT[_dig]->name + "_" + DIGIT[_dig]->ROI[i]->name + ".jpg";
}
zw->val = DIGIT[_dig]->ROI[i]->resultklasse;
zw->image = DIGIT[_dig]->ROI[i]->image;
zw->image_org = DIGIT[_dig]->ROI[i]->image_org;
result.push_back(zw);
}
return result;
}
int ClassFlowDigit::getAnzahlDIGIT()
{
return DIGIT.size();
}
string ClassFlowDigit::getNameDIGIT(int _digit)
{
if (_digit < DIGIT.size())
return DIGIT[_digit]->name;
return "DIGIT DOES NOT EXIST";
}
digit* ClassFlowDigit::GetDIGIT(int _digit)
{
if (_digit < DIGIT.size())
return DIGIT[_digit];
return NULL;
}
void ClassFlowDigit::UpdateNameNumbers(std::vector<std::string> *_name_numbers)
{
for (int _dig = 0; _dig < DIGIT.size(); _dig++)
{
std::string _name = DIGIT[_dig]->name;
bool found = false;
for (int i = 0; i < (*_name_numbers).size(); ++i)
{
if ((*_name_numbers)[i] == _name)
found = true;
}
if (!found)
(*_name_numbers).push_back(_name);
}
}

View File

@@ -5,6 +5,8 @@
#include <string>
struct roi {
int posx, posy, deltax, deltay;
int resultklasse;
@@ -13,11 +15,17 @@ struct roi {
roi* next;
};
struct digit {
string name;
std::vector<roi*> ROI;
};
class ClassFlowDigit :
public ClassFlowImage
{
protected:
std::vector<roi*> ROI;
// std::vector<roi*> ROI;
std::vector<digit*> DIGIT;
string cnnmodelfile;
int modelxsize, modelysize;
bool SaveAllFiles;
@@ -31,6 +39,7 @@ protected:
bool doNeuralNetwork(string time);
bool doAlignAndCut(string time);
void SetInitialParameter(void);
public:
@@ -40,9 +49,18 @@ public:
bool ReadParameter(FILE* pfile, string& aktparamgraph);
bool doFlow(string time);
string getHTMLSingleStep(string host);
string getReadout();
string getReadout(int _digit);
std::vector<HTMLInfo*> GetHTMLInfo();
int getAnzahlDIGIT();
digit* GetDIGIT(int _digit);
digit* GetDIGIT(string _name, bool _create);
digit* FindDIGIT(string _name_number);
string getNameDIGIT(int _digit);
void UpdateNameNumbers(std::vector<std::string> *_name_numbers);
void DrawROI(CImageBasis *_zw);
string name(){return "ClassFlowDigit";};

View File

@@ -1,6 +1,8 @@
#include <sstream>
#include "ClassFlowMQTT.h"
#include "Helper.h"
#include "time_sntp.h"
#include "interface_mqtt.h"
#include "ClassFlowPostProcessing.h"
@@ -13,6 +15,11 @@ void ClassFlowMQTT::SetInitialParameter(void)
topicError = "";
topicRate = "";
topicTimeStamp = "";
maintopic = "";
mainerrortopic = "";
topicUptime = "";
topicFreeMem = "";
clientname = "watermeter";
OldValue = "";
flowpostprocessing = NULL;
@@ -21,6 +28,9 @@ void ClassFlowMQTT::SetInitialParameter(void)
previousElement = NULL;
ListFlowControll = NULL;
disabled = false;
MQTTenable = false;
}
@@ -88,33 +98,24 @@ bool ClassFlowMQTT::ReadParameter(FILE* pfile, string& aktparamgraph)
{
this->uri = zerlegt[1];
}
if ((toUpper(zerlegt[0]) == "TOPIC") && (zerlegt.size() > 1))
{
this->topic = zerlegt[1];
}
if ((toUpper(zerlegt[0]) == "TOPICERROR") && (zerlegt.size() > 1))
{
this->topicError = zerlegt[1];
}
if ((toUpper(zerlegt[0]) == "TOPICRATE") && (zerlegt.size() > 1))
{
this->topicRate = zerlegt[1];
}
if ((toUpper(zerlegt[0]) == "TOPICTIMESTAMP") && (zerlegt.size() > 1))
{
this->topicTimeStamp = zerlegt[1];
}
if ((toUpper(zerlegt[0]) == "CLIENTID") && (zerlegt.size() > 1))
{
this->clientname = zerlegt[1];
}
if (((toUpper(zerlegt[0]) == "TOPIC") || (toUpper(zerlegt[0]) == "MAINTOPIC")) && (zerlegt.size() > 1))
{
maintopic = zerlegt[1];
}
}
if ((uri.length() > 0) && (topic.length() > 0))
if (!MQTTisConnected() && (uri.length() > 0) && (maintopic.length() > 0))
{
MQTTInit(uri, clientname, user, password, topicError, 60);
mainerrortopic = maintopic + "/connection";
MQTTInit(uri, clientname, user, password, mainerrortopic, 60);
MQTTPublish(mainerrortopic, "connected");
MQTTenable = true;
}
return true;
@@ -123,18 +124,66 @@ bool ClassFlowMQTT::ReadParameter(FILE* pfile, string& aktparamgraph)
bool ClassFlowMQTT::doFlow(string zwtime)
{
if (!MQTTenable)
return true;
std::string result;
std::string resulterror = "";
std::string resultrate = "";
std::string resulttimestamp = "";
string zw = "";
string namenumber = "";
MQTTPublish(mainerrortopic, "connected");
zw = maintopic + "/" + "uptime";
char uptimeStr[11];
sprintf(uptimeStr, "%ld", (long)getUpTime());
MQTTPublish(zw, uptimeStr);
zw = maintopic + "/" + "freeMem";
char freeheapmem[11];
sprintf(freeheapmem, "%zu", esp_get_free_heap_size());
MQTTPublish(zw, freeheapmem);
if (flowpostprocessing)
{
result = flowpostprocessing->getReadoutParam(false, true);
resulterror = flowpostprocessing->getReadoutError();
resultrate = flowpostprocessing->getReadoutRate();
resulttimestamp = flowpostprocessing->getReadoutTimeStamp();
std::vector<NumberPost*> NUMBERS = flowpostprocessing->GetNumbers();
for (int i = 0; i < NUMBERS.size(); ++i)
{
result = NUMBERS[i]->ReturnValue;
resulterror = NUMBERS[i]->ErrorMessageText;
resultrate = std::to_string(NUMBERS[i]->FlowRateAct);
resulttimestamp = NUMBERS[i]->timeStamp;
namenumber = NUMBERS[i]->name;
if (namenumber == "default")
namenumber = maintopic + "/";
else
namenumber = maintopic + "/" + namenumber + "/";
zw = namenumber + "value";
MQTTPublish(zw, result);
zw = namenumber + "error";
MQTTPublish(zw, resulterror, 1);
zw = namenumber + "rate";
MQTTPublish(zw, resultrate);
zw = namenumber + "timestamp";
MQTTPublish(zw, resulttimestamp);
std::string json="{\"value\":"+result;
json += ",\"error\":\""+resulterror;
json += "\",\"rate\":"+resultrate;
json += ",\"timestamp\":\""+resulttimestamp+"\"}";
zw = namenumber + "json";
MQTTPublish(zw, json);
}
}
else
{
@@ -149,26 +198,9 @@ bool ClassFlowMQTT::doFlow(string zwtime)
result = result + "\t" + zw;
}
}
MQTTPublish(topic, result);
}
MQTTPublish(topic, result);
if (topicError.length() > 0) {
if (resulterror.length() == 0)
{
resulterror = " ";
}
MQTTPublish(topicError, resulterror, 1);
}
if (topicRate.length() > 0) {
MQTTPublish(topicRate, resultrate);
}
if (topicTimeStamp.length() > 0) {
MQTTPublish(topicTimeStamp, resulttimestamp);
}
OldValue = result;
return true;

View File

@@ -9,10 +9,13 @@ class ClassFlowMQTT :
public ClassFlow
{
protected:
std::string uri, topic, topicError, clientname, topicRate, topicTimeStamp;
std::string uri, topic, topicError, clientname, topicRate, topicTimeStamp, topicUptime, topicFreeMem;
std::string OldValue;
ClassFlowPostProcessing* flowpostprocessing;
std::string user, password;
std::string user, password;
bool MQTTenable;
std::string maintopic, mainerrortopic;
void SetInitialParameter(void);
public:

View File

@@ -1,8 +1,6 @@
#include "ClassFlowPostProcessing.h"
#include "Helper.h"
#include "ClassFlowAnalog.h"
#include "ClassFlowDigit.h"
#include "ClassFlowMakeImage.h"
#include "ClassLogFile.h"
@@ -18,130 +16,216 @@
#define PREVALUE_TIME_FORMAT_INPUT "%d-%d-%dT%d:%d:%d"
string ClassFlowPostProcessing::GetPreValue()
string ClassFlowPostProcessing::GetPreValue(std::string _number)
{
std::string result;
bool isAnalog = false;
bool isDigit = false;
int index = -1;
int AnzahlAnalog = 0;
result = RundeOutput(PreValue, -DecimalShift);
if (_number == "")
_number = "default";
for (int i = 0; i < ListFlowControll->size(); ++i)
{
if (((*ListFlowControll)[i])->name().compare("ClassFlowAnalog") == 0)
{
isAnalog = true;
AnzahlAnalog = ((ClassFlowAnalog*)(*ListFlowControll)[i])->AnzahlROIs();
}
if (((*ListFlowControll)[i])->name().compare("ClassFlowDigit") == 0)
{
isDigit = true;
}
}
for (int i = 0; i < NUMBERS.size(); ++i)
if (NUMBERS[i]->name == _number)
index = i;
if (isDigit && isAnalog)
result = RundeOutput(PreValue, AnzahlAnalog - DecimalShift);
// result = RundeOutput(NUMBERS[index]->PreValue, -NUMBERS[index]->DecimalShift);
result = RundeOutput(NUMBERS[index]->PreValue, NUMBERS[index]->Nachkomma);
// if (NUMBERS[index]->digit_roi && NUMBERS[index]->analog_roi)
// result = RundeOutput(NUMBERS[index]->PreValue, NUMBERS[index]->AnzahlAnalog - NUMBERS[index]->DecimalShift);
return result;
}
void ClassFlowPostProcessing::SetPreValue(float zw, string _numbers, bool _extern)
{
printf("SetPrevalue: %f, %s\n", zw, _numbers.c_str());
for (int j = 0; j < NUMBERS.size(); ++j)
{
// printf("Number %d, %s\n", j, NUMBERS[j]->name.c_str());
if (NUMBERS[j]->name == _numbers)
{
NUMBERS[j]->PreValue = zw;
if (_extern)
{
time(&(NUMBERS[j]->lastvalue));
localtime(&(NUMBERS[j]->lastvalue));
}
// printf("Found %d! - set to %f\n", j, NUMBERS[j]->PreValue);
}
}
UpdatePreValueINI = true;
SavePreValue();
}
bool ClassFlowPostProcessing::LoadPreValue(void)
{
std::vector<string> zerlegt;
FILE* pFile;
char zw[1024];
string zwtime, zwvalue;
string zwtime, zwvalue, name;
bool _done = false;
UpdatePreValueINI = false; // Konvertierung ins neue Format
pFile = fopen(FilePreValue.c_str(), "r");
if (pFile == NULL)
return false;
fgets(zw, 1024, pFile);
printf("%s", zw);
printf("Read Zeile Prevalue.ini: %s", zw);
zwtime = trim(std::string(zw));
fgets(zw, 1024, pFile);
fclose(pFile);
printf("%s", zw);
zwvalue = trim(std::string(zw));
PreValue = stof(zwvalue.c_str());
time_t tStart;
int yy, month, dd, hh, mm, ss;
struct tm whenStart;
sscanf(zwtime.c_str(), PREVALUE_TIME_FORMAT_INPUT, &yy, &month, &dd, &hh, &mm, &ss);
whenStart.tm_year = yy - 1900;
whenStart.tm_mon = month - 1;
whenStart.tm_mday = dd;
whenStart.tm_hour = hh;
whenStart.tm_min = mm;
whenStart.tm_sec = ss;
whenStart.tm_isdst = -1;
lastvalue = mktime(&whenStart);
time(&tStart);
localtime(&tStart);
double difference = difftime(tStart, lastvalue);
difference /= 60;
if (difference > PreValueAgeStartup)
if (zwtime.length() == 0)
return false;
Value = PreValue;
ReturnValue = to_string(Value);
ReturnValueNoError = ReturnValue;
bool isAnalog = false;
bool isDigit = false;
int AnzahlAnalog = 0;
for (int i = 0; i < ListFlowControll->size(); ++i)
zerlegt = HelperZerlegeZeile(zwtime, "\t");
if (zerlegt.size() > 1) // neues Format
{
if (((*ListFlowControll)[i])->name().compare("ClassFlowAnalog") == 0)
isAnalog = true;
if (((*ListFlowControll)[i])->name().compare("ClassFlowDigit") == 0)
isDigit = true;
}
while ((zerlegt.size() > 1) && !_done)
{
name = trim(zerlegt[0]);
zwtime = trim(zerlegt[1]);
zwvalue = trim(zerlegt[2]);
if (isDigit || isAnalog)
for (int j = 0; j < NUMBERS.size(); ++j)
{
if (NUMBERS[j]->name == name)
{
NUMBERS[j]->PreValue = stof(zwvalue.c_str());
NUMBERS[j]->ReturnPreValue = RundeOutput(NUMBERS[j]->PreValue, NUMBERS[j]->Nachkomma);
time_t tStart;
int yy, month, dd, hh, mm, ss;
struct tm whenStart;
sscanf(zwtime.c_str(), PREVALUE_TIME_FORMAT_INPUT, &yy, &month, &dd, &hh, &mm, &ss);
whenStart.tm_year = yy - 1900;
whenStart.tm_mon = month - 1;
whenStart.tm_mday = dd;
whenStart.tm_hour = hh;
whenStart.tm_min = mm;
whenStart.tm_sec = ss;
whenStart.tm_isdst = -1;
NUMBERS[j]->lastvalue = mktime(&whenStart);
time(&tStart);
localtime(&tStart);
double difference = difftime(tStart, NUMBERS[j]->lastvalue);
difference /= 60;
if (difference > PreValueAgeStartup)
{
NUMBERS[j]->PreValueOkay = false;
}
else
{
NUMBERS[j]->PreValueOkay = true;
NUMBERS[j]->Value = NUMBERS[j]->PreValue;
NUMBERS[j]->ReturnValue = to_string(NUMBERS[j]->Value);
NUMBERS[j]->ReturnValueNoError = NUMBERS[j]->ReturnValue;
if (NUMBERS[j]->digit_roi || NUMBERS[j]->analog_roi)
{
NUMBERS[j]->ReturnValue = RundeOutput(NUMBERS[j]->Value, NUMBERS[j]->AnzahlAnalog - NUMBERS[j]->DecimalShift);
NUMBERS[j]->ReturnValueNoError = NUMBERS[j]->ReturnValue;
}
}
}
}
if (!fgets(zw, 1024, pFile))
_done = true;
else
{
printf("Read Zeile Prevalue.ini: %s", zw);
zerlegt = HelperZerlegeZeile(trim(std::string(zw)), "\t");
if (zerlegt.size() > 1)
{
name = trim(zerlegt[0]);
zwtime = trim(zerlegt[1]);
zwvalue = trim(zerlegt[2]);
}
}
}
fclose(pFile);
}
else // altes Format
{
ReturnValue = RundeOutput(Value, AnzahlAnalog - DecimalShift);
ReturnValueNoError = ReturnValue;
}
fgets(zw, 1024, pFile);
fclose(pFile);
printf("%s", zw);
zwvalue = trim(std::string(zw));
NUMBERS[0]->PreValue = stof(zwvalue.c_str());
time_t tStart;
int yy, month, dd, hh, mm, ss;
struct tm whenStart;
sscanf(zwtime.c_str(), PREVALUE_TIME_FORMAT_INPUT, &yy, &month, &dd, &hh, &mm, &ss);
whenStart.tm_year = yy - 1900;
whenStart.tm_mon = month - 1;
whenStart.tm_mday = dd;
whenStart.tm_hour = hh;
whenStart.tm_min = mm;
whenStart.tm_sec = ss;
whenStart.tm_isdst = -1;
printf("TIME: %d, %d, %d, %d, %d, %d\n", whenStart.tm_year, whenStart.tm_mon, whenStart.tm_wday, whenStart.tm_hour, whenStart.tm_min, whenStart.tm_sec);
NUMBERS[0]->lastvalue = mktime(&whenStart);
time(&tStart);
localtime(&tStart);
double difference = difftime(tStart, NUMBERS[0]->lastvalue);
difference /= 60;
if (difference > PreValueAgeStartup)
return false;
NUMBERS[0]->Value = NUMBERS[0]->PreValue;
NUMBERS[0]->ReturnValue = to_string(NUMBERS[0]->Value);
NUMBERS[0]->ReturnValueNoError = NUMBERS[0]->ReturnValue;
if (NUMBERS[0]->digit_roi || NUMBERS[0]->analog_roi)
{
NUMBERS[0]->ReturnValue = RundeOutput(NUMBERS[0]->Value, NUMBERS[0]->AnzahlAnalog - NUMBERS[0]->DecimalShift);
NUMBERS[0]->ReturnValueNoError = NUMBERS[0]->ReturnValue;
}
UpdatePreValueINI = true; // Konvertierung ins neue Format
SavePreValue();
}
return true;
}
void ClassFlowPostProcessing::SavePreValue(float value, string zwtime)
void ClassFlowPostProcessing::SavePreValue()
{
FILE* pFile;
string _zw;
if (!UpdatePreValueINI) // PreValues unverändert --> File muss nicht neu geschrieben werden
return;
pFile = fopen(FilePreValue.c_str(), "w");
if (strlen(zwtime.c_str()) == 0)
for (int j = 0; j < NUMBERS.size(); ++j)
{
time_t rawtime;
struct tm* timeinfo;
char buffer[80];
time(&rawtime);
timeinfo = localtime(&rawtime);
struct tm* timeinfo = localtime(&NUMBERS[j]->lastvalue);
strftime(buffer, 80, PREVALUE_TIME_FORMAT_OUTPUT, timeinfo);
timeStamp = std::string(buffer);
}
else
{
timeStamp = zwtime;
NUMBERS[j]->timeStamp = std::string(buffer);
// printf("SaverPreValue %d, Value: %f, Nachkomma %d\n", j, NUMBERS[j]->PreValue, NUMBERS[j]->Nachkomma);
_zw = NUMBERS[j]->name + "\t" + NUMBERS[j]->timeStamp + "\t" + RundeOutput(NUMBERS[j]->PreValue, NUMBERS[j]->Nachkomma) + "\n";
printf("Write PreValue Zeile: %s\n", _zw.c_str());
fputs(_zw.c_str(), pFile);
}
PreValue = value;
fputs(timeStamp.c_str(), pFile);
fputs("\n", pFile);
fputs(to_string(value).c_str(), pFile);
fputs("\n", pFile);
UpdatePreValueINI = false;
fclose(pFile);
}
@@ -149,22 +233,19 @@ void ClassFlowPostProcessing::SavePreValue(float value, string zwtime)
ClassFlowPostProcessing::ClassFlowPostProcessing(std::vector<ClassFlow*>* lfc)
{
FlowRateAct = 0;
// FlowRateAct = 0;
PreValueUse = false;
PreValueAgeStartup = 30;
AllowNegativeRates = false;
MaxRateValue = 0.1;
ErrorMessage = false;
ListFlowControll = NULL;
PreValueOkay = false;
useMaxRateValue = false;
checkDigitIncreaseConsistency = false;
DecimalShift = 0;
ErrorMessageText = "";
timeStamp = "";
// PreValueOkay = false;
// DecimalShift = 0;
// ErrorMessageText = "";
// timeStamp = "";
FilePreValue = FormatFileName("/sdcard/config/prevalue.ini");
ListFlowControll = lfc;
flowMakeImage = NULL;
UpdatePreValueINI = false;
for (int i = 0; i < ListFlowControll->size(); ++i)
{
@@ -175,10 +256,82 @@ ClassFlowPostProcessing::ClassFlowPostProcessing(std::vector<ClassFlow*>* lfc)
}
}
void ClassFlowPostProcessing::handleDecimalSeparator(string _decsep, string _value)
{
string _digit, _decpos;
int _pospunkt = _decsep.find_first_of(".");
// printf("Name: %s, Pospunkt: %d\n", _decsep.c_str(), _pospunkt);
if (_pospunkt > -1)
_digit = _decsep.substr(0, _pospunkt);
else
_digit = "default";
for (int j = 0; j < NUMBERS.size(); ++j)
{
int _zwdc = 0;
try
{
_zwdc = stoi(_value);
}
catch(const std::exception& e)
{
printf("ERROR - Decimalshift is not a number: %s\n", _value.c_str());
}
if (_digit == "default") // erstmal auf default setzen (falls sonst nichts gesetzt)
NUMBERS[j]->DecimalShift = _zwdc;
if (NUMBERS[j]->name == _digit)
NUMBERS[j]->DecimalShift = _zwdc;
NUMBERS[j]->Nachkomma = NUMBERS[j]->AnzahlAnalog - NUMBERS[j]->DecimalShift;
}
}
void ClassFlowPostProcessing::handleMaxRateValue(string _decsep, string _value)
{
string _digit, _decpos;
int _pospunkt = _decsep.find_first_of(".");
// printf("Name: %s, Pospunkt: %d\n", _decsep.c_str(), _pospunkt);
if (_pospunkt > -1)
_digit = _decsep.substr(0, _pospunkt);
else
_digit = "default";
for (int j = 0; j < NUMBERS.size(); ++j)
{
float _zwdc = 1;
try
{
_zwdc = stof(_value);
}
catch(const std::exception& e)
{
printf("ERROR - MaxRateValue is not a number: %s\n", _value.c_str());
}
if (_digit == "default") // erstmal auf default setzen (falls sonst nichts gesetzt)
{
NUMBERS[j]->useMaxRateValue = true;
NUMBERS[j]->MaxRateValue = _zwdc;
}
if (NUMBERS[j]->name == _digit)
{
NUMBERS[j]->useMaxRateValue = true;
NUMBERS[j]->MaxRateValue = _zwdc;
}
}
}
bool ClassFlowPostProcessing::ReadParameter(FILE* pfile, string& aktparamgraph)
{
std::vector<string> zerlegt;
int _n;
aktparamgraph = trim(aktparamgraph);
@@ -190,53 +343,148 @@ bool ClassFlowPostProcessing::ReadParameter(FILE* pfile, string& aktparamgraph)
if (aktparamgraph.compare("[PostProcessing]") != 0) // Paragraph passt nich zu MakeImage
return false;
InitNUMBERS();
while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph))
{
zerlegt = this->ZerlegeZeile(aktparamgraph);
if ((toUpper(zerlegt[0]) == "DECIMALSHIFT") && (zerlegt.size() > 1))
std::string _param = GetParameterName(zerlegt[0]);
if ((toUpper(_param) == "DECIMALSHIFT") && (zerlegt.size() > 1))
{
DecimalShift = stoi(zerlegt[1]);
handleDecimalSeparator(zerlegt[0], zerlegt[1]);
}
if ((toUpper(_param) == "MAXRATEVALUE") && (zerlegt.size() > 1))
{
handleMaxRateValue(zerlegt[0], zerlegt[1]);
}
if ((toUpper(zerlegt[0]) == "PREVALUEUSE") && (zerlegt.size() > 1))
if ((toUpper(_param) == "PREVALUEUSE") && (zerlegt.size() > 1))
{
if (toUpper(zerlegt[1]) == "TRUE")
{
PreValueUse = true;
}
}
if ((toUpper(zerlegt[0]) == "CHECKDIGITINCREASECONSISTENCY") && (zerlegt.size() > 1))
if ((toUpper(_param) == "CHECKDIGITINCREASECONSISTENCY") && (zerlegt.size() > 1))
{
if (toUpper(zerlegt[1]) == "TRUE")
checkDigitIncreaseConsistency = true;
for (_n = 0; _n < NUMBERS.size(); ++_n)
NUMBERS[_n]->checkDigitIncreaseConsistency = true;
}
if ((toUpper(zerlegt[0]) == "ALLOWNEGATIVERATES") && (zerlegt.size() > 1))
if ((toUpper(_param) == "ALLOWNEGATIVERATES") && (zerlegt.size() > 1))
{
if (toUpper(zerlegt[1]) == "TRUE")
AllowNegativeRates = true;
for (_n = 0; _n < NUMBERS.size(); ++_n)
NUMBERS[_n]->AllowNegativeRates = true;
}
if ((toUpper(zerlegt[0]) == "ERRORMESSAGE") && (zerlegt.size() > 1))
if ((toUpper(_param) == "ERRORMESSAGE") && (zerlegt.size() > 1))
{
if (toUpper(zerlegt[1]) == "TRUE")
ErrorMessage = true;
}
if ((toUpper(zerlegt[0]) == "PREVALUEAGESTARTUP") && (zerlegt.size() > 1))
if ((toUpper(_param) == "PREVALUEAGESTARTUP") && (zerlegt.size() > 1))
{
PreValueAgeStartup = std::stoi(zerlegt[1]);
}
if ((toUpper(zerlegt[0]) == "MAXRATEVALUE") && (zerlegt.size() > 1))
{
useMaxRateValue = true;
MaxRateValue = std::stof(zerlegt[1]);
}
}
if (PreValueUse) {
PreValueOkay = LoadPreValue();
LoadPreValue();
}
return true;
}
void ClassFlowPostProcessing::InitNUMBERS()
{
// ClassFlowDigit* _cdigit = NULL;
// ClassFlowAnalog* _canalog = NULL;
int anzDIGIT = 0;
int anzANALOG = 0;
std::vector<std::string> name_numbers;
flowAnalog = NULL;
flowDigit = NULL;
for (int i = 0; i < ListFlowControll->size(); ++i)
{
if (((*ListFlowControll)[i])->name().compare("ClassFlowDigit") == 0)
{
flowDigit = (ClassFlowDigit*) (*ListFlowControll)[i];
anzDIGIT = flowDigit->getAnzahlDIGIT();
}
if (((*ListFlowControll)[i])->name().compare("ClassFlowAnalog") == 0)
{
flowAnalog = (ClassFlowAnalog*)(*ListFlowControll)[i];
anzANALOG = flowAnalog->getAnzahlANALOG();
}
}
if (flowDigit)
flowDigit->UpdateNameNumbers(&name_numbers);
if (flowAnalog)
flowAnalog->UpdateNameNumbers(&name_numbers);
printf("Anzahl NUMBERS: %d - DIGITS: %d, ANALOG: %d\n", name_numbers.size(), anzDIGIT, anzANALOG);
for (int _num = 0; _num < name_numbers.size(); ++_num)
{
NumberPost *_number = new NumberPost;
_number->name = name_numbers[_num];
_number->digit_roi = NULL;
if (flowDigit)
_number->digit_roi = flowDigit->FindDIGIT(name_numbers[_num]);
if (_number->digit_roi)
_number->AnzahlDigital = _number->digit_roi->ROI.size();
else
_number->AnzahlDigital = 0;
_number->analog_roi = NULL;
if (flowAnalog)
_number->analog_roi = flowAnalog->FindANALOG(name_numbers[_num]);
if (_number->analog_roi)
_number->AnzahlAnalog = _number->analog_roi->ROI.size();
else
_number->AnzahlAnalog = 0;
_number->ReturnRawValue = ""; // Rohwert (mit N & führenden 0)
_number->ReturnValue = ""; // korrigierter Rückgabewert, ggf. mit Fehlermeldung
_number->ReturnValueNoError = ""; // korrigierter Rückgabewert ohne Fehlermeldung
_number->ErrorMessageText = ""; // Fehlermeldung bei Consistency Check
_number->ReturnPreValue = "";
_number->PreValueOkay = false;
_number->AllowNegativeRates = false;
_number->MaxRateValue = 0.1;
_number->useMaxRateValue = false;
_number->checkDigitIncreaseConsistency = false;
_number->PreValueOkay = false;
_number->useMaxRateValue = false;
_number->DecimalShift = 0;
_number->FlowRateAct = 0; // m3 / min
_number->PreValue = 0; // letzter Wert, der gut ausgelesen wurde
_number->Value = 0; // letzer ausgelesener Wert, inkl. Korrekturen
_number->ReturnRawValue = ""; // Rohwert (mit N & führenden 0)
_number->ReturnValue = ""; // korrigierter Rückgabewert, ggf. mit Fehlermeldung
_number->ReturnValueNoError = ""; // korrigierter Rückgabewert ohne Fehlermeldung
_number->ErrorMessageText = ""; // Fehlermeldung bei Consistency Check
_number->Nachkomma = _number->AnzahlAnalog;
NUMBERS.push_back(_number);
}
for (int i = 0; i < NUMBERS.size(); ++i)
printf("Number %s, Anz DIG: %d, Anz ANA %d\n", NUMBERS[i]->name.c_str(), NUMBERS[i]->AnzahlDigital, NUMBERS[i]->AnzahlAnalog);
}
string ClassFlowPostProcessing::ShiftDecimal(string in, int _decShift){
if (_decShift == 0){
@@ -285,173 +533,127 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
string digit = "";
string analog = "";
string zwvalue;
bool isdigit = false;
bool isanalog = false;
int AnzahlAnalog = 0;
string zw;
time_t imagetime = 0;
string rohwert;
ErrorMessageText = "";
for (int i = 0; i < ListFlowControll->size(); ++i)
{
if (((*ListFlowControll)[i])->name().compare("ClassFlowMakeImage") == 0)
{
imagetime = ((ClassFlowMakeImage*)(*ListFlowControll)[i])->getTimeImageTaken();
}
if (((*ListFlowControll)[i])->name().compare("ClassFlowDigit") == 0)
{
isdigit = true;
digit = (*ListFlowControll)[i]->getReadout();
}
if (((*ListFlowControll)[i])->name().compare("ClassFlowAnalog") == 0)
{
isanalog = true;
analog = (*ListFlowControll)[i]->getReadout();
AnzahlAnalog = ((ClassFlowAnalog*)(*ListFlowControll)[i])->AnzahlROIs();
}
}
// ErrorMessageText = "";
imagetime = flowMakeImage->getTimeImageTaken();
if (imagetime == 0)
time(&imagetime);
struct tm* timeinfo;
timeinfo = localtime(&imagetime);
char strftime_buf[64];
strftime(strftime_buf, sizeof(strftime_buf), "%Y-%m-%dT%H:%M:%S", timeinfo);
zwtime = std::string(strftime_buf);
printf("Anzahl NUMBERS: %d\n", NUMBERS.size());
// // TESTING ONLY////////////////////
// isdigit = true; digit = "12N";
// isanalog = true; analog = "456";
ReturnRawValue = "";
if (isdigit)
ReturnRawValue = digit;
if (isdigit && isanalog)
ReturnRawValue = ReturnRawValue + ".";
if (isanalog)
ReturnRawValue = ReturnRawValue + analog;
if (!isdigit)
for (int j = 0; j < NUMBERS.size(); ++j)
{
AnzahlAnalog = 0;
}
NUMBERS[j]->ReturnRawValue = "";
NUMBERS[j]->ErrorMessageText = "";
ReturnRawValue = ShiftDecimal(ReturnRawValue, DecimalShift);
if (NUMBERS[j]->digit_roi)
NUMBERS[j]->ReturnRawValue = flowDigit->getReadout(j);
if (NUMBERS[j]->digit_roi && NUMBERS[j]->analog_roi)
NUMBERS[j]->ReturnRawValue = NUMBERS[j]->ReturnRawValue + ".";
if (NUMBERS[j]->analog_roi)
NUMBERS[j]->ReturnRawValue = NUMBERS[j]->ReturnRawValue + flowAnalog->getReadout(j);
rohwert = ReturnRawValue;
NUMBERS[j]->ReturnRawValue = ShiftDecimal(NUMBERS[j]->ReturnRawValue, NUMBERS[j]->DecimalShift);
if (!PreValueUse || !PreValueOkay)
{
ReturnValue = ReturnRawValue;
ReturnValueNoError = ReturnRawValue;
rohwert = NUMBERS[j]->ReturnRawValue;
if ((findDelimiterPos(ReturnValue, "N") == std::string::npos) && (ReturnValue.length() > 0))
if (!PreValueUse || !NUMBERS[j]->PreValueOkay)
{
while ((ReturnValue.length() > 1) && (ReturnValue[0] == '0'))
{
ReturnValue.erase(0, 1);
}
Value = std::stof(ReturnValue);
ReturnValueNoError = ReturnValue;
NUMBERS[j]->ReturnValue = NUMBERS[j]->ReturnRawValue;
NUMBERS[j]->ReturnValueNoError = NUMBERS[j]->ReturnRawValue;
PreValueOkay = true;
PreValue = Value;
if (flowMakeImage)
if ((findDelimiterPos(NUMBERS[j]->ReturnValue, "N") == std::string::npos) && (NUMBERS[j]->ReturnValue.length() > 0))
{
lastvalue = flowMakeImage->getTimeImageTaken();
zwtime = ConvertTimeToString(lastvalue, PREVALUE_TIME_FORMAT_OUTPUT);
}
else
{
time(&lastvalue);
localtime(&lastvalue);
}
while ((NUMBERS[j]->ReturnValue.length() > 1) && (NUMBERS[j]->ReturnValue[0] == '0'))
{
NUMBERS[j]->ReturnValue.erase(0, 1);
}
NUMBERS[j]->Value = std::stof(NUMBERS[j]->ReturnValue);
NUMBERS[j]->ReturnValueNoError = NUMBERS[j]->ReturnValue;
SavePreValue(Value, zwtime);
NUMBERS[j]->PreValueOkay = true;
NUMBERS[j]->PreValue = NUMBERS[j]->Value;
NUMBERS[j]->ReturnPreValue = RundeOutput(NUMBERS[j]->PreValue, NUMBERS[j]->Nachkomma);
NUMBERS[j]->lastvalue = flowMakeImage->getTimeImageTaken();
zwtime = ConvertTimeToString(NUMBERS[j]->lastvalue, PREVALUE_TIME_FORMAT_OUTPUT);
UpdatePreValueINI = true;
SavePreValue();
}
}
else
{
zw = ErsetzteN(NUMBERS[j]->ReturnRawValue, NUMBERS[j]->PreValue);
NUMBERS[j]->Value = std::stof(zw);
if (NUMBERS[j]->checkDigitIncreaseConsistency)
{
NUMBERS[j]->Value = checkDigitConsistency(NUMBERS[j]->Value, NUMBERS[j]->DecimalShift, NUMBERS[j]->analog_roi != NULL, NUMBERS[j]->PreValue);
}
zwvalue = RundeOutput(NUMBERS[j]->Value, NUMBERS[j]->AnzahlAnalog - NUMBERS[j]->DecimalShift);
if ((!NUMBERS[j]->AllowNegativeRates) && (NUMBERS[j]->Value < NUMBERS[j]->PreValue))
{
NUMBERS[j]->ErrorMessageText = NUMBERS[j]->ErrorMessageText + "Neg. Rate - Read: " + zwvalue + " - Raw: " + NUMBERS[j]->ReturnRawValue + " - Pre: " + RundeOutput(NUMBERS[j]->PreValue, NUMBERS[j]->Nachkomma) + " ";
NUMBERS[j]->Value = NUMBERS[j]->PreValue;
zwvalue = RundeOutput(NUMBERS[j]->Value, NUMBERS[j]->AnzahlAnalog - NUMBERS[j]->DecimalShift);
}
if (NUMBERS[j]->useMaxRateValue && (abs(NUMBERS[j]->Value - NUMBERS[j]->PreValue) > NUMBERS[j]->MaxRateValue))
{
NUMBERS[j]->ErrorMessageText = NUMBERS[j]->ErrorMessageText + "Rate too high - Read: " + RundeOutput(NUMBERS[j]->Value, NUMBERS[j]->Nachkomma) + " - Pre: " + RundeOutput(NUMBERS[j]->PreValue, NUMBERS[j]->Nachkomma);
NUMBERS[j]->Value = NUMBERS[j]->PreValue;
zwvalue = RundeOutput(NUMBERS[j]->Value, NUMBERS[j]->Nachkomma);
}
NUMBERS[j]->ReturnValueNoError = zwvalue;
NUMBERS[j]->ReturnValue = zwvalue;
if (NUMBERS[j]->ErrorMessage && (NUMBERS[j]->ErrorMessageText.length() > 0))
NUMBERS[j]->ReturnValue = NUMBERS[j]->ReturnValue + "\t" + NUMBERS[j]->ErrorMessageText;
double difference = difftime(imagetime, NUMBERS[j]->lastvalue); // in Sekunden
difference /= 60; // in Minuten
NUMBERS[j]->FlowRateAct = (NUMBERS[j]->Value - NUMBERS[j]->PreValue) / difference;
NUMBERS[j]->lastvalue = imagetime;
if (NUMBERS[j]->ErrorMessageText.length() == 0)
{
NUMBERS[j]->PreValue = NUMBERS[j]->Value;
NUMBERS[j]->ReturnPreValue = RundeOutput(NUMBERS[j]->PreValue, NUMBERS[j]->Nachkomma);
NUMBERS[j]->ErrorMessageText = "no error";
UpdatePreValueINI = true;
}
}
return true;
}
zw = ErsetzteN(ReturnRawValue);
Value = std::stof(zw);
if (checkDigitIncreaseConsistency)
{
Value = checkDigitConsistency(Value, DecimalShift, isanalog);
}
zwvalue = RundeOutput(Value, AnzahlAnalog - DecimalShift);
if ((!AllowNegativeRates) && (Value < PreValue))
{
ErrorMessageText = ErrorMessageText + "Negative Rate - Returned old value - read value: " + zwvalue + " - raw value: " + ReturnRawValue + " - checked value: " + std::to_string(Value) + " ";
Value = PreValue;
zwvalue = RundeOutput(Value, AnzahlAnalog - DecimalShift);
}
if (useMaxRateValue && (abs(Value - PreValue) > MaxRateValue))
{
ErrorMessageText = ErrorMessageText + "Rate too high - Returned old value - read value: " + zwvalue + " - checked value: " + RundeOutput(Value, AnzahlAnalog - DecimalShift) + " ";
Value = PreValue;
zwvalue = RundeOutput(Value, AnzahlAnalog - DecimalShift);
}
ReturnValueNoError = zwvalue;
ReturnValue = zwvalue;
if (ErrorMessage && (ErrorMessageText.length() > 0))
ReturnValue = ReturnValue + "\t" + ErrorMessageText;
time_t currenttime;
if (flowMakeImage)
{
currenttime = flowMakeImage->getTimeImageTaken();
zwtime = ConvertTimeToString(currenttime, PREVALUE_TIME_FORMAT_OUTPUT);
}
else
{
time(&currenttime);
localtime(&currenttime);
}
double difference = difftime(currenttime, lastvalue); // in Sekunden
difference /= 60; // in Minuten
FlowRateAct = (Value - PreValue) / difference;
lastvalue = currenttime;
// std::string _zw = "CalcRate: " + std::to_string(FlowRateAct) + " TimeDifference[min]: " + std::to_string(difference);
// _zw = _zw + " Value: " + std::to_string(Value) + " PreValue: " + std::to_string(PreValue);
// LogFile.WriteToFile(_zw);
if (ErrorMessageText.length() == 0)
{
PreValue = Value;
ErrorMessageText = "no error";
SavePreValue(Value, zwtime);
}
SavePreValue();
return true;
}
string ClassFlowPostProcessing::getReadout()
string ClassFlowPostProcessing::getReadout(int _number)
{
return ReturnValue;
return NUMBERS[_number]->ReturnValue;
}
string ClassFlowPostProcessing::getReadoutParam(bool _rawValue, bool _noerror)
string ClassFlowPostProcessing::getReadoutParam(bool _rawValue, bool _noerror, int _number)
{
if (_rawValue)
return ReturnRawValue;
return NUMBERS[_number]->ReturnRawValue;
if (_noerror)
return ReturnValueNoError;
return ReturnValue;
return NUMBERS[_number]->ReturnValueNoError;
return NUMBERS[_number]->ReturnValue;
}
string ClassFlowPostProcessing::RundeOutput(float _in, int _anzNachkomma){
@@ -478,7 +680,7 @@ string ClassFlowPostProcessing::RundeOutput(float _in, int _anzNachkomma){
}
string ClassFlowPostProcessing::ErsetzteN(string input)
string ClassFlowPostProcessing::ErsetzteN(string input, float _prevalue)
{
int posN, posPunkt;
int pot, ziffer;
@@ -499,7 +701,7 @@ string ClassFlowPostProcessing::ErsetzteN(string input)
pot = posPunkt - posN;
}
zw = PreValue / pow(10, pot);
zw =_prevalue / pow(10, pot);
ziffer = ((int) zw) % 10;
input[posN] = ziffer + 48;
@@ -509,7 +711,7 @@ string ClassFlowPostProcessing::ErsetzteN(string input)
return input;
}
float ClassFlowPostProcessing::checkDigitConsistency(float input, int _decilamshift, bool _isanalog){
float ClassFlowPostProcessing::checkDigitConsistency(float input, int _decilamshift, bool _isanalog, float _preValue){
int aktdigit, olddigit;
int aktdigit_before, olddigit_before;
int pot, pot_max;
@@ -527,12 +729,12 @@ float ClassFlowPostProcessing::checkDigitConsistency(float input, int _decilamsh
{
zw = input / pow(10, pot-1);
aktdigit_before = ((int) zw) % 10;
zw = PreValue / pow(10, pot-1);
zw = _preValue / pow(10, pot-1);
olddigit_before = ((int) zw) % 10;
zw = input / pow(10, pot);
aktdigit = ((int) zw) % 10;
zw = PreValue / pow(10, pot);
zw = _preValue / pow(10, pot);
olddigit = ((int) zw) % 10;
no_nulldurchgang = (olddigit_before <= aktdigit_before);
@@ -558,18 +760,18 @@ float ClassFlowPostProcessing::checkDigitConsistency(float input, int _decilamsh
return input;
}
string ClassFlowPostProcessing::getReadoutRate()
string ClassFlowPostProcessing::getReadoutRate(int _number)
{
return std::to_string(FlowRateAct);
return std::to_string(NUMBERS[_number]->FlowRateAct);
}
string ClassFlowPostProcessing::getReadoutTimeStamp()
string ClassFlowPostProcessing::getReadoutTimeStamp(int _number)
{
return timeStamp;
return NUMBERS[_number]->timeStamp;
}
string ClassFlowPostProcessing::getReadoutError()
string ClassFlowPostProcessing::getReadoutError(int _number)
{
return ErrorMessageText;
return NUMBERS[_number]->ErrorMessageText;
}

View File

@@ -1,58 +1,94 @@
#pragma once
#include "ClassFlow.h"
#include "ClassFlowMakeImage.h"
#include "ClassFlowAnalog.h"
#include "ClassFlowDigit.h"
#include <string>
struct NumberPost {
// int PreValueAgeStartup;
float MaxRateValue;
bool useMaxRateValue;
bool ErrorMessage;
bool PreValueOkay;
bool AllowNegativeRates;
bool checkDigitIncreaseConsistency;
time_t lastvalue;
string timeStamp;
float FlowRateAct; // m3 / min
float PreValue; // letzter Wert, der gut ausgelesen wurde
float Value; // letzer ausgelesener Wert, inkl. Korrekturen
string ReturnRawValue; // Rohwert (mit N & führenden 0)
string ReturnValue; // korrigierter Rückgabewert, ggf. mit Fehlermeldung
string ReturnPreValue; // korrigierter Rückgabewert ohne Fehlermeldung
string ReturnValueNoError;
string ErrorMessageText; // Fehlermeldung bei Consistency Check
int AnzahlAnalog;
int AnzahlDigital;
int DecimalShift;
int Nachkomma;
// ClassFlowAnalog* ANALOG;
// ClassFlowDigit* DIGIT;
digit *digit_roi;
analog *analog_roi;
string name;
};
class ClassFlowPostProcessing :
public ClassFlow
{
protected:
std::vector<NumberPost*> NUMBERS;
bool UpdatePreValueINI;
bool PreValueUse;
int PreValueAgeStartup;
bool AllowNegativeRates;
float MaxRateValue;
bool useMaxRateValue;
bool ErrorMessage;
bool PreValueOkay;
bool checkDigitIncreaseConsistency;
int DecimalShift;
time_t lastvalue;
float FlowRateAct; // m3 / min
ClassFlowAnalog* flowAnalog;
ClassFlowDigit* flowDigit;
string FilePreValue;
float PreValue; // letzter Wert, der gut ausgelesen wurde
float Value; // letzer ausgelesener Wert, inkl. Korrekturen
string ReturnRawValue; // Rohwert (mit N & führenden 0)
string ReturnValue; // korrigierter Rückgabewert, ggf. mit Fehlermeldung
string ReturnValueNoError; // korrigierter Rückgabewert ohne Fehlermeldung
string ErrorMessageText; // Fehlermeldung bei Consistency Check
string timeStamp;
ClassFlowMakeImage *flowMakeImage;
bool LoadPreValue(void);
string ShiftDecimal(string in, int _decShift);
string ErsetzteN(string);
float checkDigitConsistency(float input, int _decilamshift, bool _isanalog);
string ErsetzteN(string, float _prevalue);
float checkDigitConsistency(float input, int _decilamshift, bool _isanalog, float _preValue);
string RundeOutput(float _in, int _anzNachkomma);
void InitNUMBERS();
void handleDecimalSeparator(string _decsep, string _value);
void handleMaxRateValue(string _decsep, string _value);
public:
ClassFlowPostProcessing(std::vector<ClassFlow*>* lfc);
bool ReadParameter(FILE* pfile, string& aktparamgraph);
bool doFlow(string time);
string getReadout();
string getReadoutParam(bool _rawValue, bool _noerror);
string getReadoutError();
string getReadoutRate();
string getReadoutTimeStamp();
void SavePreValue(float value, string time = "");
string GetPreValue();
string getReadout(int _number);
string getReadoutParam(bool _rawValue, bool _noerror, int _number = 0);
string getReadoutError(int _number = 0);
string getReadoutRate(int _number = 0);
string getReadoutTimeStamp(int _number = 0);
void SavePreValue();
string GetPreValue(std::string _number = "");
void SetPreValue(float zw, string _numbers, bool _extern = false);
std::vector<NumberPost*> GetNumbers(){return NUMBERS;};
string name(){return "ClassFlowPostProcessing";};
};

View File

@@ -10,6 +10,7 @@
#include <string.h>
#include <esp_log.h>
#include "ClassLogFile.h"
//#include "ClassLogFile.h"
@@ -77,8 +78,9 @@ void memCopyGen(uint8_t* _source, uint8_t* _target, int _size)
FILE* OpenFileAndWait(const char* nm, char* _mode, int _waitsec)
FILE* OpenFileAndWait(const char* nm, const char* _mode, int _waitsec)
{
printf("open config file %s in mode %s\n", nm, _mode);
FILE *pfile = fopen(nm, _mode);
if (pfile == NULL)
@@ -313,6 +315,14 @@ string toUpper(string in)
return in;
}
string toLower(string in)
{
for (int i = 0; i < in.length(); ++i)
in[i] = tolower(in[i]);
return in;
}
// CPU Temp
extern "C" uint8_t temprature_sens_read();
float temperatureRead()
@@ -358,3 +368,30 @@ int removeFolder(const char* folderPath, const char* logTag) {
return deleted;
}
std::vector<string> HelperZerlegeZeile(std::string input, std::string _delimiter = "")
{
std::vector<string> Output;
std::string delimiter = " =,";
if (_delimiter.length() > 0){
delimiter = _delimiter;
}
input = trim(input, delimiter);
size_t pos = findDelimiterPos(input, delimiter);
std::string token;
while (pos != std::string::npos) {
token = input.substr(0, pos);
token = trim(token, delimiter);
Output.push_back(token);
input.erase(0, pos + 1);
input = trim(input, delimiter);
pos = findDelimiterPos(input, delimiter);
}
Output.push_back(input);
return Output;
}

View File

@@ -1,6 +1,7 @@
#pragma once
#include <string>
#include <fstream>
#include <vector>
using namespace std;
@@ -10,7 +11,7 @@ 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);
FILE* OpenFileAndWait(const char* nm, const char* _mode, int _waitsec = 1);
size_t findDelimiterPos(string input, string delimiter);
//string trim(string istring);
@@ -22,6 +23,7 @@ string getFileType(string filename);
int mkdir_r(const char *dir, const mode_t mode);
int removeFolder(const char* folderPath, const char* logTag);
string toLower(string in);
string toUpper(string in);
float temperatureRead();
@@ -30,6 +32,8 @@ time_t addDays(time_t startTime, int days);
void memCopyGen(uint8_t* _source, uint8_t* _target, int _size);
std::vector<string> HelperZerlegeZeile(std::string input, std::string _delimiter);
///////////////////////////
size_t getInternalESPHeapSize();
size_t getESPHeapSize();

View File

@@ -354,12 +354,10 @@ CImageBasis::CImageBasis(CImageBasis *_copyfrom, int _anzrepeat)
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;
printf("Create Image from Copy - Speicher ist voll - Versuche es erneut: %d.\n", anz);
rgb_image = (unsigned char*) malloc(memsize);
anz++;
}

View File

@@ -12,7 +12,7 @@ ClassLogFile LogFile("/sdcard/log/message", "log_%Y-%m-%d.txt");
void ClassLogFile::WriteHeapInfo(std::string _id)
{
std::string _zw = "\t" + _id;
std::string _zw = "\t" + _id;
if (loglevel > 0)
_zw = _zw + "\t" + getESPHeapInfo();

View File

@@ -1,12 +1,14 @@
#include "interface_mqtt.h"
//#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
#include "esp_log.h"
#include "mqtt_client.h"
#include "ClassLogFile.h"
static const char *TAG = "interface_mqtt";
static const char *TAG_INTERFACEMQTT = "interface_mqtt";
std::map<std::string, std::function<void()>>* connectFunktionMap = NULL;
std::map<std::string, std::function<bool(std::string, char*, int)>>* subscribeFunktionMap = NULL;
bool debugdetail = true;
// #define CONFIG_BROKER_URL "mqtt://192.168.178.43:1883"
@@ -23,44 +25,67 @@ void MQTTPublish(std::string _key, std::string _content, int retained_flag){
msg_id = esp_mqtt_client_publish(client, _key.c_str(), _content.c_str(), 0, 1, retained_flag);
zw = "sent publish successful in MQTTPublish, msg_id=" + std::to_string(msg_id) + ", " + _key + ", " + _content;
if (debugdetail) LogFile.WriteToFile(zw);
ESP_LOGI(TAG, "sent publish successful in MQTTPublish, msg_id=%d, %s, %s", msg_id, _key.c_str(), _content.c_str());
ESP_LOGD(TAG_INTERFACEMQTT, "sent publish successful in MQTTPublish, msg_id=%d, %s, %s", msg_id, _key.c_str(), _content.c_str());
}
else {
ESP_LOGI(TAG, "Problem with Publish, client=%d, mqtt_connected %d", (int) client, (int) mqtt_connected);
ESP_LOGW(TAG_INTERFACEMQTT, "Problem with Publish, client=%d, mqtt_connected %d", (int) client, (int) mqtt_connected);
}
}
static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event)
{
int msg_id;
std::string topic = "";
switch (event->event_id) {
case MQTT_EVENT_BEFORE_CONNECT:
ESP_LOGI(TAG_INTERFACEMQTT, "MQTT_EVENT_BEFORE_CONNECT");
break;
case MQTT_EVENT_CONNECTED:
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
ESP_LOGI(TAG_INTERFACEMQTT, "MQTT_EVENT_CONNECTED");
mqtt_connected = true;
MQTTconnected();
break;
case MQTT_EVENT_DISCONNECTED:
ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
ESP_LOGI(TAG_INTERFACEMQTT, "MQTT_EVENT_DISCONNECTED");
break;
case MQTT_EVENT_SUBSCRIBED:
ESP_LOGI(TAG_INTERFACEMQTT, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
msg_id = esp_mqtt_client_publish(client, "/topic/qos0", "data", 0, 0, 0);
ESP_LOGI(TAG_INTERFACEMQTT, "sent publish successful, msg_id=%d", msg_id);
break;
case MQTT_EVENT_UNSUBSCRIBED:
ESP_LOGI(TAG_INTERFACEMQTT, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
break;
case MQTT_EVENT_PUBLISHED:
ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
ESP_LOGI(TAG_INTERFACEMQTT, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
break;
case MQTT_EVENT_DATA:
ESP_LOGI(TAG, "MQTT_EVENT_DATA");
printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
printf("DATA=%.*s\r\n", event->data_len, event->data);
ESP_LOGI(TAG_INTERFACEMQTT, "MQTT_EVENT_DATA");
ESP_LOGI(TAG_INTERFACEMQTT, "TOPIC=%.*s\r\n", event->topic_len, event->topic);
ESP_LOGI(TAG_INTERFACEMQTT, "DATA=%.*s\r\n", event->data_len, event->data);
topic.assign(event->topic, event->topic_len);
if (subscribeFunktionMap != NULL) {
if (subscribeFunktionMap->find(topic) != subscribeFunktionMap->end()) {
ESP_LOGD(TAG_INTERFACEMQTT, "call handler function\r\n");
(*subscribeFunktionMap)[topic](topic, event->data, event->data_len);
}
} else {
ESP_LOGW(TAG_INTERFACEMQTT, "no handler available\r\n");
}
break;
case MQTT_EVENT_ERROR:
ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
ESP_LOGI(TAG_INTERFACEMQTT, "MQTT_EVENT_ERROR");
break;
default:
ESP_LOGI(TAG, "Other event id:%d", event->event_id);
ESP_LOGI(TAG_INTERFACEMQTT, "Other event id:%d", event->event_id);
break;
}
return ESP_OK;
}
static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data) {
ESP_LOGD(TAG, "Event dispatched from event loop base=%s, event_id=%d", base, event_id);
ESP_LOGD(TAG_INTERFACEMQTT, "Event dispatched from event loop base=%s, event_id=%d", base, event_id);
mqtt_event_handler_cb((esp_mqtt_event_handle_t) event_data);
}
@@ -82,7 +107,7 @@ void MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user, st
if (_user.length() && _password.length()){
mqtt_cfg.username = _user.c_str();
mqtt_cfg.password = _password.c_str();
printf("Connect to MQTT: %s, %s", mqtt_cfg.username, mqtt_cfg.password);
ESP_LOGI(TAG_INTERFACEMQTT, "Connect to MQTT: %s, %s", mqtt_cfg.username, mqtt_cfg.password);
};
client = esp_mqtt_client_init(&mqtt_cfg);
@@ -91,3 +116,91 @@ void MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user, st
MQTTPublish(_LWTContext, "", 1);
}
void MQTTdestroy() {
if (client != NULL) {
esp_mqtt_client_stop(client);
esp_mqtt_client_destroy(client);
}
}
bool MQTTisConnected() {
return mqtt_connected;
}
void MQTTregisterConnectFunction(std::string name, std::function<void()> func){
ESP_LOGD(TAG_INTERFACEMQTT, "MQTTregisteronnectFunction %s\r\n", name.c_str());
if (connectFunktionMap == NULL) {
connectFunktionMap = new std::map<std::string, std::function<void()>>();
}
if ((*connectFunktionMap)[name] != NULL) {
ESP_LOGW(TAG_INTERFACEMQTT, "connect function %s already registred", name.c_str());
return;
}
(*connectFunktionMap)[name] = func;
if (mqtt_connected) {
func();
}
}
void MQTTunregisterConnectFunction(std::string name){
ESP_LOGD(TAG_INTERFACEMQTT, "MQTTregisteronnectFunction %s\r\n", name.c_str());
if ((connectFunktionMap != NULL) && (connectFunktionMap->find(name) != connectFunktionMap->end())) {
connectFunktionMap->erase(name);
}
}
void MQTTregisterSubscribeFunction(std::string topic, std::function<bool(std::string, char*, int)> func){
ESP_LOGD(TAG_INTERFACEMQTT, "MQTTregisterSubscribeFunction %s\r\n", topic.c_str());
if (subscribeFunktionMap == NULL) {
subscribeFunktionMap = new std::map<std::string, std::function<bool(std::string, char*, int)>>();
}
if ((*subscribeFunktionMap)[topic] != NULL) {
ESP_LOGW(TAG_INTERFACEMQTT, "topic %s already registred for subscription", topic.c_str());
return;
}
(*subscribeFunktionMap)[topic] = func;
if (mqtt_connected) {
int msg_id = esp_mqtt_client_subscribe(client, topic.c_str(), 0);
ESP_LOGD(TAG_INTERFACEMQTT, "topic %s subscribe successful, msg_id=%d", topic.c_str(), msg_id);
}
}
void MQTTconnected(){
if (mqtt_connected) {
if (connectFunktionMap != NULL) {
for(std::map<std::string, std::function<void()>>::iterator it = connectFunktionMap->begin(); it != connectFunktionMap->end(); ++it) {
it->second();
ESP_LOGD(TAG_INTERFACEMQTT, "call connect function %s", it->first.c_str());
}
}
if (subscribeFunktionMap != NULL) {
for(std::map<std::string, std::function<bool(std::string, char*, int)>>::iterator it = subscribeFunktionMap->begin(); it != subscribeFunktionMap->end(); ++it) {
int msg_id = esp_mqtt_client_subscribe(client, it->first.c_str(), 0);
ESP_LOGD(TAG_INTERFACEMQTT, "topic %s subscribe successful, msg_id=%d", it->first.c_str(), msg_id);
}
}
}
}
void MQTTdestroySubscribeFunction(){
if (subscribeFunktionMap != NULL) {
if (mqtt_connected) {
for(std::map<std::string, std::function<bool(std::string, char*, int)>>::iterator it = subscribeFunktionMap->begin(); it != subscribeFunktionMap->end(); ++it) {
int msg_id = esp_mqtt_client_unsubscribe(client, it->first.c_str());
ESP_LOGI(TAG_INTERFACEMQTT, "topic %s unsubscribe successful, msg_id=%d", it->first.c_str(), msg_id);
}
}
subscribeFunktionMap->clear();
delete subscribeFunktionMap;
subscribeFunktionMap = NULL;
}
}

View File

@@ -1,7 +1,23 @@
#ifndef INTERFACE_MQTT_H
#define INTERFACE_MQTT_H
#include <string>
#include <map>
#include <functional>
void MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user, std::string _password, std::string _LWTContext, int _keepalive);
void MQTTdestroy();
//void MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user = "", std::string _password = "");
void MQTTPublish(std::string _key, std::string _content, int retained_flag = 0);
void MQTTPublish(std::string _key, std::string _content, int retained_flag = 0);
bool MQTTisConnected();
void MQTTregisterConnectFunction(std::string name, std::function<void()> func);
void MQTTunregisterConnectFunction(std::string name);
void MQTTregisterSubscribeFunction(std::string topic, std::function<bool(std::string, char*, int)> func);
void MQTTdestroySubscribeFunction();
void MQTTconnected();
#endif //INTERFACE_MQTT_H

View File

@@ -98,7 +98,8 @@ void CTfLiteClass::GetOutPut()
void CTfLiteClass::Invoke()
{
interpreter->Invoke();
if (interpreter != nullptr)
interpreter->Invoke();
}
@@ -155,9 +156,9 @@ void CTfLiteClass::MakeAllocate()
}
void CTfLiteClass::GetInputTensorSize(){
#ifdef DEBUG_DETAIL_ON
float *zw = this->input;
int test = sizeof(zw);
#ifdef DEBUG_DETAIL_ON
printf("Input Tensor Dimension: %d\n", test);
#endif
}
@@ -184,13 +185,11 @@ unsigned char* CTfLiteClass::ReadFileToCharArray(std::string _fn)
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++;
}
@@ -208,7 +207,7 @@ unsigned char* CTfLiteClass::ReadFileToCharArray(std::string _fn)
return result;
}
void CTfLiteClass::LoadModel(std::string _fn){
bool CTfLiteClass::LoadModel(std::string _fn){
#ifdef SUPRESS_TFLITE_ERRORS
this->error_reporter = new tflite::OwnMicroErrorReporter;
@@ -219,9 +218,14 @@ void CTfLiteClass::LoadModel(std::string _fn){
unsigned char *rd;
rd = ReadFileToCharArray(_fn.c_str());
if (rd == NULL)
return false;
this->model = tflite::GetModel(rd);
free(rd);
TFLITE_MINIMAL_CHECK(model != nullptr);
return true;
}

View File

@@ -56,7 +56,7 @@ class CTfLiteClass
public:
CTfLiteClass();
~CTfLiteClass();
void LoadModel(std::string _fn);
bool LoadModel(std::string _fn);
void MakeAllocate();
void GetInputTensorSize();
bool LoadInputImageBasis(CImageBasis *rs);

View File

@@ -8,6 +8,7 @@
#include <iomanip>
#include <sstream>
#include "defines.h"
#include "Helper.h"
#include "esp_camera.h"
@@ -17,8 +18,9 @@
#include "ClassFlowControll.h"
#include "ClassLogFile.h"
#include "server_GPIO.h"
//#define DEBUG_DETAIL_ON
// #define DEBUG_DETAIL_ON
ClassFlowControll tfliteflow;
@@ -37,6 +39,9 @@ bool auto_isrunning = false;
int countRounds = 0;
static const char *TAGTFLITE = "server_tflite";
int getCountFlowRounds() {
return countRounds;
}
@@ -64,9 +69,11 @@ void KillTFliteTasks()
#ifdef DEBUG_DETAIL_ON
printf("Handle: xHandleblink_task_doFlow: %ld\n", (long) xHandleblink_task_doFlow);
#endif
if (xHandleblink_task_doFlow)
if (xHandleblink_task_doFlow != NULL)
{
vTaskDelete(xHandleblink_task_doFlow);
TaskHandle_t xHandleblink_task_doFlowTmp = xHandleblink_task_doFlow;
xHandleblink_task_doFlow = NULL;
vTaskDelete(xHandleblink_task_doFlowTmp);
#ifdef DEBUG_DETAIL_ON
printf("Killed: xHandleblink_task_doFlow\n");
#endif
@@ -75,9 +82,11 @@ void KillTFliteTasks()
#ifdef DEBUG_DETAIL_ON
printf("Handle: xHandletask_autodoFlow: %ld\n", (long) xHandletask_autodoFlow);
#endif
if (xHandletask_autodoFlow)
if (xHandletask_autodoFlow != NULL)
{
vTaskDelete(xHandletask_autodoFlow);
TaskHandle_t xHandletask_autodoFlowTmp = xHandletask_autodoFlow;
xHandletask_autodoFlow = NULL;
vTaskDelete(xHandletask_autodoFlowTmp);
#ifdef DEBUG_DETAIL_ON
printf("Killed: xHandletask_autodoFlow\n");
#endif
@@ -87,11 +96,10 @@ 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);
tfliteflow.InitFlow(CONFIG_FILE);
#ifdef DEBUG_DETAIL_ON
printf("Finished tfliteflow.InitFlow(config);\n");
#endif
@@ -136,7 +144,7 @@ esp_err_t handler_init(httpd_req_t *req)
printf("handler_doinit uri:\n"); printf(req->uri); printf("\n");
#endif
char* resp_str = "Init started<br>";
const char* resp_str = "Init started<br>";
httpd_resp_send(req, resp_str, strlen(resp_str));
doInit();
@@ -159,8 +167,6 @@ esp_err_t handler_doflow(httpd_req_t *req)
LogFile.WriteHeapInfo("handler_doflow - Start");
#endif
char* resp_str;
printf("handler_doFlow uri: "); printf(req->uri); printf("\n");
if (flowisrunning)
@@ -173,7 +179,7 @@ esp_err_t handler_doflow(httpd_req_t *req)
{
xTaskCreate(&blink_task_doFlow, "blink_doFlow", configMINIMAL_STACK_SIZE * 64, NULL, tskIDLE_PRIORITY+1, &xHandleblink_task_doFlow);
}
resp_str = "doFlow gestartet - dauert ca. 60 Sekunden";
const char* resp_str = "doFlow gestartet - dauert ca. 60 Sekunden";
httpd_resp_send(req, resp_str, strlen(resp_str));
/* Respond with an empty chunk to signal HTTP response completion */
httpd_resp_send_chunk(req, NULL, 0);
@@ -196,6 +202,8 @@ esp_err_t handler_wasserzaehler(httpd_req_t *req)
bool _rawValue = false;
bool _noerror = false;
bool _all = false;
std::string _type = "value";
string zw;
printf("handler_wasserzaehler uri:\n"); printf(req->uri); printf("\n");
@@ -206,6 +214,22 @@ esp_err_t handler_wasserzaehler(httpd_req_t *req)
if (httpd_req_get_url_query_str(req, _query, 100) == ESP_OK)
{
// printf("Query: "); printf(_query); printf("\n");
if (httpd_query_key_value(_query, "all", _size, 10) == ESP_OK)
{
#ifdef DEBUG_DETAIL_ON
printf("all is found"); printf(_size); printf("\n");
#endif
_all = true;
}
if (httpd_query_key_value(_query, "type", _size, 10) == ESP_OK)
{
#ifdef DEBUG_DETAIL_ON
printf("all is found"); printf(_size); printf("\n");
#endif
_type = std::string(_size);
}
if (httpd_query_key_value(_query, "rawvalue", _size, 10) == ESP_OK)
{
#ifdef DEBUG_DETAIL_ON
@@ -222,6 +246,29 @@ esp_err_t handler_wasserzaehler(httpd_req_t *req)
}
}
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
if (_all)
{
httpd_resp_set_type(req, "text/plain");
printf("TYPE: %s\n", _type.c_str());
int _intype = READOUT_TYPE_VALUE;
if (_type == "prevalue")
_intype = READOUT_TYPE_PREVALUE;
if (_type == "raw")
_intype = READOUT_TYPE_RAWVALUE;
if (_type == "error")
_intype = READOUT_TYPE_ERROR;
zw = tfliteflow.getReadoutAll(_intype);
printf("ZW: %s\n", zw.c_str());
if (zw.length() > 0)
httpd_resp_sendstr_chunk(req, zw.c_str());
httpd_resp_sendstr_chunk(req, NULL);
return ESP_OK;
}
zw = tfliteflow.getReadout(_rawValue, _noerror);
if (zw.length() > 0)
httpd_resp_sendstr_chunk(req, zw.c_str());
@@ -429,7 +476,7 @@ esp_err_t handler_editflow(httpd_req_t *req)
// printf("Parameter host: "); printf(_host.c_str()); printf("\n");
// string zwzw = "Do " + _task + " start\n"; printf(zwzw.c_str());
bool changed = Camera.SetBrightnessContrastSaturation(bri, con, sat);
Camera.SetBrightnessContrastSaturation(bri, con, sat);
std::string zw = tfliteflow.doSingleStep("[MakeImage]", _host);
httpd_resp_sendstr_chunk(req, zw.c_str());
}
@@ -498,6 +545,7 @@ esp_err_t handler_prevalue(httpd_req_t *req)
char _query[100];
char _size[10] = "";
char _numbers[50] = "default";
if (httpd_req_get_url_query_str(req, _query, 100) == ESP_OK)
{
@@ -511,15 +559,24 @@ esp_err_t handler_prevalue(httpd_req_t *req)
printf("Value: "); printf(_size); printf("\n");
#endif
}
httpd_query_key_value(_query, "numbers", _numbers, 50);
}
if (strlen(_size) == 0)
zw = tfliteflow.GetPrevalue();
{
zw = tfliteflow.GetPrevalue(std::string(_numbers));
}
else
zw = "SetPrevalue to " + tfliteflow.UpdatePrevalue(_size);
{
zw = "SetPrevalue to " + tfliteflow.UpdatePrevalue(_size, _numbers, true);
}
resp_str = zw.c_str();
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
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);
@@ -535,17 +592,17 @@ void task_autodoFlow(void *pvParameter)
{
int64_t fr_start, fr_delta_ms;
printf("task_autodoFlow: start\r\n");
doInit();
auto_isrunning = tfliteflow.isAutoStart(auto_intervall);
gpio_handler_init();
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)
{
std::string _zw = "task_autodoFlow - next round - Round #" + std::to_string(++countRounds);
@@ -590,6 +647,7 @@ void task_autodoFlow(void *pvParameter)
}
vTaskDelete(NULL); //Delete this task if it exits from the loop above
xHandletask_autodoFlow = NULL;
printf("task_autodoFlow: end\r\n");
}
void TFliteDoAutoStart()

View File

@@ -5,8 +5,6 @@
//#include "ClassControllCamera.h"
static const char *TAGTFLITE = "server_tflite";
void register_server_tflite_uri(httpd_handle_t server);
void KillTFliteTasks();

View File

@@ -18,6 +18,7 @@
static const char *TAG = "sntp";
bool setTimeAlwaysOnReboot = true;
time_t bootTime;
static void obtain_time(void);
static void initialize_sntp(void);
@@ -125,4 +126,17 @@ static void initialize_sntp(void)
sntp_setservername(0, "pool.ntp.org");
// sntp_set_time_sync_notification_cb(time_sync_notification_cb);
sntp_init();
}
void setBootTime()
{
time(&bootTime);
}
time_t getUpTime()
{
time_t now;
time(&now);
return now - bootTime;
}

View File

@@ -18,4 +18,7 @@ std::string gettimestring(const char * frm);
std::string ConvertTimeToString(time_t _time, const char * frm);
void setTimeZone(std::string _tzstring);
void reset_servername(std::string _servername);
void reset_servername(std::string _servername);
void setBootTime();
time_t getUpTime();

6
code/include/defines.h Normal file
View File

@@ -0,0 +1,6 @@
#ifndef defines_h
#define defines_h
#define CONFIG_FILE "/sdcard/config/config.ini"
#endif // ifndef defines_h

View File

@@ -19,6 +19,7 @@
#include "connect_wlan.h"
#include "read_wlanini.h"
#include "server_main.h"
#include "server_tflite.h"
#include "server_file.h"
#include "server_ota.h"
@@ -30,16 +31,14 @@
#define __SD_USE_ONE_LINE_MODE__
#ifdef __SD_USE_ONE_LINE_MODE__
#include "server_GPIO.h"
#endif
#define BLINK_GPIO GPIO_NUM_33
static const char *TAGMAIN = "connect_wlan_main";
static const char *TAGMAIN = "main";
#define FLASH_GPIO GPIO_NUM_4
//#define FLASH_GPIO GPIO_NUM_4
bool Init_NVS_SDCard()
{
@@ -50,7 +49,7 @@ bool Init_NVS_SDCard()
}
////////////////////////////////////////////////
ESP_LOGI(TAG, "Using SDMMC peripheral");
ESP_LOGI(TAGMAIN, "Using SDMMC peripheral");
sdmmc_host_t host = SDMMC_HOST_DEFAULT();
// This initializes the slot without card detect (CD) and write protect (WP) signals.
@@ -92,10 +91,10 @@ bool Init_NVS_SDCard()
if (ret != ESP_OK) {
if (ret == ESP_FAIL) {
ESP_LOGE(TAG, "Failed to mount filesystem. "
ESP_LOGE(TAGMAIN, "Failed to mount filesystem. "
"If you want the card to be formatted, set format_if_mount_failed = true.");
} else {
ESP_LOGE(TAG, "Failed to initialize the card (%s). "
ESP_LOGE(TAGMAIN, "Failed to initialize the card (%s). "
"Make sure SD card lines have pull-up resistors in place.", esp_err_to_name(ret));
}
return false;
@@ -108,9 +107,9 @@ bool Init_NVS_SDCard()
// Init the GPIO
// Flash ausschalten
gpio_pad_select_gpio(FLASH_GPIO);
gpio_set_direction(FLASH_GPIO, GPIO_MODE_OUTPUT);
gpio_set_level(FLASH_GPIO, 0);
// gpio_pad_select_gpio(FLASH_GPIO);
// gpio_set_direction(FLASH_GPIO, GPIO_MODE_OUTPUT);
// gpio_set_level(FLASH_GPIO, 0);
return true;
}
@@ -174,11 +173,12 @@ extern "C" void app_main(void)
TickType_t xDelay;
xDelay = 2000 / portTICK_PERIOD_MS;
printf("Autoflow: sleep for : %ldms\n", (long) xDelay);
printf("main: sleep for : %ldms\n", (long) xDelay);
// LogFile.WriteToFile("Startsequence 06");
vTaskDelay( xDelay );
// LogFile.WriteToFile("Startsequence 07");
setup_time();
setBootTime();
LogFile.WriteToFile("=============================================================================================");
LogFile.WriteToFile("=================================== Main Started ============================================");
LogFile.WriteToFile("=============================================================================================");
@@ -190,7 +190,7 @@ extern "C" void app_main(void)
// Camera.InitCam();
// Camera.LightOnOff(false);
xDelay = 2000 / portTICK_PERIOD_MS;
printf("Autoflow: sleep for : %ldms\n", (long) xDelay);
printf("main: sleep for : %ldms\n", (long) xDelay);
vTaskDelay( xDelay );
server = start_webserver();
@@ -199,13 +199,12 @@ extern "C" void app_main(void)
register_server_file_uri(server, "/sdcard");
register_server_ota_sdcard_uri(server);
#ifdef __SD_USE_ONE_LINE_MODE__
register_server_GPIO_uri(server);
#endif
printf("vor reg server main\n");
gpio_handler_create(server);
printf("vor reg server main\n");
register_server_main_uri(server, "/sdcard");
printf("vor dotautostart\n");
TFliteDoAutoStart();
}

View File

@@ -20,9 +20,9 @@
httpd_handle_t server = NULL;
std::string starttime = "";
static const char *TAG_SERVERMAIN = "server-main";
/* An HTTP GET handler */
esp_err_t info_get_handler(httpd_req_t *req)
@@ -198,7 +198,7 @@ esp_err_t hello_main_handler(httpd_req_t *req)
printf("File requested: %s\n", filetosend.c_str());
if (!filename) {
ESP_LOGE(TAG, "Filename is too long");
ESP_LOGE(TAG_SERVERMAIN, "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;
@@ -234,7 +234,7 @@ esp_err_t img_tmp_handler(httpd_req_t *req)
filetosend = filetosend + "/img_tmp/" + std::string(filename);
printf("File to upload: %s\n", filetosend.c_str());
esp_err_t res = send_file(req, filetosend);
esp_err_t res = send_file(req, filetosend);
if (res != ESP_OK)
return res;
@@ -299,7 +299,9 @@ esp_err_t sysinfo_handler(httpd_req_t *req)
std::string gitbranch = libfive_git_branch();
std::string gitbasebranch = git_base_branch();
std::string htmlversion = getHTMLversion();
char freeheapmem[11];
sprintf(freeheapmem, "%zu", esp_get_free_heap_size());
tcpip_adapter_ip_info_t ip_info;
ESP_ERROR_CHECK(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip_info));
const char *hostname;
@@ -314,7 +316,8 @@ esp_err_t sysinfo_handler(httpd_req_t *req)
\"html\" : \"" + htmlversion + "\",\
\"cputemp\" : \"" + cputemp + "\",\
\"hostname\" : \"" + hostname + "\",\
\"IPv4\" : \"" + ip4addr_ntoa(&ip_info.ip) + "\"\
\"IPv4\" : \"" + ip4addr_ntoa(&ip_info.ip) + "\",\
\"freeHeapMem\" : \"" + freeheapmem + "\"\
}\
]";
@@ -387,7 +390,7 @@ httpd_handle_t start_webserver(void)
httpd_config_t config = { };
config.task_priority = tskIDLE_PRIORITY+5;
config.stack_size = 32384; // bei 32k stürzt das Programm beim Bilderaufnehmen ab
config.stack_size = 32768; // bei 32k stürzt das Programm beim Bilderaufnehmen ab
config.core_id = tskNO_AFFINITY;
config.server_port = 80;
config.ctrl_port = 32768;
@@ -403,21 +406,22 @@ httpd_handle_t start_webserver(void)
config.global_transport_ctx = NULL;
config.global_transport_ctx_free_fn = NULL;
config.open_fn = NULL;
config.close_fn = NULL;
config.close_fn = NULL;
config.lru_purge_enable = true; // neu, um schlechte Serverbindung zu verhindern
// config.uri_match_fn = NULL;
config.uri_match_fn = httpd_uri_match_wildcard;
starttime = gettimestring("%Y%m%d-%H%M%S");
// Start the httpd server
ESP_LOGI(TAG, "Starting server on port: '%d'", config.server_port);
ESP_LOGI(TAG_SERVERMAIN, "Starting server on port: '%d'", config.server_port);
if (httpd_start(&server, &config) == ESP_OK) {
// Set URI handlers
ESP_LOGI(TAG, "Registering URI handlers");
ESP_LOGI(TAG_SERVERMAIN, "Registering URI handlers");
return server;
}
ESP_LOGI(TAG, "Error starting server!");
ESP_LOGI(TAG_SERVERMAIN, "Error starting server!");
return NULL;
}
@@ -432,7 +436,7 @@ void disconnect_handler(void* arg, esp_event_base_t event_base,
{
httpd_handle_t* server = (httpd_handle_t*) arg;
if (*server) {
ESP_LOGI(TAG, "Stopping webserver");
ESP_LOGI(TAG_SERVERMAIN, "Stopping webserver");
stop_webserver(*server);
*server = NULL;
}
@@ -443,9 +447,7 @@ void connect_handler(void* arg, esp_event_base_t event_base,
{
httpd_handle_t* server = (httpd_handle_t*) arg;
if (*server == NULL) {
ESP_LOGI(TAG, "Starting webserver");
ESP_LOGI(TAG_SERVERMAIN, "Starting webserver");
*server = start_webserver();
}
}

View File

@@ -8,18 +8,17 @@
#include <nvs_flash.h>
#include <sys/param.h>
#include "nvs_flash.h"
#include "tcpip_adapter.h"
#include "esp_netif.h"
#include "esp_eth.h"
#include "server_GPIO.h"
#include <esp_http_server.h>
static const char *TAG = "server-main";
extern httpd_handle_t server;
httpd_handle_t start_webserver(void);
void register_server_main_uri(httpd_handle_t server, const char *base_path);
#endif

View File

@@ -1,4 +1,4 @@
const char* GIT_REV="21a59fb";
const char* GIT_TAG="v7.1.1";
const char* GIT_REV="17a87b2";
const char* GIT_TAG="";
const char* GIT_BRANCH="master";
const char* BUILD_TIME="2021-06-17 19:59";
const char* BUILD_TIME="2021-08-01 21:47";

View File

@@ -13,7 +13,7 @@ extern "C"
#include "Helper.h"
#include <fstream>
const char* GIT_BASE_BRANCH = "master - v7.1.2 - 2020-06-17";
const char* GIT_BASE_BRANCH = "master - v8.0.5 - 2021-08-01";
const char* git_base_branch(void)

View File

@@ -22,7 +22,8 @@ framework = espidf
;board_build.partitions = partitions_singleapp.csv
board_build.partitions = partitions.csv
lib_deps =
lib_deps =
jomjol_configfile
jomjol_helper
jomjol_wlan
jomjol_image_proc
@@ -36,6 +37,9 @@ lib_deps =
jomjol_mqtt
jomjol_controlGPIO
monitor_speed = 115200
monitor_rts = 0
monitor_dtr = 0
debug_tool = esp-prog

View File

@@ -138,7 +138,8 @@ CONFIG_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y
# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set
# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set
# CONFIG_COMPILER_CXX_EXCEPTIONS is not set
CONFIG_COMPILER_CXX_EXCEPTIONS=y
CONFIG_COMPILER_CXX_EXCEPTIONS_EMG_POOL_SIZE=0
# CONFIG_COMPILER_CXX_RTTI is not set
CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y
# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set
@@ -165,8 +166,6 @@ CONFIG_APPTRACE_LOCK_ENABLE=y
#
# CONFIG_BT_ENABLED is not set
CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0
CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0
CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0
CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF=0
CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF=0
CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF=0
@@ -241,7 +240,6 @@ CONFIG_ESP_TLS_USING_MBEDTLS=y
#
# ESP32-specific
#
CONFIG_ESP32_ECO3_CACHE_LOCK_FIX=y
CONFIG_ESP32_REV_MIN_0=y
# CONFIG_ESP32_REV_MIN_1 is not set
# CONFIG_ESP32_REV_MIN_2 is not set
@@ -659,10 +657,8 @@ CONFIG_LWIP_SO_REUSE=y
CONFIG_LWIP_SO_REUSE_RXTOALL=y
# CONFIG_LWIP_SO_RCVBUF is not set
# CONFIG_LWIP_NETBUF_RECVINFO is not set
CONFIG_LWIP_IP4_FRAG=y
CONFIG_LWIP_IP6_FRAG=y
# CONFIG_LWIP_IP4_REASSEMBLY is not set
# CONFIG_LWIP_IP6_REASSEMBLY is not set
CONFIG_LWIP_IP_FRAG=y
# CONFIG_LWIP_IP_REASSEMBLY is not set
# CONFIG_LWIP_STATS is not set
# CONFIG_LWIP_ETHARP_TRUST_IP_MAC is not set
CONFIG_LWIP_ESP_GRATUITOUS_ARP=y
@@ -686,10 +682,8 @@ CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8
#
# TCP
#
CONFIG_LWIP_TCP_ISN_HOOK=y
CONFIG_LWIP_MAX_ACTIVE_TCP=16
CONFIG_LWIP_MAX_LISTENING_TCP=16
CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y
CONFIG_LWIP_TCP_MAXRTX=12
CONFIG_LWIP_TCP_SYNMAXRTX=6
CONFIG_LWIP_TCP_MSS=1440
@@ -704,7 +698,6 @@ CONFIG_LWIP_TCP_QUEUE_OOSEQ=y
CONFIG_LWIP_TCP_OVERSIZE_MSS=y
# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set
# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set
CONFIG_LWIP_TCP_RTO_TIME=1500
# end of TCP
#
@@ -720,8 +713,6 @@ CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y
# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU1 is not set
CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF
# CONFIG_LWIP_PPP_SUPPORT is not set
CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3
CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5
#
# ICMP
@@ -1005,8 +996,6 @@ CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30
#
CONFIG_WPA_MBEDTLS_CRYPTO=y
# CONFIG_WPA_TLS_V12 is not set
# CONFIG_WPA_WPS_WARS is not set
# CONFIG_WPA_DEBUG_PRINT is not set
# end of Supplicant
#
@@ -1061,7 +1050,8 @@ CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y
CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y
# CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set
# CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set
# CONFIG_CXX_EXCEPTIONS is not set
CONFIG_CXX_EXCEPTIONS=y
CONFIG_CXX_EXCEPTIONS_EMG_POOL_SIZE=0
CONFIG_STACK_CHECK_NONE=y
# CONFIG_STACK_CHECK_NORM is not set
# CONFIG_STACK_CHECK_STRONG is not set

View File

@@ -131,8 +131,8 @@ CONFIG_EXAMPLE_CONNECT_IPV6=y
#
# Compiler options
#
CONFIG_COMPILER_OPTIMIZATION_DEFAULT=y
# CONFIG_COMPILER_OPTIMIZATION_SIZE is not set
# CONFIG_COMPILER_OPTIMIZATION_DEFAULT is not set
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
# CONFIG_COMPILER_OPTIMIZATION_PERF is not set
# CONFIG_COMPILER_OPTIMIZATION_NONE is not set
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y
@@ -598,7 +598,6 @@ CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0
# CONFIG_FREERTOS_USE_TRACE_FACILITY is not set
# CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set
# CONFIG_FREERTOS_DEBUG_INTERNALS is not set
CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER=y
CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y
# CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set
CONFIG_FREERTOS_DEBUG_OCDAWARE=y

View File

@@ -1,4 +1,4 @@
const char* GIT_REV="21a59fb";
const char* GIT_TAG="v7.1.1";
const char* GIT_REV="17a87b2";
const char* GIT_TAG="";
const char* GIT_BRANCH="master";
const char* BUILD_TIME="2021-06-17 19:47";
const char* BUILD_TIME="2021-08-01 21:47";

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
images/numbers.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

BIN
images/powermeter.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

View File

@@ -1,61 +1,69 @@
[MakeImage]
;LogImageLocation = /log/source
;LogfileRetentionInDays = 15
WaitBeforeTakingPicture = 5
;LogfileRetentionInDays = 15
Brightness = -2
;Contrast = 0
;Saturation = 0
ImageQuality = 5
ImageSize = VGA
;Brightness = -2
FixedExposure = false
[Alignment]
InitialRotate=180
FlipImageSize = false
/config/ref0.jpg 119 273
/config/ref1.jpg 456 138
InitialRotate = 179
InitialMirror = false
SearchFieldX = 20
SearchFieldY = 20
InitialMirror= false
AlignmentAlgo = Default
FlipImageSize = false
/config/ref0.jpg 103 271
/config/ref1.jpg 442 142
[Digits]
Model = /config/dig0870s3q.tflite
Model = /config/dig1100s2q.tflite
;LogImageLocation = /log/digit
;LogfileRetentionInDays = 3
ModelInputSize = 20 32
digit1 306 120 37 67
digit2 355 120 37 67
digit3 404 120 37 67
main.dig1 294 126 30 54
main.dig2 343 126 30 54
main.dig3 391 126 30 54
[Analog]
Model = /config/ana0700s1lq.tflite
;LogImageLocation = /log/analog
;LogfileRetentionInDays = 3
ModelInputSize = 32 32
analog1 444 225 92 92
analog2 391 329 92 92
analog3 294 369 92 92
analog4 168 326 92 92
ExtendedResolution = false
ExtendedResolution = true
main.ana1 432 230 92 92
main.ana2 379 332 92 92
main.ana3 283 374 92 92
main.ana4 155 328 92 92
[PostProcessing]
DecimalShift = 0
main.DecimalShift = 0
PreValueUse = true
PreValueAgeStartup = 720
AllowNegativeRates = false
MaxRateValue = 0.1
main.MaxRateValue = 0.1
ErrorMessage = true
CheckDigitIncreaseConsistency = false
CheckDigitIncreaseConsistency = true
[MQTT]
;[MQTT]
;Uri = mqtt://IP-ADRESS:1883
;Topic = wasserzaehler/zaehlerstand
;TopicError = wasserzaehler/error
;TopicRate = wasserzaehler/rate
;TopicTimeStamp = wasserzaehler/timestamp
;MainTopic = wasserzaehler
;ClientID = wasser
;user = USERNAME
;password = PASSWORD
;[GPIO]
;MainTopicMQTT = wasserzaehler/GPIO
;IO0 = input disabled 10 false false
;IO1 = input disabled 10 false false
;IO3 = input disabled 10 false false
;IO4 = built-in-led disabled 10 false false
;IO12 = input-pullup disabled 10 false false
;IO13 = input-pullup disabled 10 false false
[AutoTimer]
AutoStart = true
Intervall = 4.85
@@ -66,8 +74,7 @@ LogfileRetentionInDays = 3
[System]
TimeZone = CET-1CEST,M3.5.0,M10.5.0/3
;TimeServer = fritz.box
;hostname = watermeter
;TimeServer = undefined
;AutoAdjustSummertime = false
;Hostname = undefined
SetupMode = true
[Ende]

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -61,7 +61,7 @@ select {
<option value="1" >Reference 1</option>
</select>
</td>
<td colspan="2">Storage Path/Name: <input type="text" name="name" id="name"></td>
<td colspan="2">Storage Path/Name: <input type="text" name="name" id="name" onchange="namechanged()"></td>
</tr>
<tr>
<td style="padding-top: 10px">x: <input type="number" name="refx" id="refx" step=1 onchange="valuemanualchanged()"></td>
@@ -90,9 +90,8 @@ select {
</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 type="text/javascript" src="./readconfigparam.js"></script>
<script language="JavaScript">
var canvas = document.getElementById('canvas'),
@@ -105,7 +104,8 @@ select {
enhanceCon = false,
param;
basepath = "http://192.168.178.26";
basepath = "";
basepath = "",
param;
function ChangeSelection(){
aktindex = parseInt(document.getElementById("index").value);
@@ -113,14 +113,9 @@ function ChangeSelection(){
}
function SaveToConfig(){
/*
refInfo[aktindex]["name"] = document.getElementById("name").value;
refInfo[aktindex]["x"] = document.getElementById("refx").value;
refInfo[aktindex]["y"] = document.getElementById("refy").value;
refInfo[aktindex]["dx"] = document.getElementById("refdx").value;
refInfo[aktindex]["dy"] = document.getElementById("refdy").value;
*/
UpdateConfigReference(refInfo, basepath);
WriteConfigININew();
UpdateConfigReference(basepath)
SaveConfigToServer(basepath);
}
function EnhanceContrast(){
@@ -133,10 +128,6 @@ function EnhanceContrast(){
enhanceCon = true;
MakeContrastImageZW(refInfo[aktindex], enhanceCon, basepath);
UpdateReference();
// var url = basepath + "/fileserver" + "/img_tmp/ref_zw.jpg?" + Date.now();
// document.getElementById("img_ref").src = url;
// var url = basepath + "/fileserver" + "/img_tmp/ref_zw_org.jpg?" + Date.now();
// document.getElementById("img_ref_org").src = url;
}
function UpdateReference(){
@@ -211,6 +202,7 @@ function dataURLtoBlob(dataurl) {
basepath = getbasepath();
loadConfig(basepath);
ParseConfig();
param = getConfigParameters();
canvas.addEventListener('mousedown', mouseDown, false);
canvas.addEventListener('mouseup', mouseUp, false);
@@ -355,6 +347,12 @@ function dataURLtoBlob(dataurl) {
}
}
function namechanged()
{
_name = document.getElementById("name").value;
refInfo[aktindex]["name"] = _name;
}
function valuemanualchanged(){
if (!drag) {
rect.w = document.getElementById("refdx").value;

View File

@@ -69,13 +69,28 @@ th, td {
<div id="div1">
<table>
<tr>
<td><canvas id="canvas" crossorigin></canvas></td>
</tr>
</table>
<p>
<table>
<tr>
<class id="Numbers_text" style="color:black;"><b>Number: </b></class>
<select id="Numbers_value1" onchange="numberChanged()">
<option value="0" selected>default</option>
<option value="1" >NT</option>
<option value="2" >HT</option>
</select>
<input class="move" type="submit" id="renameNumber" name="renameNumber" onclick="renameNumber()" value="Rename">
<input class="move" type="submit" id="newNumber" name="newNumber" onclick="newNumber()" value="New">
<input class="move" type="submit" id="removeNumber" name="removeNumber" onclick="removeNumber()" value="Remove">
</tr>
</table>
</p>
<table>
<tr>
<td><input class="button" type="submit" id= "newROI" name="newROI" onclick="newROI()" value="New ROI (after current)"></td>
@@ -89,10 +104,12 @@ th, td {
<option value="1" >ROI 1</option>
</select>
</td>
<td>Name: <input type="text" name="name" id="name" onchange="onNameChange()" size="13"></td>
<td>
<input class="button" type="submit" id="renameROI" name="renameROI" onclick="renameROI()" value="Rename">
<td>
<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>
<input class="move" type="submit" id="moveNext" onclick="moveNext()" value="move Next">
<input class="move" type="submit" id="movePrevious" onclick="movePrevious()" value="move Previous">
</td>
</tr>
<tr>
@@ -114,11 +131,10 @@ th, td {
</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 type="text/javascript" src="./gethost.js"></script>
<script type="text/javascript" src="./readconfigcommon.js"></script>
<script type="text/javascript" src="./readconfigparam.js"></script>
<script language="JavaScript">
var canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d'),
@@ -179,21 +195,22 @@ function deleteROI(){
}
function newROI(){
var zw = ROIInfo[ROIInfo.length-1];
ROIInfo.push(zw);
for (var i = ROIInfo.length-2; i > aktindex + 1; --i){
ROIInfo[i] = ROIInfo[i-1];
}
aktindex++;
ROIInfo[aktindex] = new Object;
ROIInfo[aktindex]["pos_ref"] = -1;
ROIInfo[aktindex]["name"] = "ROI" + aktindex;
ROIInfo[aktindex]["x"] = 1;
ROIInfo[aktindex]["y"] = 1;
ROIInfo[aktindex]["dx"] = ROIInfo[aktindex-1]["dx"];
ROIInfo[aktindex]["dy"] = ROIInfo[aktindex-1]["dy"];
ROIInfo[aktindex]["ar"] = ROIInfo[aktindex-1]["ar"];
UpdateROIs();
var sel = document.getElementById("Numbers_value1");
var _number= sel.options[sel.selectedIndex].text;
sel = document.getElementById("index");
var _roialt= sel.options[sel.selectedIndex].text;
var _roinew = prompt("Please enter name of new ROI", "name");
if (ROIInfo.length > 0)
erg = CreateROI(_number, "analog", sel.selectedIndex, _roinew, 1, 1, ROIInfo[aktindex]["dx"], ROIInfo[aktindex]["dy"]);
else
erg = CreateROI(_number, "analog", sel.selectedIndex, _roinew, 1, 1, 30, 30);
if (erg != "")
alert(erg);
else
UpdateROIs(_roinew);
}
function movePrevious(){
@@ -223,34 +240,64 @@ function ChangeSelection(){
}
function SaveToConfig(){
_enabled = document.getElementById("Category_Analog_enabled").checked;
SaveROIToConfig(ROIInfo, "[Analog]", basepath, _enabled);
UpdatePage();
_zwcat = getConfigCategory();
_zwcat["Analog"]["enabled"] = document.getElementById("Category_Analog_enabled").checked;
WriteConfigININew();
SaveConfigToServer(basepath);
}
function UpdateROIs(){
document.getElementById("Category_Analog_enabled").checked = true;
var sel = document.getElementById("Numbers_value1");
var _number = sel.options[sel.selectedIndex].text;
ROIInfo = getROIInfo("analog", _number);
_catzw = getConfigCategory();
if (_catzw["Analog"]["enabled"] == false)
{
document.getElementById("Category_Analog_enabled").checked = false;
EnDisableDigits();
alert("Analog ROIs are disabled - please enable (Check box top left).\n");
return;
}
if (ROIInfo.length == 0){
alert("There are no ROIs defined.\nPlease first define minimum one ROI in the config.ini by hand.\n");
document.getElementById("newROI").disabled = true;
alert("There are no ROIs defined.\nPlease first create a new ROI (\"New ROIs ...\").\n");
document.getElementById("newROI").disabled = false;
document.getElementById("deleteROI").disabled = true;
document.getElementById("index").disabled = true;
document.getElementById("saveroi").disabled = true;
document.getElementById("renameROI").disabled = true;
document.getElementById("moveNext").disabled = true;
document.getElementById("movePrevious").disabled = true;
return;
}
else
{
document.getElementById("newROI").disabled = false;
document.getElementById("deleteROI").disabled = false;
document.getElementById("renameROI").disabled = false;
document.getElementById("index").disabled = false;
}
var _index = document.getElementById("index");
while (_index.length){
_index.remove(0);
}
if (aktindex > ROIInfo.length)
aktindex = ROIInfo.length;
for (var i = 0; i < ROIInfo.length; ++i){
var option = document.createElement("option");
option.text = "ROI " + (i + 1);
option.text = ROIInfo[i]["name"];
option.value = i;
_index.add(option);
_index.add(option);
if (typeof _sel !== 'undefined') {
if (option.text == _sel)
aktindex = i;
}
}
_index.selectedIndex = aktindex;
@@ -267,7 +314,6 @@ function UpdateROIs(){
document.getElementById("lockAR").checked = lockAR;
document.getElementById("name").value = ROIInfo[aktindex]["name"];
document.getElementById("refx").value = ROIInfo[aktindex]["x"];
document.getElementById("refy").value = ROIInfo[aktindex]["y"];
document.getElementById("refdx").value = ROIInfo[aktindex]["dx"];
@@ -277,26 +323,8 @@ function UpdateROIs(){
rect.w = ROIInfo[aktindex]["dx"];
rect.h = ROIInfo[aktindex]["dy"];
draw();
}
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();
}
function loadCanvas(dataURL) {
var canvas = document.getElementById('canvas');
@@ -334,7 +362,10 @@ function ParseIni(_basepath) {
canvas.addEventListener('mouseup', mouseUp, false);
canvas.addEventListener('mousemove', mouseMove, false);
loadCanvas(basepath + "/fileserver/config/reference.jpg");
ParseIni(basepath);
loadConfig(basepath);
ParseConfig();
param = getConfigParameters();
UpdateNUMBERS();
drawImage();
draw();
}
@@ -349,6 +380,66 @@ function ParseIni(_basepath) {
// context.restore();
}
function UpdateNUMBERS(_sel){
zw = getNUMBERInfo();
index = 0;
var _index = document.getElementById("Numbers_value1");
while (_index.length){
_index.remove(0);
}
for (var i = 0; i < zw.length; ++i){
var option = document.createElement("option");
option.text = zw[i]["name"];
option.value = i;
_index.add(option);
if (typeof _sel !== 'undefined') {
if (zw[i]["name"] == _sel)
index = i
}
}
_index.selectedIndex = index;
UpdateROIs();
}
function renameNumber(){
var sel = document.getElementById("Numbers_value1");
var _delte= sel.options[sel.selectedIndex].text;
var _numbernew = prompt("Please enter new name", _delte);
erg = RenameNUMBER(_delte, _numbernew);
if (erg != "")
alert(erg);
else
UpdateNUMBERS(_numbernew);
}
function newNumber(){
var _numbernew = prompt("Please enter name of new number", "name");
erg = CreateNUMBER(_numbernew);
if (erg != "")
alert(erg);
else
UpdateNUMBERS(_numbernew);
}
function removeNumber(){
if (confirm("This will remove the number complete (analog and digital).\nIf you only want to remove the digital ROIs, please use \"Delete ROIs\".\nDo you want to proceed?")) {
var sel = document.getElementById("Numbers_value1");
var _delte= sel.options[sel.selectedIndex].text;
erg = DeleteNUMBER(_delte);
if (erg != "")
alert(erg);
UpdateNUMBERS();
}
}
function draw() {
var canvas = document.getElementById('canvas');
@@ -356,6 +447,26 @@ function ParseIni(_basepath) {
context.drawImage(imageObj, 0, 0);
if (document.getElementById("Category_Analog_enabled").checked)
{
var sel = document.getElementById("index");
var _number = sel.selectedIndex;
for (var _nb = 0; _nb < ROIInfo.length; _nb++)
{
if (_nb != _number)
{
lw = 1;
context.lineWidth = lw;
context.strokeStyle = "#990000";
var x0 = parseInt(ROIInfo[_nb].x) - parseInt(lw/2);
var y0 = parseInt(ROIInfo[_nb].y) - parseInt(lw/2);
var dx = parseInt(ROIInfo[_nb].dx) + parseInt(lw);
var dy = parseInt(ROIInfo[_nb].dy) + parseInt(lw);
context.strokeRect(x0, y0, dx, dy);
}
}
lw = 4
context.lineWidth = lw;
context.strokeStyle = "#FF0000";
@@ -483,6 +594,30 @@ function ParseIni(_basepath) {
}
}
function renameROI(){
var sel = document.getElementById("Numbers_value1");
var _number= sel.options[sel.selectedIndex].text;
sel = document.getElementById("index");
var _roialt= sel.options[sel.selectedIndex].text;
var _roinew = prompt("Please enter new name", _roialt);
erg = RenameROI(_number, "analog", _roialt, _roinew);
if (erg != "")
alert(erg);
else
UpdateROIs(_roinew);
}
function numberChanged()
{
UpdateROIs();
}
init();
</script>

View File

@@ -41,7 +41,6 @@ textarea {
</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 type="text/javascript">

File diff suppressed because it is too large Load Diff

View File

@@ -64,8 +64,24 @@ th, td {
<tr>
<canvas id="canvas" crossorigin></canvas>
</tr>
</table>
</table>
<p>
<table>
<tr>
<class id="Numbers_text" style="color:black;"><b>Number:</b> </class>
<select id="Numbers_value1" onchange="numberChanged()">
<option value="0" selected>default</option>
<option value="1" >NT</option>
<option value="2" >HT</option>
</select>
<input class="move" type="submit" id="renameNumber" name="renameNumber" onclick="renameNumber()" value="Rename">
<input class="move" type="submit" id="newNumber" name="newNumber" onclick="newNumber()" value="New">
<input class="move" type="submit" id="removeNumber" name="removeNumber" onclick="removeNumber()" value="Remove">
</tr>
</table>
</p>
<table>
<tr>
<td><input class="button" type="submit" id="newROI" name="newROI" onclick="newROI()" value="New ROI (after current)"></td>
@@ -79,7 +95,8 @@ th, td {
<option value="1" >ROI 1</option>
</select>
</td>
<td>Name: <input type="text" name="name" id="name" onchange="onNameChange()" size="13"></td>
<td>
<input class="button" type="submit" id="renameROI" name="renameROI" onclick="renameROI()" value="Rename">
<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">
@@ -105,9 +122,10 @@ th, td {
</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 type="text/javascript" src="./jquery-3.5.1.min.js"></script>
<script type="text/javascript" src="./readconfigcommon.js"></script>
<script type="text/javascript" src="./readconfigparam.js"></script>
<script type="text/javascript" src="./jquery-3.6.0.min.js"></script>
<script language="JavaScript">
var canvas = document.getElementById('canvas'),
@@ -169,22 +187,23 @@ function deleteROI(){
UpdateROIs();
}
function newROI(){
var zw = ROIInfo[ROIInfo.length-1];
ROIInfo.push(zw);
for (var i = ROIInfo.length-2; i > aktindex + 1; --i){
ROIInfo[i] = ROIInfo[i-1];
}
aktindex++;
ROIInfo[aktindex] = new Object;
ROIInfo[aktindex]["pos_ref"] = -1;
ROIInfo[aktindex]["name"] = "ROI" + aktindex;
ROIInfo[aktindex]["x"] = 1;
ROIInfo[aktindex]["y"] = 1;
ROIInfo[aktindex]["dx"] = ROIInfo[aktindex-1]["dx"];
ROIInfo[aktindex]["dy"] = ROIInfo[aktindex-1]["dy"];
ROIInfo[aktindex]["ar"] = ROIInfo[aktindex-1]["ar"];
UpdateROIs();
function newROI() {
var sel = document.getElementById("Numbers_value1");
var _number= sel.options[sel.selectedIndex].text;
sel = document.getElementById("index");
var _roialt= sel.options[sel.selectedIndex].text;
var _roinew = prompt("Please enter name of new ROI", "name");
if (ROIInfo.length > 0)
erg = CreateROI(_number, "digit", sel.selectedIndex, _roinew, 1, 1, ROIInfo[aktindex]["dx"], ROIInfo[aktindex]["dy"]);
else
erg = CreateROI(_number, "digit", sel.selectedIndex, _roinew, 1, 1, 30, 51);
if (erg != "")
alert(erg);
else
UpdateROIs(_roinew);
}
function movePrevious(){
@@ -214,34 +233,66 @@ function ChangeSelection(){
}
function SaveToConfig(){
_enabled = document.getElementById("Category_Digits_enabled").checked;
SaveROIToConfig(ROIInfo, "[Digits]", basepath, _enabled);
UpdatePage();
_zwcat = getConfigCategory();
_zwcat["Digits"]["enabled"] = document.getElementById("Category_Digits_enabled").checked;
WriteConfigININew();
SaveConfigToServer(basepath);
}
function UpdateROIs(){
function UpdateROIs(_sel){
document.getElementById("Category_Digits_enabled").checked = true;
var sel = document.getElementById("Numbers_value1");
var _number = sel.options[sel.selectedIndex].text;
ROIInfo = getROIInfo("digit", _number);
_catzw = getConfigCategory();
if (_catzw["Digits"]["enabled"] == false)
{
document.getElementById("Category_Digits_enabled").checked = false;
EnDisableDigits();
alert("Digital ROIs are disabled - please enable (Check box top left).\n");
return;
}
if (ROIInfo.length == 0){
alert("There are no ROIs defined.\nPlease first define minimum one ROI in the config.ini by hand.\n");
document.getElementById("newROI").disabled = true;
alert("There are no ROIs defined.\nPlease first create a new ROI (\"New ROIs ...\").\n");
document.getElementById("newROI").disabled = false;
document.getElementById("deleteROI").disabled = true;
document.getElementById("index").disabled = true;
document.getElementById("saveroi").disabled = true;
document.getElementById("renameROI").disabled = true;
document.getElementById("moveNext").disabled = true;
document.getElementById("movePrevious").disabled = true;
return;
}
else
{
document.getElementById("newROI").disabled = false;
document.getElementById("deleteROI").disabled = false;
document.getElementById("renameROI").disabled = false;
document.getElementById("index").disabled = false;
document.getElementById("saveroi").disabled = false;
}
var _index = document.getElementById("index");
while (_index.length){
_index.remove(0);
}
if (aktindex > ROIInfo.length)
aktindex = ROIInfo.length;
for (var i = 0; i < ROIInfo.length; ++i){
var option = document.createElement("option");
option.text = "ROI " + (i + 1);
option.text = ROIInfo[i]["name"];
option.value = i;
_index.add(option);
_index.add(option);
if (typeof _sel !== 'undefined') {
if (option.text == _sel)
aktindex = i;
}
}
_index.selectedIndex = aktindex;
@@ -258,7 +309,6 @@ function UpdateROIs(){
document.getElementById("lockAR").checked = lockAR;
document.getElementById("name").value = ROIInfo[aktindex]["name"];
document.getElementById("refx").value = ROIInfo[aktindex]["x"];
document.getElementById("refy").value = ROIInfo[aktindex]["y"];
document.getElementById("refdx").value = ROIInfo[aktindex]["dx"];
@@ -269,26 +319,6 @@ function UpdateROIs(){
rect.h = ROIInfo[aktindex]["dy"];
draw();
}
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();
}
function loadCanvas(dataURL) {
var canvas = document.getElementById('canvas');
@@ -317,8 +347,6 @@ function ParseIni(_basepath) {
var left = box.left + scrollLeft - clientLeft;
return { top: Math.round(top), left: Math.round(left) };
}
function init() {
basepath = getbasepath();
@@ -326,10 +354,14 @@ function ParseIni(_basepath) {
canvas.addEventListener('mouseup', mouseUp, false);
canvas.addEventListener('mousemove', mouseMove, false);
loadCanvas(basepath + "/fileserver/config/reference.jpg");
ParseIni(basepath);
loadConfig(basepath);
ParseConfig();
param = getConfigParameters();
UpdateNUMBERS();
drawImage();
draw();
}
function drawImage(){
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
@@ -340,6 +372,66 @@ function ParseIni(_basepath) {
// context.restore();
}
function UpdateNUMBERS(_sel){
zw = getNUMBERInfo();
index = 0;
var _index = document.getElementById("Numbers_value1");
while (_index.length){
_index.remove(0);
}
for (var i = 0; i < zw.length; ++i){
var option = document.createElement("option");
option.text = zw[i]["name"];
option.value = i;
_index.add(option);
if (typeof _sel !== 'undefined') {
if (zw[i]["name"] == _sel)
index = i
}
}
_index.selectedIndex = index;
UpdateROIs();
}
function renameNumber(){
var sel = document.getElementById("Numbers_value1");
var _delte= sel.options[sel.selectedIndex].text;
var _numbernew = prompt("Please enter new name", _delte);
erg = RenameNUMBER(_delte, _numbernew);
if (erg != "")
alert(erg);
else
UpdateNUMBERS(_numbernew);
}
function newNumber(){
var _numbernew = prompt("Please enter name of new number", "name");
erg = CreateNUMBER(_numbernew);
if (erg != "")
alert(erg);
else
UpdateNUMBERS(_numbernew);
}
function removeNumber(){
if (confirm("This will remove the number complete (analog and digital).\nIf you only want to remove the digital ROIs, please use \"Delete ROIs\".\nDo you want to proceed?")) {
var sel = document.getElementById("Numbers_value1");
var _delte= sel.options[sel.selectedIndex].text;
erg = DeleteNUMBER(_delte);
if (erg != "")
alert(erg);
UpdateNUMBERS();
}
}
function draw() {
var canvas = document.getElementById('canvas');
@@ -347,6 +439,24 @@ function draw() {
context.drawImage(imageObj, 0, 0);
if (document.getElementById("Category_Digits_enabled").checked)
{
var sel = document.getElementById("index");
var _number = sel.selectedIndex;
for (var _nb = 0; _nb < ROIInfo.length; _nb++)
{
if (_nb != _number)
{
lw = 2;
context.lineWidth = lw;
context.strokeStyle = "#990000";
var x0 = parseInt(ROIInfo[_nb].x) - parseInt(lw/2);
var y0 = parseInt(ROIInfo[_nb].y) - parseInt(lw/2);
var dx = parseInt(ROIInfo[_nb].dx) + parseInt(lw);
var dy = parseInt(ROIInfo[_nb].dy) + parseInt(lw);
context.strokeRect(x0, y0, dx, dy);
}
}
lw = 4
context.lineWidth = lw;
context.strokeStyle = "#FF0000";
@@ -468,8 +578,31 @@ function draw() {
}
}
function renameROI(){
var sel = document.getElementById("Numbers_value1");
var _number= sel.options[sel.selectedIndex].text;
sel = document.getElementById("index");
var _roialt= sel.options[sel.selectedIndex].text;
var _roinew = prompt("Please enter new name", _roialt);
erg = RenameROI(_number, "digit", _roialt, _roinew);
if (erg != "")
alert(erg);
else
UpdateROIs(_roinew);
}
function numberChanged()
{
UpdateROIs();
}
init();
</script>
</body>

View File

@@ -63,10 +63,10 @@ p {font-size: 1em;}
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);
WriteConfigININew();
SaveConfigToServer(basepath);
var stringota = "/reboot";
window.location = stringota;

View File

@@ -53,7 +53,7 @@ table {
</tr>
<tr>
<td><label for="mirror">Pre-rotate Angle:</label></td>
<td><input type="number" id="prerotateangle" name="prerotateangle" value=0 min="-360" max="360" onchange="drawRotated()">Degrees</td>
<td><input type="number" id="prerotateangle" name="prerotateangle" value="0" min="-360" max="360" onchange="drawRotated()">Degrees</td>
<td>
<class id="MakeImage_Brightness_text" style="color:black;">Brightness: </class>
<input type="number" id="MakeImage_Brightness_value1" size="13" value=0 min="-2" max="2" style="float: right; clear: both;">
@@ -86,7 +86,6 @@ 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 type="text/javascript" src="./readconfigparam.js"></script>
@@ -209,7 +208,11 @@ table {
param["Alignment"]["InitialRotate"].value1 = document.getElementById("prerotateangle").value;
if ((param["Alignment"]["InitialMirror"].found == true) && (document.getElementById("mirror").checked))
{
param["Alignment"]["InitialMirror"].value1 = "true";
param["Alignment"]["InitialMirror"]["found"] = true;
param["Alignment"]["InitialMirror"]["enabled"] = true;
}
else
param["Alignment"]["InitialMirror"].value1 = "false";
@@ -228,9 +231,8 @@ table {
var canvas = document.getElementById("canvas");
drawRotated(false);
var textToSave = setConfigParameters(param);
FileDeleteOnServer("/config/config.ini", basepath);
FileSendContent(textToSave, "/config/config.ini", basepath);
WriteConfigININew();
SaveConfigToServer(basepath);
SaveCanvasToImage(canvas, "/config/reference.jpg", true, basepath);
showReference();

View File

@@ -22,7 +22,7 @@ p {font-size: 1em;}
<body style="font-family: arial">
<h4>Define Digits</h4>
Here you define your digits you want to read.
Here you define your digits you want to read. If you have more than one number on the reading you can define several numbers with the <b>"Number"</b> selector. There you can also define new numbers.
<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>

View File

@@ -22,7 +22,7 @@ p {font-size: 1em;}
<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.
Here you define your analog counters you want to read. If you have more than one number on the reading you can define several numbers with the <b>"Number"</b> selector. There you can also define new numbers. 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>

View File

@@ -5,11 +5,12 @@ function gethost_Version(){
function getbasepath(){
var host = window.location.hostname;
if ((host == "127.0.0.1") || (host == "localhost"))
if ((host == "127.0.0.1") || (host == "localhost") || (host == ""))
{
// host = "http://192.168.2.118"; // jomjol interner test
// host = "http://192.168.178.26"; // jomjol interner test
// host = "http://192.168.2.219"; // jomjol interner test
// host = "http://192.168.178.46"; // jomjol interner test
host = "http://192.168.178.22"; // jomjol interner Real
// host = "http://192.168.43.191";
// host = "."; // jomjol interner localhost
}

View File

@@ -24,8 +24,25 @@ div {
</head>
<body style="font-family: arial; padding: 0px 10px;">
<h3>Current</h3>
<table style="font-family: arial">
<tr>
<td>
Last restart:
</td>
<td>
<div id="gitbranch">
<object data="/starttime"></object>
</div>
</td>
</tr>
</table>
<table style="font-family: arial">
<h3>Host Info</h3>
<table style="font-family: arial">
<tr>
<td>

File diff suppressed because one or more lines are too long

2
sd-card/html/jquery-3.6.0.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -36,33 +36,23 @@ input[type=number] {
</head>
<script src="/jquery-3.5.1.min.js"></script>
<script>
$ (document).ready(function() {
$("#prevalue").load("/setPreValue.html");
});
</script>
<script>
function setprevalue() {
var inputVal = document.getElementById("myInput").value;
inputVal = inputVal.replace(",", ".");
_value = "<object data=" + "/setPreValue.html?value=" + inputVal + " ></object>";
document.getElementById("result").innerHTML=_value;
// location.reload();
}
</script>
<body style="font-family: arial; padding: 0px 10px;">
<h3>Set the previous value for consistency check and substitution for NaN</h3>
<class id="Numbers_text" style="font-size: 120%; color:black;"><b>Choose Number: </b>
<select id="Numbers_value1" onchange="numberChanged()">
<option value="0" selected>default</option>
<option value="1" >NT</option>
<option value="2" >HT</option>
</select>
</class>
<table style="width:100%">
<tr>
<h2>Current Value:</h2><p>
<h3>Current Value:</h3><p>
<div id="prevalue"></div>
</tr>
<tr>
<h2>Set Value:</h2><p>
<h3>Set Value:</h3><p>
Input (Format = 123.456):<p>
PreValue:
<input type="number" id="myInput" name="myInput"
@@ -72,10 +62,100 @@ function setprevalue() {
<button class="button" type="button" onclick="setprevalue()">Set PreValue</button>
</tr>
<tr>
<h2>Result:</h2><p>
<h3>Result:</h3><p>
<div id="result" readonly></div>
</tr>
</table>
</body></html>
</body></html>
<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 basepath = "http://192.168.178.22";
var NUMBERS;
function setprevalue() {
var inputVal = document.getElementById("myInput").value;
var sel = document.getElementById("Numbers_value1");
var _number = sel.options[sel.selectedIndex].text;
inputVal = inputVal.replace(",", ".");
var xhttp = new XMLHttpRequest();
try {
url = basepath + "/setPreValue.html?value=" + inputVal + "&numbers=" + _number;
xhttp.open("GET", url, false);
xhttp.send();
response = xhttp.responseText;
document.getElementById("result").innerHTML=response;
}
catch (error)
{
// alert("Deleting Config.ini failed");
}
}
function loadPrevalue(_basepath) {
var sel = document.getElementById("Numbers_value1");
var _number = sel.options[sel.selectedIndex].text;
var xhttp = new XMLHttpRequest();
try {
url = _basepath + '/setPreValue.html?numbers=' + _number;
xhttp.open("GET", url, false);
xhttp.send();
response = xhttp.responseText;
document.getElementById("prevalue").innerHTML=response;
}
catch (error)
{
// alert("Deleting Config.ini failed");
}
return true;
}
function numberChanged(){
loadPrevalue(basepath);
}
function UpdateNUMBERS(_sel){
zw = getNUMBERInfo();
index = 0;
var _index = document.getElementById("Numbers_value1");
while (_index.length){
_index.remove(0);
}
for (var i = 0; i < zw.length; ++i){
var option = document.createElement("option");
option.text = zw[i]["name"];
option.value = i;
_index.add(option);
if (typeof _sel !== 'undefined') {
if (zw[i]["name"] == _sel)
index = i
}
}
_index.selectedIndex = index;
loadPrevalue(basepath);
}
function init(){
basepath = getbasepath();
loadConfig(basepath);
ParseConfig();
UpdateNUMBERS();
loadPrevalue(basepath);
}
init();
</script>

View File

@@ -1,427 +0,0 @@
function readconfig_Version(){
return "1.0.0 - 20200910";
}
var config_gesamt;
var config_split;
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){
_filetarget = zw["name"].replace("/config/", "/img_tmp/");
_filetarget = _filetarget.replace(".jpg", "_org.jpg");
url = _basepath + "/editflow.html?task=cutref&in=/config/reference.jpg&out="+_filetarget+"&x=" + zw["x"] + "&y=" + zw["y"] + "&dx=" + zw["dx"] + "&dy=" + zw["dy"];
var xhttp = new XMLHttpRequest();
try {
xhttp.open("GET", url, false);
xhttp.send(); }
catch (error)
{
// alert("Deleting Config.ini failed");
}
_filetarget2 = zw["name"].replace("/config/", "/img_tmp/");
// _filetarget2 = _filetarget2.replace(".jpg", "_org.jpg");
FileCopyOnServer(_filetarget, _filetarget2, _basepath);
}
function CopyReferenceToImgTmp(_basepath)
{
for (index = 0; index < 2; ++index)
{
_filenamevon = ref[index]["name"];
_filenamenach = _filenamevon.replace("/config/", "/img_tmp/");
FileDeleteOnServer(_filenamenach, _basepath);
FileCopyOnServer(_filenamevon, _filenamenach, _basepath);
_filenamevon = _filenamevon.replace(".jpg", "_org.jpg");
_filenamenach = _filenamenach.replace(".jpg", "_org.jpg");
FileDeleteOnServer(_filenamenach, _basepath);
FileCopyOnServer(_filenamevon, _filenamenach, _basepath);
}
}
function GetReferencesInfo(){
return ref;
}
function ParseConfigAlignment(_aktline){
var akt_ref = 0;
++_aktline;
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))
{
initalrotate["mirror"] = linesplit[1].toUpperCase().localeCompare("TRUE") == 0;
initalrotate["pos_config_mirror"] = _aktline;
}
if (((linesplit[0].toUpperCase() == "INITALROTATE") || (linesplit[0].toUpperCase() == "INITIALROTATE")) && (linesplit.length > 1))
{
initalrotate["angle"] = parseInt(linesplit[1]);
initalrotate["pos_config"] = _aktline;
}
if (linesplit.length == 3)
{
ref[akt_ref] = new Object();
ref[akt_ref]["pos_ref"] = _aktline;
ref[akt_ref]["name"] = linesplit[0];
ref[akt_ref]["x"] = linesplit[1];
ref[akt_ref]["y"] = linesplit[2];
akt_ref++;
}
++_aktline;
}
return _aktline;
}
function ParseConfigDigit(_aktline){
++_aktline;
digit.length = 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)
{
zw = new Object();
zw["pos_ref"] = _aktline;
zw["name"] = linesplit[0];
zw["x"] = linesplit[1];
zw["y"] = linesplit[2];
zw["dx"] = linesplit[3];
zw["dy"] = linesplit[4];
zw["ar"] = parseFloat(linesplit[3]) / parseFloat(linesplit[4]);
digit.push(zw);
}
++_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] == "[")
&& !((config_split[_aktline][0] == ";") && (config_split[_aktline][1] == "["))) {
var linesplit = ZerlegeZeile(config_split[_aktline]);
if (linesplit.length >= 5)
{
zw = new Object();
zw["pos_ref"] = _aktline;
zw["name"] = linesplit[0];
zw["x"] = linesplit[1];
zw["y"] = linesplit[2];
zw["dx"] = linesplit[3];
zw["dy"] = linesplit[4];
zw["ar"] = parseFloat(linesplit[3]) / parseFloat(linesplit[4]);
analog.push(zw);
}
++_aktline;
}
return _aktline;
}
function getROIInfo(_typeROI){
if (_typeROI == "[Digits]"){
targetROI = digit;
}
if (_typeROI == "[Analog]"){
targetROI = analog;
}
return targetROI.slice(); // Kopie senden, nicht orginal!!!
}
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;
}
// Abstimmen Anzahl ROIs:
var _pos = targetROI[targetROI.length-1]["pos_ref"];
for (var i = targetROI.length; i < _ROIInfo.length; ++i){
var zw = config_split[config_split.length-1];
config_split.push(zw);
for (var j = config_split.length-2; j > _pos + 1; --j){
config_split[j] = config_split[j-1];
}
}
for (i = targetROI.length-1; i > _ROIInfo.length-1; --i){
var _zwpos = targetROI[i]["pos_ref"];
config_split.splice(_zwpos, 1);
}
var linewrite = 0;
for (i = 0; i < _ROIInfo.length; ++i){
if (i < targetROI.length){
linewrite = targetROI[i]["pos_ref"];
}
else {
linewrite++;
}
config_split[linewrite] = _ROIInfo[i]["name"] + " " + _ROIInfo[i]["x"] + " " + _ROIInfo[i]["y"] + " " + _ROIInfo[i]["dx"] + " " + _ROIInfo[i]["dy"];
}
SaveConfigToServer(_basepath);
}
function ParseConfig() {
config_split = config_gesamt.split("\n");
var aktline = 0;
while (aktline < config_split.length){
if ((config_split[aktline].trim().toUpperCase() == "[ALIGNMENT]") || (config_split[aktline].trim().toUpperCase() == ";[ALIGNMENT]")){
aktline = ParseConfigAlignment(aktline);
continue;
}
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]") || (config_split[aktline].trim().toUpperCase() == ";[ANALOG]")) {
posAnalogHeader = aktline;
if (config_split[aktline][0] == "[") {
analogEnabled = true;
}
aktline = ParseConfigAnalog(aktline);
continue;
}
aktline++;
}
}
function getPreRotate(){
return initalrotate["angle"];
}
function setPreRotate(_prerotate){
initalrotate["angle"] = _prerotate;
}
function getMirror(){
if (initalrotate.hasOwnProperty("mirror")) {
return initalrotate["mirror"];
}
return false;
}
function setMirror(_mirror){
initalrotate["mirror"] = _mirror;
}
function SaveCanvasToImage(_canvas, _filename, _delete = true, _basepath = ""){
var JPEG_QUALITY=0.8;
var dataUrl = _canvas.toDataURL('image/jpeg', JPEG_QUALITY);
var rtn = dataURLtoBlob(dataUrl);
if (_delete) {
FileDeleteOnServer(_filename, _basepath);
}
FileSendContent(rtn, _filename, _basepath);
}
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 UpdateConfigReference(zw, _basepath){
for (var index = 0; index < 2; ++index)
{
var zeile = zw[index]["name"] + " " + zw[index]["x"] + " " + zw[index]["y"];
var _pos = zw[index]["pos_ref"];
config_split[_pos] = zeile;
_filenamenach = ref[index]["name"];
_filenamevon = _filenamenach.replace("/config/", "/img_tmp/");
FileDeleteOnServer(_filenamenach, _basepath);
FileCopyOnServer(_filenamevon, _filenamenach, _basepath);
_filenamenach = _filenamenach.replace(".jpg", "_org.jpg");
_filenamevon = _filenamevon.replace(".jpg", "_org.jpg");
FileDeleteOnServer(_filenamenach, _basepath);
FileCopyOnServer(_filenamevon, _filenamenach, _basepath);
}
SaveConfigToServer(_basepath);
}
function MakeContrastImageZW(zw, _enhance, _basepath){
_filename = zw["name"].replace("/config/", "/img_tmp/");
url = _basepath + "/editflow.html?task=cutref&in=/config/reference.jpg&out=" + _filename + "&x=" + zw["x"] + "&y=" + zw["y"] + "&dx=" + zw["dx"] + "&dy=" + zw["dy"];
if (_enhance == true){
url = url + "&enhance=true";
}
var xhttp = new XMLHttpRequest();
try {
xhttp.open("GET", url, false);
xhttp.send(); }
catch (error)
{
// alert("Deleting Config.ini failed");
}
}
function GetReferenceSize(name){
img = new Image();
var xhttp = new XMLHttpRequest();
url = "http://192.168.178.22/fileserver" + name;
xhttp.open("GET", url, false);
xhttp.send();
var response = xhttp.responseText;
var binary = ""
for (var responseText = xhttp.responseText, responseTextLen = responseText.length, binary = "", i = 0; i < responseTextLen; ++i) {
binary += String.fromCharCode(responseText.charCodeAt(i) & 255)
}
img.src = 'data:image/jpeg;base64,'+ window.btoa(binary);
return [img.width, img.height];
}
function getConfig() {
return config_gesamt;
}
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 SaveReferenceImage(_id_canvas, _filename, _doDelete, _basepath = ""){
if (_doDelete){
FileDeleteOnServer(_filename, _basepath);
}
var canvas = document.getElementById(_id_canvas);
var JPEG_QUALITY=0.8;
var dataUrl = canvas.toDataURL('image/jpeg', JPEG_QUALITY);
var rtn = dataURLtoBlob(dataUrl);
if (!FileSendContent(rtn, _filename, _basepath)){
alert("Error on saving reference image (" + _filename + ")!\nPlease retry.");
location.reload();
};
}

View File

@@ -20,65 +20,7 @@ function SaveConfigToServer(_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");
@@ -102,10 +44,10 @@ function createReader(file) {
function ZerlegeZeile(input)
function ZerlegeZeile(input, delimiter = " =\t\r")
{
var Output = Array(0);
delimiter = " =,\r";
// delimiter = " =,\t";
input = trim(input, delimiter);
var pos = findDelimiterPos(input, delimiter);
@@ -164,6 +106,11 @@ function trim(istring, adddelimiter)
}
function getConfig()
{
return config_gesamt;
}
function loadConfig(_basepath) {
var xhttp = new XMLHttpRequest();
@@ -261,4 +208,54 @@ function FileSendContent(_content, _filename, _basepath = ""){
// alert("Deleting Config.ini failed");
}
return okay;
}
}
function SaveCanvasToImage(_canvas, _filename, _delete = true, _basepath = ""){
var JPEG_QUALITY=0.8;
var dataUrl = _canvas.toDataURL('image/jpeg', JPEG_QUALITY);
var rtn = dataURLtoBlob(dataUrl);
if (_delete) {
FileDeleteOnServer(_filename, _basepath);
}
FileSendContent(rtn, _filename, _basepath);
}
function MakeContrastImageZW(zw, _enhance, _basepath){
_filename = zw["name"].replace("/config/", "/img_tmp/");
url = _basepath + "/editflow.html?task=cutref&in=/config/reference.jpg&out=" + _filename + "&x=" + zw["x"] + "&y=" + zw["y"] + "&dx=" + zw["dx"] + "&dy=" + zw["dy"];
if (_enhance == true){
url = url + "&enhance=true";
}
var xhttp = new XMLHttpRequest();
try {
xhttp.open("GET", url, false);
xhttp.send(); }
catch (error)
{
// alert("Deleting Config.ini failed");
}
}
function MakeRefZW(zw, _basepath){
_filetarget = zw["name"].replace("/config/", "/img_tmp/");
_filetarget = _filetarget.replace(".jpg", "_org.jpg");
url = _basepath + "/editflow.html?task=cutref&in=/config/reference.jpg&out="+_filetarget+"&x=" + zw["x"] + "&y=" + zw["y"] + "&dx=" + zw["dx"] + "&dy=" + zw["dy"];
var xhttp = new XMLHttpRequest();
try {
xhttp.open("GET", url, false);
xhttp.send(); }
catch (error)
{
// alert("Deleting Config.ini failed");
}
_filetarget2 = zw["name"].replace("/config/", "/img_tmp/");
// _filetarget2 = _filetarget2.replace(".jpg", "_org.jpg");
FileCopyOnServer(_filetarget, _filetarget2, _basepath);
}

View File

@@ -7,6 +7,8 @@ var config_split;
var param;
var category;
var ref = new Array(2);
var NUMBERS = new Array(0);
var REFERENCES = new Array(0);
function ParseConfig() {
config_split = config_gesamt.split("\n");
@@ -68,11 +70,11 @@ function ParseConfig() {
category[catname]["enabled"] = false;
category[catname]["found"] = false;
param[catname] = new Object();
ParamAddValue(param, catname, "DecimalShift");
ParamAddValue(param, catname, "DecimalShift", 1, true);
ParamAddValue(param, catname, "PreValueUse");
ParamAddValue(param, catname, "PreValueAgeStartup");
ParamAddValue(param, catname, "AllowNegativeRates");
ParamAddValue(param, catname, "MaxRateValue");
ParamAddValue(param, catname, "MaxRateValue", 1, true);
ParamAddValue(param, catname, "ErrorMessage");
ParamAddValue(param, catname, "CheckDigitIncreaseConsistency");
@@ -82,13 +84,23 @@ function ParseConfig() {
category[catname]["found"] = false;
param[catname] = new Object();
ParamAddValue(param, catname, "Uri");
ParamAddValue(param, catname, "Topic");
ParamAddValue(param, catname, "TopicError");
ParamAddValue(param, catname, "TopicRate");
ParamAddValue(param, catname, "TopicTimeStamp");
ParamAddValue(param, catname, "MainTopic", 1, false, [/^([a-zA-Z0-9_-]+\/){0,10}[a-zA-Z0-9_-]+$/]);
ParamAddValue(param, catname, "ClientID");
ParamAddValue(param, catname, "user");
ParamAddValue(param, catname, "password");
ParamAddValue(param, catname, "password");
var catname = "GPIO";
category[catname] = new Object();
category[catname]["enabled"] = false;
category[catname]["found"] = false;
param[catname] = new Object();
ParamAddValue(param, catname, "MainTopicMQTT", 1, false, [/^([a-zA-Z0-9_-]+\/){0,10}[a-zA-Z0-9_-]+$/]);
ParamAddValue(param, catname, "IO0", 6, false, [null, null, /^[0-9]*$/, null, null, /^[a-zA-Z0-9_-]*$/]);
ParamAddValue(param, catname, "IO1", 6, false, [null, null, /^[0-9]*$/, null, null, /^[a-zA-Z0-9_-]*$/]);
ParamAddValue(param, catname, "IO3", 6, false, [null, null, /^[0-9]*$/, null, null, /^[a-zA-Z0-9_-]*$/]);
ParamAddValue(param, catname, "IO4", 6, false, [null, null, /^[0-9]*$/, null, null, /^[a-zA-Z0-9_-]*$/]);
ParamAddValue(param, catname, "IO12", 6, false, [null, null, /^[0-9]*$/, null, null, /^[a-zA-Z0-9_-]*$/]);
ParamAddValue(param, catname, "IO13", 6, false, [null, null, /^[0-9]*$/, null, null, /^[a-zA-Z0-9_-]*$/]);
var catname = "AutoTimer";
category[catname] = new Object();
@@ -115,8 +127,9 @@ function ParseConfig() {
ParamAddValue(param, catname, "TimeServer");
ParamAddValue(param, catname, "AutoAdjustSummertime");
ParamAddValue(param, catname, "Hostname");
ParamAddValue(param, catname, "SetupMode");
ParamAddValue(param, catname, "SetupMode");
while (aktline < config_split.length){
for (var cat in category) {
zw = cat.toUpperCase();
@@ -136,16 +149,16 @@ function ParseConfig() {
}
}
function ParamAddValue(param, _cat, _param, _anzParam = 1){
function ParamAddValue(param, _cat, _param, _anzParam = 1, _isNUMBER = false, _checkRegExList = null){
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;
param[_cat][_param]["anzParam"] = _anzParam;
param[_cat][_param]["Numbers"] = _isNUMBER;
param[_cat][_param].checkRegExList = _checkRegExList;
};
function ParseConfigParamAll(_aktline, _catname){
++_aktline;
@@ -156,6 +169,18 @@ function ParseConfigParamAll(_aktline, _catname){
let [isCom, input] = isCommented(_input);
var linesplit = ZerlegeZeile(input);
ParamExtractValueAll(param, linesplit, _catname, _aktline, isCom);
if (!isCom && (linesplit.length == 5) && (_catname == 'Digits'))
ExtractROIs(input, "digit");
if (!isCom && (linesplit.length == 5) && (_catname == 'Analog'))
ExtractROIs(input, "analog");
if (!isCom && (linesplit.length == 3) && (_catname == 'Alignment'))
{
_newref = new Object();
_newref["name"] = linesplit[0];
_newref["x"] = linesplit[1];
_newref["y"] = linesplit[2];
REFERENCES.push(_newref);
}
++_aktline;
}
@@ -177,14 +202,59 @@ function ParamExtractValue(_param, _linesplit, _catname, _paramname, _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"]))
_AktROI = "default";
_AktPara = _linesplit[0];
_pospunkt = _AktPara.indexOf (".");
if (_pospunkt > -1)
{
_AktROI = _AktPara.substring(0, _pospunkt);
_AktPara = _AktPara.substring(_pospunkt+1);
}
if (_AktPara.toUpperCase() == paramname.toUpperCase())
{
while (_linesplit.length <= _param[_catname][paramname]["anzParam"]) {
_linesplit.push("");
}
_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];
if (_param[_catname][paramname]["Numbers"] == true) // möglicher Multiusage
{
abc = getNUMBERS(_linesplit[0]);
abc[_catname][paramname] = new Object;
abc[_catname][paramname]["found"] = true;
abc[_catname][paramname]["enabled"] = !_iscom;
for (var j = 1; j <= _param[_catname][paramname]["anzParam"]; ++j) {
abc[_catname][paramname]["value"+j] = _linesplit[j];
}
if (abc["name"] == "default")
{
for (_num in NUMBERS) // wert mit Default belegen
{
if (NUMBERS[_num][_catname][paramname]["found"] == false)
{
NUMBERS[_num][_catname][paramname]["found"] = true;
NUMBERS[_num][_catname][paramname]["enabled"] = !_iscom;
NUMBERS[_num][_catname][paramname]["line"] = _aktline;
for (var j = 1; j <= _param[_catname][paramname]["anzParam"]; ++j) {
NUMBERS[_num][_catname][paramname]["value"+j] = _linesplit[j];
}
}
}
}
}
else
{
_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];
}
}
}
}
}
@@ -193,54 +263,114 @@ function getConfigParameters() {
return 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"];
function WriteConfigININew()
{
// Cleanup empty NUMBERS
for (var j = 0; j < NUMBERS.length; ++j)
{
if ((NUMBERS[j]["digit"].length + NUMBERS[j]["analog"].length) == 0)
{
NUMBERS.splice(j, 1);
}
}
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];
config_split = new Array(0);
for (var cat in param) {
text = "[" + cat + "]";
if (!category[cat]["enabled"]) {
text = ";" + text;
}
config_split.push(text);
for (var name in param[cat]) {
if (param[cat][name]["Numbers"])
{
for (_num in NUMBERS)
{
text = NUMBERS[_num]["name"] + "." + name;
var text = text + " ="
for (var j = 1; j <= param[cat][name]["anzParam"]; ++j) {
if (!(typeof NUMBERS[_num][cat][name]["value"+j] == 'undefined'))
text = text + " " + NUMBERS[_num][cat][name]["value"+j];
}
if (!NUMBERS[_num][cat][name]["enabled"]) {
text = ";" + text;
}
config_split.push(text);
}
if (param[cat][name]["found"]) {
}
else
{
var text = name + " ="
for (var j = 1; j <= _param[cat][name]["anzParam"]; ++j) {
text = text + " " + param[cat][name]["value"+j];
for (var j = 1; j <= param[cat][name]["anzParam"]; ++j) {
if (!(typeof param[cat][name]["value"+j] == 'undefined'))
text = text + " " + param[cat][name]["value"+j];
}
if (!param[cat][name]["enabled"]) {
text = ";" + text;
}
config_split[param[cat][name]["line"]] = text;
config_split.push(text);
}
}
}
for (var cat in _category) {
if (category[cat]["found"])
if (cat == "Digits")
{
category[cat]["enabled"] = _category[cat]["enabled"];
text = "[" + cat + "]";
if (!category[cat]["enabled"]) {
text = ";" + text;
for (var _roi in NUMBERS)
{
if (NUMBERS[_roi]["digit"].length > 0)
{
for (var _roiddet in NUMBERS[_roi]["digit"])
{
text = NUMBERS[_roi]["name"] + "." + NUMBERS[_roi]["digit"][_roiddet]["name"];
text = text + " " + NUMBERS[_roi]["digit"][_roiddet]["x"];
text = text + " " + NUMBERS[_roi]["digit"][_roiddet]["y"];
text = text + " " + NUMBERS[_roi]["digit"][_roiddet]["dx"];
text = text + " " + NUMBERS[_roi]["digit"][_roiddet]["dy"];
config_split.push(text);
}
}
}
}
if (cat == "Analog")
{
for (var _roi in NUMBERS)
{
if (NUMBERS[_roi]["analog"].length > 0)
{
for (var _roiddet in NUMBERS[_roi]["analog"])
{
text = NUMBERS[_roi]["name"] + "." + NUMBERS[_roi]["analog"][_roiddet]["name"];
text = text + " " + NUMBERS[_roi]["analog"][_roiddet]["x"];
text = text + " " + NUMBERS[_roi]["analog"][_roiddet]["y"];
text = text + " " + NUMBERS[_roi]["analog"][_roiddet]["dx"];
text = text + " " + NUMBERS[_roi]["analog"][_roiddet]["dy"];
config_split.push(text);
}
}
}
}
if (cat == "Alignment")
{
for (var _roi in REFERENCES)
{
text = REFERENCES[_roi]["name"];
text = text + " " + REFERENCES[_roi]["x"];
text = text + " " + REFERENCES[_roi]["y"];
config_split.push(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];
}
return config_gesamt;
config_split.push("");
}
}
function isCommented(input)
{
let isComment = false;
@@ -275,6 +405,271 @@ function getConfig() {
function getConfigCategory() {
return category;
}
function ExtractROIs(_aktline, _type){
var linesplit = ZerlegeZeile(_aktline);
abc = getNUMBERS(linesplit[0], _type);
abc["pos_ref"] = _aktline;
abc["x"] = linesplit[1];
abc["y"] = linesplit[2];
abc["dx"] = linesplit[3];
abc["dy"] = linesplit[4];
abc["ar"] = parseFloat(linesplit[3]) / parseFloat(linesplit[4]);
}
function getNUMBERS(_name, _type, _create = true)
{
_pospunkt = _name.indexOf (".");
if (_pospunkt > -1)
{
_digit = _name.substring(0, _pospunkt);
_roi = _name.substring(_pospunkt+1);
}
else
{
_digit = "default";
_roi = _name;
}
_ret = -1;
for (i = 0; i < NUMBERS.length; ++i)
{
if (NUMBERS[i]["name"] == _digit)
_ret = NUMBERS[i];
}
if (!_create) // nicht gefunden und soll auch nicht erzeugt werden, ggf. geht eine NULL zurück
return _ret;
if (_ret == -1)
{
_ret = new Object();
_ret["name"] = _digit;
_ret['digit'] = new Array();
_ret['analog'] = new Array();
for (_cat in param)
for (_param in param[_cat])
if (param[_cat][_param]["Numbers"] == true){
if (typeof _ret[_cat] == 'undefined')
_ret[_cat] = new Object();
_ret[_cat][_param] = new Object();
_ret[_cat][_param]["found"] = false;
_ret[_cat][_param]["enabled"] = false;
_ret[_cat][_param]["anzParam"] = param[_cat][_param]["anzParam"];
}
NUMBERS.push(_ret);
}
if (typeof _type == 'undefined') // muss schon existieren !!! - also erst nach Digits / Analog aufrufen
return _ret;
neuroi = new Object();
neuroi["name"] = _roi;
_ret[_type].push(neuroi);
return neuroi;
}
function CopyReferenceToImgTmp(_basepath)
{
for (index = 0; index < 2; ++index)
{
_filenamevon = REFERENCES[index]["name"];
_filenamenach = _filenamevon.replace("/config/", "/img_tmp/");
FileDeleteOnServer(_filenamenach, _basepath);
FileCopyOnServer(_filenamevon, _filenamenach, _basepath);
_filenamevon = _filenamevon.replace(".jpg", "_org.jpg");
_filenamenach = _filenamenach.replace(".jpg", "_org.jpg");
FileDeleteOnServer(_filenamenach, _basepath);
FileCopyOnServer(_filenamevon, _filenamenach, _basepath);
}
}
function GetReferencesInfo(){
return REFERENCES;
}
function UpdateConfigReference(_basepath){
for (var index = 0; index < 2; ++index)
{
_filenamenach = REFERENCES[index]["name"];
_filenamevon = _filenamenach.replace("/config/", "/img_tmp/");
FileDeleteOnServer(_filenamenach, _basepath);
FileCopyOnServer(_filenamevon, _filenamenach, _basepath);
_filenamenach = _filenamenach.replace(".jpg", "_org.jpg");
_filenamevon = _filenamevon.replace(".jpg", "_org.jpg");
FileDeleteOnServer(_filenamenach, _basepath);
FileCopyOnServer(_filenamevon, _filenamenach, _basepath);
}
}
function getNUMBERInfo(){
return NUMBERS;
}
function RenameNUMBER(_alt, _neu){
index = -1;
found = false;
for (i = 0; i < NUMBERS.length; ++i) {
if (NUMBERS[i]["name"] == _alt)
index = i;
if (NUMBERS[i]["name"] == _neu)
found = true;
}
if (found)
return "Name is already existing - please use another name";
NUMBERS[index]["name"] = _neu;
return "";
}
function DeleteNUMBER(_delte){
if (NUMBERS.length == 1)
return "The last number cannot be deleted."
index = -1;
for (i = 0; i < NUMBERS.length; ++i) {
if (NUMBERS[i]["name"] == _delte)
index = i;
}
if (index > -1) {
NUMBERS.splice(index, 1);
}
return "";
}
function CreateNUMBER(_numbernew){
found = false;
for (i = 0; i < NUMBERS.length; ++i) {
if (NUMBERS[i]["name"] == _numbernew)
found = true;
}
if (found)
return "Name does already exist, please choose another one!";
_ret = new Object();
_ret["name"] = _numbernew;
_ret['digit'] = new Array();
_ret['analog'] = new Array();
for (_cat in param)
for (_param in param[_cat])
if (param[_cat][_param]["Numbers"] == true)
{
if (typeof (_ret[_cat]) === "undefined")
{
_ret[_cat] = new Object();
}
_ret[_cat][_param] = new Object();
_ret[_cat][_param]["found"] = false;
_ret[_cat][_param]["enabled"] = false;
_ret[_cat][_param]["anzParam"] = param[_cat][_param]["anzParam"];
}
NUMBERS.push(_ret);
return "";
}
function getROIInfo(_typeROI, _number){
index = 0;
for (var i = 0; i < NUMBERS.length; ++i)
if (NUMBERS[i]["name"] == _number)
index = i;
return NUMBERS[index][_typeROI];
}
function RenameROI(_number, _type, _alt, _neu){
index = -1;
found = false;
_indexnumber = -1;
for (j = 0; j < NUMBERS.length; ++j)
if (NUMBERS[j]["name"] == _number)
_indexnumber = j;
for (i = 0; i < NUMBERS[_indexnumber][_type].length; ++i) {
if (NUMBERS[_indexnumber][_type][i]["name"] == _alt)
index = i;
if (NUMBERS[_indexnumber][_type][i]["name"] == _neu)
found = true;
}
if (found)
return "Name is already existing - please use another name";
NUMBERS[_indexnumber][_type][index]["name"] = _neu;
return "";
}
function DeleteNUMBER(_delte){
if (NUMBERS.length == 1)
return "The last number cannot be deleted."
index = -1;
for (i = 0; i < NUMBERS.length; ++i) {
if (NUMBERS[i]["name"] == _delte)
index = i;
}
if (index > -1) {
NUMBERS.splice(index, 1);
}
return "";
}
function CreateROI(_number, _type, _pos, _roinew, _x, _y, _dx, _dy){
_indexnumber = -1;
for (j = 0; j < NUMBERS.length; ++j)
if (NUMBERS[j]["name"] == _number)
_indexnumber = j;
found = false;
for (i = 0; i < NUMBERS.length; ++i) {
if (NUMBERS[_indexnumber][_type]["name"] == _roinew)
found = true;
}
if (found)
return "ROI does already exist, please choose another name!";
_ret = new Object();
_ret["name"] = _roinew;
_ret["x"] = _x;
_ret["y"] = _y;
_ret["dx"] = _dx;
_ret["dy"] = _dy;
_ret["ar"] = _dx / _dy;
NUMBERS[_indexnumber][_type].splice(_pos+1, 0, _ret);
return "";
}

32
sd-card/html/test.html Normal file
View File

@@ -0,0 +1,32 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body style="font-family: arial">
testschrift
<div id="value"></div>
</html>
<script type="text/javascript" src="./gethost.js"></script>
<script type="text/javascript">
var basepath = "http://192.168.178.22";
function testinit(){
basepath = getbasepath();
url = basepath + '/wasserzaehler.html?all=true';
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
// Typical action to be performed when the document is ready:
document.getElementById("value").innerHTML = xhttp.responseText;
}
};
xhttp.open("GET", url, true);
xhttp.send();
}
testinit();
</script>
</body>

View File

@@ -1 +1 @@
6.8.0
9.5.2

View File

@@ -7,7 +7,7 @@
<style>
.tg {border-collapse:collapse;border-spacing:0;width:100%;color: darkslategray;border: inset;height:585px;}
.tg td{font-size:14px;padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;}
.tg th{height: 55px;font-size:24px;font-weight:bold;text-align:left;padding:0px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;background-color:#f0f0f0}
.tg th{height: 50px;font-size:24px;font-weight:bold;text-align:left;padding:0px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;background-color:#f0f0f0}
.tg .tg-1{width:77%;font-size:20px;font-family:Arial, Helvetica, sans-serif !important;border: inset;}
.tg .tg-2{font-size:20px;font-family:Arial, Helvetica, sans-serif !important;border: inset;}
.tg .tg-3{height: 15px;font-size:14px;font-family:Arial, Helvetica, sans-serif !important;border: inset;}
@@ -15,27 +15,72 @@
</head>
<script src="/jquery-3.5.1.min.js"></script>
<body style="font-family: arial">
<script>
function addZero(i) {
<table class="tg">
<tr>
<td class="tg-1" rowspan="9"><div id="img"></div></td>
<th class="th">Value:</th>
</tr>
<tr>
<td class="tg-2">
<div id="value"></div>
</td>
</tr>
<tr>
<th class="th">Previous Value:</th>
</tr>
<tr>
<td class="tg-2">
<div id="prevalue"></div>
</td>
</tr>
<tr>
<th class="th">Raw Value:</th>
</tr>
<tr>
<td class="tg-2">
<div id="raw"></div>
</td>
</tr>
<tr>
<th class="th">Error:</th>
</tr>
<tr>
<td class="tg-2">
<div id="error"></div>
</td>
</tr>
<tr>
<td class="tg-3">
<div id="timestamp" ></div>
</td>
</tr>
</table>
</body>
</html>
<script src="/jquery-3.6.0.min.js"></script>
<script type="text/javascript" src="./gethost.js"></script>
<script type="text/javascript" src="./readconfigcommon.js"></script>
<script type="text/javascript">
function addZero(i) {
if (i < 10) {
i = "0" + i;
}
return i;
}
$ (document).ready(function() {
$(document).ready(function() {
var d = new Date();
var h = addZero(d.getHours());
var m = addZero(d.getMinutes());
var s = addZero(d.getSeconds());
$('#img').html('<img src="/img_tmp/alg_roi.jpg" style="max-height:555px; display:block; margin-left:auto; margin-right:auto;"></img>');
$("#raw").load("/wasserzaehler.html?rawvalue=true");
$("#corrected").load("/wasserzaehler.html");
$("#checked").load("/setPreValue.html");
$("#start").load("/starttime");
$('#timestamp').html("Last Page Refresh:" + (h + ":" + m + ":" + s));
refresh();
});
@@ -50,58 +95,63 @@
var s = addZero(d.getSeconds());
// reassign the url to be like alg_roi.jpg?timestamp=456784512 based on timestamp
$('#img').html('<img src="/img_tmp/alg_roi.jpg?timestamp='+ timestamp +'"max-height:555px; display:block; margin-left:auto; margin-right:auto;"></img>');
$("#raw").load("/wasserzaehler.html?rawvalue=true");
$("#corrected").load("/wasserzaehler.html");
$("#checked").load("/setPreValue.html");
$("#start").load("/starttime");
$('#timestamp').html("Last Page Refresh:" + (h + ":" + m + ":" + s));
init();
refresh();
}, 300000);
}
var basepath = "http://192.168.178.22";
function loadValue(_type, _div, _style) {
url = basepath + '/wasserzaehler.html?all=true&type=' + _type;
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var _rsp = xhttp.responseText;
var _split = _rsp.split("\r");
if (typeof _style == undefined)
out = "<table>";
else
out = "<table style=\"" + _style + "\">";
if (_split.length == 1)
{
var _zer = ZerlegeZeile(_split[0], "\t")
if (_zer.length > 1)
out = _zer[1];
else
out = "";
}
else
{
for (var j = 0; j < _split.length; ++j)
{
var _zer = ZerlegeZeile(_split[j], "\t")
if (_zer.length == 1)
out = out + "<tr><td>" + _zer[0] + "</td><td> </td></tr>";
else
out = out + "<tr><td>" + _zer[0] + "</td><td>" + _zer[1] + "</td></tr>";
}
out = out + "</table>"
}
document.getElementById(_div).innerHTML = out;
}
};
xhttp.open("GET", url, true);
xhttp.send();
}
function init(){
basepath = getbasepath();
loadValue("value", "value");
loadValue("raw", "raw");
loadValue("prevalue", "prevalue");
loadValue("error", "error", "font-size:8px");
}
init();
</script>
<body style="font-family: arial">
<table class="tg">
<tr>
<td class="tg-1" rowspan="9"><div id="img"></div></td>
<th class="th">Raw Value:</th>
</tr>
<tr>
<td class="tg-2">
<div id="raw"></div>
</td>
</tr>
<tr>
<th class="th">Corrected Value:</th>
</tr>
<tr>
<td class="tg-2">
<div id="corrected"></div>
</td>
</tr>
<tr>
<th class="th">Checked Value:</th>
</tr>
<tr>
<td class="tg-2">
<div id="checked"></div>
</td>
</tr>
<tr>
<th class="th">Start Time:</th>
</tr>
<tr>
<td class="tg-2">
<div id="start"></div>
</td>
</tr>
<tr>
<td class="tg-3">
<div id="timestamp"></div>
</td>
</tr>
</table>
</body>
</html>