Merge branch 'rolling'

This commit is contained in:
jomjol
2023-07-22 11:41:24 +02:00
69 changed files with 4126 additions and 2609 deletions

View File

@@ -1,3 +1,19 @@
## [15.3.0] - 2023-07-22
### Changes
For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/v15.2.1...v15.2.4)
#### Changed
- Updated PlatformIO to `6.3.2`
- Updated analog tflite files
- ana-cont_1207_s2_q.tflite
- dig-cont_0620_s3_q.tflite
## [15.2.4] - 2023-05-02
### Changes

View File

@@ -717,7 +717,8 @@ static esp_err_t upload_post_handler(httpd_req_t *req)
/* Close file upon upload completion */
fclose(fd);
ESP_LOGI(TAG, "File reception complete");
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "File saved: " + string(filename));
ESP_LOGI(TAG, "File reception completed");
std::string directory = std::string(filepath);
size_t zw = directory.find("/");
@@ -736,21 +737,27 @@ static esp_err_t upload_post_handler(httpd_req_t *req)
// ESP_LOGD(TAG, "Directory danach 2: %s", directory.c_str());
/* Redirect onto root to see the updated file list */
httpd_resp_set_status(req, "303 See Other");
httpd_resp_set_hdr(req, "Location", directory.c_str());
if (strcmp(filename, "/config/config.ini") == 0 ||
strcmp(filename, "/config/ref0.jpg") == 0 ||
strcmp(filename, "/config/ref0_org.jpg") == 0 ||
strcmp(filename, "/config/ref1.jpg") == 0 ||
strcmp(filename, "/config/ref1_org.jpg") == 0 ||
strcmp(filename, "/config/reference.jpg") == 0 ||
strcmp(filename, "/img_tmp/ref0.jpg") == 0 ||
strcmp(filename, "/img_tmp/ref0_org.jpg") == 0 ||
strcmp(filename, "/img_tmp/ref1.jpg") == 0 ||
strcmp(filename, "/img_tmp/ref1_org.jpg") == 0 ||
strcmp(filename, "/img_tmp/reference.jpg") == 0 )
{
httpd_resp_set_status(req, HTTPD_200); // Avoid reloading of folder content
}
else {
httpd_resp_set_status(req, "303 See Other"); // Reload folder content after upload
}
/* Redirect onto root to see the updated file list */
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) {
ESP_LOGD(TAG, "New config found. Reload handler.");
gpio_handler_deinit();
MQTTdestroy();
}
*/
return ESP_OK;
}
@@ -837,16 +844,15 @@ static esp_err_t delete_post_handler(httpd_req_t *req)
return ESP_FAIL;
}
if (stat(filepath, &file_stat) == -1) {
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "File does not exist: " + string(filename));
/* Respond with 400 Bad Request */
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "File does not exist");
return ESP_FAIL;
if (stat(filepath, &file_stat) == -1) { // File does not exist
/* This is ok, we would delete it anyway */
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "File does not exist: " + string(filename));
}
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Deleting file: " + string(filename));
/* Delete file */
unlink(filepath);
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "File deleted: " + string(filename));
ESP_LOGI(TAG, "File deletion completed");
directory = std::string(filepath);
size_t zw = directory.find("/");
@@ -863,16 +869,30 @@ static esp_err_t delete_post_handler(httpd_req_t *req)
directory = directory.substr(start_fn, found - start_fn + 1);
directory = "/fileserver" + directory;
ESP_LOGD(TAG, "Directory danach 4: %s", directory.c_str());
}
//////////////////////////////////////////////////////////////
/* Redirect onto root to see the updated file list */
if (strcmp(filename, "/config/config.ini") == 0 ||
strcmp(filename, "/config/ref0.jpg") == 0 ||
strcmp(filename, "/config/ref0_org.jpg") == 0 ||
strcmp(filename, "/config/ref1.jpg") == 0 ||
strcmp(filename, "/config/ref1_org.jpg") == 0 ||
strcmp(filename, "/config/reference.jpg") == 0 ||
strcmp(filename, "/img_tmp/ref0.jpg") == 0 ||
strcmp(filename, "/img_tmp/ref0_org.jpg") == 0 ||
strcmp(filename, "/img_tmp/ref1.jpg") == 0 ||
strcmp(filename, "/img_tmp/ref1_org.jpg") == 0 ||
strcmp(filename, "/img_tmp/reference.jpg") == 0 )
{
httpd_resp_set_status(req, HTTPD_200); // Avoid reloading of folder content
}
else {
httpd_resp_set_status(req, "303 See Other"); // Reload folder content after upload
}
}
//////////////////////////////////////////////////////////////
/* Redirect onto root to see the updated file list */
httpd_resp_set_status(req, "303 See Other");
httpd_resp_set_hdr(req, "Location", directory.c_str());
httpd_resp_sendstr(req, "File successfully deleted");
return ESP_OK;
@@ -929,7 +949,7 @@ std::string unzip_new(std::string _in_zip_file, std::string _target_zip, std::st
// Get and print information about each file in the archive.
int numberoffiles = (int)mz_zip_reader_get_num_files(&zip_archive);
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Numbers of files to be extracted: " + to_string(numberoffiles));
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Files to be extracted: " + to_string(numberoffiles));
sort_iter = 0;
{
@@ -993,7 +1013,7 @@ std::string unzip_new(std::string _in_zip_file, std::string _target_zip, std::st
string filename_zw = zw + SUFFIX_ZW;
ESP_LOGI(TAG, "Filename to extract: %s, Zwischenfilename: %s", zw.c_str(), filename_zw.c_str());
ESP_LOGI(TAG, "File to extract: %s, Temp. Filename: %s", zw.c_str(), filename_zw.c_str());
std::string folder = filename_zw.substr(0, filename_zw.find_last_of('/'));
MakeDir(folder);
@@ -1097,7 +1117,7 @@ void unzip(std::string _in_zip_file, std::string _target_directory){
// Save to File.
zw = std::string(archive_filename);
zw = _target_directory + zw;
ESP_LOGD(TAG, "Filename to extract: %s", zw.c_str());
ESP_LOGD(TAG, "File to extract: %s", zw.c_str());
FILE* fpTargetFile = fopen(zw.c_str(), "wb");
fwrite(p, 1, (uint)uncomp_size, fpTargetFile);
fclose(fpTargetFile);

View File

@@ -61,7 +61,13 @@ esp_err_t send_file(httpd_req_t *req, std::string filename)
endsWith(filename, ".jpeg") ||
endsWith(filename, ".ico") ||
endsWith(filename, ".png")) {
httpd_resp_set_hdr(req, "Cache-Control", "max-age=86400");
if (filename == "/sdcard/html/setup.html") {
httpd_resp_set_hdr(req, "Clear-Site-Data", "\"*\"");
}
else {
httpd_resp_set_hdr(req, "Cache-Control", "max-age=86400");
}
}
set_content_type_from_file(req, filename.c_str());

View File

@@ -55,7 +55,7 @@ string ClassFlowCNNGeneral::getReadout(int _analog = 0, bool _extendedResolution
// LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "getReadout(analog) number=" + std::to_string(number) + ", result_after_decimal_point=" + std::to_string(result_after_decimal_point) + ", prev=" + std::to_string(prev));
result = std::to_string(prev);
if (_extendedResolution && (CNNType != Digital))
if (_extendedResolution)
result = result + std::to_string(result_after_decimal_point);
for (int i = GENERAL[_analog]->ROI.size() - 2; i >= 0; --i)
@@ -142,11 +142,10 @@ int ClassFlowCNNGeneral::PointerEvalHybridNew(float number, float number_of_pred
int result_before_decimal_point = ((int) floor(number) + 10) % 10;
if (eval_predecessors < 0)
{
if ((result_after_decimal_point <= Digital_Uncertainty * 10) || (result_after_decimal_point >= Digital_Uncertainty * 10)) // Band around the digit --> Rounding, as digit reaches inaccuracy in the frame
result = (int) (round(number) + 10) % 10;
else
result = (int) ((int) trunc(number) + 10) % 10;
{
// on first digit is no spezial logic for transition needed
// we use the recognition as given. The result is the int value of the recognition
result = (int) ((int) trunc(number) + 10) % 10;
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "PointerEvalHybridNew - No predecessor - Result = " + std::to_string(result) +
" number: " + std::to_string(number) + " number_of_predecessors = " + std::to_string(number_of_predecessors)+ " eval_predecessors = " + std::to_string(eval_predecessors) + " Digital_Uncertainty = " + std::to_string(Digital_Uncertainty));

View File

@@ -34,13 +34,14 @@ protected:
bool AutoStart;
float AutoInterval;
bool SetupModeActive;
void SetInitialParameter(void);
std::string aktstatusWithTime;
std::string aktstatus;
int aktRunNr;
public:
bool SetupModeActive;
void InitFlow(std::string config);
bool doFlow(string time);
void doFlowTakeImageOnly(string time);

View File

@@ -866,12 +866,12 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "handleAllowNegativeRate for device: " + NUMBERS[j]->name);
if ((NUMBERS[j]->Value < NUMBERS[j]->PreValue))
{
#ifdef SERIAL_DEBUG
ESP_LOGD(TAG, "Neg: value=%f, preValue=%f, preToll%f", NUMBERS[j]->Value, NUMBERS[j]->PreValue,
NUMBERS[j]->PreValue-(2/pow(10, NUMBERS[j]->Nachkomma))
) ;
#endif
// more debug if extended resolution is on, see #2447
if (NUMBERS[j]->isExtendedResolution) {
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Neg: value=" + std::to_string(NUMBERS[j]->Value)
+ ", preValue=" + std::to_string(NUMBERS[j]->PreValue)
+ ", preToll=" + std::to_string(NUMBERS[j]->PreValue-(2/pow(10, NUMBERS[j]->Nachkomma))));
}
// Include inaccuracy of 0.2 for isExtendedResolution.
if (NUMBERS[j]->Value >= (NUMBERS[j]->PreValue-(2/pow(10, NUMBERS[j]->Nachkomma))) && NUMBERS[j]->isExtendedResolution) {
NUMBERS[j]->Value = NUMBERS[j]->PreValue;

View File

@@ -230,7 +230,7 @@ esp_err_t handler_stream(httpd_req_t *req)
if (httpd_query_key_value(_query, "flashlight", _value, 10) == ESP_OK)
{
#ifdef DEBUG_DETAIL_ON
ESP_LOGD(TAG, "flashlight is found%s", _size);
ESP_LOGD(TAG, "flashlight is found%s", _value);
#endif
if (strlen(_value) > 0)
flashlightOn = true;
@@ -453,7 +453,7 @@ esp_err_t handler_wasserzaehler(httpd_req_t *req)
else {
/* Digital ROIs */
txt = "<body style=\"font-family: arial\">";
txt += "<h3>Recognized Digit ROIs (previous round)</h3>\n";
txt += "<hr><h3>Recognized Digit ROIs (previous round)</h3>\n";
txt += "<table style=\"border-spacing: 5px\"><tr style=\"text-align: center; vertical-align: top;\">\n";
std::vector<HTMLInfo*> htmlinfodig;
@@ -488,7 +488,7 @@ esp_err_t handler_wasserzaehler(httpd_req_t *req)
/* Analog ROIs */
txt = "<h3>Recognized Analog ROIs (previous round)</h3>\n";
txt = "<hr><h3>Recognized Analog ROIs (previous round)</h3>\n";
txt += "<table style=\"border-spacing: 5px\"><tr style=\"text-align: center; vertical-align: top;\">\n";
std::vector<HTMLInfo*> htmlinfoana;
@@ -510,7 +510,7 @@ esp_err_t handler_wasserzaehler(httpd_req_t *req)
/* Full Image
* Only show it after the image got taken and aligned */
txt = "<h3>Aligned Image (current round)</h3>\n";
txt = "<hr><h3>Aligned Image (current round)</h3>\n";
if ((*status == std::string("Initialization")) ||
(*status == std::string("Initialization (delayed)")) ||
(*status == std::string("Take Image"))) {
@@ -657,14 +657,7 @@ esp_err_t handler_editflow(httpd_req_t *req)
string out2 = out.substr(0, out.length() - 4) + "_org.jpg";
std::string state = *flowctrl.getActStatus();
/* To be able to provide the image, several conditions must be met due to the shared PSRAM usage:
- Ether the round most be completed or not started yet
- Or we must be in Setup Mode
- Additionally, the initialization of the shared PSRAM must be successful */
if (((state == "Flow finished") || (state == "Initialization") || (state == "Initialization (delayed)") || isSetupModusActive()) &&
psram_init_shared_memory_for_take_image_step()) {
if ((flowctrl.SetupModeActive || (*flowctrl.getActStatus() == "Flow finished")) && psram_init_shared_memory_for_take_image_step()) {
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Taking image for Alignment Mark Update...");
CAlignAndCutImage *caic = new CAlignAndCutImage("cutref", in);
@@ -687,7 +680,7 @@ esp_err_t handler_editflow(httpd_req_t *req)
}
else {
LogFile.WriteToFile(ESP_LOG_WARN, TAG, std::string("Taking image for Alignment Mark not possible while device") +
" is busy with a round (Current State: '" + state + "')!");
" is busy with a round (Current State: '" + *flowctrl.getActStatus() + "')!");
zw = "Device Busy";
}
@@ -897,7 +890,7 @@ esp_err_t handler_prevalue(httpd_req_t *req)
if (httpd_query_key_value(_query, "value", _value, 20) == ESP_OK) {
#ifdef DEBUG_DETAIL_ON
ESP_LOGD(TAG, "Value: %s", _size);
ESP_LOGD(TAG, "Value: %s", _value);
#endif
}
}

View File

@@ -116,7 +116,7 @@ static esp_err_t http_event_handler(esp_http_client_event_t *evt)
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP Client Error encountered");
break;
case HTTP_EVENT_ON_CONNECTED:
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP Client Error encountered");
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP Client connected");
ESP_LOGI(TAG, "HTTP Client Connected");
break;
case HTTP_EVENT_HEADERS_SENT:

View File

@@ -9,6 +9,11 @@
#include "cJSON.h"
#include "../../include/defines.h"
#if DEBUG_DETAIL_ON
#include "esp_timer.h"
#endif
static const char *TAG = "MQTT IF";
std::map<std::string, std::function<void()>>* connectFunktionMap = NULL;

View File

@@ -174,10 +174,12 @@ int LoadWlanFromFile(std::string fn)
}
/* Check if password is empty (mandatory parameter) */
/* Disabled see issue #2393
if (wlan_config.password.empty()) {
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Password empty. Device init aborted!");
return -2;
}
*/
return 0;
}

View File

@@ -19,7 +19,7 @@
[common:esp32-idf]
extends = common:idf
platform = platformio/espressif32 @ 6.2.0
platform = platformio/espressif32 @ 6.3.2
framework = espidf
lib_deps =
${common:idf.lib_deps}

View File

@@ -109,6 +109,11 @@ CONFIG_ESP_INT_WDT_TIMEOUT_MS=300
CONFIG_HTTPD_MAX_REQ_HDR_LEN=1024
CONFIG_HTTPD_PURGE_BUF_LEN=16
<<<<<<< Updated upstream
=======
CONFIG_HTTPD_WS_SUPPORT=y
CONFIG_LWIP_MAX_SOCKETS=12
>>>>>>> Stashed changes
CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=16
CONFIG_ESP32_WIFI_CACHE_TX_BUFFER_NUM=16

Binary file not shown.

Binary file not shown.

BIN
images/icon/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -12,7 +12,7 @@ FixedExposure = false
Demo = false
[Alignment]
InitialRotate = 179
InitialRotate = 0.0
InitialMirror = false
SearchFieldX = 20
SearchFieldY = 20
@@ -22,7 +22,7 @@ FlipImageSize = false
/config/ref1.jpg 442 142
[Digits]
Model = /config/dig-cont_0611_s3_q.tflite
Model = /config/dig-cont_0620_s3_q.tflite
CNNGoodThreshold = 0.5
;ROIImagesLocation = /log/digit
;ROIImagesRetention = 3
@@ -31,7 +31,7 @@ main.dig2 343 126 30 54 false
main.dig3 391 126 30 54 false
[Analog]
Model = /config/ana-cont_1105_s2_q.tflite
Model = /config/ana-cont_1207_s2_q.tflite
CNNGoodThreshold = 0.5
;ROIImagesLocation = /log/analog
;ROIImagesRetention = 3
@@ -106,6 +106,6 @@ LogfilesRetention = 3
TimeZone = CET-1CEST,M3.5.0,M10.5.0/3
;TimeServer = pool.ntp.org
;Hostname = undefined
;RSSIThreshold = 0
RSSIThreshold = -75
CPUFrequency = 160
SetupMode = true

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 38 KiB

View File

@@ -1,42 +1,41 @@
<!DOCTYPE html>
<html>
<html lang="en" xml:lang="en">
<head>
<link rel="icon" href="favicon.ico?v=$COMMIT_HASH" type="image/x-icon">
<title>Backup/Restore Configuration</title>
<meta charset="utf-8">
<title>Backup/Restore Configuration</title>
<meta charset="UTF-8" />
<style>
h1 {font-size: 2em;}
h2 {font-size: 1.5em;}
h3 {font-size: 1.2em;}
p {font-size: 1em;}
<style>
h1 {font-size: 2em;}
h2 {font-size: 1.5em; margin-block-start: 0.0em; margin-block-end: 0.2em;}
h3 {font-size: 1.2em;}
p {font-size: 1em;}
input[type=number] {
width: 138px;
padding: 10px 5px;
display: inline-block;
border: 1px solid #ccc;
font-size: 16px;
}
input[type=number] {
width: 138px;
padding: 10px 5px;
display: inline-block;
border: 1px solid #ccc;
font-size: 16px;
}
.button {
padding: 10px 20px;
width: 211px;
font-size: 16px;
}
</style>
.button {
padding: 5px 10px;
width: 205px;
font-size: 16px;
}
</style>
</head>
<body style="font-family: arial; padding: 0px 10px;">
<h2>Backup Configuration</h2>
<p>With the following action the <a href="/fileserver/config/" target="_self">config</a> folder on the SD-card gets zipped and provided as a download.</p>
<h2>Backup Configuration</h2>
<p>With the following action the <a href="/fileserver/config/" target="_self">config</a> folder on the SD-card gets zipped and provided as a download.</p>
<button class="button" id="startBackup" type="button" onclick="startBackup()">Create Config backup</button>
<p id=progress></p>
<hr>
<h2>Restore Configuration</h2>
<p>Use the <a href="/fileserver/config/" target="_self">File Server</a> to upload individual files.</p>
<button class="button" id="startBackup" type="button" onclick="startBackup()">Create Backup</button>
<p id=progress></p>
<hr>
<h2>Restore Configuration</h2>
<p>Use the <a href="/fileserver/config/" target="_self">File Server</a> to upload individual files.</p>
</body>

View File

@@ -1,7 +1,7 @@
/* The UI can also be run locally, but you have to set the IP of your devide accordingly.
* And you also might have to disable CORS in your webbrowser! */
var domainname_for_testing = "192.168.178.23";
var domainname_for_testing = "192.168.1.151";
/* Returns the domainname with prepended protocol.
@@ -13,7 +13,7 @@ function getDomainname(){
)
{
console.log("Using pre-defined domainname for testing: " + domainname_for_testing);
//console.log("Using pre-defined domainname for testing: " + domainname_for_testing);
domainname = "http://" + domainname_for_testing
}
else
@@ -139,8 +139,8 @@ function compareVersions() {
console.log("FW Hash: " + fWGitHash + ", Web UI Hash: " + webUiHash);
if (fWGitHash != webUiHash) {
firework.launch("The Version of the Web Interface (" + webUiHash +
") does not match the Firmware Version (" +
firework.launch("The version of the web interface (" + webUiHash +
") does not match the firmware version (" +
fWGitHash + ")! It is suggested to keep them on the same version!", 'warning', 30000);
}
}

View File

@@ -1,17 +1,26 @@
<html>
<!DOCTYPE html>
<html lang="en" xml:lang="en">
<head>
<title>Data Viewer</title>
<meta charset="UTF-8" />
<style>
h1 {font-size: 2em;}
h2 {font-size: 1.5em; margin-block-start: 0.0em; margin-block-end: 0.2em;}
h3 {font-size: 1.2em;}
p {font-size: 1em;}
html,
body {
height: 100%;
margin: 2px;
margin: 1px;
font-family: Arial, Helvetica, sans-serif;
}
.box {
display: flex;
flex-flow: column;
height: 100%;
height: 99.75%;
}
.box .row.header {
@@ -30,26 +39,31 @@
font-family: 'Courier New', Courier, monospace;
font-size: small;
}
.button {
padding: 5px 10px;
width: 160px;
font-size: 16px;
}
</style>
<script type="text/javascript" src="common.js?v=$COMMIT_HASH"></script>
</head>
<body>
<h3>Todays Data</h3>
<h4>Last part of Todays Data</h4>
<h2>Data Viewer</h2>
<h4>Today's latest data</h4>
<div class="box">
<div class="row header">
<button onClick="reload();">Refresh</button>
<button onClick="window.open(getDomainname() + '/datafileact');">Show Full File</button>
<button onClick="window.location.href = getDomainname() + '/fileserver/log/data/'">Show Data Files</button>
<button onClick="window.location.href = 'graph.html?v=$COMMIT_HASH'">Show Graph</button>
<button class="button" onClick="reload();">Refresh</button>
<button class="button" onClick="window.open(getDomainname() + '/datafileact');">Show Full File</button>
<button class="button" onClick="window.location.href = getDomainname() + '/fileserver/log/data/'">Show Data Files</button>
<button class="button" onClick="window.location.href = 'graph.html?v=$COMMIT_HASH'">Show Graph</button>
</div>
<div class="row content" id="data"><br><br><br><b>Loading Data file, please wait...</b></div>
<div class="row content" id="data"><br><br><br><b>Loading data file, please wait...</b></div>
<div class="row footer">
<button onClick="reload();">Refresh</button>
<button onClick="window.open(getDomainname() + '/datafileact');">Show Full File</button>
<button onClick="window.location.href = getDomainname() + '/fileserver/log/data/'">Show Data Files</button>
<button onClick="window.location.href = 'graph.html?v=$COMMIT_HASH'">Show Graph</button>
<p></p>
<button class="button" onClick="reload();">Refresh</button>
<button class="button" onClick="window.open(getDomainname() + '/datafileact');">Show Full File</button>
<button class="button" onClick="window.location.href = getDomainname() + '/fileserver/log/data/'">Show Data Files</button>
<button class="button" onClick="window.location.href = 'graph.html?v=$COMMIT_HASH'">Show Graph</button>
</div>
</div>
</body>

View File

@@ -1,101 +1,135 @@
<!DOCTYPE html>
<html>
<html lang="en" xml:lang="en">
<head>
<link rel="icon" href="favicon.ico?v=$COMMIT_HASH" type="image/x-icon">
<title>Alignment Marks</title>
<meta charset="utf-8"/>
<style>
h1 {font-size: 2em;}
h2 {font-size: 1.5em; margin-block-start: 0.0em; margin-block-end: 0.2em;}
h3 {font-size: 1.2em;}
p {font-size: 1em;}
<title>Alignment marker</title>
<meta charset="UTF-8" />
<style>
h1 {font-size: 2em;}
h2 {font-size: 1.5em; margin-block-start: 0.0em; margin-block-end: 0.2em;}
h3 {font-size: 1.2em;}
p {font-size: 1em;}
input[type=number] {
width: 100px;
margin-right: 10px;
padding: 3px 5px;
display: inline-block;
border: 1px solid #ccc;
font-size: 16px;
}
input[type=number] {
width: 60px;
margin-right: 10px;
padding: 3px 5px;
display: inline-block;
border: 1px solid #ccc;
font-size: 16px;
}
input[type=text] {
padding: 3px 5px;
display: inline-block;
border: 1px solid #ccc;
font-size: 16px;
}
input[type=text] {
padding: 3px 5px;
display: inline-block;
border: 1px solid #ccc;
font-size: 16px;
}
select {
padding: 3px 5px;
display: inline-block;
border: 1px solid #ccc;
font-size: 16px;
margin-right: 10px;
}
input:out-of-range {
background-color: rgba(255, 0, 0, 0.25);
border: 1px solid red;
}
.button {
padding: 5px 10px;
width: 210px;
font-size: 16px;
}
</style>
<link href="firework.css?v=$COMMIT_HASH" rel="stylesheet">
<script type="text/javascript" src="jquery-3.6.0.min.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="firework.js?v=$COMMIT_HASH"></script>
select {
padding: 3px 5px;
display: inline-block;
border: 1px solid #ccc;
font-size: 16px;
margin-right: 10px;
min-width: 100px;
vertical-align: middle;
}
.button {
padding: 5px 10px;
width: 205px;
font-size: 16px;
}
th, td {
padding: 5px 5px 5px 0px;
}
table {
width: 660px;
padding: 5px;
}
</style>
<link href="firework.css?v=$COMMIT_HASH" rel="stylesheet">
<script type="text/javascript" src="jquery-3.6.0.min.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="firework.js?v=$COMMIT_HASH"></script>
</head>
<body style="font-family: arial; padding: 0px 10px;">
<h2>Alignment Marks</h2>
<p>On this page you define two Reference Marks.
See <a href=https://jomjol.github.io/AI-on-the-edge-device-docs/Alignment/ target=_blank>https://jomjol.github.io/AI-on-the-edge-device-docs/Alignment/</a> for explanations.</p>
<p>After saving the Reference Marks, you can define the <a href=edit_digits.html>digit</a> resp. <a href=edit_analog.html>analog</a> ROI's.<br>
Only after those steps a reboot is required.</p>
<h2>Alignment Marker</h2>
<details id="desc_details" style="font-size:16px">
<summary><b>CLICK HERE</b> for usage description. More infos in documentation:
<a href=https://jomjol.github.io/AI-on-the-edge-device-docs/Alignment/ target=_blank>Alignment</a>
</summary>
<p>
Two alignment marker with clear contour and proper contrast are needed to identify unique "fix points" on the image.
The marker area should be not be part of the variable area of ROI evaluation. Please find more information in documenation:
<a href=https://jomjol.github.io/AI-on-the-edge-device-docs/Alignment/ target=_blank>Alignment</a>
</p>
<p>
Select an alignment marker area using drag and dop feature by mouse operation or by manually entering the coordinates and sizes in the fields below the image.
After you selected a suitable first alignment marker area, push the <b>"Update Marker"</b> button. Switch to second alignment marker with <b>"Marker"</b>
and repeat the procedure.
</p>
<p>
After definition of both alignment marker is completed don't forget to save with the <b>"Save New Marker"</b> button!<br>
<b>NOTE:</b> There is no need to perform a reboot after every saving or step. It's sufficient to reboot after all configuration steps
(reference image, alignment, ROI configuration) are completed to activate new configuration.
</p>
</details>
<hr />
<table>
<colgroup>
<col span="1" style="width: 33.3%;">
<col span="1" style="width: 33.3%;">
<col span="1" style="width: 33.3%;">
</colgroup>
<tr>
<td><canvas id="canvas" crossorigin></canvas></td>
</tr>
</table>
<table>
<tr>
<td>Select Reference:
<td>Marker:
<select id="index" name="reference" onchange="ChangeSelection()">
<option value="0" selected>Reference 0</option>
<option value="1" >Reference 1</option>
<option value="0" selected>Marker 1</option>
<option value="1" >Marker 2</option>
</select>
</td>
<td colspan="2">Storage Path/Name: <input type="text" name="name" id="name" onchange="namechanged()"></td>
<td colspan="2" style="padding-left: 22px; color: grey;">Filename: <output 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>
<td style="padding-top: 10px">dx: <input type="number" name="refdx" id="refdx" step=1 onchange="valuemanualchanged()"></td>
<td rowspan="2" style="padding-top: 10px"><input class="button" type="button" value="Update Reference Image" onclick="CutOutReference()"></td>
<td rowspan="2" style="padding-top: 10px;"><input class="button" type="button" value="Update Marker" onclick="CutOutReference()"></td>
</tr>
<tr>
<td>y: <input type="number" name="refy" id="refy" step=1 onchange="valuemanualchanged()"></td>
<td>dy: <input type="number" name="refdy" id="refdy" step=1 onchange="valuemanualchanged()"></td>
</tr>
<tr>
<td style="padding-top: 10px">Original Image:</td>
<td style="padding-top: 10px">Reference Image:</td>
<td rowspan="2"><input class="button" type="button" id="enhancecontrast" value="Enhance Contrast" onclick="EnhanceContrast()"></td>
<td style="vertical-align: bottom;">Selected Image Area:</td>
<td style="vertical-align: bottom;">Resulting Marker:</td>
<td><input class="button" type="button" id="enhancecontrast" value="Enhance Image Contrast" onclick="EnhanceContrast()"></td>
</tr>
<tr>
<td><img id="img_ref_org" src = "/img_tmp/ref_zw_org.jpg"></td>
<td><img id="img_ref" src = "/img_tmp/ref_zw.jpg"></td>
</tr>
</table>
<td style="height:70px; vertical-align: top;"><img id="img_ref_org" src = ""></td> <!--/img_tmp/ref_zw_org.jpg-->
<td style="height:70px; vertical-align: top;"><img id="img_ref" src = ""></td> <!--/img_tmp/ref_zw.jpg-->
</tr>
<tr>
<td style="vertical-align:bottom;"><b>Reference Image:</b></td>
<td></td>
<td><input style="font-weight:bold;" class="button" type="submit" name="saveroi" id="savemarker" onclick="SaveToConfig()" value="Save New Marker">
</td>
</tr>
<tr>
<td colspan="3"><canvas id="canvas" crossorigin></canvas></td>
</tr>
</table>
<table>
<tr>
<td><input class="button" type="submit" name="saveroi" onclick="SaveToConfig()" value="Save">
<p>Proceed to update the <a href=edit_digits.html>digit</a> resp. <a href=edit_analog.html>analog</a> ROI's when you are done.</p></td>
</tr>
</table>
<script type="text/javascript" src="common.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="readconfigcommon.js?v=$COMMIT_HASH"></script>
@@ -130,10 +164,15 @@ function ChangeSelection(){
}
function SaveToConfig(){
WriteConfigININew();
UpdateConfigReference(domainname)
SaveConfigToServer(domainname);
firework.launch('Reference Marks got updated. The change will get applied after the next reboot!', 'success', 5000);
if (confirm("Are you sure you want to save the new alignment marker configuration?")) {
WriteConfigININew();
UpdateConfigReference(domainname)
SaveConfigToServer(domainname);
document.getElementById("savemarker").disabled = true;
document.getElementById("enhancecontrast").disabled = true;
firework.launch('Alignment marker saved. They will get applied after next reboot', 'success', 5000);
}
}
function EnhanceContrast(){
@@ -146,6 +185,7 @@ function EnhanceContrast(){
enhanceCon = true;
if (MakeContrastImageZW(refInfo[aktindex], enhanceCon, domainname)) {
UpdateReference();
document.getElementById("enhancecontrast").disabled = true;
}
}
@@ -174,7 +214,6 @@ function UpdateReference(){
document.getElementById("refy").value = refInfo[aktindex]["y"];
rect.startX = document.getElementById("refx").value;
rect.startY = document.getElementById("refy").value;
document.getElementById("enhancecontrast").disabled = true;
draw();
}
@@ -215,14 +254,27 @@ function dataURLtoBlob(dataurl) {
return { top: Math.round(top), left: Math.round(left) };
}
/* hash #description open the details part of the page */
function openDescription() {
if(window.location.hash) {
var hash = window.location.hash.substring(1); //Puts hash in variable, and removes the # character
if(hash == 'description')
document.getElementById("desc_details").open = true;
}
}
function init() {
function init() {
openDescription();
domainname = getDomainname();
loadConfig(domainname);
ParseConfig();
param = getConfigParameters();
document.getElementById("savemarker").disabled = true;
document.getElementById("enhancecontrast").disabled = true;
canvas.addEventListener('mousedown', mouseDown, false);
canvas.addEventListener('mouseup', mouseUp, false);
canvas.addEventListener('mousemove', mouseMove, false);
@@ -235,6 +287,8 @@ function dataURLtoBlob(dataurl) {
drawImage();
}
function drawImage(){
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
@@ -254,6 +308,7 @@ function dataURLtoBlob(dataurl) {
if (MakeRefZW(refInfo[aktindex], domainname)) {
UpdateReference();
document.getElementById("enhancecontrast").disabled = false;
document.getElementById("savemarker").disabled = false;
}
}

View File

@@ -1,142 +1,221 @@
<!DOCTYPE html>
<html>
<html lang="en" xml:lang="en">
<head>
<link rel="icon" href="favicon.ico?v=$COMMIT_HASH" type="image/x-icon">
<meta charset="utf-8"/>
<title>Analog ROI's</title>
<meta charset="UTF-8" />
<title>Analog ROI</title>
<style>
h1 {font-size: 2em;}
h2 {font-size: 1.5em; margin-block-start: 0.0em; margin-block-end: 0.2em;}
h3 {font-size: 1.2em;}
p {font-size: 1em;}
<style>
h1 {font-size: 2em;}
h2 {font-size: 1.5em; margin-block-start: 0.0em; margin-block-end: 0.2em;}
h3 {font-size: 1.2em;}
p {font-size: 1em;}
input[type=number] {
width: 100px;
margin-right: 10px;
padding: 3px 5px;
display: inline-block;
border: 1px solid #ccc;
font-size: 16px;
}
input[type=number] {
width: 60px;
margin-right: 10px;
padding: 3px 5px;
display: inline-block;
border: 1px solid #ccc;
font-size: 16px;
}
input[type=text] {
padding: 3px 5px;
display: inline-block;
border: 1px solid #ccc;
font-size: 16px;
}
input[type=text] {
padding: 3px 5px;
display: inline-block;
border: 1px solid #ccc;
font-size: 16px;
}
select {
padding: 3px 5px;
display: inline-block;
border: 1px solid #ccc;
font-size: 16px;
margin-right: 10px;
}
input:out-of-range {
background-color: rgba(255, 0, 0, 0.25);
border: 1px solid red;
}
.button {
padding: 5px 10px;
width: 210px;
font-size: 16px;
}
select {
padding: 3px 5px;
display: inline-block;
border: 1px solid #ccc;
font-size: 16px;
margin-right: 10px;
min-width: 100px;
max-width: 100%;
vertical-align: middle;
overflow: hidden;
}
.move {
padding: 4px 4px;
width: 100px;
font-size: 12px;
}
.button {
padding: 5px 10px;
width: 160px;
font-size: 16px;
}
th, td {
padding: 5px 5px 5px 0px;
}
.multiplier {
padding: 0px 0px;
font-size: 12px;
}
th, td {
padding: 5px 5px 5px 0px;
}
#div2{
background-color:#777;
margin-bottom:20px;
}
.disabledDiv {
pointer-events: none;
opacity: 0.4;
}
table {
width: 660px;
padding: 5px;
table-layout: fixed;
}
</style>
<link href="firework.css?v=$COMMIT_HASH" rel="stylesheet">
<script type="text/javascript" src="jquery-3.6.0.min.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="firework.js?v=$COMMIT_HASH"></script>
#div2{
background-color:#777;
margin-bottom:20px;
}
.disabledDiv {
pointer-events: none;
opacity: 0.4;
}
</style>
<link href="firework.css?v=$COMMIT_HASH" rel="stylesheet">
<script type="text/javascript" src="jquery-3.6.0.min.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="firework.js?v=$COMMIT_HASH"></script>
</head>
<body style="font-family: arial; padding: 0px 10px;">
<h2>Analog ROI's</h2>
<p>On this page you define ROI's for the analog counters.
See <a href=https://jomjol.github.io/AI-on-the-edge-device-docs/ROI-Configuration/ target=_blank>https://jomjol.github.io/AI-on-the-edge-device-docs/ROI-Configuration/</a> for explanations.</p>
<input type="checkbox" id="Category_Analog_enabled" value="1" onclick = 'EnDisableAnalog()' checked ><label for="Category_Analog_enabled">Enable Analog ROI's</label></p>
<div id="div1">
<table>
<tr>
<td><canvas id="canvas" crossorigin></canvas></td>
</tr>
</table>
<h2>Analog ROI</h2>
<details id="desc_details" style="font-size:16px">
<summary><b>CLICK HERE</b> for usage description. More infos in documentation:
<a href=https://jomjol.github.io/AI-on-the-edge-device-docs/ROI-Configuration/ target=_blank>ROI Configuration</a>
</summary>
<p>
<b>R</b>egion <b>O</b>f <b>I</b>nterest (ROI) for analog pointer counter can be defined on this page. If no analog pointer counter need to be
processed, disable analog pointer counter processing by deselecting <b>"Analog ROI Processing"</b>.
</p>
<p>
By default one number sequence (a number seqence contains of 1-x digit ROIs + 1-x analog counter ROIs which are processed together) is
predefined and already selected in the drop down <b>"Number Sequence"</b>. If you need more than one number sequence additional
one's can be added with the buttons next to the drop down. Each number sequence will be processed separately.
</p>
<p>
Using drag and drop by mouse of by manually entering the parameters into the given fields the analog ROIs can be positined to the analog pointer
counters on the reference image. To have proper ROI definition please check the documentation:
<a href=https://jomjol.github.io/AI-on-the-edge-device-docs/ROI-Configuration/ target=_blank>ROI Configuration</a>. It's very important to be
really precise to have reliable processing. With the drop down <b>"ROI"</b> you can change between the different ROIs in the selected
number sequence. To create new ROIs use <b>"New ROI"</b>.
</p>
<p>
The order of the ROIs defines the position (and therefore the multiplication factor) within the reading sequence. The position
in the number sequence can be changed with the buttons <b>"Move ROI Lower"</b> and <b>"Move ROI Higher"</b>. The multiplication factor which is
shown below the ROI drop down is the multiplication factor of pure position/order in number sequence and the factor right-hand side to this is
the additionally corrected by decimal shift setting (configuration, expert parameter, default: 0).
</p>
<p>
After definition of digit ROIs is completed don't forget to save with the <b>"Save Config"</b> button!<br>
<b>NOTE:</b> There is no need to perform a reboot after every saving or step. It's sufficient to reboot after all configuration steps
(reference image, alignment, ROI configuration) are completed to activate new configuration.
</p>
</details>
<hr />
<p>
<table>
<tr>
<class id="Numbers_text" style="color:black;"><b>Number: </b></class>
<select id="Numbers_value1" onchange="numberChanged()">
</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>
<input type="checkbox" id="Category_Analog_enabled" value="1" onclick = 'EnDisableAnalog()' checked >
<label style="font-weight: bold; font-size: larger;" for="Category_Analog_enabled">Analog ROI Processing</label>
</p>
<table>
<tr>
<td><input class="button" type="submit" id= "newROI" name="newROI" onclick="newROI()" value="New ROI (after current)"></td>
<td><input class="button" type="submit" id= "deleteROI" name="deleteROI" onclick="deleteROI()" value="Delete ROI"></td>
<td></td>
</tr>
<tr>
<td>
<select id="index" name="index" onchange="ChangeSelection()" tabindex=1>
</select>
</td>
<td>
<input class="button" type="submit" id="renameROI" name="renameROI" onclick="renameROI()" value="Rename">
</td>
<td>
<input class="move" type="submit" id="moveNext" onclick="moveNext()" value="move Next">
<input class="move" type="submit" id="movePrevious" onclick="movePrevious()" value="move Previous">
</td>
</tr>
<tr>
<td>x: <input type="number" name="refx" id="refx" step=1 onchange="valuemanualchanged()" tabindex=2></td>
<td>Δx: <input type="number" name="refdx" id="refdx" step=1 onchange="valuemanualchangeddx()" tabindex=4></td>
<td><input type="checkbox" id="lockAspectRatio" name="lockAspectRatio" value="1" onclick="changelockAspectRatio()" checked tabindex=6><label for="lockAspectRatio"> Lock aspect ratio</label></td>
</tr>
<tr>
<td>y: <input type="number" name="refy" id="refy" step=1 onchange="valuemanualchanged()" tabindex=3></td>
<td>Δy: <input type="number" name="refdy" id="refdy" step=1 onchange="valuemanualchanged()" tabindex=5></td>
<td><input type="checkbox" id="lockSizes" name="lockSizes" value="1" onclick="changelockSizes()" checked tabindex=7><label for="lockSizes"> Synchronize Δx and Δy between ROIs</label></td>
</tr>
<tr>
<td colspan="2"></td>
<td><input type="checkbox" id="CCW" name="CCW" value="0" onclick="changeCCW()" unchecked tabindex=8><label for="CCW"> Counter-Clockwise Rotation: </label></td>
</tr>
</table>
</div>
<div id="div1">
<table>
<colgroup>
<col span="1" style="width: 22%;">
<col span="1" style="width: 26%;">
<col span="1" style="width: 26%;">
<col span="1" style="width: 26%;">
</colgroup>
<tr>
<td colspan="4" style="padding: 0px"><class id="Numbers_text" style="color:black;">Number Sequence:</class></td>
</tr>
<tr>
<td>
<select id="Numbers_value1" onchange="numberChanged()">
</select>
</td>
<td><input class="button" type="submit" id="newNumber" name="newNumber" onclick="newNumber()" value="New Sequence"></td>
<td><input class="button" type="submit" id="renameNumber" name="renameNumber" onclick="renameNumber()" value="Rename Sequence"></td>
<td><input class="button" type="submit" id="removeNumber" name="removeNumber" onclick="removeNumber()" value="Delete Sequence"></td>
</tr>
</table>
<hr />
<table>
<colgroup>
<col span="1" style="width: 22%;">
<col span="1" style="width: 26%;">
<col span="1" style="width: 26%;">
<col span="1" style="width: 26%;">
</colgroup>
<tr>
<td style="padding: 0px">ROI:</td>
</tr>
<tr>
<td><select id="index" name="index" onchange="ChangeSelection()" tabindex=1></select></td>
<td><input class="button" type="submit" id="newROI" name="newROI" onclick="newROI()" value="New ROI"></td>
<td><input class="button" type="submit" id="renameROI" name="renameROI" onclick="renameROI()" value="Rename ROI"></td>
<td><input class="button" type="submit" id="deleteROI" name="deleteROI" onclick="deleteROI()" value="Delete ROI"></td>
</tr>
<tr>
<td class="multiplier">Multiplier: <output type="text" id="multiplier" name="multiplier"></output><br>
(only based on order)
</td>
<td class="multiplier">Multiplier: <output type="text" id="multiplier_decshift" name="multiplier_decshift"></output><br>
(order + decimal shift: <output type="text" id="decimalShift" name="decimalShift"></output>)
</td>
<td><input class="button" type="submit" id="movePrevious" onclick="movePrevious()" value="Move ROI Higher"></td>
<td><input class="button" type="submit" id="moveNext" onclick="moveNext()" value="Move ROI Lower"></td>
</tr>
</table>
<table>
<tr>
<td><input class="button" type="submit" id="saveroi" name="saveroi" onclick="SaveToConfig()" value="Save" tabindex=9>
</tr>
<tr>
<td><button class="button" id="reboot" type="button" onclick="doReboot()">Reboot to activate the changes</button></td>
</tr>
</table>
<colgroup>
<col span="1" style="width: 18%;">
<col span="1" style="width: 18%;">
<col span="1" style="width: 64%;">
</colgroup>
<tr>
<td>x: <input type="number" name="refx" id="refx" step=1 onchange="valuemanualchanged()" tabindex=2></td>
<td>Δx: <input type="number" name="refdx" id="refdx" step=1 onchange="valuemanualchangeddx()" tabindex=4></td>
<td><input type="checkbox" id="lockAspectRatio" name="lockAspectRatio" value="1" onclick="changelockAspectRatio()" checked tabindex=6><label for="lockAspectRatio"> Lock aspect ratio </label></td>
</tr>
<tr>
<td>y: <input type="number" name="refy" id="refy" step=1 onchange="valuemanualchanged()" tabindex=3></td>
<td>Δy: <input type="number" name="refdy" id="refdy" step=1 onchange="valuemanualchanged()" tabindex=5></td>
<td><input type="checkbox" id="lockSizes" name="lockSizes" value="1" onclick="changelockSizes()" checked tabindex=7><label for="lockSizes"> Synchronize y, Δx and Δy between ROIs</label></td>
</tr>
<tr>
<td colspan="2"></td>
<td><input type="checkbox" id="CCW" name="CCW" value="0" onclick="changeCCW()" unchecked tabindex=8><label for="CCW">Counter clockwise rotation (CCW)</label></td>
</tr>
</table>
</div>
<table>
<colgroup>
<col span="1" style="width: 22%;">
<col span="1" style="width: 26%;">
<col span="1" style="width: 26%;">
<col span="1" style="width: 26%;">
</colgroup>
<tr>
<td colspan="3" style="vertical-align: bottom;"><b>Reference Image:</b></td>
<!---<td><button class="button" id="reboot" type="button" onclick="doReboot()">Reboot device</button></td>-->
<td><input style="font-weight:bold;" class="button" type="submit" id="saveroi" name="saveroi" onclick="SaveToConfig()" value="Save Config" tabindex=10></td>
</tr>
<tr>
<td colspan="4"><canvas id="canvas" crossorigin></canvas></td>
</tr>
</table>
<script type="text/javascript" src="common.js?v=$COMMIT_HASH"></script>
@@ -158,16 +237,15 @@ th, td {
lockSizes = false;
domainname = getDomainname();
function doReboot() {
if (confirm("Are you sure you want to reboot? Did you save your changes?")) {
var stringota = getDomainname() + "/reboot";
window.location = stringota;
window.location.href = stringota;
window.location.assign(stringota);
window.location.replace(stringota);
function doReboot() {
if (confirm("Are you sure you want to reboot? Did you save your changes?")) {
var stringota = getDomainname() + "/reboot";
window.location = stringota;
window.location.href = stringota;
window.location.assign(stringota);
window.location.replace(stringota);
}
}
}
function EnDisableAnalog() {
isEnabled = document.getElementById("Category_Analog_enabled").checked;
@@ -186,9 +264,9 @@ function EnDisableAnalog() {
sah1(document.getElementById("div1"), !isEnabled);
cofcat["Analog"]["enabled"] = isEnabled;
document.getElementById("saveroi").disabled = false;
if (isEnabled)
{
UpdateROIs();
@@ -212,6 +290,10 @@ function onNameChange(){
}
function deleteROI(){
if (!confirm("Delete the selected ROI?")) {
return; //break out of the function early because prompt was aborted
}
ROIInfo.splice(aktindex, 1);
if (aktindex > ROIInfo.length - 1){
aktindex = ROIInfo.length - 1;
@@ -220,18 +302,21 @@ function deleteROI(){
draw();
}
function newROI(){
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");
var _roinew = prompt("Please enter a name for the new ROI", "name");
if (_roinew === null) {
return; //break out of the function early because prompt was aborted
}
if (ROIInfo.length > 0)
erg = CreateROI(_number, "analog", sel.selectedIndex, _roinew, 1, 1, ROIInfo[aktindex]["dx"], ROIInfo[aktindex]["dy"], ROIInfo[aktindex]["CCW"]=="true");
erg = CreateROI(_number, "analog", sel.selectedIndex, _roinew, 15, 30, ROIInfo[aktindex]["dx"], ROIInfo[aktindex]["dy"], ROIInfo[aktindex]["CCW"]=="true");
else
erg = CreateROI(_number, "analog", sel.selectedIndex, _roinew, 1, 1, 30, 30, false);
erg = CreateROI(_number, "analog", sel.selectedIndex, _roinew, 15, 30, 30, 30, false);
if (erg != "")
firework.launch(erg, 'danger', 30000);
@@ -275,7 +360,9 @@ function changeCCW(){
ROIInfo[aktindex]["CCW"] = "true";
else
ROIInfo[aktindex]["CCW"] = "false";
UpdateROIs();
UpdateROIs();
}
function ChangeSelection(){
@@ -285,11 +372,68 @@ function ChangeSelection(){
}
function SaveToConfig(){
// _zwcat = getConfigCategory();
cofcat["Analog"]["enabled"] = document.getElementById("Category_Analog_enabled").checked;
WriteConfigININew();
SaveConfigToServer(domainname);
firework.launch('Configuration got updated. It will get applied after the next reboot!', 'success', 5000);
if (confirm("Are you sure you want to save the new analog ROI configuration?")) {
//_zwcat = getConfigCategory();
cofcat["Analog"]["enabled"] = document.getElementById("Category_Analog_enabled").checked;
WriteConfigININew();
SaveConfigToServer(domainname);
UpdateROIs();
document.getElementById("saveroi").disabled = true;
firework.launch('Configuration saved. It will get applied after next reboot', 'success', 5000);
}
}
function ShowMultiplier()
{
var decimalShift = 0;
var multiplier;
var multiplier_decshift;
var fixedDecimals;
var fixedDecimals_decshift;
var NumberInfo = getNUMBERInfo();
var CategoryInfo = getConfigCategory();
var sel = document.getElementById("Numbers_value1");
var _number= sel.options[sel.selectedIndex].text;
document.getElementById("decimalShift").value = 0;
for (var i = 0; i < NumberInfo.length; ++i) {
if (NumberInfo[i]["name"] == _number) {
if (NumberInfo[i]["PostProcessing"]["DecimalShift"]["enabled"]) {
decimalShift = NumberInfo[i]["PostProcessing"]["DecimalShift"]["value1"];
document.getElementById("decimalShift").value=decimalShift;
}
}
}
if (CategoryInfo["Analog"]["enabled"] == true && CategoryInfo["Digits"]["enabled"] == true) { // Digit + Analog
multiplier = fixedDecimals = aktindex + 1;
multiplier_decshift = fixedDecimals_decshift = multiplier - Number(decimalShift);
if (multiplier < 0)
fixedDecimals = 0;
if (multiplier_decshift < 0)
fixedDecimals_decshift = 0;
document.getElementById("multiplier").value="x" + Number(10 ** (-1*multiplier)).toFixed(fixedDecimals);
document.getElementById("multiplier_decshift").value="x" + Number(10 ** (-1*multiplier_decshift)).toFixed(fixedDecimals_decshift);
}
else if (CategoryInfo["Analog"]["enabled"] == true && CategoryInfo["Digits"]["enabled"] == false) { // Only Analog
multiplier = ROIInfo.length - 1 - aktindex;
multiplier_decshift = fixedDecimals_decshift = multiplier + Number(decimalShift);
if (multiplier_decshift > 0)
fixedDecimals_decshift = 0;
if (fixedDecimals_decshift < 0) {
fixedDecimals_decshift = -1 * fixedDecimals_decshift;
}
document.getElementById("multiplier").value="x" + Number(10 ** multiplier).toFixed(0);
document.getElementById("multiplier_decshift").value="x" + Number(10 ** multiplier_decshift).toFixed(fixedDecimals_decshift);
}
}
@@ -305,19 +449,28 @@ function UpdateROIs(_sel){
{
document.getElementById("Category_Analog_enabled").checked = false;
EnDisableAnalog();
firework.launch('Analog ROIs are disabled - please enable first (Check box top left)', 'warning', 10000);
firework.launch('Analog ROI processing is disabled. Activate with checkbox if needed', 'warning', 10000);
return;
}
if (ROIInfo.length == 0){
firework.launch('There are no ROIs defined. Please first create a new ROI ("New ROIs ...")', 'danger', 10000);
firework.launch('No analog ROIs defined in selected number sequence', 'warning', 10000);
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("index").disabled = true;
document.getElementById("multiplier").style.display = "none";
document.getElementById("multiplier_decshift").style.display = "none";
document.getElementById("refx").disabled = true;
document.getElementById("refdx").disabled = true;
document.getElementById("refy").disabled = true;
document.getElementById("refdy").disabled = true;
document.getElementById("lockSizes").disabled = true;
document.getElementById("lockAspectRatio").disabled = true;
document.getElementById("CCW").disabled = true;
document.getElementById("moveNext").disabled = true;
document.getElementById("movePrevious").disabled = true;
document.getElementById("saveroi").disabled = false;
return;
}
else
@@ -326,6 +479,15 @@ function UpdateROIs(_sel){
document.getElementById("deleteROI").disabled = false;
document.getElementById("renameROI").disabled = false;
document.getElementById("index").disabled = false;
document.getElementById("multiplier").style.display = "";
document.getElementById("multiplier_decshift").style.display = "";
document.getElementById("refx").disabled = false;
document.getElementById("refdx").disabled = false;
document.getElementById("refy").disabled = false;
document.getElementById("refdy").disabled = false;
document.getElementById("lockSizes").disabled = false;
document.getElementById("lockAspectRatio").disabled = false;
document.getElementById("CCW").disabled = false;
document.getElementById("saveroi").disabled = false;
}
@@ -335,7 +497,7 @@ function UpdateROIs(_sel){
}
if (aktindex > ROIInfo.length)
aktindex = ROIInfo.length;
aktindex = ROIInfo.length-1;
for (var i = 0; i < ROIInfo.length; ++i){
var option = document.createElement("option");
@@ -358,7 +520,9 @@ function UpdateROIs(_sel){
document.getElementById("moveNext").disabled = false;
if (aktindex == (ROIInfo.length-1)){
document.getElementById("moveNext").disabled = true;
}
}
ShowMultiplier();
document.getElementById("lockAspectRatio").checked = lockAspectRatio;
document.getElementById("lockSizes").checked = lockSizes;
@@ -373,8 +537,7 @@ function UpdateROIs(_sel){
rect.startY = ROIInfo[aktindex]["y"];
rect.w = ROIInfo[aktindex]["dx"];
rect.h = ROIInfo[aktindex]["dy"];
draw();
draw();
}
function loadCanvas(dataURL) {
@@ -404,10 +567,20 @@ function UpdateROIs(_sel){
var left = box.left + scrollLeft - clientLeft;
return { top: Math.round(top), left: Math.round(left) };
}
/* hash #description open the details part of the page */
function openDescription() {
if(window.location.hash) {
var hash = window.location.hash.substring(1); //Puts hash in variable, and removes the # character
if(hash == 'description')
document.getElementById("desc_details").open = true;
}
}
function init() {
openDescription();
domainname = getDomainname();
canvas.addEventListener('mousedown', mouseDown, false);
canvas.addEventListener('mouseup', mouseUp, false);
@@ -440,11 +613,12 @@ function UpdateROIs(_sel){
console.log("Not all ROI have the same dX and dY, unticking the sync checkbox!");
}
document.getElementById("saveroi").disabled = true;
drawImage();
draw();
}
function drawImage(){
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
@@ -483,10 +657,13 @@ function UpdateNUMBERS(_sel){
function renameNumber(){
var sel = document.getElementById("Numbers_value1");
var _delte= sel.options[sel.selectedIndex].text;
var _numbernew = prompt("Please enter new name", _delte);
var _delete= sel.options[sel.selectedIndex].text;
var _numbernew = prompt("Please enter a new name for the selected number sequence", _delete);
if (_numbernew === null) {
return; //break out of the function early because prompt was aborted
}
erg = RenameNUMBER(_delte, _numbernew);
erg = RenameNUMBER(_delete, _numbernew);
if (erg != "")
firework.launch(erg, 'danger', 30000);
else
@@ -494,7 +671,10 @@ function renameNumber(){
}
function newNumber(){
var _numbernew = prompt("Please enter name of new number", "name");
var _numbernew = prompt("Please enter a name for the new number sequence", "name");
if (_numbernew === null) {
return; //break out of the function early because prompt was aborted
}
erg = CreateNUMBER(_numbernew);
if (erg != "")
@@ -505,10 +685,13 @@ function newNumber(){
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?")) {
if (confirm("The entire number sequence will be removed (digit + analog parts). " +
"To remove single ROI of the number sequence, use \"Delete ROI\" instead.\n" +
"Do you really want to proceed?"))
{
var sel = document.getElementById("Numbers_value1");
var _delte= sel.options[sel.selectedIndex].text;
erg = DeleteNUMBER(_delte);
var _delete= sel.options[sel.selectedIndex].text;
erg = DeleteNUMBER(_delete);
if (erg != "")
firework.launch(erg, 'danger', 30000);
UpdateNUMBERS();
@@ -576,8 +759,12 @@ function drawTextBG(context, txt, x, y, padding) {
var dx = parseInt(ROIInfo[_nb].dx) + parseInt(lw);
var dy = parseInt(ROIInfo[_nb].dy) + parseInt(lw);
context.strokeRect(x0, y0, dx, dy);
drawTextBG(context, ROIInfo[_nb]["name"], x0+dx/2-0.5, y0-13, 5);
if (ROIInfo[_nb]["CCW"] != "true")
drawTextBG(context, ROIInfo[_nb]["name"], x0+dx/2-0.5, y0-13, 5);
else
drawTextBG(context, ROIInfo[_nb]["name"]+" (CCW)", x0+dx/2-0.5, y0-13, 5);
lw = 1;
var x0 = parseInt(ROIInfo[_nb].x) - parseInt(lw/2);
var y0 = parseInt(ROIInfo[_nb].y) - parseInt(lw/2);
@@ -586,7 +773,8 @@ function drawTextBG(context, txt, x, y, padding) {
context.strokeRect(x0, y0, dx, dy);
context.lineWidth = lw;
context.beginPath();
context.arc(x0+dx/2, y0+dy/2, dx/2, 0, 2 * Math.PI);
// context.arc (x0+dx/2, y0+dy/2, dx/2, 0, 2 * Math.PI);
context.ellipse(x0+dx/2, y0+dy/2, dx/2, dy/2, 0, 0, 2 * Math.PI);
context.moveTo(x0+dx/2, y0);
context.lineTo(x0+dx/2, y0+dy);
context.moveTo(x0, y0+dy/2);
@@ -602,11 +790,17 @@ function drawTextBG(context, txt, x, y, padding) {
var y0 = parseInt(rect.startY) - parseInt(lw/2);
var dx = parseInt(rect.w) + parseInt(lw);
var dy = parseInt(rect.h) + parseInt(lw);
context.strokeRect(x0, y0, dx, dy);
drawTextBG(context, ROIInfo[aktindex]["name"], x0+dx/2, y0-11, 5);
context.strokeRect(x0, y0, dx, dy);
if (ROIInfo[aktindex]["CCW"] != "true")
drawTextBG(context, ROIInfo[aktindex]["name"], x0+dx/2, y0-11, 5);
else
drawTextBG(context, ROIInfo[aktindex]["name"] + " (CCW)", x0+dx/2, y0-11, 5);
context.lineWidth = 1;
context.beginPath();
context.arc(x0+dx/2, y0+dy/2, dx/2, 0, 2 * Math.PI);
// context.arc(x0+dx/2, y0+dy/2, dx/2, 0, 2 * Math.PI);
context.ellipse(x0+dx/2, y0+dy/2, dx/2, dy/2, 0, 0, 2 * Math.PI);
context.moveTo(x0+dx/2, y0);
context.lineTo(x0+dx/2, y0+dy);
context.moveTo(x0, y0+dy/2);
@@ -706,6 +900,7 @@ function drawTextBG(context, txt, x, y, padding) {
rect.startY = document.getElementById("refy").value;
draw();
}
document.getElementById("saveroi").disabled = false;
}
function valuemanualchangeddx(){
@@ -721,6 +916,7 @@ function drawTextBG(context, txt, x, y, padding) {
rect.startY = document.getElementById("refy").value;
draw();
}
document.getElementById("saveroi").disabled = false;
}
@@ -730,8 +926,10 @@ function drawTextBG(context, txt, x, y, padding) {
sel = document.getElementById("index");
var _roialt= sel.options[sel.selectedIndex].text;
var _roinew = prompt("Please enter new name", _roialt);
var _roinew = prompt("Please enter a new name for the selected ROI", _roialt);
if (_roinew === null) {
return; //break out of the function early because prompt was aborted
}
erg = RenameROI(_number, "analog", _roialt, _roinew);
if (erg != "")
@@ -742,13 +940,15 @@ function drawTextBG(context, txt, x, y, padding) {
function numberChanged()
{
aktindex = 0;
UpdateROIs();
}
init();
</script>
</body>
</html>

View File

@@ -1,136 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<link rel="icon" href="favicon.ico?v=$COMMIT_HASH" type="image/x-icon">
<meta charset="utf-8"/>
<title>Check</title>
<style>
h1 {font-size: 2em;}
h2 {font-size: 1.5em; margin-block-start: 0.0em; margin-block-end: 0.2em;}
h3 {font-size: 1.2em;}
p {font-size: 1em;}
.button {
padding: 5px 10px;
width: 210px;
font-size: 16px;
}
</style>
</head>
<body style="font-family: arial">
<table>
<tr><td colspan="2">Result:</td></tr>
<tr>
<td>
<iframe name="maincontent" id ="maincontent" width="700px" height="700px"></iframe>
</td>
<td style="padding-left: 15px;">
<p>
<input class="button" type="submit" id="take" onclick="doTake()" value="1. Take Picture">
</p>
<p>
<input class="button" type="submit" id="align" onclick="doAlign()" value="2. Align Image"><br>
</p>
<p>
Takes up to 2 Minutes!
</p>
Digits and Analog recognition not yet implemented.
<p>
<input class="button" type="submit" id="digits" onclick="doDigits()" value="3a. Analyse Digits">
</p>
<p>
<input class="button" type="submit" id="analog" onclick="doAnalog()" value="3b Analyse Analog">
</p>
</td>
</tr>
</table>
<script type="text/javascript" src="common.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="readconfig.js?v=$COMMIT_HASH"></script>
<script type="text/javascript">
var domainname = getDomainname();
function doAnalog(){
var xhttp = new XMLHttpRequest();
url = domainname + "/editflow?task=test_analog";
if (domainname.length > 0){
url = url + "&host=" + domainname;
}
xhttp.open("GET", url, false);
xhttp.send();
var html = xhttp.responseText;
html = html.replace("src=\"/", "src=\"" + domainname + "/");
document.getElementById("maincontent").src = 'data:text/html,' + encodeURIComponent(html);
}
function doDigits(){
var xhttp = new XMLHttpRequest();
url = domainname + "/editflow?task=test_digits";
if (domainname.length > 0){
url = url + "&host=" + domainname;
}
xhttp.open("GET", url, false);
xhttp.send();
var html = xhttp.responseText;
html = html.replace("src=\"/", "src=\"" + domainname + "/");
document.getElementById("maincontent").src = 'data:text/html,' + encodeURIComponent(html);
}
function doAlign(){
var xhttp = new XMLHttpRequest();
url = domainname + "/editflow?task=test_align";
if (domainname.length > 0){
url = url + "&host=" + domainname;
}
xhttp.open("GET", url, false);
xhttp.send();
var html = xhttp.responseText;
html = html.replace("src=\"/", "src=\"" + domainname + "/");
document.getElementById("maincontent").src = 'data:text/html,' + encodeURIComponent(html);
document.getElementById("align").disabled = false;
// document.getElementById("digits").disabled = false;
// document.getElementById("analog").disabled = false;
}
function doTake(){
var xhttp = new XMLHttpRequest();
url = domainname + "/editflow?task=test_take";
if (domainname.length > 0){
url = url + "&host=" + domainname;
}
xhttp.open("GET", url, false);
xhttp.send();
var html = xhttp.responseText;
document.getElementById("maincontent").src = 'data:text/html,' + encodeURIComponent(html);
document.getElementById("align").disabled = false;
document.getElementById("digits").disabled = true;
document.getElementById("analog").disabled = true;
}
function Init(){
domainname = getDomainname();
document.getElementById("align").disabled = true;
document.getElementById("digits").disabled = true;
document.getElementById("analog").disabled = true;
}
Init();
</script>
</body>
</html>

View File

@@ -1,25 +1,24 @@
<!DOCTYPE html>
<html>
<html lang="en" xml:lang="en">
<head>
<link rel="icon" href="favicon.ico?v=$COMMIT_HASH" type="image/x-icon">
<title>Edit Config</title>
<meta charset="utf-8">
<meta charset="UTF-8" />
<style>
h1 {font-size: 2em;}
h2 {font-size: 1.5em; margin-block-start: 0.0em; margin-block-end: 0.2em;}
h3 {font-size: 1.2em;}
p {font-size: 1em;}
h1 {font-size: 2em;}
h2 {font-size: 1.5em; margin-block-start: 0.0em; margin-block-end: 0.2em;}
h3 {font-size: 1.2em;}
p {font-size: 1em;}
.button {
padding: 5px 20px;
width: 211px;
font-size: 16px;
}
.button {
padding: 5px 10px;
width: 220px;
font-size: 16px;
}
textarea {
font-size: 14px;
}
textarea {
font-size: 15px;
}
</style>
<link href="firework.css?v=$COMMIT_HASH" rel="stylesheet">
<script type="text/javascript" src="jquery-3.6.0.min.js?v=$COMMIT_HASH"></script>
@@ -28,59 +27,60 @@ textarea {
<body style="font-family: arial; padding: 0px 10px;">
<table>
<tr><td><h2>Config.ini:</h2></td></tr>
<tr>
<td colspan="3">
<textarea id="inputTextToSave" cols="100" rows="33"></textarea>
</td>
</tr>
<tr>
<td><button class="button" onclick="saveTextAsFile()">Save</button></td>
</tr>
<tr>
<td><button class="button" id="reboot" type="button" onclick="doReboot()">Reboot to activate changes</button></td>
</tr>
</table>
<table style="width:660px">
<h2>Configuration - "Config.ini" Editor</h2>
<td>
<textarea id="inputTextToSave" rows="30" style="width:100%"></textarea>
</td>
</table>
<script type="text/javascript" src="common.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="readconfigcommon.js?v=$COMMIT_HASH"></script>
<script type="text/javascript">
var canvas = document.getElementById('canvas'),
domainname = getDomainname();
<table>
<td>
<button class="button" onclick="saveTextAsFile()">Save Config</button>
</td>
<td>
<button class="button" id="reboot" type="button" onclick="doReboot()">Reboot to activate changes</button>
</td>
</table>
<script type="text/javascript" src="common.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="readconfigcommon.js?v=$COMMIT_HASH"></script>
<script type="text/javascript">
var canvas = document.getElementById('canvas'),
domainname = getDomainname();
function LoadConfigNeu() {
domainname = getDomainname();
loadConfig(domainname);
document.getElementById("inputTextToSave").value = getConfig();
function LoadConfigNeu() {
domainname = getDomainname();
loadConfig(domainname);
document.getElementById("inputTextToSave").value = getConfig();
}
function saveTextAsFile()
{
if (confirm("Are you sure you want to save the configuration?")) {
FileDeleteOnServer("/config/config.ini", domainname);
var textToSave = document.getElementById("inputTextToSave").value;
FileSendContent(textToSave, "/config/config.ini", domainname);
firework.launch('Configuration saved. It will get applied after next reboot', 'success', 5000);
}
}
function saveTextAsFile()
{
if (confirm("Are you sure you want to update \"config.ini\"?")) {
FileDeleteOnServer("/config/config.ini", domainname);
var textToSave = document.getElementById("inputTextToSave").value;
FileSendContent(textToSave, "/config/config.ini", domainname);
firework.launch('Configuration got updated. It will get applied after the next reboot!', 'success', 5000);
function doReboot() {
if (confirm("Are you sure you want to reboot?")) {
var stringota = "/reboot";
window.location = stringota;
window.location.href = stringota;
window.location.assign(stringota);
window.location.replace(stringota);
}
}
}
function doReboot() {
if (confirm("Are you sure you want to reboot the ESP32?")) {
var stringota = "/reboot";
window.location = stringota;
window.location.href = stringota;
window.location.assign(stringota);
window.location.replace(stringota);
}
}
LoadConfigNeu();
</script>
LoadConfigNeu();
</script>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@@ -1,137 +1,212 @@
<!DOCTYPE html>
<html>
<html lang="en" xml:lang="en">
<head>
<link rel="icon" href="favicon.ico?v=$COMMIT_HASH" type="image/x-icon">
<meta charset="utf-8"/>
<title>Digit ROI's</title>
<meta charset="UTF-8" />
<title>Digit ROI</title>
<style>
h1 {font-size: 2em;}
h2 {font-size: 1.5em; margin-block-start: 0.0em; margin-block-end: 0.2em;}
h3 {font-size: 1.2em;}
p {font-size: 1em;}
<style>
h1 {font-size: 2em;}
h2 {font-size: 1.5em; margin-block-start: 0.0em; margin-block-end: 0.2em;}
h3 {font-size: 1.2em;}
p {font-size: 1em;}
input[type=number] {
width: 100px;
margin-right: 10px;
padding: 3px 5px;
display: inline-block;
border: 1px solid #ccc;
font-size: 16px;
}
input[type=number] {
width: 60px;
margin-right: 10px;
padding: 3px 5px;
display: inline-block;
border: 1px solid #ccc;
font-size: 16px;
}
input[type=text] {
padding: 3px 5px;
display: inline-block;
border: 1px solid #ccc;
font-size: 16px;
}
input[type=text] {
padding: 3px 5px;
display: inline-block;
border: 1px solid #ccc;
font-size: 16px;
}
select {
padding: 3px 5px;
display: inline-block;
border: 1px solid #ccc;
font-size: 16px;
margin-right: 10px;
}
input:out-of-range {
background-color: rgba(255, 0, 0, 0.25);
border: 1px solid red;
}
.button {
padding: 5px 10px;
width: 210px;
font-size: 16px;
}
select {
padding: 3px 5px;
display: inline-block;
border: 1px solid #ccc;
font-size: 16px;
margin-right: 10px;
min-width: 100px;
max-width: 100%;
vertical-align: middle;
overflow: hidden;
}
.move {
padding: 4px 4px;
width: 100px;
font-size: 12px;
}
.button {
padding: 5px 10px;
width: 160px;
font-size: 16px;
}
.multiplier {
padding: 0px 0px;
font-size: 12px;
}
th, td {
padding: 5px 5px 5px 0px;
}
table {
width: 660px;
padding: 5px;
table-layout: fixed;
}
</style>
<link href="firework.css?v=$COMMIT_HASH" rel="stylesheet">
<script type="text/javascript" src="jquery-3.6.0.min.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="firework.js?v=$COMMIT_HASH"></script>
th, td {
padding: 5px 5px 5px 0px;
}
</style>
<link href="firework.css?v=$COMMIT_HASH" rel="stylesheet">
<script type="text/javascript" src="jquery-3.6.0.min.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="firework.js?v=$COMMIT_HASH"></script>
</head>
<body style="font-family: arial; padding: 0px 10px;">
<h2>Digit ROI's</h2>
<p>On this page you define ROI's for the digits.
See <a href=https://jomjol.github.io/AI-on-the-edge-device-docs/ROI-Configuration/ target=_blank>https://jomjol.github.io/AI-on-the-edge-device-docs/ROI-Configuration/</a> for explanations.</p>
<p><input type="checkbox" id="Category_Digits_enabled" value="1" onclick = 'EnDisableDigits()' checked><label for="Category_Digits_enabled">Enable Digit ROI's</label></p>
<h2>Digit ROI</h2>
<details id="desc_details" style="font-size:16px">
<summary><b>CLICK HERE</b> for usage description. More infos in documentation:
<a href=https://jomjol.github.io/AI-on-the-edge-device-docs/ROI-Configuration/ target=_blank>ROI Configuration</a>
</summary>
<p>
<b>R</b>egion <b>O</b>f <b>I</b>nterest (ROI) for digit numbers can be defined on this page. If no digit numbers need to be processed,
disable digit processing by deselecting <b>"Digit ROI Processing"</b>.
</p>
<p>
By default one number sequence (a number seqence contains of 1-x digit ROIs + 1-x analog counter ROIs which are processed together) is
predefined and already selected in the drop down <b>"Number sequence"</b>. If you need more than one number sequence additional
one's can be added with the buttons next to the drop down. Each number sequence will be processed separately.
</p>
<p>
Using drag and drop by mouse of by manually entering the parameters into the given fields the digit ROIs can be positined to the digit numbers
on the reference image. To have proper ROI definition please check the documentation:
<a href=https://jomjol.github.io/AI-on-the-edge-device-docs/ROI-Configuration/ target=_blank>ROI Configuration</a>. It's very important to be
really precise to have reliable processing. With the drop down <b>"ROI"</b> you can change between the different ROIs in the selected
number sequence. To create new ROIs use <b>"New ROI"</b>.
</p>
<p>
The order of the ROIs defines the position (and therefore the multiplication factor) within the reading sequence. The position
in the number sequence can be changed with the buttons <b>"Move ROI Lower"</b> and <b>"Move ROI Higher"</b>. The multiplication factor which is
shown below the ROI drop down is the multiplication factor of pure position/order in number sequence and the factor right-hand side to this is
the additionally corrected by decimal shift setting (configuration, expert parameter, default: 0).
</p>
<p>
After definition of digit ROIs is completed don't forget to save with the <b>"Save Config"</b> button!<br>
<b>NOTE:</b> There is no need to perform a reboot after every saving or step. It's sufficient to reboot after all configuration steps
(reference image, alignment, ROI configuration) are completed to activate new configuration.
</p>
</details>
<hr />
<p>
<input type="checkbox" id="Category_Digits_enabled" value="1" onclick = 'EnDisableDigits()' checked>
<label style="font-weight: bold; font-size: larger;" for="Category_Digits_enabled">Digit ROI Processing</label>
</p>
<p>After saving the digit ROI's, you can define the <a href=edit_analog.html>analog</a> ROI's if your meter has analog counters.<br>
Only after those steps a reboot is required.</p>
<div id="div1">
<table>
<tr>
<canvas id="canvas" crossorigin></canvas>
</tr>
</table>
<p>
<table>
<tr>
<class id="Numbers_text" style="color:black;"><b>Number:</b> </class>
<table>
<colgroup>
<col span="1" style="width: 22%;">
<col span="1" style="width: 26%;">
<col span="1" style="width: 26%;">
<col span="1" style="width: 26%;">
</colgroup>
<tr>
<td colspan="4" style="padding: 0px"><class id="Numbers_text" style="color:black;">Number Sequence:</class></td>
</tr>
<tr>
<td>
<select id="Numbers_value1" onchange="numberChanged()">
</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>
</td>
<td><input class="button" type="submit" id="newNumber" name="newNumber" onclick="newNumber()" value="New Sequence"></td>
<td><input class="button" type="submit" id="renameNumber" name="renameNumber" onclick="renameNumber()" value="Rename Sequence"></td>
<td><input class="button" type="submit" id="removeNumber" name="removeNumber" onclick="removeNumber()" value="Delete Sequence"></td>
</tr>
</table>
<hr />
<table>
<colgroup>
<col span="1" style="width: 22%;">
<col span="1" style="width: 26%;">
<col span="1" style="width: 26%;">
<col span="1" style="width: 26%;">
</colgroup>
<tr>
<td style="padding: 0px">ROI:</td>
</tr>
<tr>
<td><select id="index" name="index" onchange="ChangeSelection()" tabindex=1></select></td>
<td><input class="button" type="submit" id="newROI" name="newROI" onclick="newROI()" value="New ROI"></td>
<td><input class="button" type="submit" id="renameROI" name="renameROI" onclick="renameROI()" value="Rename ROI"></td>
<td><input class="button" type="submit" id="deleteROI" name="deleteROI" onclick="deleteROI()" value="Delete ROI"></td>
</tr>
<tr>
<td class="multiplier">Multiplier: <output type="text" id="multiplier" name="multiplier"></output><br>
(only based on order)
</td>
<td class="multiplier">Multiplier: <output type="text" id="multiplier_decshift" name="multiplier_decshift"></output><br>
(order + decimal shift: <output type="text" id="decimalShift" name="decimalShift"></output>)
</td>
<td><input class="button" type="submit" id="movePrevious" onclick="movePrevious()" value="Move ROI Higher"></td>
<td><input class="button" type="submit" id="moveNext" onclick="moveNext()" value="Move ROI Lower"></td>
</tr>
</table>
<table>
<tr>
<td><input class="button" type="submit" id="newROI" name="newROI" onclick="newROI()" value="New ROI (after current)"></td>
<td><input class="button" type="submit" id="deleteROI" name="deleteROI" onclick="deleteROI()" value="Delete ROI"></td>
<td></td>
</tr>
<tr>
<td>
<select id="index" name="index" onchange="ChangeSelection()" tabindex=1>
</select>
</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">
</td>
</tr>
<tr>
<td>x: <input type="number" name="refx" id="refx" step=1 onchange="valuemanualchanged()" tabindex=2></td>
<td>Δx: <input type="number" name="refdx" id="refdx" step=1 onchange="valuemanualchangeddx()" tabindex=4></td>
<td><input type="checkbox" id="lockAspectRatio" name="lockAspectRatio" value="1" onclick="changelockAspectRatio()" checked tabindex=6><label for="lockAspectRatio"> Lock aspect ratio </label></td>
</tr>
<tr>
<td>y: <input type="number" name="refy" id="refy" step=1 onchange="valuemanualchanged()" tabindex=3></td>
<td>Δy: <input type="number" name="refdy" id="refdy" step=1 onchange="valuemanualchanged()" tabindex=5></td>
<td><input type="checkbox" id="lockSizes" name="lockSizes" value="1" onclick="changelockSizes()" checked tabindex=7><label for="lockSizes"> Synchronize y, Δx and Δy between ROIs</label></td>
</tr>
<tr>
<td colspan="2"></td>
<td ><input type="checkbox" id="lockSpaceEquidistant" name="lockSpaceEquidistant" value="1" onclick="changeLockSpaceEquidistant()" checked tabindex=9>
<label for="lockSpaceEquidistant">Keep equidistance of <input type="number" name="space" id="space" step=1 onchange="valuemanualchangedspace()" tabindex=8> between all ROIs</label></td>
</tr>
<colgroup>
<col span="1" style="width: 18%;">
<col span="1" style="width: 18%;">
<col span="1" style="width: 64%;">
</colgroup>
<tr>
<td>x: <input type="number" name="refx" id="refx" step=1 onchange="valuemanualchanged()" tabindex=2></td>
<td>Δx: <input type="number" name="refdx" id="refdx" step=1 onchange="valuemanualchangeddx()" tabindex=4></td>
<td><input type="checkbox" id="lockAspectRatio" name="lockAspectRatio" value="1" onclick="changelockAspectRatio()" checked tabindex=6><label for="lockAspectRatio"> Lock aspect ratio </label></td>
</tr>
<tr>
<td>y: <input type="number" name="refy" id="refy" step=1 onchange="valuemanualchanged()" tabindex=3></td>
<td>Δy: <input type="number" name="refdy" id="refdy" step=1 onchange="valuemanualchanged()" tabindex=5></td>
<td><input type="checkbox" id="lockSizes" name="lockSizes" value="1" onclick="changelockSizes()" checked tabindex=7><label for="lockSizes"> Synchronize y, Δx and Δy between ROIs</label></td>
</tr>
<tr>
<td colspan="2"></td>
<td><input type="checkbox" id="lockSpaceEquidistant" name="lockSpaceEquidistant" value="1" onclick="changeLockSpaceEquidistant()" checked tabindex=8>
<label for="lockSpaceEquidistant">Keep equidistance of <input type="number" name="space" id="space" step=1 onchange="valuemanualchangedspace()" tabindex=9> between all ROIs</label>
</td>
</tr>
</table>
</div>
<table>
<tr>
<td><input class="button" type="submit" id="saveroi" name="saveroi" onclick="SaveToConfig()" value="Save" tabindex=10>
<p>Proceed to update the <a href=edit_analog.html>analog</a> ROI's when you are done or <a href=reboot_page.html>reboot</a> if there are no analogue counters.</p></td>
</tr>
</table>
<colgroup>
<col span="1" style="width: 22%;">
<col span="1" style="width: 26%;">
<col span="1" style="width: 26%;">
<col span="1" style="width: 26%;">
</colgroup>
<tr>
<td colspan="3" style="vertical-align: bottom;"><b>Reference Image:</b></td>
<td><input style="font-weight:bold;" class="button" type="submit" id="saveroi" name="saveroi" onclick="SaveToConfig()" value="Save Config" tabindex=10></td>
</tr>
<tr>
<td colspan="4"><canvas id="canvas" crossorigin></canvas></td>
</tr>
</table>
<script type="text/javascript" src="common.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="readconfigcommon.js?v=$COMMIT_HASH"></script>
@@ -183,6 +258,7 @@ function EnDisableDigits() {
sah1(document.getElementById("div1"), !isEnabled);
cofcat["Digits"]["enabled"] = isEnabled;
document.getElementById("saveroi").disabled = false;
if (isEnabled)
{
@@ -208,6 +284,10 @@ function onNameChange(){
}
function deleteROI(){
if (!confirm("Delete the selected ROI?")) {
return; //break out of the function early because prompt was aborted
}
ROIInfo.splice(aktindex, 1);
if (aktindex > ROIInfo.length - 1){
aktindex = ROIInfo.length - 1;
@@ -222,7 +302,10 @@ function newROI() {
sel = document.getElementById("index");
var _roialt= sel.options[sel.selectedIndex].text;
var _roinew = prompt("Please enter name of new ROI", "name");
var _roinew = prompt("Please enter a name for the new ROI", "name");
if (_roinew === null) {
return; //break out of the function early because prompt was aborted
}
if (ROIInfo.length > 0) {
if (ROIInfo.length > 1) {
@@ -232,7 +315,7 @@ function newROI() {
parseInt(ROIInfo[sel.selectedIndex].y), ROIInfo[aktindex]["dx"], ROIInfo[aktindex]["dy"], 0);
}
else
erg = CreateROI(_number, "digit", sel.selectedIndex, _roinew, 1, 1, 30, 51, 0);
erg = CreateROI(_number, "digit", sel.selectedIndex, _roinew, 15, 30, 30, 51, 0);
if (erg != "")
firework.launch(erg, 'danger', 30000);
@@ -274,7 +357,7 @@ function changelockSizes(){
valuemanualchangedspace();
if (!lockSizes) {
firework.launch("For best results it is in most cases advised to keep the y, Δx and Δy identical!", 'warning', 10000);
firework.launch("In most cases it's advised to keep the y, Δx and Δy identical!", 'warning', 10000);
}
}
@@ -296,11 +379,51 @@ function ChangeSelection(){
}
function SaveToConfig(){
// _zwcat = getConfigCategory();
cofcat["Digits"]["enabled"] = document.getElementById("Category_Digits_enabled").checked;
WriteConfigININew();
SaveConfigToServer(domainname);
firework.launch('Configuration got updated. It will get applied after the next reboot!', 'success', 5000);
if (confirm("Are you sure you want to save the new digit ROI configuration?")) {
// _zwcat = getConfigCategory();
cofcat["Digits"]["enabled"] = document.getElementById("Category_Digits_enabled").checked;
WriteConfigININew();
SaveConfigToServer(domainname);
UpdateROIs();
document.getElementById("saveroi").disabled = true;
firework.launch('Configuration saved. It will get applied after next reboot', 'success', 5000);
}
}
function ShowMultiplier()
{
var decimalShift = 0;
var multiplier;
var multiplier_decshift;
var fixedDecimals_decshift;
var NumberInfo = getNUMBERInfo();
var sel = document.getElementById("Numbers_value1");
var _number= sel.options[sel.selectedIndex].text;
document.getElementById("decimalShift").value = 0;
for (var i = 0; i < NumberInfo.length; ++i) {
if (NumberInfo[i]["name"] == _number) {
if (NumberInfo[i]["PostProcessing"]["DecimalShift"]["enabled"]) {
decimalShift = NumberInfo[i]["PostProcessing"]["DecimalShift"]["value1"];
document.getElementById("decimalShift").value = decimalShift;
}
}
}
multiplier = ROIInfo.length - 1 - aktindex;
multiplier_decshift = fixedDecimals_decshift = multiplier + Number(decimalShift);
if (multiplier_decshift > 0)
fixedDecimals_decshift = 0;
if (fixedDecimals_decshift < 0) {
fixedDecimals_decshift = -1*fixedDecimals_decshift;
}
document.getElementById("multiplier").value="x" + Number(10 ** multiplier).toFixed(0);
document.getElementById("multiplier_decshift").value="x" + Number(10 ** multiplier_decshift).toFixed(fixedDecimals_decshift);
}
@@ -316,19 +439,28 @@ function UpdateROIs(_sel){
{
document.getElementById("Category_Digits_enabled").checked = false;
EnDisableDigits();
firework.launch('Digital ROIs are disabled - please enable first (Check box top left)', 'warning', 10000);
firework.launch('Digit ROI processing is disabled. Activate with checkbox if needed', 'warning', 10000);
return;
}
if (ROIInfo.length == 0){
firework.launch('There are no ROIs defined. Please first create a new ROI ("New ROIs ...")', 'danger', 10000);
firework.launch('No digit ROIs defined in selected number sequence', 'warning', 10000);
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("index").disabled = true;
document.getElementById("multiplier").style.display = "none";
document.getElementById("multiplier_decshift").style.display = "none";
document.getElementById("refx").disabled = true;
document.getElementById("refdx").disabled = true;
document.getElementById("refy").disabled = true;
document.getElementById("refdy").disabled = true;
document.getElementById("lockSizes").disabled = true;
document.getElementById("lockAspectRatio").disabled = true;
document.getElementById("lockSpaceEquidistant").disabled = true;
document.getElementById("moveNext").disabled = true;
document.getElementById("movePrevious").disabled = true;
document.getElementById("saveroi").disabled = false;
return;
}
else
@@ -337,6 +469,15 @@ function UpdateROIs(_sel){
document.getElementById("deleteROI").disabled = false;
document.getElementById("renameROI").disabled = false;
document.getElementById("index").disabled = false;
document.getElementById("multiplier").style.display = "";
document.getElementById("multiplier_decshift").style.display = "";
document.getElementById("refx").disabled = false;
document.getElementById("refdx").disabled = false;
document.getElementById("refy").disabled = false;
document.getElementById("refdy").disabled = false;
document.getElementById("lockSizes").disabled = false;
document.getElementById("lockAspectRatio").disabled = false;
document.getElementById("lockSpaceEquidistant").disabled = false;
document.getElementById("saveroi").disabled = false;
}
@@ -346,7 +487,7 @@ function UpdateROIs(_sel){
}
if (aktindex > ROIInfo.length)
aktindex = ROIInfo.length;
aktindex = ROIInfo.length-1;
for (var i = 0; i < ROIInfo.length; ++i){
var option = document.createElement("option");
@@ -369,7 +510,9 @@ function UpdateROIs(_sel){
document.getElementById("moveNext").disabled = false;
if (aktindex == (ROIInfo.length-1)){
document.getElementById("moveNext").disabled = true;
}
}
ShowMultiplier();
document.getElementById("lockAspectRatio").checked = lockAspectRatio;
document.getElementById("lockSizes").checked = lockSizes;
@@ -390,7 +533,7 @@ function UpdateROIs(_sel){
rect.startY = ROIInfo[aktindex]["y"];
rect.w = ROIInfo[aktindex]["dx"];
rect.h = ROIInfo[aktindex]["dy"];
draw();
draw();
}
function loadCanvas(dataURL) {
@@ -420,8 +563,20 @@ function UpdateROIs(_sel){
var left = box.left + scrollLeft - clientLeft;
return { top: Math.round(top), left: Math.round(left) };
}
/* hash #description open the details part of the page */
function openDescription() {
if(window.location.hash) {
var hash = window.location.hash.substring(1); //Puts hash in variable, and removes the # character
if(hash == 'description')
document.getElementById("desc_details").open = true;
}
}
function init() {
openDescription();
domainname = getDomainname();
canvas.addEventListener('mousedown', mouseDown, false);
canvas.addEventListener('mouseup', mouseUp, false);
@@ -481,6 +636,8 @@ function UpdateROIs(_sel){
document.getElementById("space").value = space;
}
document.getElementById("saveroi").disabled = true;
drawImage();
draw();
}
@@ -523,10 +680,13 @@ function UpdateNUMBERS(_sel){
function renameNumber(){
var sel = document.getElementById("Numbers_value1");
var _delte= sel.options[sel.selectedIndex].text;
var _numbernew = prompt("Please enter new name", _delte);
var _delete= sel.options[sel.selectedIndex].text;
var _numbernew = prompt("Please enter a new name for the selected number sequence", _delete);
if (_numbernew === null) {
return; //break out of the function early because prompt was aborted
}
erg = RenameNUMBER(_delte, _numbernew);
erg = RenameNUMBER(_delete, _numbernew);
if (erg != "")
firework.launch(erg, 'danger', 30000);
else
@@ -534,21 +694,27 @@ function renameNumber(){
}
function newNumber(){
var _numbernew = prompt("Please enter name of new number", "name");
var _numbernew = prompt("Please enter a name for the new number sequence", "name");
if (_numbernew === null) {
return; //break out of the function early because prompt was aborted
}
erg = CreateNUMBER(_numbernew);
if (erg != "")
firework.launch(erg, 'danger', 30000);
firework.launch(erg, 'danger', 30000);
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?")) {
if (confirm("The entire number sequence will be removed (digit + analog parts). " +
"To remove single ROI of the number sequence, use \"Delete ROI\" instead.\n" +
"Do you really want to proceed?"))
{
var sel = document.getElementById("Numbers_value1");
var _delte= sel.options[sel.selectedIndex].text;
erg = DeleteNUMBER(_delte);
var _delete= sel.options[sel.selectedIndex].text;
erg = DeleteNUMBER(_delete);
if (erg != "")
firework.launch(erg, 'danger', 30000);
UpdateNUMBERS();
@@ -755,6 +921,7 @@ function draw() {
}
draw();
}
document.getElementById("saveroi").disabled = false;
}
function valuemanualchangeddx(){
@@ -780,6 +947,7 @@ function draw() {
draw();
}
document.getElementById("saveroi").disabled = false;
}
function valuemanualchangedspace(){
@@ -821,8 +989,10 @@ function draw() {
sel = document.getElementById("index");
var _roialt= sel.options[sel.selectedIndex].text;
var _roinew = prompt("Please enter new name", _roialt);
var _roinew = prompt("Please enter a new name for the selected ROI", _roialt);
if (_roinew === null) {
return; //break out of the function early because prompt was aborted
}
erg = RenameROI(_number, "digit", _roialt, _roinew);
if (erg != "")
@@ -833,6 +1003,7 @@ function draw() {
function numberChanged()
{
aktindex = 0;
UpdateROIs();
}

View File

@@ -1,10 +1,8 @@
<!DOCTYPE html>
<html style="width: fit-content">
<html lang="en" xml:lang="en">
<head>
<link rel="icon" href="favicon.ico?v=$COMMIT_HASH" type="image/x-icon">
<title>AI on the edge</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="UTF-8" />
<style>
h1 {font-size: 2em; margin-block-end: 0.3em;}
@@ -19,7 +17,7 @@ p {font-size: 1em;}
<body style="font-family: arial">
<h2>Welcome to the Setup of the Digitizer</h2>
<h2>Welcome to the setup of the AI-on-the-edge-device</h2>
<p>
@@ -27,41 +25,48 @@ p {font-size: 1em;}
</p>
<p>
This is the first time you started the digitizer after the initial installation. You have been automatically routed to the <b>initial setup procedure</b>.
Here you adjust the settings for your meter within five steps. In the final step the inital setup will be disabled and it will restart to the normal mode.
All settings will also be accessible there. See <a href=https://jomjol.github.io/AI-on-the-edge-device-docs/initial-setup target=_blank>
https://jomjol.github.io/AI-on-the-edge-device-docs/initial-setup</a> for additional explanations.</p>
This is the first time you started the device after the initial installation. You have been automatically routed to the <b>initial setup procedure</b>.
With the prodecure the basic setup of your device within seven steps will be performed. After completion of all steps the setup mode will be completed
and the device restarts automatically to the regular web interface.<br>
Note: All settings of the initial setup will be also accessible using regular web interface.
See documentation: <a href=https://jomjol.github.io/AI-on-the-edge-device-docs/initial-setup target=_blank>Initial setup procedure</a> for additional explanations.</p>
</p>
<p>You can navigate forward and backward during the setup with the buttons "Next" and "Previous".<br><br>
<span color=red>Do not forget to save in each step before heading to another step!</span><br>
<p> You can navigate forward and backward during the setup with the buttons "Next Step" and "Previous Step".<br>
With the button "Abort Setup" the setup will be skipped and abort screen will be presented.<br>
To restart the setup process, push the button "Restart Setup".
</p>
<p>
This is an overview over the five steps:
This is an overview over the seven steps:
</p>
<p>
<ol>
<li><p>Create the <b>Reference Image</b>.<br>
<li><p>Adjust <b>lens focus</b> and check for <b>reflections of flashlight</b>.<br>
Ensure you camera lens has proper focus to object and flashlight do not create any distoring reflections.</p></li>
<li><p>Create the <b>reference image</b>.<br>
It is the base for the position referencing and the identification of the digits and counters.</p></li>
<li><p>Define two unique <b>Reference Marks</b>.<br>
They is used to align the individual camera images and identify the absolut positions.</p></li>
<li></p>Define <b>ROI's</b> for the <b>Digits</b>.<br>
<li><p>Define two unique <b>alignment marker</b>.<br>
They are used to perform an orientation alignment of the taken camera images before further processing</p></li>
<li></p>Define <b>ROI's</b> for the <b>digits</b>.<br>
They will be used to digitize the digit part of your meter.<br>
If your meter has no digits, this step can be skipped.</p></li>
<li>Define <b>ROI's</b>> for the <b>Analog Counters</b>.<br>
NOTE: If your meter has no digits, this step can be skipped.</p></li>
<li>Define <b>ROI's</b> for the <b>analog counters</b>.<br>
They will be used to digitize the analog part of your meter.<br>
If your meter has no analog counters, this step can be skipped.</p></li>
<li><p><b>General Settings</b><br>
Further configuration of your device.</p></li>
NOTE: If your meter has no analog counters, this step can be skipped.</p></li>
<li><p><b>Additional configuration:</b> List of all parameters<br>
Further configuration of your device can be done here.<br>
NOTE: This can also be performed later with regular web interface, e.g. to setup any publishing service like MQTT</p>
</li>
<li><p><b>Setup Completion:</b> End/Abort setup mode<br>
In the final step the setup mode needs to be properly terminated by pushing the button in this page.<br>
NOTE: This is important, otherwise the setup mode is recalled again after reboot.</p>
</li>
</ol>
<p>Please be patient when switching to another step. The device takes some time to load all needed information!</p>
<p>After step 5 the setup is completed, you then can reboot and starts into the normal operation mode.</p>
<p>If you need support, have a look to the <a href=https://jomjol.github.io/AI-on-the-edge-device-docs target=_blank>documentation</a> or the <a href=https://github.com/jomjol/AI-on-the-edge-device/discussions target=_blank>discussion</a> pages.</p>
<p><b>Have fun with your digitizer!</b></p>
<p><b>Have fun with your AI-on-the-edge-device!</b></p>
</body>
</html>

View File

@@ -0,0 +1,74 @@
<!DOCTYPE html>
<html lang="en" xml:lang="en">
<head>
<title>AI on the edge</title>
<meta charset="UTF-8" />
<style>
h1 {font-size: 2em; margin-block-end: 0.3em;}
h2 {font-size: 1.5em;margin-block-start: 0.3em;}
h3 {font-size: 1.2em;}
p {font-size: 1em;}
.button {
padding: 5px 10px;
width: 205px;
font-size: 16px;
}
</style>
<link href="firework.css?v=$COMMIT_HASH" rel="stylesheet">
<script type="text/javascript" src="jquery-3.6.0.min.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="firework.js?v=$COMMIT_HASH"></script>
</head>
<body style="font-family: arial">
<h4>Step 7 / 7: Initial setup completed!</h4>
<p>
Congratulations! You have completed the initial setup and you are now ready to restart to the regular operation mode!
</p>
<p>
Once you push the button below, the setup mode will be completed and the device will be automatically restart to regular web interface.
If configuration is error free, the device will automatically start with first processing. It will take some time until you get the first reading.
</p>
<p>
<button class="button" onclick="reboot()">Complete Setup + Reboot</button>
</p>
<script type="text/javascript" src="common.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="readconfigparam.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="readconfigcommon.js?v=$COMMIT_HASH"></script>
<script type="text/javascript">
function reboot() {
if (confirm("Do you want to complete the setup mode and switch to regular web interface?")) {
domainname = getDomainname();
if (!loadConfig(domainname)) {
firework.launch('Setup mode could not be deactivated! Please try again!', 'danger', 30000);
return;
}
ParseConfig();
param = getConfigParameters();
param["System"]["SetupMode"]["enabled"] = true;
param["System"]["SetupMode"]["value1"] = "false";
WriteConfigININew();
SaveConfigToServer(domainname);
var stringota = getDomainname() + "/reboot";
parent.location = stringota;
parent.location.href = stringota;
parent.location.assign(stringota);
parent.location.replace(stringota);
}
}
</script>
</body>
</html>

View File

@@ -1,10 +1,8 @@
<!DOCTYPE html>
<html style="width: fit-content">
<html lang="en" xml:lang="en">
<head>
<link rel="icon" href="favicon.ico?v=$COMMIT_HASH" type="image/x-icon">
<title>AI on the edge</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="UTF-8" />
<style>
h1 {font-size: 2em; margin-block-end: 0.3em;}
@@ -14,8 +12,8 @@ p {font-size: 1em;}
.button {
padding: 5px 20px;
width: 211px;
padding: 5px 10px;
width: 205px;
font-size: 16px;
}
@@ -28,15 +26,16 @@ p {font-size: 1em;}
<body style="font-family: arial">
<h4>Step 6: Setup Completed!</h4>
<h4>Initial setup aborted!</h4>
<p>Congratulations, you completed the setup and are now ready to reboot to the normal mode!</p>
<p>Once you have pushed the button below, the setup modus will be left and the digitizer will restart to normal operation mode.<br>
The Web Interface will automatically reload. It will take some minutes until you get the first reading.
<p>You have <b>aborted</b> the initial setup!</p>
<p>Once you push the button below, the setup mode will be ended and the device will be automatically restart to regular web interface.
Please be aware: The configuration of the device is not or only parly adapted to your needs!<br>
Configuration can still be adapted / completed using regular web interface.
</p>
<p>
<button class="button" onclick="reboot()">Leave Setup Modus and Reboot to Normal modus</button>
<button class="button" onclick="reboot()">Abort Setup + Reboot</button>
</p>
<script type="text/javascript" src="common.js?v=$COMMIT_HASH"></script>
@@ -44,15 +43,12 @@ p {font-size: 1em;}
<script type="text/javascript" src="readconfigcommon.js?v=$COMMIT_HASH"></script>
<script type="text/javascript">
var canvas = document.getElementById('canvas'),
domainname = getDomainname();
aktstatu = 0;
function reboot() {
if (confirm("Do you want to leave the configuration mode and restart the ESP32?")) {
if (confirm("Do you want to abort the setup mode and switch to regular web interface?")) {
domainname = getDomainname();
if (!loadConfig(domainname)) {
firework.launch('Setup Modus could not be deactivated! Please try again!', 'danger', 30000);
firework.launch('Setup mode could not be deactivated! Please try again!', 'danger', 30000);
return;
}
ParseConfig();
@@ -63,12 +59,11 @@ p {font-size: 1em;}
WriteConfigININew();
SaveConfigToServer(domainname);
var stringota = "/reboot";
window.location = stringota;
window.location.href = stringota;
window.location.assign(stringota);
window.location.replace(stringota);
var stringota = getDomainname() + "/reboot";
parent.location = stringota;
parent.location.href = stringota;
parent.location.assign(stringota);
parent.location.replace(stringota);
}
}

View File

@@ -1,100 +1,175 @@
<!DOCTYPE html>
<html>
<html lang="en" xml:lang="en">
<head>
<link rel="icon" href="favicon.ico?v=$COMMIT_HASH" type="image/x-icon">
<title>Reference Image</title>
<meta charset="utf-8"/>
<style>
h1 {font-size: 2em;}
h2 {font-size: 1.5em; margin-block-start: 0.0em; margin-block-end: 0.2em;}
h3 {font-size: 1.2em;}
p {font-size: 1em;}
<title>Reference Image</title>
<meta charset="utf-8"/>
<style>
h1 {font-size: 2em;}
h2 {font-size: 1.5em; margin-block-start: 0.0em; margin-block-end: 0.2em;}
h3 {font-size: 1.2em;}
p {font-size: 1em;}
input[type=number] {
width: 100px;
margin-right: 10px;
padding: 3px 5px;
display: inline-block;
border: 1px solid #ccc;
font-size: 16px;
}
input[type=number] {
width: 60px;
margin-right: 10px;
padding: 3px 5px;
display: inline-block;
border: 1px solid #ccc;
font-size: 16px;
vertical-align: middle;
}
.button {
padding: 5px 10px;
width: 210px;
font-size: 16px;
}
input:out-of-range {
background-color: rgba(255, 0, 0, 0.25);
border: 1px solid red;
}
table {
padding: 5px;
}
</style>
<link href="firework.css?v=$COMMIT_HASH" rel="stylesheet">
<script type="text/javascript" src="jquery-3.6.0.min.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="firework.js?v=$COMMIT_HASH"></script>
input:invalid {
background-color: rgba(255, 0, 0, 0.25);
border: 1px solid red;
}
.button {
padding: 5px 10px;
width: 205px;
font-size: 16px;
}
th, td {
padding: 5px 5px 5px 0px;
}
table {
width: 660px;
padding: 5px;
}
</style>
<link href="firework.css?v=$COMMIT_HASH" rel="stylesheet">
<script type="text/javascript" src="jquery-3.6.0.min.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="firework.js?v=$COMMIT_HASH"></script>
</head>
<body style="font-family: arial; padding: 0px 10px;">
<h2>Reference Image</h2>
<p>On this page you define the Reference Image.
See <a href=https://jomjol.github.io/AI-on-the-edge-device-docs/Reference-Image/ target=_blank>https://jomjol.github.io/AI-on-the-edge-device-docs/Reference-Image/</a> for explanations.</p>
<p>After saving a new Reference Image, make sure to update the <a href=edit_alignment.html>Alignment Marks</a> and then
the <a href=edit_digits.html>digit</a> resp. <a href=edit_analog.html>analog</a> ROI's.<br>
Only after those steps a reboot is required.</p>
<details id="desc_details" style="font-size:16px">
<summary><b>CLICK HERE</b> for usage description. More infos in documentation:
<a href=https://jomjol.github.io/AI-on-the-edge-device-docs/Reference-Image/ target=_blank>Reference Image</a>
</summary>
<p>
The reference image is the base image on which the alignment markers, digit ROIs and anlog ROIs will be defined.
</p>
<p>
Firstly the actual saved reference image is shown. If you start with the setup from scratch a default image is shown as placeholder.
Use the button <b>"Create New Reference"</b> to start creation of your own reference image. After selecting the button a new image will be taken
all configured parameter will be applied to the shown image. With the button <b>"Update Image"</b> you can update the image again (still all parameter
get applied to the new image).
</p>
<p>
To have reliable evaluation processing a properly horizontal aligned evaluation area is mandatory. Using the parameters "Rotation angle" and
"Rotation angle (Fine-tune)" the image can be rotated in both directions. The resulting rotation anlge is used to prerotate the image before
the alignment algorithm is processed to compensate only small misalignments. Further information can be found in documenation:
<a href=https://jomjol.github.io/AI-on-the-edge-device-docs/Reference-Image/ target=_blank>Reference Image</a>
</p>
<p>
After setting up your reference image don't forget to save with the <b>"Save New Reference"</b> button!<br>
<b>NOTE:</b> There is no need to perform a reboot after every saving or step. It's sufficient to reboot after all configuration steps
(reference image, alignment, ROI configuration) are completed to activate new configuration.
</p>
</details>
<hr />
<table>
<tr>
<td><input class="button" type="button" value="Show Actual Reference" onclick="showReference(param)"></td>
<td><input class="button" type="button" value="Create New Reference" onclick="loadRawImage()"></td>
<td><input class="button" type="submit" id="take" onclick="doTake()" value="Take Image"></td>
</tr>
<tr>
<td style="padding-top: 10px"><label for="mirror" id="labelmirror">Mirror Image:</label></td>
<td style="padding-top: 10px"><input type="checkbox" id="mirror" name="mirror" value="1" onchange="drawRotated()"></td>
<td>
<class id="TakeImage_LEDIntensity_text" style="color:black;">LEDIntensity: </class>
<input type="number" id="TakeImage_LEDIntensity_value1" size="13" value=0 min="0" max="100" style="float: right; clear: both;">
</td>
</tr>
<tr>
<td><label for="flip" id="labelflip">Flip Image Size:</label></td>
<td><input type="checkbox" id="flip" name="flip" value="1" onchange="drawRotated()"></td>
<td>
<class id="TakeImage_Brightness_text" style="color:black;">Brightness: </class>
<input type="number" id="TakeImage_Brightness_value1" size="13" value=0 min="-2" max="2" style="float: right; clear: both;">
</td>
</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>
<class id="TakeImage_Contrast_text" style="color:black;">Contrast</class>
<input type="number" id="TakeImage_Contrast_value1" size="13" value=0 min="-2" max="2" style="float: right; clear: both;">
</td>
</tr>
<tr>
<td><label for="mirror">Fine Alignment:</label></td>
<td><input type="number" id="finerotate" name="finerotate" value=0.0 min="-1" max="1" step="0.2" onchange="drawRotated()">Degrees</td>
<td>
<class id="TakeImage_Saturation_text" style="color:black;">Saturation</class>
<input type="number" id="TakeImage_Saturation_value1" size="13" value=0 min="-2" max="2" style="float: right; clear: both;">
</td>
</tr>
</table>
<table>
<tr>
<td><canvas id="canvas"></canvas></td>
</tr>
<tr>
<td><input class="button" type="button" id="updatereferenceimage" value="Save" onclick="SaveReference()">
<p>Proceed to update the <a href=edit_alignment.html>Alignment Marks</a> when you are done.</p></td>
</tr>
</table>
<colgroup>
<col span="1" style="width: 33.3%;">
<col span="1" style="width: 33.3%;">
<col span="1" style="width: 33.3%;">
</colgroup>
<tr>
<td><input class="button" type="button" value="Show Actual Reference" onclick="showReference(param)"></td>
<td><input class="button" type="button" id="startreference" value="Create New Reference" onclick="loadRawImage(false)"></td>
<td><input class="button" type="submit" id="take" onclick="doTake()" value="Update Image">
</tr>
</table>
<table>
<colgroup>
<col span="1" style="width: 32%;">
<col span="1" style="width: 28%;">
<col span="1" style="width: 18%;">
<col span="1" style="width: 22%;">
</colgroup>
<tr>
<td><label for="mirror" id="labelmirror">Mirror image:</label></td>
<td><input type="checkbox" id="mirror" name="mirror" value="1" onchange="drawRotated()"></td>
<td>
<class id="TakeImage_LEDIntensity_text" style="color:black;">LED intensity:</class>
</td>
<td>
<input required style="clear: both" type="number" id="TakeImage_LEDIntensity_value1" size="13" value="0" min="0" max="100"
oninput="(!validity.rangeOverflow||(value=100)) && (!validity.rangeUnderflow||(value=0)) &&
(!validity.stepMismatch||(value=parseInt(this.value)));">
</td>
</tr>
<tr>
<td><label for="flip" id="labelflip">Flip image size:</label></td>
<td><input type="checkbox" id="flip" name="flip" value="1" onchange="drawRotated()"></td>
<td>
<class id="TakeImage_Brightness_text" style="color:black;">Brightness:</class>
</td>
<td>
<input style="clear: both; width: 80%;vertical-align:middle" type="range" id="TakeImage_Brightness_value1" size="13" value=0 min="-2" max="2" oninput="this.nextElementSibling.value = this.value">
<output id="TakeImage_Brightness_value1_output" style="vertical-align:middle; min-width:15px; padding-right:5px; text-align:right; float:left">0</output>
</td>
</tr>
<tr>
<td><label for="prerotateangle">Rotation angle:</label></td>
<td>
<input required type="number" id="prerotateangle" name="prerotateangle" value="0" min="-360" max="360" onchange="drawRotated()"
oninput="(!validity.rangeOverflow||(value=360)) && (!validity.rangeUnderflow||(value=-360)) &&
(!validity.stepMismatch||(value=parseInt(this.value)));">degree
</td>
<td>
<class id="TakeImage_Contrast_text" style="color:black;">Contrast:</class>
</td>
<td>
<input style="clear: both; width: 80%;vertical-align:middle" type="range" id="TakeImage_Contrast_value1" size="13" value=0 min="-2" max="2" oninput="this.nextElementSibling.value = this.value">
<output id="TakeImage_Contrast_value1_output" style="vertical-align:middle; min-width:15px; padding-right:5px; text-align:right; float:left">0</output>
</td>
</tr>
<tr>
<td><label for="finerotate">Rotation angle (Fine-tune):</label></td>
<td>
<input required type="number" id="finerotate" name="finerotate" value=0.0 min="-1" max="1" step="0.1" onchange="drawRotated()"
oninput="(!validity.rangeOverflow||(value=1)) && (!validity.rangeUnderflow||(value=-1)) &&
(!validity.stepMismatch||(value=parseInt(this.value)));">degree
</td>
<td>
<class id="TakeImage_Saturation_text" style="color:black;">Saturation:</class>
</td>
<td>
<input style="clear: both; width: 80%;vertical-align:middle" type="range" id="TakeImage_Saturation_value1" size="13" value=0 min="-2" max="2" oninput="this.nextElementSibling.value = this.value">
<output id="TakeImage_Saturation_value1_output" style="vertical-align:middle; min-width:15px; padding-right:5px; text-align:right; float:left">0</output>
</td>
</tr>
</table>
<table>
<colgroup>
<col span="1" style="width: 33.3%;">
<col span="1" style="width: 33.3%;">
<col span="1" style="width: 33.3%;">
</colgroup>
<tr>
<td style="vertical-align: bottom;"><b>Reference Image:</b></td>
<td></td>
<td>
<input style="font-weight:bold;" class="button" type="button" id="updatereferenceimage" value="Save New Reference" onclick="SaveReference()">
</td>
</tr>
<tr>
<td colspan="3"><canvas id="canvas"></canvas></td>
</tr>
</table>
<script type="text/javascript" src="common.js?v=$COMMIT_HASH"></script>
@@ -102,7 +177,6 @@ table {
<script type="text/javascript" src="readconfigparam.js?v=$COMMIT_HASH"></script>
<script language="JavaScript">
var canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d'),
@@ -110,7 +184,8 @@ table {
domainname = getDomainname();
isActReference = false;
param;
function doReboot() {
if (confirm("Are you sure you want to reboot? Did you save the config?")) {
var stringota = getDomainname() + "/reboot";
@@ -121,6 +196,7 @@ table {
}
}
function doTake(){
var xhttp = new XMLHttpRequest();
if (param["TakeImage"]["Brightness"].found && param["TakeImage"]["Brightness"].enabled)
@@ -144,15 +220,24 @@ table {
xhttp.open("GET", url, false);
xhttp.send();
loadRawImage();
firework.launch('Taking updated image...', 'success', 5000);
loadRawImage(true);
}
function loadRawImage(){
url = getDomainname() + "/img_tmp/raw.jpg" + "?session=" + Math.floor((Math.random() * 1000000) + 1);
function loadRawImage(new_image) {
if (new_image) {
url = getDomainname() + "/img_tmp/raw.jpg" + "?session=" + Math.floor((Math.random() * 1000000) + 1);
document.getElementById("updatereferenceimage").disabled = false;
}
else {
document.getElementById("updatereferenceimage").disabled = true;
doTake();
}
document.getElementById("finerotate").disabled = false;
document.getElementById("prerotateangle").disabled = false;
document.getElementById("updatereferenceimage").disabled = false;
document.getElementById("startreference").disabled = true;
document.getElementById("take").disabled = false;
if (param["Alignment"]["InitialMirror"].found)
document.getElementById("mirror").disabled = false;
@@ -188,14 +273,22 @@ table {
// document.getElementById("TakeImage_Contrast_value1").disabled = false;
isActReference = false;
loadCanvas(url);
drawRotated();
}
loadCanvas(url, true);
}
function showReference(_param){
url = getDomainname() + "/fileserver/config/reference.jpg" + "?session=" + Math.floor((Math.random() * 1000000) + 1);;
document.getElementById("finerotate").value = 0;
document.getElementById("prerotateangle").value = _param["Alignment"]["InitialRotate"].value1;
url = getDomainname() + "/fileserver/config/reference.jpg" + "?session=" + Math.floor((Math.random() * 1000000) + 1);
if (_param["Alignment"]["InitialRotate"].value1 < 0) {
document.getElementById("prerotateangle").value = Math.ceil(_param["Alignment"]["InitialRotate"].value1);
}
else {
document.getElementById("prerotateangle").value = Math.floor(_param["Alignment"]["InitialRotate"].value1);
}
document.getElementById("finerotate").value = (Number(_param["Alignment"]["InitialRotate"].value1) -
Number(document.getElementById("prerotateangle").value)).toFixed(1);
if (_param["Alignment"]["InitialMirror"].found && (_param["Alignment"]["InitialMirror"].value1 == "true"))
document.getElementById("mirror").checked = true;
@@ -206,6 +299,7 @@ table {
document.getElementById("finerotate").disabled = true;
document.getElementById("prerotateangle").disabled = true;
document.getElementById("updatereferenceimage").disabled = true;
document.getElementById("startreference").disabled = false;
document.getElementById("take").disabled = true;
document.getElementById("TakeImage_Brightness_value1").disabled = true;
document.getElementById("TakeImage_Saturation_value1").disabled = true;
@@ -224,10 +318,10 @@ table {
document.getElementById("flip").disabled = true;
isActReference = true;
loadCanvas(url);
drawRotated(false, true);
loadCanvas(url, false);
}
function dataURLtoBlob(dataurl) {
var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
@@ -236,10 +330,12 @@ table {
}
return new Blob([u8arr], {type:mime});
}
function SaveReference(){
if (confirm("Are you sure you want to update the Reference Image?")) {
param["Alignment"]["InitialRotate"].value1 = document.getElementById("prerotateangle").value;
if (confirm("Are you sure you want to save the new reference image configuration?")) {
param["Alignment"]["InitialRotate"].value1 = (Number(document.getElementById("prerotateangle").value) +
Number(document.getElementById("finerotate").value)).toFixed(1);
if ((param["Alignment"]["InitialMirror"].found == true) && (document.getElementById("mirror").checked))
{
@@ -268,22 +364,28 @@ table {
WriteConfigININew();
SaveConfigToServer(getDomainname());
document.getElementById("updatereferenceimage").disabled = true;
SaveCanvasToImage(canvas, "/config/reference.jpg", true, getDomainname());
showReference(param);
UpdatePage();
firework.launch('Reference got saved. It will get applied after the next reboot!', 'success', 5000);
//UpdatePage();
firework.launch('Reference image configuration saved. It will get applied after next reboot', 'success', 5000);
}
}
function loadCanvas(dataURL) {
function loadCanvas(dataURL, grid) {
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
imageObj.onload = function() {
canvas.width = this.width;
canvas.height = this.height;
drawRotated();
if (grid)
drawRotated(true);
else
drawRotated(false);
};
imageObj.src = dataURL;
@@ -303,7 +405,19 @@ table {
return { top: Math.round(top), left: Math.round(left) };
}
/* hash #description open the details part of the page */
function openDescription() {
if(window.location.hash) {
var hash = window.location.hash.substring(1); //Puts hash in variable, and removes the # character
if(hash == 'description')
document.getElementById("desc_details").open = true;
}
}
function init() {
openDescription();
canvas.addEventListener('mousemove', mouseMove, false);
loadConfig(getDomainname());
ParseConfig();
@@ -339,10 +453,11 @@ table {
showReference(param);
}
function UpdateInput() {
WriteParameter(param, category, "TakeImage", "Brightness", false);
WriteParameter(param, category, "TakeImage", "Contrast", false);
WriteParameter(param, category, "TakeImage", "Saturation", false);
WriteParameter(param, category, "TakeImage", "Brightness", false, true);
WriteParameter(param, category, "TakeImage", "Contrast", false, true);
WriteParameter(param, category, "TakeImage", "Saturation", false, true);
WriteParameter(param, category, "TakeImage", "LEDIntensity", false);
}
@@ -365,7 +480,7 @@ table {
}
function WriteParameter(_param, _category, _cat, _name, _optional, _select = false, _anzpara = 1){
function WriteParameter(_param, _category, _cat, _name, _optional, outval = false, _select = false, _anzpara = 1){
if (_param[_cat][_name]["found"]){
if (_optional) {
document.getElementById(_cat+"_"+_name+"_enabled").checked = _param[_cat][_name]["enabled"];
@@ -389,7 +504,8 @@ table {
document.getElementById(_cat+"_"+_name+"_value"+j).value = _param[_cat][_name]["value"+j];
}
}
if (outval)
document.getElementById(_cat+"_"+_name+"_value1_output").value = document.getElementById(_cat+"_"+_name+"_value1").value;
}
else {
if (_optional) {
@@ -403,7 +519,7 @@ table {
}
function drawRotated(_grid = true, _isreference = false){
function drawRotated(_grid = true) {
finerot= parseFloat(document.getElementById("finerotate").value);
prerot = parseFloat(document.getElementById("prerotateangle").value);
mirror = document.getElementById("mirror").checked;
@@ -455,12 +571,12 @@ table {
context.restore();
if (_grid == true && !isActReference){
drawGrid();
}
if (_grid)
drawGrid();
}
function drawGrid(){
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
@@ -489,8 +605,13 @@ table {
ctx.restore();
}
function mouseMove(e) {
drawRotated();
if (isActReference)
drawRotated(false);
else
drawRotated(true);
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
@@ -508,8 +629,8 @@ table {
context.stroke();
}
init();
</script>
</body>

View File

@@ -1,34 +1,33 @@
<!DOCTYPE html>
<html style="width: fit-content">
<html lang="en" xml:lang="en">
<head>
<link rel="icon" href="favicon.ico?v=$COMMIT_HASH" type="image/x-icon">
<title>AI on the edge</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="UTF-8" />
<style>
h1 {font-size: 2em; margin-block-end: 0.3em;}
h2 {font-size: 1.5em;margin-block-start: 0.3em;}
h3 {font-size: 1.2em;}
p {font-size: 1em;}
</style>
</head>
<body style="font-family: arial">
<h4>Step 1: Define a Reference Image</h4>
The reference image is the base to define the digits, counters and references positions.
<p>
Firstly you see the default image. Use the Button "Create New Reference" to start to create your own reference image.<br>
Most important feature is a straight alignment of the image. Use the Pre-rotate angle and the fine alignment to adjust the rotation of the image.
</p>
<p>
Don't forget to save your changes with the <b>"Save"</b> button!
</p>
<h4>Step 1 / 7: Adjust Focus And Verify Flashlight</h4>
Firstly you have find a proper mounting position and potentially have to adjust the focus of the camera lens to get a sharp and crisp image.
This <b>live stream with flashlight on</b> could be helpful for this task. More details about adjusting the camera lens can be found here:
<a href=https://jomjol.github.io/AI-on-the-edge-device-docs/Reference-Image/#focus target=_blank>Focus Adjustment</a><br>
Additionally it should be verfied that the flashlight is not creating any distrubing reflection in the processing relevant areas.
Beside using the built-in internal flash LED it's also possible to attach additional external LEDs to the device to have more possiblities
to get proper light condition. Please read the documentation if you'd like to use extenal LEDs:
<a href=https://jomjol.github.io/AI-on-the-edge-device-docs/External-LED/ target=_blank>Installation Of External LEDs</a>
<p>
NOTE: The flashlight indensity is set to default (50%) for initial verfication in this step and can be modified in next step. After modification
you can come back to this step if you'd like to test with adjusted light intensity.<br>
The live stream can also be called at any time also after setup mode is completed on regular web interface.
</p>
</body>
</html>

View File

@@ -1,34 +1,21 @@
<!DOCTYPE html>
<html style="width: fit-content">
<html lang="en" xml:lang="en">
<head>
<link rel="icon" href="favicon.ico?v=$COMMIT_HASH" type="image/x-icon">
<title>AI on the edge</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="UTF-8" />
<style>
h1 {font-size: 2em; margin-block-end: 0.3em;}
h2 {font-size: 1.5em;margin-block-start: 0.3em;}
h3 {font-size: 1.2em;}
p {font-size: 1em;}
</style>
</head>
<body style="font-family: arial">
<h4>Step 2: Define two Alignment Marks</h4>
Two opposite alignment marks are needed to identify unique fix points on the image.
<p>
Mark the reference by drag and dop with the mouse or with the coordinates and push <b>"Update Reference"</b>.
<br>
You can switch between the two reference with <b>"Select Reference"</b>.
</p>
<p>
Don't forget to save your changes with the <b>"Save"</b> button!
</p>
<h4>Step 2 / 7: Create A Reference Image</h4>
</body>
</html>

View File

@@ -1,36 +1,21 @@
<!DOCTYPE html>
<html style="width: fit-content">
<html lang="en" xml:lang="en">
<head>
<link rel="icon" href="favicon.ico?v=$COMMIT_HASH" type="image/x-icon">
<title>AI on the edge</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="UTF-8" />
<style>
h1 {font-size: 2em; margin-block-end: 0.3em;}
h2 {font-size: 1.5em;margin-block-start: 0.3em;}
h3 {font-size: 1.2em;}
p {font-size: 1em;}
</style>
</head>
<body style="font-family: arial">
<h4>Step 3: Define ROI's for your Digits</h4>
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>
To create new ROIs use <b>"New ROIs"</b>. The order of the ROIs defines the positon within the reading. <br>
You can change it with <b>"move Next" / "move Previous"</b>.
</p>
<p>
Don't forget to save your changes with the <b>"Save"</b> button!
</p>
<h4>Step 3 / 7: Definement Of Alignment Marker</h4>
</body>
</html>

View File

@@ -1,35 +1,21 @@
<!DOCTYPE html>
<html style="width: fit-content">
<html lang="en" xml:lang="en">
<head>
<link rel="icon" href="favicon.ico?v=$COMMIT_HASH" type="image/x-icon">
<title>AI on the edge</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="UTF-8" />
<style>
h1 {font-size: 2em; margin-block-end: 0.3em;}
h2 {font-size: 1.5em;margin-block-start: 0.3em;}
h3 {font-size: 1.2em;}
p {font-size: 1em;}
</style>
</head>
<body style="font-family: arial">
<h4>Step 4: Define ROI's for your Analog Counters</h4>
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>
To create new ROIs use <b>"New ROIs"</b>. The order of the ROIs defines the positon within the reading. <br>
You can change it with <b>"move Next" / "move Previous"</b>.
</p>
<p>
Don't forget to save your changes with the <b>"Save"</b> button!
</p>
<h4>Step 4 / 7: Configuration Of ROIs For Digit Numbers</h4>
</body>
</html>

View File

@@ -1,31 +1,21 @@
<!DOCTYPE html>
<html style="width: fit-content">
<head>
<link rel="icon" href="favicon.ico?v=$COMMIT_HASH" type="image/x-icon">
<title>AI on the edge</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<html lang="en" xml:lang="en">
<style>
<head>
<title>AI on the edge</title>
<meta charset="UTF-8" />
<style>
h1 {font-size: 2em; margin-block-end: 0.3em;}
h2 {font-size: 1.5em;margin-block-start: 0.3em;}
h3 {font-size: 1.2em;}
p {font-size: 1em;}
</style>
</head>
<body style="font-family: arial">
<h4>Step 5: General Configuration Settings</h4>
<p>Here you can define additional settings. The default settings should fit for a normal/initial setup.</p>
<p>You will also be able to change them later, so don't worry if you do not understand the parameters yet!</p>
</p>
<p>
Don't forget to save your changes with the <b>"Save"</b> button!
</p>
<h4>Step 5 / 7: Configuration Of ROIs For Analog Counters</h4>
</body>
</html>
</html>

View File

@@ -1 +1,23 @@
<!-- This page is never shown -->
<!DOCTYPE html>
<html lang="en" xml:lang="en">
<head>
<title>AI on the edge</title>
<meta charset="UTF-8" />
<style>
h1 {font-size: 2em; margin-block-end: 0.3em;}
h2 {font-size: 1.5em;margin-block-start: 0.3em;}
h3 {font-size: 1.2em;}
p {font-size: 1em;}
</style>
</head>
<body style="font-family: arial">
<h4>Step 6 / 7: Configuration Page: List Of All Parameters</h4>
<p>
NOTE: All parameter can be edited later in the regular web interface. So don't worry if you do not understand the parameters yet!
</p>
</body>
</html>

View File

@@ -0,0 +1 @@
<!-- This page is never shown -->

View File

@@ -1,9 +1,15 @@
<html>
<!DOCTYPE html>
<html lang="en" xml:lang="en">
<head>
<link href="/firework.css?v=$COMMIT_HASH" rel="stylesheet">
<script type="text/javascript" src="/jquery-3.6.0.min.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="/firework.js?v=$COMMIT_HASH"></script>
<style>
h1 {font-size: 2em;}
h2 {font-size: 1.5em; margin-block-start: 0.0em; margin-block-end: 0.2em;}
h3 {font-size: 1.2em;}
p {font-size: 1em;}
#files_table {
font-family: Arial, Helvetica, sans-serif;
border-collapse: collapse;
@@ -27,147 +33,172 @@
padding-top: 12px;
padding-bottom: 12px;
text-align: left;
background-color: #0011ff;
color: white;
background-color:lightgrey;
color: black;
}
input[type=file] {
padding: 5px 0px;
display: inline-block;
font-size: 16px;
}
input[type=text] {
padding: 5px 10px;
display: inline-block;
border: 1px solid #ccc;
font-size: 16px;
}
.button {
padding: 4px 10px;
width: 100px;
font-size: 16px;
}
</style>
</head>
</body>
<table class="fixed" border="0" width=100% style="font-family: arial">
<tr><td>
<h2>Content on SD-Card</h2>
</td>
<td rowspan="2" width="500px">
<table border="0">
</body>
<table class="fixed" border="0" width=100% style="font-family: arial">
<tr>
<td>
<label for="newfile">Upload a file</label>
<td style="vertical-align: top;width: 300px;">
<h2>Fileserver</h2>
</td>
<td colspan="2">
<input id="newfile" type="file" onchange="setpath()" style="width:100%;">
<td rowspan="2">
<table border="0" style="width:100%">
<tr>
<td style="width:80px">
<label for="newfile">Source</label>
</td>
<td colspan="2">
<input id="newfile" type="file" onchange="setpath()" style="width:100%;">
</td>
</tr>
<tr>
<td>
<label for="filepath">Destination</label>
</td>
<td>
<input id="filepath" type="text" style="width:94%;">
</td>
<td>
<button id="upload" type="button" class="button" onclick="upload()">Upload</button>
</td>
</tr>
</table>
</td>
</tr>
<tr></tr>
<tr>
<td>
<label for="filepath">Set path on server</label>
</td>
<td>
<input id="filepath" type="text" style="width:100%;">
</td>
<td>
<button id="upload" type="button" onclick="upload()">Upload</button>
<td colspan="2">
<button style="font-size:16px; padding: 5px 10px" id="dirup" type="button" onclick="dirup()" disabled>&#129145; Directory up</button>
<span style="padding-left:15px" id="currentpath"></span>
</td>
</tr>
</table>
</td></tr>
<tr>
<td>
<span id="currentpath"></span> &nbsp;&nbsp;&nbsp;&nbsp;<button id="dirup" type="button" onclick="dirup()" disabled>&#129041; Directory up</button>
</td>
</tr>
</table>
<script type="text/javascript" src="/common.js?v=$COMMIT_HASH">
</script>
<script language="JavaScript">
function setpath() {
var fileserverpraefix = "/fileserver";
var anz_zeichen_fileserver = fileserverpraefix.length;
var default_path = window.location.pathname.substring(anz_zeichen_fileserver) + document.getElementById("newfile").files[0].name;
document.getElementById("filepath").value = default_path;
}
<script type="text/javascript" src="/common.js?v=$COMMIT_HASH">
</script>
<script language="JavaScript">
function setpath() {
var fileserverpraefix = "/fileserver";
var anz_zeichen_fileserver = fileserverpraefix.length;
var default_path = window.location.pathname.substring(anz_zeichen_fileserver) + document.getElementById("newfile").files[0].name;
document.getElementById("filepath").value = default_path;
}
function dirup() {
var str = window.location.href;
str = str.substring(0, str.length-1);
var zw = str.indexOf("/");
var found = zw;
while (zw >= 0)
{
zw = str.indexOf("/", found+1);
if (zw >= 0)
found = zw;
}
var res = str.substring(0, found+1);
window.location.href = res;
}
function upload() {
var filePath = document.getElementById("filepath").value;
var upload_path = "/upload/" + filePath;
var fileInput = document.getElementById("newfile").files;
/* Max size of an individual file. Make sure this
* value is same as that set in file_server.c */
var MAX_FILE_SIZE = 8000*1024;
var MAX_FILE_SIZE_STR = "8000KB";
if (fileInput.length == 0) {
firework.launch('No file selected!', 'danger', 30000);
} else if (filePath.length == 0) {
firework.launch('File path on server is not set!', 'danger', 30000);
} else if (filePath.length > 100) {
firework.launch('Filename is to long! Max 100 characters.', 'danger', 30000);
} else if (filePath.indexOf(' ') >= 0) {
firework.launch('File path on server cannot have spaces!', 'danger', 30000);
} else if (filePath[filePath.length-1] == '/') {
firework.launch('File name not specified after path!', 'danger', 30000);
} else if (fileInput[0].size > MAX_FILE_SIZE) {
firework.launch("File size must be less than " + MAX_FILE_SIZE_STR + "!", 'danger', 30000);
} else {
document.getElementById("newfile").disabled = true;
document.getElementById("filepath").disabled = true;
document.getElementById("upload").disabled = true;
var file = fileInput[0];
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4) {
if (xhttp.status == 200) {
document.open();
document.write(xhttp.responseText);
document.close();
} else if (xhttp.status == 0) {
firework.launch('Server closed the connection abruptly!', 'danger', 30000);
UpdatePage(false);
} else {
firework.launch('An error occured: ' + xhttp.responseText, 'danger', 30000);
UpdatePage(false);
}
function dirup() {
var str = window.location.href;
str = str.substring(0, str.length-1);
var zw = str.indexOf("/");
var found = zw;
while (zw >= 0)
{
zw = str.indexOf("/", found+1);
if (zw >= 0)
found = zw;
}
};
xhttp.open("POST", upload_path, true);
xhttp.send(file);
}
}
var res = str.substring(0, found+1);
window.location.href = res;
}
function checkAtRootLevel(res) {
if (getPath() == "/fileserver/") { // Already at root level
document.getElementById("dirup").disabled = true;
console.log("Already on sd-card root level!");
return true;
}
function upload() {
var filePath = document.getElementById("filepath").value;
var upload_path = "/upload/" + filePath;
var fileInput = document.getElementById("newfile").files;
document.getElementById("dirup").disabled = false;
return false;
}
/* Max size of an individual file. Make sure this
* value is same as that set in file_server.c */
var MAX_FILE_SIZE = 8000*1024;
var MAX_FILE_SIZE_STR = "8000KB";
if (fileInput.length == 0) {
firework.launch('No file selected!', 'danger', 30000);
} else if (filePath.length == 0) {
firework.launch('File path on server is not set!', 'danger', 30000);
} else if (filePath.length > 100) {
firework.launch('Filename is to long! Max 100 characters.', 'danger', 30000);
} else if (filePath.indexOf(' ') >= 0) {
firework.launch('File path on server cannot have spaces!', 'danger', 30000);
} else if (filePath[filePath.length-1] == '/') {
firework.launch('File name not specified after path!', 'danger', 30000);
} else if (fileInput[0].size > MAX_FILE_SIZE) {
firework.launch("File size must be less than " + MAX_FILE_SIZE_STR + "!", 'danger', 30000);
} else {
document.getElementById("newfile").disabled = true;
document.getElementById("filepath").disabled = true;
document.getElementById("upload").disabled = true;
var file = fileInput[0];
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4) {
if (xhttp.status == 200) {
document.open();
document.write(xhttp.responseText);
document.close();
firework.launch('File upload completed', 'success', 5000);
} else if (xhttp.status == 0) {
firework.launch('Server closed the connection abruptly!', 'danger', 30000);
UpdatePage(false);
} else {
firework.launch('An error occured: ' + xhttp.responseText, 'danger', 30000);
UpdatePage(false);
}
}
};
xhttp.open("POST", upload_path, true);
xhttp.send(file);
}
}
function getPath() {
return window.location.pathname.replace(/\/+$/, '') + "/"
}
function checkAtRootLevel(res) {
if (getPath() == "/fileserver/") { // Already at root level
document.getElementById("dirup").disabled = true;
console.log("Already on sd-card root level!");
return true;
}
checkAtRootLevel();
document.getElementById("dirup").disabled = false;
return false;
}
console.log("Current path: " + getPath().replace("/fileserver", ""));
document.getElementById("currentpath").innerHTML = "Current path: <b>" + getPath().replace("/fileserver", "") + "</b>";
document.cookie = "page=" + getPath() + "; path=/";
function getPath() {
return window.location.pathname.replace(/\/+$/, '') + "/"
}
</script>
checkAtRootLevel();
</body>
console.log("Current path: " + getPath().replace("/fileserver", ""));
document.getElementById("currentpath").innerHTML = "Current path: <b>" + getPath().replace("/fileserver", "") + "</b>";
document.cookie = "page=" + getPath() + "; path=/";
</script>
</body>
</html>

View File

@@ -4,13 +4,15 @@
border-color: #888;
border-radius: 6px;
color: #fff;
left: 200px;
left: 10%;
padding: 5px;
position: fixed;
opacity: 0;
text-align: center;
top: 0px;
width: 600px;
width: 80%;
min-width:30%;
max-width:580px;
z-index: 99;
font-size:120%;
}

View File

@@ -29,7 +29,7 @@
p += parseInt($(this).height()) + 30
});
$('<div id="'+ fid +'" class="'+ c +'">'+ m +'<a onclick="firework.remove(\'#'+ fid +'\')"><img src=close.png></a></div>')
$('<div id="'+ fid +'" class="'+ c +'">'+ m +'<a onclick="firework.remove(\'#'+ fid +'\')"><img style="height:28px;" src=close.png></a></div>')
.appendTo('body')
.animate({
opacity: 1,

View File

@@ -1,16 +1,40 @@
<html>
<head>
<!DOCTYPE html>
<html lang="en" xml:lang="en">
<head>
<title>Data Graph</title>
<script type="text/javascript" src='plotly-basic-2.18.2.min.js?v=$COMMIT_HASH'></script>
<script type="text/javascript" src="common.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="readconfigcommon.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="readconfigparam.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="readconfigparam.js?v=$COMMIT_HASH"></script>
<style>
h1 {font-size: 2em;}
h2 {font-size: 1.5em; margin-block-start: 0.0em; margin-block-end: 0.2em;}
h3 {font-size: 1.2em;}
p {font-size: 1em;}
body {
font-family: Arial, Helvetica, sans-serif;
}
select {
padding: 3px 5px;
display: inline-block;
border: 1px solid #ccc;
font-size: 16px;
margin-right: 10px;
min-width: 100px;
vertical-align: middle;
}
.button {
padding: 5px 10px;
width: 160px;
font-size: 16px;
}
</style>
<script>
function run() {
datefile = document.getElementById("datafiles").value;
@@ -23,7 +47,7 @@
.then(response => {
// handle the response
if (response.status == 404) {
firework.launch("No log data available for " + dateString, 'warning', 10000);
firework.launch("No data available for " + dateString, 'warning', 10000);
}
response.text()
.then( result => {
@@ -132,17 +156,17 @@
},
margin: {
l: 50,
r: 50,
l: 70,
r: 70,
b: 50,
t: 50,
t: 40,
pad: 4
},
legend: {
x: 0.2,
y: 0.9,
xanchor: 'right'
x: 0.02,
y: 0.97,
xanchor: 'left'
}
};
@@ -158,19 +182,19 @@
<link href="firework.css?v=$COMMIT_HASH" rel="stylesheet">
<script type="text/javascript" src="jquery-3.6.0.min.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="firework.js?v=$COMMIT_HASH"></script>
</head>
<body>
<h3>Data Graph</h3>
<div id='chart'><p>Loading...<br></p></div>
<select id="datafiles" onchange="run();"></select>
<select id="numbers" onchange="run();"></select>
<input type="checkbox" id="showRrelativeValues" onclick = 'run();' unchecked ><label for="showRrelativeValues">Show relative values</label>
<button onclick="run();">Refresh</button>
&nbsp;&nbsp;|&nbsp;&nbsp;
<button onClick="window.location.href = 'data.html?v=$COMMIT_HASH'">Show data</button>
<button onClick="window.location.href = getDomainname() + '/fileserver/log/data/'">Show data files</button>
</head>
</div>
<body>
<h2>Data Graph</h2>
<div id='chart'><p>Loading...<br></p></div>
Number sequence:
<select id="numbers" onchange="run();"></select>
Day:
<select id="datafiles" onchange="run();"></select>
<input type="checkbox" id="showRrelativeValues" onclick = 'run();' unchecked ><label for="showRrelativeValues">Show relative values</label><br><br>
<button class="button" onclick="run();">Refresh</button>
<button class="button" onClick="window.location.href = 'data.html?v=$COMMIT_HASH'">Show Data Viewer</button>
<button class="button" onClick="window.location.href = getDomainname() + '/fileserver/log/data/'">Show Data Files</button>
<script>
function WriteModelFiles()
@@ -214,7 +238,15 @@
WriteModelFiles();
WriteNumbers();
function Refresh() {
setTimeout (function() {
run();
Refresh();
}, 300000);
}
run();
Refresh();
</script>
</body>
</html>

View File

@@ -1,94 +1,120 @@
<!DOCTYPE html>
<html>
<html lang="en" xml:lang="en">
<head>
<link rel="icon" href="favicon.ico?v=$COMMIT_HASH" type="image/x-icon">
<title>AI on the edge</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css?v=$COMMIT_HASH" type="text/css" >
<link href="firework.css?v=$COMMIT_HASH" rel="stylesheet">
<link rel="icon" href="favicon.ico?v=$COMMIT_HASH" type="image/x-icon">
<title>AI on the edge</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="style.css?v=$COMMIT_HASH" type="text/css" >
<link href="firework.css?v=$COMMIT_HASH" rel="stylesheet">
<script type="text/javascript" src="common.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="readconfigcommon.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="readconfigparam.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="common.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="readconfigcommon.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="readconfigparam.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="jquery-3.6.0.min.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="common.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="firework.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="jquery-3.6.0.min.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="firework.js?v=$COMMIT_HASH"></script>
<script>
async function loadPage(page) {
console.log("loadPage(" + page + ")");
document.cookie = "page="+page + "; path=/";
document.getElementById('maincontent').src = page;
<script>
var streamPopup;
var streamFlashlight = false;
var streamWindowFeatures =
'channelmode=no,directories=no,fullscreen=no,' +
'location=no,dependent=yes,menubar=no,resizable=no,scrollbars=no,' +
'status=no,toolbar=no,titlebar=no,' +
'left=10,top=250,width=640px,height=480px';
[].forEach.call(document.querySelectorAll('.submenu'), function (el) {
el.style.visibility = 'hidden';
});
}
function loadPage(page) {
console.log("loadPage( " + page + " )");
function resetMenu() {
[].forEach.call(document.querySelectorAll('.submenu'), function (el) {
el.style.visibility = 'visible';
});
}
function getCookie(cname) {
let name = cname + "=";
let decodedCookie = decodeURIComponent(document.cookie);
let ca = decodedCookie.split(';');
for(let i = 0; i <ca.length; i++) {
let c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
if (streamPopup) // Ensure that stream popup is closed because it's blocking web interface
streamPopup.close();
asyncPageLoad(page);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
</script>
async function asyncPageLoad(page ) {
console.log(" loading " + page + " ...");
document.cookie = "page="+page + "; path=/";
document.getElementById('maincontent').src = page;
[].forEach.call(document.querySelectorAll('.submenu'), function (el) {
el.style.visibility = 'hidden';
});
}
function resetMenu() {
[].forEach.call(document.querySelectorAll('.submenu'), function (el) {
el.style.visibility = 'visible';
});
}
function getCookie(cname) {
let name = cname + "=";
let decodedCookie = decodeURIComponent(document.cookie);
let ca = decodedCookie.split(';');
for(let i = 0; i <ca.length; i++) {
let c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
</script>
</head>
<body>
<div class="main">
<table style="border: none">
<tr><td style="padding-right: 10px;"><img src="favicon.ico?v=$COMMIT_HASH"></td>
<td><h1 id="id_title"> Digitizer - AI on the edge</h1>
<h2>An ESP32 all inclusive neural network recognition system for meter digitalization</h2>
</td></tr>
<table style="border: none; width:100%">
<tr>
<td style="padding-right: 10px;"><img style="width:64px; height:64px" src="favicon.ico?v=$COMMIT_HASH"></td>
<td><h1 id="id_title"> Digitizer - AI on the edge</h1>
<h2>An ESP32 all inclusive neural network recognition system for meter digitalization</h2>
</td>
</tr>
</table>
<div class="menu" onmouseover="resetMenu()">
<ul>
<li><a href="#" onclick="loadPage('overview.html?v=$COMMIT_HASH');">Overview</a></li>
<li><a>Settings <i class="arrow down"></i></a>
<ul class="submenu">
<li><a href="#" onclick="loadPage('prevalue_set.html?v=$COMMIT_HASH');">Set Previous Value</a></li>
<li><a href="#" onclick="loadPage('prevalue_set.html?v=$COMMIT_HASH');">Set "Previous Value"</a></li>
<li><a href="#" onclick="loadPage('edit_config_param.html?v=$COMMIT_HASH');">Configuration</a></li>
<li><a>Alignment <i class="arrow right"></i></a>
<ul>
<li><a href="#" onclick="loadPage('edit_reference.html?v=$COMMIT_HASH');">Reference Image</a></li>
<li><a href="#" onclick="loadPage('edit_alignment.html?v=$COMMIT_HASH');">Alignment Marks</a></li>
<li><a href="#" onclick="loadPage('edit_alignment.html?v=$COMMIT_HASH');">Alignment Marker</a></li>
</ul>
</li>
<li><a><strong>R</strong>egions <strong>O</strong>f <strong>I</strong>nterest <i class="arrow right"></i></a>
<ul>
<li><a href="#" onclick="loadPage('edit_digits.html?v=$COMMIT_HASH');">Digital ROIs</a></li>
<li><a href="#" onclick="loadPage('edit_analog.html?v=$COMMIT_HASH');">Analog ROIs</a></li>
<li><a href="#" onclick="loadPage('edit_digits.html?v=$COMMIT_HASH');">Digit ROI</a></li>
<li><a href="#" onclick="loadPage('edit_analog.html?v=$COMMIT_HASH');">Analog ROI</a></li>
</ul>
</li>
</ul>
<li><a>Data <i class="arrow down"></i></a>
<li><a>Data<i class="arrow down"></i></a>
<ul class="submenu">
<li><a href="#" onclick="loadPage(getDomainname() + '/value?full');">Recognition</a></li>
<li><a>Livestream <i class="arrow right"></i></a>
<ul>
<li><a href="#" onclick="start_livestream(false);">Live Stream (Light off)</a></li>
<li><a href="#" onclick="start_livestream(true);">Live Stream (Light on)</a></li>
</ul>
</li>
<li><a href="#" onclick="loadPage('graph.html?v=$COMMIT_HASH');">Data Graph</a></li>
<li><a href="#" onclick="loadPage('data.html?v=$COMMIT_HASH');">Data Viewer</a></li>
<li><a href="#" onclick="loadPage('data.html?v=$COMMIT_HASH');">Data Table</a></li>
<li><a href="#" onclick="loadPage(getDomainname() + '/fileserver/log/data/');">Data Files</a></li>
</ul>
</li>
@@ -102,28 +128,96 @@
<li><a href="#" onclick="loadPage(getDomainname() + '/fileserver/');">File Server</a></li>
<li><a href="#" onclick="loadPage('reboot_page.html?v=$COMMIT_HASH');">Reboot</a></li>
<li><a href="#" onclick="loadPage('info.html?v=$COMMIT_HASH');">Info</a></li>
<li><a href="https://jomjol.github.io/AI-on-the-edge-device-docs/" target="_blank">Help</a></li>
</ul>
</li>
<li id="ManualControl" style="display:none;"><a>Manual Control <i class="arrow down"></i></a> <!-- Workaround: Hide menu if no entry is available -->
<ul class="submenu">
<!--<li><a href="#" onclick="flow_start()">Start Round</a></li>--> <!-- Needs to be adapted on code side first to ensure proper user feedback -->
<li id="HASendDiscovery" style="display:none;"><a href="#" onclick="HA_send_discovery()">Resend HA Discovery</a></li>
</ul>
</li>
</ul>
</div>
<iframe name="maincontent" class="iframe" id="maincontent"></iframe>
<iframe title="maincontent" name="maincontent" class="iframe" id="maincontent"></iframe>
<span id="Version" style="font-size: 10px; margin-top: -5px">Loading version...</span>
<span id="Version" style="font-size: 10px; margin-top: -5px;padding-left: 10px;">Loading version...</span>
<script type="text/javascript">
LoadHostname();
LoadFwVersion();
LoadWebUiVersion();
LoadHostname();
LoadFwVersion();
LoadWebUiVersion();
HA_send_discovery_visibility();
if (getCookie("page") == "" || getCookie("page") == "reboot_page.html?v=$COMMIT_HASH") {
if (getCookie("page") == "" || getCookie("page") == "reboot_page.html?v=$COMMIT_HASH") {
document.cookie = "page=overview.html?v=$COMMIT_HASH" + "; path=/";
}
console.log("Loading page: " + getCookie("page"));
document.getElementById('maincontent').src = getCookie("page");
</script>
}
console.log("Loading page: " + getCookie("page"));
document.getElementById('maincontent').src = getCookie("page");
</div>
/*
function flow_start() {
var url = getDomainname() + '/flow_start';
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
if (xhttp.responseText.substring(0,3) == "001") {
firework.launch('Flow start triggered', 'success', 5000);
window.location.reload();
}
else if (xhttp.responseText.substring(0,3) == "002") {
firework.launch('Flow start scheduled. Start after round is completed', 'success', 5000);
}
else if (xhttp.responseText.substring(0,3) == "099") {
firework.launch('Flow start triggered, but start not possible (no flow task available)', 'danger', 5000);
}
}
}
xhttp.open("GET", url, true);
xhttp.send();
}
*/
function HA_send_discovery_visibility() {
loadConfig(domainname);
ParseConfig();
category = getConfigCategory();
param = getConfigParameters();
if (category["MQTT"]["enabled"] && param["MQTT"]["HomeassistantDiscovery"]["value1"] == "true") {
document.getElementById("ManualControl").style.display="";
document.getElementById("HASendDiscovery").style.display="";
}
}
function HA_send_discovery() {
console.log("HA Discovery scheduled");
var url = getDomainname() + '/mqtt_publish_discovery';
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
firework.launch('Sending HA discovery topics scheduled. The sending will be processed in state "Publish to MQTT"', 'success', 5000);
}
}
xhttp.open("GET", url, true);
xhttp.send();
}
function start_livestream(streamFlashlight) {
if (streamPopup)
streamPopup.close();
if (streamFlashlight)
streamPopup = window.open(getDomainname() + '/stream?flashlight=true','LivestreamWithlight',streamWindowFeatures);
else
streamPopup = window.open(getDomainname() + '/stream','Livestream',streamWindowFeatures);
streamPopup.focus();
}
</script>
</body>
</html>

View File

@@ -1,9 +1,8 @@
<!DOCTYPE html>
<html>
<html lang="en" xml:lang="en">
<head>
<link rel="icon" href="favicon.ico?v=$COMMIT_HASH" type="image/x-icon">
<title>Info</title>
<meta charset="utf-8">
<meta charset="UTF-8" />
<style>
h1 {font-size: 2em;}
@@ -11,190 +10,490 @@ h2 {font-size: 1.5em;}
h3 {font-size: 1.2em;}
p {font-size: 1em;}
div {
width: 350px;
padding: 10px 5px;
border: 1px solid #ccc;
font-family: arial;
font-size: 16px;
max-height: 35px;
th, td {
padding: 5px 5px 5px 5px;
border-width: 1px;
border-style: solid;
border-color: rgb(240, 240, 240);
}
output {
padding-left:5px;
}
table {
width: 660px;
padding: 5px;
border-collapse:collapse;
}
</style>
<script type="text/javascript" src="common.js?v=$COMMIT_HASH"></script>
</head>
<body style="font-family: arial; padding: 0px 10px;">
<h3>Runtime Information</h3>
<table style="font-family: arial">
<tr>
<td>
Last restart:
</td>
<td>
<div id="starttime">
<object data="/starttime"></object>
</div>
</td>
</tr>
<tr>
<td>
Uptime:
</td>
<td>
<div id="uptime">
<object data="/uptime"></object>
</div>
</td>
</tr>
</table>
<table>
<colgroup>
<col span="1" style="width: 35%;">
<col span="1" style="width: 65%;">
</colgroup>
<tr>
<h3>Runtime Information</h3>
</tr>
<tr>
<td>Start time:</td>
<td><output id="starttime"></output></td>
</tr>
<tr>
<td>Uptime:</td>
<td><output id="uptime"></output></td>
</tr>
</table>
<h3>Build Info</h3>
<table style="font-family: arial">
<tr>
<td>
Firmware Version:
</td>
<td>
<div id="firmware" style="width: 700px">
<object data="/info?type=FirmwareVersion" style="width: 700px"></object>
</div>
</td>
</tr>
<tr>
<td>
Firmware Build Time:
</td>
<td>
<div id="build-time">
<object data="/info?type=BuildTime"></object>
</div>
</td>
</tr>
<table>
<colgroup>
<col span="1" style="width: 35%;">
<col span="1" style="width: 65%;">
</colgroup>
<tr>
<h3>Build Info</h3>
</tr>
<tr>
<td>Firmware version:</td>
<td>
<output id="firmware"></output>
</td>
</tr>
<tr>
<td>Firmware build time:</td>
<td>
<output id="build-time"></output>
</td>
</tr>
<tr>
<td>
Web Interface Version:
</td>
<td>
<div id="web-ui" style="width: 700px">
<object data="/info?type=HTMLVersion" style="width: 700px"></object>
</div>
</td>
</tr>
</table>
<tr>
<td>Web interface version:</td>
<td>
<output id="web-ui"></output>
</td>
</tr>
</table>
<h3>Host Info</h3>
<table style="font-family: arial">
<tr>
<td>
Hostname:
</td>
<td>
<div id="Hostname">
<object data="/info?type=Hostname"></object>
</div>
</td>
</tr>
<tr>
<td>
IP-Address:
</td>
<td>
<div id="IP">
<object data="/info?type=IP"></object>
</div>
</td>
</tr>
<tr>
<td>
WLan-SSID:
</td>
<td>
<div id="SSID">
<object data="/info?type=SSID"></object>
</div>
</td>
</tr>
</table>
<table>
<colgroup>
<col span="1" style="width: 35%;">
<col span="1" style="width: 65%;">
</colgroup>
<tr>
<h3>Host Info</h3>
</tr>
<tr>
<td>Hostname:</td>
<td>
<output id="hostname"></output>
</td>
</tr>
<tr>
<td>IP Address:</td>
<td>
<output id="IP-address"></output>
</td>
</tr>
<tr>
<td>WLAN SSID:</td>
<td>
<output id="wlan-ssid"></output>
</td>
</tr>
</table>
<table>
<colgroup>
<col span="1" style="width: 35%;">
<col span="1" style="width: 65%;">
</colgroup>
<tr>
<h3>SD Card Info</h3>
</tr>
<tr>
<td>SD card manufacturer:</td>
<td>
<output id="SDCardManufacturer"></output>
</td>
</tr>
<tr>
<td>SD card name:</td>
<td>
<output id="SDCardName"></output>
</td>
</tr>
<tr>
<td>SD card size:</td>
<td>
<output id="SDCardCapacity"></output>
</td>
</tr>
<tr>
<td>SD card sector size:</td>
<td>
<output id="SDCardSectorSize"></output>
</td>
</tr>
<tr>
<td>Partition size:</td>
<td>
<output id="SDCardPartitionSize"></output>
</td>
</tr>
<tr>
<td>Partition free space:</td>
<td>
<output id="SDCardFreePartitionSpace"></output>
</td>
</tr>
<tr>
<td>Partition allocation size:</td>
<td>
<output id="SDCardPartitionAllocationSize"></output>
</td>
</tr>
</table>
<table>
<colgroup>
<col span="1" style="width: 35%;">
<col span="1" style="width: 65%;">
</colgroup>
<tr>
<h3>Memory Info</h3>
</tr>
<tr>
<td>Total Free (Int + Ext):</td>
<td>
<output id="RAMTotalFree"></output>
</td>
</tr>
<tr>
<td>Ext. RAM - Free:</td>
<td>
<output id="ExtRAMFree"></output>
</td>
</tr>
<tr>
<td>Ext. RAM - Largest Free Block:</td>
<td>
<output id="ExtRAMLargestFree"></output>
</td>
</tr>
<tr>
<td>Ext. RAM - Min Free:</td>
<td>
<output id="ExtRAMMinFree"></output>
</td>
</tr>
<tr>
<td>Int. RAM - Free:</td>
<td>
<output id="IntRAMFree"></output>
</td>
</tr>
<tr>
<td>Int. RAM - Largest Free Block:</td>
<td>
<output id="IntRAMLargestFree"></output>
</td>
</tr>
<tr>
<td>Int. RAM - Min Free:</td>
<td>
<output id="IntRAMMinFree"></output>
</td>
</tr>
</table>
<h3>SD Card Info</h3>
<table style="font-family: arial">
<tr>
<td>
SD Card Manufacturer:
</td>
<td>
<div id="SDCardManufacturer">
<object data="/info?type=SDCardManufacturer"></object>
</div>
</td>
</tr>
<tr>
<td>
SD Card Name:
</td>
<td>
<div id="SDCardName">
<object data="/info?type=SDCardName"></object>
</div>
</td>
</tr>
<tr>
<td>
SD Card Size [MB]:
</td>
<td>
<div id="SDCardCapacity">
<object data="/info?type=SDCardCapacity"></object>
</div>
</td>
</tr>
<tr>
<td>
SD Card Sector Size [byte]:
</td>
<td>
<div id="SDCardSectorSize">
<object data="/info?type=SDCardSectorSize"></object>
</div>
</td>
</tr>
<tr>
<td>
Partition Size [MB]:
</td>
<td>
<div id="SDPartitionSize">
<object data="/info?type=SDCardPartitionSize"></object>
</div>
</td>
</tr>
<tr>
<td>
Partition Free Space [MB]:
</td>
<td>
<div id="SDFreePartitionSpace">
<object data="/info?type=SDCardFreePartitionSpace"></object>
</div>
</td>
</tr>
<tr>
<td>
Partition Allocation Size [byte]:
</td>
<td>
<div id="SDCardPartitionAllocationSize">
<object data="/info?type=SDCardPartitionAllocationSize"></object>
</div>
</td>
</tr>
</table>
<h3>Copyright</h3>
Copyright &copy; 2020 - 2023 by <a href="https://github.com/jomjol/AI-on-the-edge-device" target=_blank>Jomjol</a> and others.
</body>
</html>
<script type="text/javascript">
function loadLastRestart()
{
url = getDomainname() + '/starttime';
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
//Input format: 19700101-010019
var timestamp = xhttp.response.substr(6,2) + "." +
xhttp.response.substr(4,2) + "." +
xhttp.response.substr(0,4) + " " +
xhttp.response.substr(9,2) + ":" +
xhttp.response.substr(11,2) + ":" +
xhttp.response.substr(13,2);
document.getElementById("starttime").value = timestamp;
}
}
xhttp.open("GET", url, true);
xhttp.send();
}
function loadUptime()
{
url = getDomainname() + '/uptime';
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("uptime").value = xhttp.response;
}
}
xhttp.open("GET", url, true);
xhttp.send();
}
function loadFWVersion()
{
url = getDomainname() + '/info?type=FirmwareVersion';
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("firmware").value = xhttp.response;
}
}
xhttp.open("GET", url, true);
xhttp.send();
}
function loadFWBuildTime()
{
url = getDomainname() + '/info?type=BuildTime';
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
// Input format: 2023-04-02 10:56
var timestamp = xhttp.response.substr(8,2) + "." +
xhttp.response.substr(5,2) + "." +
xhttp.response.substr(0,4) + " " +
xhttp.response.substr(11,2) + ":" +
xhttp.response.substr(14,2);
document.getElementById("build-time").value = timestamp;
}
}
xhttp.open("GET", url, true);
xhttp.send();
}
function loadHTMLVersion()
{
url = getDomainname() + '/info?type=HTMLVersion';
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("web-ui").value = xhttp.response;
}
}
xhttp.open("GET", url, true);
xhttp.send();
}
function loadHostname()
{
url = getDomainname() + '/info?type=Hostname';
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("hostname").value = xhttp.response;
}
}
xhttp.open("GET", url, true);
xhttp.send();
}
function loadIPAddress()
{
url = getDomainname() + '/info?type=IP';
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("IP-address").value = xhttp.response;
}
}
xhttp.open("GET", url, true);
xhttp.send();
}
function loadWLANSSID()
{
url = getDomainname() + '/info?type=SSID';
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("WLAN-SSID").value = xhttp.response;
}
}
xhttp.open("GET", url, true);
xhttp.send();
}
function loadWLANSSID()
{
url = getDomainname() + '/info?type=SSID';
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("wlan-ssid").value = xhttp.response;
}
}
xhttp.open("GET", url, true);
xhttp.send();
}
function loadWLANSSID()
{
url = getDomainname() + '/info?type=SSID';
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("wlan-ssid").value = xhttp.response;
}
}
xhttp.open("GET", url, true);
xhttp.send();
}
function loadSDCardManufacturer()
{
url = getDomainname() + '/info?type=SDCardManufacturer';
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("SDCardManufacturer").value = xhttp.response;
}
}
xhttp.open("GET", url, true);
xhttp.send();
}
function loadSDCardName()
{
url = getDomainname() + '/info?type=SDCardName';
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("SDCardName").value = xhttp.response;
}
}
xhttp.open("GET", url, true);
xhttp.send();
}
function loadSDCardCapacity()
{
url = getDomainname() + '/info?type=SDCardCapacity';
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("SDCardCapacity").value = xhttp.response + " MB";
}
}
xhttp.open("GET", url, true);
xhttp.send();
}
function loadSDCardSectorSize()
{
url = getDomainname() + '/info?type=SDCardSectorSize';
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("SDCardSectorSize").value = xhttp.response + " byte";
}
}
xhttp.open("GET", url, true);
xhttp.send();
}
function loadSDCardPartitionSize()
{
url = getDomainname() + '/info?type=SDCardPartitionSize';
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("SDCardPartitionSize").value = xhttp.response + " MB";
}
}
xhttp.open("GET", url, true);
xhttp.send();
}
function loadSDCardFreePartitionSpace()
{
url = getDomainname() + '/info?type=SDCardFreePartitionSpace';
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("SDCardFreePartitionSpace").value = xhttp.response + " MB";
}
}
xhttp.open("GET", url, true);
xhttp.send();
}
function loadSDCardPartitionAllocationSize()
{
url = getDomainname() + '/info?type=SDCardPartitionAllocationSize';
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("SDCardPartitionAllocationSize").value = xhttp.response + " byte";
}
}
xhttp.open("GET", url, true);
xhttp.send();
}
function loadMemoryInfo()
{
url = getDomainname() + '/heap';
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
data = xhttp.response.split("|");
document.getElementById("RAMTotalFree").value = data[0].split("l: ")[1] + " byte";
document.getElementById("IntRAMFree").value = data[4].split(":")[1] + " byte";
document.getElementById("IntRAMLargestFree").value = data[5].split(":")[1] + " byte";
document.getElementById("IntRAMMinFree").value = data[6].split(":")[1] + " byte";
document.getElementById("ExtRAMFree").value = data[1].split(":")[1] + " byte";
document.getElementById("ExtRAMLargestFree").value = data[2].split(":")[1] + " byte";
document.getElementById("ExtRAMMinFree").value = data[3].split(":")[1] + " byte";
}
}
xhttp.open("GET", url, true);
xhttp.send();
}
function init()
{
loadMemoryInfo();
loadLastRestart();
loadUptime();
loadFWVersion();
loadFWBuildTime();
loadHTMLVersion();
loadHostname();
loadIPAddress();
loadWLANSSID();
loadSDCardManufacturer();
loadSDCardName();
loadSDCardCapacity();
loadSDCardSectorSize();
loadSDCardPartitionSize();
loadSDCardFreePartitionSpace();
loadSDCardPartitionAllocationSize();
}
init();
</script>

View File

@@ -1,16 +1,19 @@
<html>
<!DOCTYPE html>
<html lang="en" xml:lang="en">
<head>
<title>Log Viewer</title>
<style>
html,
body {
height: 100%;
margin: 2px;
margin: 1px;
}
.box {
display: flex;
flex-flow: column;
height: 100%;
height: 99.75%;
}
.box .row.header {
@@ -29,21 +32,27 @@
font-family: 'Courier New', Courier, monospace;
font-size: small;
}
.button {
padding: 5px 10px;
width: 190px;
font-size: 16px;
}
</style>
<script type="text/javascript" src="common.js?v=$COMMIT_HASH"></script>
</head>
<body>
<div class="box">
<div class="row header">
<button onClick="reload();">Reload</button>
<button onClick="window.open(getDomainname() + '/logfileact');">Show full log</button>
<button onClick="window.location.href = getDomainname() + '/fileserver/log/message/'">Show older log files</button>
<button class="button" onClick="reload();">Reload</button>
<button class="button" onClick="window.open(getDomainname() + '/logfileact');">Show Full Log</button>
<button class="button" onClick="window.location.href = getDomainname() + '/fileserver/log/message/'">Show Older Log Files</button>
</div>
<div class="row content" id="log"><br><br><br><b>Loading Logfile, please wait...</b></div>
<div class="row content" id="log"><br><br><br><b>Loading logfile, please wait...</b></div>
<div class="row footer">
<button onClick="reload();">Reload</button>
<button onClick="window.open(getDomainname() + '/logfileact');">Show full log</button>
<button onClick="window.location.href = getDomainname() + '/fileserver/log/message/'">Show older log files</button>
<button class="button" onClick="reload();">Reload</button>
<button class="button" onClick="window.open(getDomainname() + '/logfileact');">Show Full Log</button>
<button class="button" onClick="window.location.href = getDomainname() + '/fileserver/log/message/'">Show Older Log Files</button>
</div>
</div>
</body>

View File

@@ -1,27 +1,25 @@
<!DOCTYPE html>
<html>
<html lang="en" xml:lang="en">
<head>
<link rel="icon" href="favicon.ico?v=$COMMIT_HASH" type="image/x-icon">
<title>OTA Update</title>
<meta charset="utf-8">
<meta charset="UTF-8" />
<style>
h1 {font-size: 2em;}
h2 {font-size: 1.5em;}
h3 {font-size: 1.2em;}
h2 {font-size: 1.5em; margin-block-start: 0.0em; margin-block-end: 0.2em;}
h3 {font-size: 1.2em;}
p {font-size: 1em;}
input[type=number] {
width: 138px;
padding: 10px 5px;
input[type=file] {
width: 660px;
padding: 5px 0px;
display: inline-block;
border: 1px solid #ccc;
font-size: 16px;
}
}
.button {
padding: 10px 20px;
width: 211px;
padding: 5px 10px;
width: 205px;
font-size: 16px;
}
</style>
@@ -51,11 +49,11 @@
<form id="upload_form" enctype="multipart/form-data" method="post">
<input type="file" accept=".bin,.zip,.tfl,.tflite" name="file_selector" id="file_selector" onchange="validate_file()"><br><br>
<button class="button" style="width:300px" id="start_OTA_button" type="button" onclick="start_OTA()" disabled>Upload and install</button>
<button class="button" id="start_OTA_button" type="button" onclick="start_OTA()" disabled>Upload And Install</button>
<br><br>
<progress id="progressBar" value="0" max="100" style="width:600px;"></progress>
<h3><span id="status">Status: Idle</span></h3>
<p id="loaded_n_total"></p>
<h3><span id="status">Status: idle</span></h3>
</form>
@@ -262,10 +260,10 @@
function progressHandler(event) {
_("loaded_n_total").innerHTML = "Uploaded " + (event.loaded / 1024 / 1024).toFixed(2) +
" MBytes of " + (event.total / 1024/ 1024).toFixed(2) + " MBytes.";
" MB of " + (event.total / 1024/ 1024).toFixed(2) + " MB";
var percent = (event.loaded / event.total) * 100;
_("progressBar").value = Math.round(percent);
_("status").innerHTML = "Status: " + Math.round(percent) + "% uploaded... please wait";
_("status").innerHTML = "Status: " + Math.round(percent) + "% uploaded. Please wait...";
}

View File

@@ -1,77 +1,89 @@
<!DOCTYPE html>
<html>
<html lang="en" xml:lang="en">
<head>
<link rel="icon" href="favicon.ico?v=$COMMIT_HASH" type="image/x-icon">
<title>Overview</title>
<meta charset="utf-8">
<meta charset="UTF-8" />
<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: 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:700px;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;}
.tg {border-collapse:collapse;border-spacing:0;width:100%;min-width:600px;height:100%;color:darkslategray;}
.tg th{min-width:325px;width:325px;height:20px;font-size:18px;text-align:left;font-weight:bold;padding:5px 10px 5px 10px;;overflow:hidden;word-break:normal;background-color:lightgrey;}
.tg td{font-size:15px;padding:5px 10px 5px 10px;overflow:hidden;word-break:normal;}
.tg .tg-1{font-size:15px;vertical-align: top; font-family:Arial, Helvetica, sans-serif !important;}
.tg .tg-2{height:52px;font-size:15px;padding:3px 0px 3px 10px;vertical-align:middle;font-family:Arial, Helvetica, sans-serif !important;}
.tg .tg-3{height:45px;font-size:15px;padding:3px 10px 3px 10px;vertical-align:middle;font-family:Arial, Helvetica, sans-serif !important;}
.tg .tg-4{height:fit-content;font-size:15px;padding:5px 10px 5px 10px;vertical-align:text-top;font-family:Arial, Helvetica, sans-serif !important;}
</style>
</head>
<body style="font-family: arial">
<table class="tg">
<tr>
<td class="tg-1" rowspan="9" style="vertical-align: top"><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">Status:</th>
</tr>
<tr>
<td class="tg-2">
<div id="error"></div>
</td>
</tr>
<tr>
<td class="tg-3">
<div id="statusflow" ></div>
<div id="timestamp" ></div>
<div id="cputemp" ></div>
<div id="rssi" ></div>
<div>
<span id="uptime" ></span>
<span id="round" ></span>
</div>
</td>
</tr>
</table>
<table class="tg">
<tr>
<th class="th">Value</th>
<td class="tg-1" rowspan="13">
<img style="padding-left: 5px; padding-top: 0px; max-width:100%; width:100%; height:auto;" id="img" src="">
</td>
</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">Value Status</th>
</tr>
<tr>
<td class="tg-2">
<div id="error"></div>
</td>
</tr>
<tr>
<th class="th">Process State</th>
</tr>
<tr>
<td class="tg-3">
<div id="statusflow" ></div>
</td>
</tr>
<tr>
<th class="th">System Info</th>
</tr>
<tr>
<td class="tg-4">
<div id="timestamp" ></div>
<div id="cputemp" ></div>
<div id="rssi" ></div>
<div>
<span id="uptime" ></span>
<span id="round" ></span>
</div>
</td>
</tr>
</table>
<script type="text/javascript" src="jquery-3.6.0.min.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="common.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="readconfigcommon.js?v=$COMMIT_HASH"></script>
<script type="text/javascript">
<script type="text/javascript" src="jquery-3.6.0.min.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="common.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="readconfigcommon.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="readconfigparam.js?v=$COMMIT_HASH"></script>
<script type="text/javascript">
function addZero(i) {
if (i < 10) {
@@ -88,10 +100,10 @@
function LoadData(){
loadValue("value", "value");
loadValue("raw", "raw");
loadValue("prevalue", "prevalue");
loadValue("error", "error", "font-size:8px");
loadValue("value", "value", "border-collapse: collapse; width: 100%");
loadValue("raw", "raw", "border-collapse: collapse; width: 100%");
loadValue("prevalue", "prevalue", "border-collapse: collapse; width: 100%");
loadValue("error", "error", "border-collapse: collapse; width: 100%");
loadStatus();
loadCPUTemp();
loadRSSI();
@@ -106,7 +118,7 @@
var h = addZero(d.getHours());
var m = addZero(d.getMinutes());
var s = addZero(d.getSeconds());
$('#img').html('<img src=' + getDomainname() + '/img_tmp/alg_roi.jpg?timestamp='+ timestamp +'" max-height:555px; display:block; margin-left:auto; margin-right:auto;"></img>');
document.getElementById("img").src = getDomainname() + '/img_tmp/alg_roi.jpg?timestamp=' + timestamp;
$('#timestamp').html("Last Page Refresh:" + (h + ":" + m + ":" + s));
}
@@ -126,7 +138,7 @@
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var _rsp = xhttp.responseText;
$('#statusflow').html("State: " + _rsp);
$('#statusflow').html(_rsp);
}
}
xhttp.open("GET", url, true);
@@ -231,9 +243,11 @@
{
var _zer = ZerlegeZeile(_split[j], "\t")
if (_zer.length == 1)
out = out + "<tr><td>" + _zer[0] + "</td><td> </td></tr>";
out = out + "<tr><td style=\"width: 22%; padding: 3px 5px; text-align: left; vertical-align:middle; border: 1px solid lightgrey\">" +
_zer[0] + "</td><td style=\"padding: 3px 5px; text-align: left; vertical-align:middle; border: 1px solid lightgrey\"> </td></tr>";
else
out = out + "<tr><td>" + _zer[0] + "</td><td>" + _zer[1] + "</td></tr>";
out = out + "<tr><td style=\"width: 22%; padding: 3px 5px; text-align: left; vertical-align:middle; border: 1px solid lightgrey\">" +
_zer[0] + "</td><td style=\"padding: 3px 5px; text-align: left; vertical-align:middle; border: 1px solid lightgrey\" >" + _zer[1] + "</td></tr>";
}
out = out + "</table>"
@@ -246,8 +260,33 @@
}
function setImageMaxWidth()
{
loadConfig(domainname);
ParseConfig();
param = getConfigParameters();
if(param["TakeImage"]["ImageSize"]["value1"] == "QVGA") {
if (param["Alignment"]["FlipImageSize"]["value1"] == "false") {
document.getElementById("img").style.maxWidth = "320px";
}
else {
document.getElementById("img").style.maxWidth = "240px";
}
}
else {
if (param["Alignment"]["FlipImageSize"]["value1"] == "false") {
document.getElementById("img").style.maxWidth = "640px";
}
else {
document.getElementById("img").style.maxWidth = "480px";
}
}
}
function init(){
domainname = getDomainname();
setImageMaxWidth();
Refresh();
}

View File

@@ -1,84 +1,136 @@
<!DOCTYPE html>
<html>
<html lang="en" xml:lang="en">
<head>
<link rel="icon" href="favicon.ico?v=$COMMIT_HASH" type="image/x-icon">
<title>Set PreValue</title>
<meta charset="utf-8">
<style>
h1 {font-size: 2em;}
h2 {font-size: 1.5em;}
h3 {font-size: 1.2em;}
p {font-size: 1em;}
<title>Set PreValue</title>
<meta charset="UTF-8" />
div {
width: 200px;
padding: 10px 5px;
display: inline-block;
border: 1px solid #ccc;
font-size: 16px;
max-height: 35px;
}
<style>
h1 {font-size: 2em;}
h2 {font-size: 1.5em; margin-block-start: 0.0em; margin-block-end: 0.2em;}
h3 {font-size: 1.2em;}
p {font-size: 1em;}
input[type=number] {
width: 125px;
padding: 10px 5px;
display: inline-block;
border: 1px solid #ccc;
font-size: 16px;
}
div {
padding: 3px 5px;
display: inline-block;
border: 1px solid #ccc;
font-size: 16px;
height: 20px;
width: 120px;
vertical-align: middle;
}
input[type=number] {
width: 120px;
margin-right: 10px;
padding: 3px 5px;
display: inline-block;
border: 1px solid #ccc;
font-size: 16px;
}
.invalid-input {
background-color: #FFAA00;
}
th, td {
padding: 5px 5px 5px 0px;
}
select {
padding: 3px 5px;
display: inline-block;
border: 1px solid #ccc;
font-size: 16px;
margin-right: 10px;
min-width: 100px;
vertical-align: middle;
}
.button {
padding: 5px 10px;
width: 205px;
font-size: 16px;
}
table {
width: 660px;
padding: 5px;
}
</style>
.button {
padding: 10px 20px;
width: 211px;
font-size: 16px;
}
</style>
</head>
<body style="font-family: arial; padding: 0px 10px;">
<h3>Set the previous value for consistency check and substitution for NaN</h3>
<h2>Set "Previous Value"</h2>
<details id="desc_details">
<summary><b>CLICK HERE</b> for usage description. More infos in documentation:
<a href=https://jomjol.github.io/AI-on-the-edge-device-docs/FAQs/#pre-value target=_blank>"Previous Value"</a>
</summary>
<p>
Set the "previous value" for consistency checks and substitution for NaN
</p>
<p>
Previous value is a bit missleading, because normally it is the last valid value but not always the value of the previous round.
The result of the the new round, as long it's a vaild result, will be promoted to the new "previous value". If the result is not usable the
"previous value" will not be updated.
If activated in configuration, the "previous value" will be used in the following round to check negtive rates, high rates
(MaxRateValue / MaxRateType) and for the option "Check Digit Increase Consistency" (configuration paramter, only for dig-class11 models).
</p>
<p>
The field to enter new "previous value" is prefilled with actual "raw value" because it's the most likely use case. Nevertheless every other
positive value can be set as new "previous value".
</p>
</details>
<hr />
<class id="Numbers_text" style="font-size: 120%; color:black;"><b>Choose Number: </b>
<select id="Numbers_value1" onchange="numberChanged()">
</select>
</class>
<table>
<colgroup>
<col span="1" style="width: 35.0%;">
<col span="1" style="width: 65.0%;">
</colgroup>
<tr>
<td style="height: 40px;">
<class id="Numbers_text" style="color:black;">Number sequence:</class>
</td>
<td>
<select id="Numbers_value1" onchange="numberChanged()"></select>
</td>
</tr>
</table>
<hr />
<table style="width:100%">
<tr>
<td>
<h3>Current "Previous Value":</h3>
</td>
<td>
<div id="prevalue"></div>
</td>
</tr>
<tr>
<td>
<h3>New "Previous Value":<br>(Format = 123.456)</h3><p>&nbsp;</p>
</td>
<td>
<input type="number" id="myInput" name="myInput"
pattern="[0-9]+([\.,][0-9]+)?" step="0.001"
title="This should be a number with up to 4 decimal places.">
<button class="button" type="button" onclick="setprevalue()">Set Previous Value</button>
<p>(The current "Raw Value" got entered as the suggested new "Previous Value")</p>
</td>
</tr>
<tr>
<td>
<h3>Result:</h3>
</td>
<td>
<div id="result" readonly></div>
</td>
</tr>
<table>
<colgroup>
<col span="1" style="width: 35%;">
<col span="1" style="width: 65%;">
</colgroup>
<tr>
<td>Current "previous value":</td>
<td>
<div style="padding-left:5px" id="prevalue"></div>
</td>
</tr>
<tr>
<td style="vertical-align: text-top; padding-top: 12px;">Enter new "previous value":</td>
<td>
<input required type="number" id="myInput" name="myInput" min="0" oninput="(!validity.rangeUnderflow||(value=0));">
<button class="button" type="button" onclick="setprevalue()">Update Value</button>
<p style="padding-left: 5px;">NOTE: The current "raw value" is prefilled as
<br>the suggested new "previous value"</p>
</td>
</tr>
<tr>
<td id="result_text">"Previous value" updated to:</td>
<td>
<div id="result" style="padding-left:5px;"></div>
</td>
</tr>
</table>
</table>
</body></html>
</body>
</html>
<link href="firework.css?v=$COMMIT_HASH" rel="stylesheet">
<script type="text/javascript" src="jquery-3.6.0.min.js?v=$COMMIT_HASH"></script>
@@ -104,6 +156,7 @@ function setprevalue() {
xhttp.send();
response = xhttp.responseText;
document.getElementById("result").innerHTML=response;
firework.launch('New \"previous value\" set', 'success', 5000);
}
catch (error)
{
@@ -145,11 +198,10 @@ function loadPrevalue(_domainname) {
lines.forEach(function(line) {
arr = line.split("\t");
if (_number == arr[0]) {
document.getElementById("myInput").value=arr[1];
document.getElementById("myInput").value = Number(arr[1]);
return;
}
});
}
catch (error)
{
@@ -190,7 +242,7 @@ function UpdateNUMBERS(_sel){
function init(){
domainname = getDomainname();
domainname = getDomainname();
loadConfig(domainname);
ParseConfig();
UpdateNUMBERS();

View File

@@ -85,6 +85,7 @@ function ZerlegeZeile(input, delimiter = " =\t\r")
}
function findDelimiterPos(input, delimiter)
{
var pos = -1;
@@ -131,7 +132,8 @@ function getConfig()
}
function loadConfig(_domainname) {
function loadConfig(_domainname)
{
var xhttp = new XMLHttpRequest();
try {
url = _domainname + '/fileserver/config/config.ini';
@@ -148,17 +150,17 @@ function loadConfig(_domainname) {
}
function dataURLtoBlob(dataurl) {
function dataURLtoBlob(dataurl)
{
var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while(n--){
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], {type:mime});
}
}
function FileCopyOnServer(_source, _target, _domainname = ""){
url = _domainname + "/editflow?task=copy&in=" + _source + "&out=" + _target;
var xhttp = new XMLHttpRequest();
@@ -171,6 +173,7 @@ function FileCopyOnServer(_source, _target, _domainname = ""){
}
}
function FileDeleteOnServer(_filename, _domainname = ""){
var xhttp = new XMLHttpRequest();
var okay = false;
@@ -201,6 +204,7 @@ function FileDeleteOnServer(_filename, _domainname = ""){
return okay;
}
function FileSendContent(_content, _filename, _domainname = ""){
var xhttp = new XMLHttpRequest();
var okay = false;
@@ -242,6 +246,7 @@ function SaveCanvasToImage(_canvas, _filename, _delete = true, _domainname = "")
FileSendContent(rtn, _filename, _domainname);
}
function MakeContrastImageZW(zw, _enhance, _domainname){
_filename = zw["name"].replace("/config/", "/img_tmp/");
url = _domainname + "/editflow?task=cutref&in=/config/reference.jpg&out=" + _filename + "&x=" + zw["x"] + "&y=" + zw["y"] + "&dx=" + zw["dx"] + "&dy=" + zw["dy"];
@@ -260,7 +265,7 @@ function MakeContrastImageZW(zw, _enhance, _domainname){
}
if (xhttp.responseText == "CutImage Done") {
firework.launch('Reference Image Contrast got enhanced.', 'success', 5000);
firework.launch('Image Contrast got enhanced', 'success', 5000);
return true;
}
else {
@@ -270,7 +275,6 @@ function MakeContrastImageZW(zw, _enhance, _domainname){
}
function MakeRefZW(zw, _domainname){
_filetarget = zw["name"].replace("/config/", "/img_tmp/");
_filetarget = _filetarget.replace(".jpg", "_org.jpg");
@@ -289,7 +293,7 @@ function MakeRefZW(zw, _domainname){
_filetarget2 = zw["name"].replace("/config/", "/img_tmp/");
// _filetarget2 = _filetarget2.replace(".jpg", "_org.jpg");
FileCopyOnServer(_filetarget, _filetarget2, _domainname);
firework.launch('Reference Image got updated.', 'success', 5000);
firework.launch('Marker got updated', 'success', 5000);
return true;
}
else {

View File

@@ -710,9 +710,10 @@ function getNUMBERInfo(){
}
function RenameNUMBER(_alt, _neu){
if ((_neu.indexOf(".") >= 0) || (_neu.indexOf(",") >= 0) || (_neu.indexOf(" ") >= 0) || (_neu.indexOf("\"") >= 0))
if ((_neu.indexOf(".") >= 0) || (_neu.indexOf(",") >= 0) ||
(_neu.indexOf(" ") >= 0) || (_neu.indexOf("\"") >= 0))
{
return "Name must not contain ',', '.', ' ' or '\"' - please change name";
return "Number sequence name must not contain , . \" or a space";
}
index = -1;
@@ -725,21 +726,21 @@ function RenameNUMBER(_alt, _neu){
}
if (found)
return "Name is already existing - please use another name";
return "Number sequence name is already existing, please choose another name";
NUMBERS[index]["name"] = _neu;
return "";
}
function DeleteNUMBER(_delte){
function DeleteNUMBER(_delete){
if (NUMBERS.length == 1)
return "The last number cannot be deleted."
return "One number sequence is mandatory. Therefore this cannot be deleted"
index = -1;
for (i = 0; i < NUMBERS.length; ++i) {
if (NUMBERS[i]["name"] == _delte)
if (NUMBERS[i]["name"] == _delete)
index = i;
}
@@ -758,7 +759,7 @@ function CreateNUMBER(_numbernew){
}
if (found)
return "Name does already exist, please choose another one!";
return "Number sequence name is already existing, please choose another name";
_ret = new Object();
_ret["name"] = _numbernew;
@@ -796,24 +797,26 @@ function CreateNUMBER(_numbernew){
function getROIInfo(_typeROI, _number){
index = 0;
index = -1;
for (var i = 0; i < NUMBERS.length; ++i)
if (NUMBERS[i]["name"] == _number)
index = i;
return NUMBERS[index][_typeROI];
if (index != -1)
return NUMBERS[index][_typeROI];
else
return "";
}
function RenameROI(_number, _type, _alt, _neu){
if ((_neu.includes("=")) || (_neu.includes(".")) || (_neu.includes(":")) ||
(_neu.includes(",")) || (_neu.includes(";")) || (_neu.includes(" ")) ||
(_neu.includes("\""))) {
return "Name must not contain any of the following characters: . : , ; = \" ' '";
(_neu.includes("\"")))
{
return "ROI name must not contain . : , ; = \" or space";
}
index = -1;
found = false;
_indexnumber = -1;
@@ -821,6 +824,9 @@ function RenameROI(_number, _type, _alt, _neu){
if (NUMBERS[j]["name"] == _number)
_indexnumber = j;
if (_indexnumber == -1)
return "Number sequence not existing. ROI cannot be renamed"
for (i = 0; i < NUMBERS[_indexnumber][_type].length; ++i) {
if (NUMBERS[_indexnumber][_type][i]["name"] == _alt)
index = i;
@@ -829,18 +835,18 @@ function RenameROI(_number, _type, _alt, _neu){
}
if (found)
return "Name is already existing - please use another name";
return "ROI name is already existing, please choose another name";
NUMBERS[_indexnumber][_type][index]["name"] = _neu;
return "";
}
function DeleteNUMBER(_delte){
if (NUMBERS.length == 1)
return "The last number cannot be deleted."
return "The last number cannot be deleted"
index = -1;
for (i = 0; i < NUMBERS.length; ++i) {
if (NUMBERS[i]["name"] == _delte)
@@ -854,21 +860,24 @@ function DeleteNUMBER(_delte){
return "";
}
function CreateROI(_number, _type, _pos, _roinew, _x, _y, _dx, _dy, _CCW){
_indexnumber = -1;
for (j = 0; j < NUMBERS.length; ++j)
if (NUMBERS[j]["name"] == _number)
_indexnumber = j;
if (_indexnumber == -1)
return "Number sequence not existing. ROI cannot be created"
found = false;
for (i = 0; i < NUMBERS.length; ++i) {
if (NUMBERS[_indexnumber][_type]["name"] == _roinew)
for (i = 0; i < NUMBERS[_indexnumber][_type].length; ++i) {
if (NUMBERS[_indexnumber][_type][i]["name"] == _roinew)
found = true;
}
if (found)
return "ROI does already exist, please choose another name!";
return "ROI name is already existing, please choose another name";
_ret = new Object();
_ret["name"] = _roinew;

View File

@@ -1,9 +1,8 @@
<!DOCTYPE html>
<html>
<html lang="en" xml:lang="en">
<head>
<link rel="icon" href="favicon.ico?v=$COMMIT_HASH" type="image/x-icon">
<title>Reboot</title>
<meta charset="utf-8">
<meta charset="UTF-8" />
<style>
h1 {font-size: 2em;}
@@ -12,8 +11,8 @@ h3 {font-size: 1.2em;}
p {font-size: 1em;}
.button {
padding: 10px 20px;
width: 211px;
padding: 5px 10px;
width: 205px;
font-size: 16px;
}
</style>
@@ -22,13 +21,13 @@ p {font-size: 1em;}
</head>
<body style="font-family: arial; padding: 0px 10px;">
<h3>Do you really want to reboot your ESP32 now?</h3>
<h3>Do you really want to reboot now?</h3>
<table class="fixed" border="0">
<tr>
<td>
<button class="button" id="reboot" type="button" onclick="doReboot()">Yes, please reboot</button>
<button class="button" id="reboot" type="button" onclick="doReboot()">Reboot</button>
</td>
</tr>
</table>

View File

@@ -1,17 +1,25 @@
<!DOCTYPE html>
<html style="width: fit-content">
<html lang="en" xml:lang="en">
<head>
<link rel="icon" href="favicon.ico?v=$COMMIT_HASH" type="image/x-icon">
<title>AI on the edge</title>
<meta charset="utf-8">
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.h_iframe iframe {width:995px;height:760px;}
.h_iframe {width:995px;height:605px;}
.h_iframe_explain iframe {width:995px;height:200px;}
.h_iframe_explain {width:995px;height:200px;}
<style>
.h_iframe_explain iframe {
width:995px;
height:155px;
padding:5px;
padding-top:0px;
padding-bottom:0px;
}
.h_iframe iframe {
width:995px;
height:800px;
padding:5px;
}
h1 {font-size: 2em; margin-block-end: 0.3em;}
h2 {font-size: 1.5em;margin-block-start: 0.3em;}
@@ -19,132 +27,318 @@ h3 {font-size: 1.2em;}
p {font-size: 1em;}
.button {
padding: 5px 20px;
width: 211px;
font-size: 16px;
padding: 5px 10px;
width: 125px;
font-size: 16px;
}
table {
width: 1015px;
padding: 0px;
}
.main {
display: flex;
width: 100%;
height: 100%;
flex-direction: column;
overflow: hidden;
}
body, html {
width: 100%;
height: 100%;
min-height: 800px;
margin: 0px 0px 0px 2px;
padding: 0;
font-family: arial;
width: -moz-fit-content;
width: fit-content;
}
</style>
<script type="text/javascript">
function resizeIframe(obj) {
obj.style.height = obj.contentWindow.document.documentElement.scrollHeight + 20 + 'px';
}
</script>
</head>
<body style="font-family: arial">
<table style="border: none">
<tr><td style="padding-right: 10px;"><img src="favicon.ico?v=$COMMIT_HASH"></td>
<td><h1 id="id_title"> Digitizer - Initial Setup</h1>
<h2>An ESP32 all inclusive neural network recognition system for meter digitalization</h2>
</td></tr>
</table>
<table style="border: none">
<tr>
<td style="padding-right: 10px;"><img src="favicon.ico?v=$COMMIT_HASH"></td>
<td>
<h1> Digitizer - AI on the edge - Initial setup</h1>
<h2>An ESP32 all inclusive neural network recognition system for meter digitalization</h2>
</td>
</tr>
</table>
<table>
<tr>
<td>
<button class="button" id="previous" name="previous" onclick="clickPrevious()">Previous</button>
<button class="button" id="next" name="next" onclick="clickNext()">Next</button>
If you need support, have a look to the <a href=https://jomjol.github.io/AI-on-the-edge-device-docs target=_blank>documentation</a> or the <a href=https://github.com/jomjol/AI-on-the-edge-device/discussions target=_blank>discussion</a> pages.
</td>
</tr>
</table>
<table>
<colgroup>
<col span="1" style="width: 45.0%;">
<col span="1" style="width: 15.0%;">
<col span="1" style="width: 25.0%;">
</colgroup>
<tr>
<td>
<button class="button" id="restart" name="restart" onclick="clickStart()">Restart Setup</button>
<button class="button" id="previous" name="previous" onclick="clickPrevious()">Previous Step</button>
<button class="button" id="next" name="next" onclick="clickNext()">Next Step</button>
<button class="button" id="skip" name="skip" onclick="clickAbort()">Abort Setup</button>
</td>
<td style="padding-left:10px;">Setup Progress:<br><progress id="progressBar" value="0" max="7" style="width:120px;"></progress></td>
<td style="padding-left:10px; padding-top: 10px; padding-right: 5px; float:right;">
<output id="rssi" name="rssi"></output>
</td>
</tr>
</table>
<div class="h_iframe_explain" id="h_iframe_explain">
<iframe name="explaincontent" id ="explaincontent" src="" allowfullscreen></iframe>
</div>
<div class="h_iframe_explain" id="h_iframe_explain">
<iframe name="explaincontent" id ="explaincontent" src="" allowfullscreen></iframe>
</div>
<div class="h_iframe">
<iframe name="maincontent" id ="maincontent" src="" allowfullscreen></iframe>
</div>
<div class="h_iframe" id="h_iframe">
<iframe name="maincontent" id ="maincontent" src="" onload="resizeIframe(this)" allowfullscreen></iframe>
<iframe name="stream" id ="stream" src="" display="none" allowfullscreen></iframe>
</div>
<script type="text/javascript" src="common.js?v=$COMMIT_HASH"></script>
<script type="text/javascript">
var canvas = document.getElementById('canvas'),
domainname = getDomainname();
aktstatu = 0;
var aktstep = 0;
var setupCompleted = false;
document.getElementById('stream').style.display = "none"; // Make sure that stream iframe is always hidden
document.getElementById("progressBar").value = 0;
function clickNext() {
aktstatu++;
if (aktstatu > 6) {
aktstatu = 6;
function clickStart() {
aktstep = 0;
setupCompleted = false;
document.getElementById('stream').src = "";
document.getElementById('stream').style.display = "none"; // Make sure that stream iframe is always hidden
LoadStep();
}
function clickAbort() {
setupCompleted = false;
aktstep = 7;
document.getElementById('stream').src = "";
document.getElementById('stream').style.display = "none"; // Make sure that stream iframe is always hidden
LoadStep();
}
function clickNext() {
aktstep++;
if (aktstep > 7) {
aktstep = 7;
}
document.getElementById('stream').src = "";
document.getElementById('stream').style.display = "none"; // Make sure that stream iframe is always hidden
LoadStep();
}
function clickPrevious() {
aktstep--;
if (aktstep < 0) {
aktstep = 0;
}
document.getElementById('stream').src = "";
document.getElementById('stream').style.display = "none"; // Make sure that stream iframe is always hidden
LoadStep();
}
LoadStep();
}
function clickPrevious() {
aktstatu--;
if (aktstatu < 0) {
aktstatu = 0;
function LoadStep(){
loadRSSI();
switch (aktstep) {
case 0: // Start page
document.getElementById('maincontent').src = 'edit_explain_0.html?v=$COMMIT_HASH';
document.getElementById('maincontent').style.display = "";
document.getElementById('h_iframe_explain').style.display = "none";
document.getElementById("restart").disabled = true;
document.getElementById("previous").disabled = true;
document.getElementById("next").disabled = false;
document.getElementById("skip").disabled = false;
document.getElementById("progressBar").value = 0;
setupCompleted = false;
break;
case 1: // Live stream
document.getElementById('maincontent').style.display = "none";
document.getElementById('h_iframe_explain').style.display = "";
document.getElementById('h_iframe_explain').style="height:155px;"
document.getElementById('explaincontent').style="height:155px;"
document.getElementById('explaincontent').scrolling="yes"
document.getElementById('explaincontent').src = 'explain_1.html?v=$COMMIT_HASH';
document.getElementById("restart").disabled = false;
document.getElementById("previous").disabled = false;
document.getElementById("next").disabled = false;
document.getElementById("skip").disabled = false;
document.getElementById('h_iframe').style="height:480px;"
document.getElementById('stream').style="height:480px;"
document.getElementById("progressBar").value = 1;
setupCompleted = false;
setTimeout(function() {
document.getElementById('stream').src = getDomainname() + '/stream?flashlight=true'; // needs to be the last statement because it's kind of blocking
document.getElementById('stream').style.display = "";
}, 500);
break;
case 2: // Reference image
document.getElementById('maincontent').src = 'edit_reference.html?v=$COMMIT_HASH#description';
document.getElementById('maincontent').style.display = "";
document.getElementById('h_iframe_explain').style.display = "";
document.getElementById('h_iframe_explain').style="height:45px;"
document.getElementById('explaincontent').style="height:45px;"
document.getElementById('explaincontent').scrolling="no"
document.getElementById('explaincontent').src = 'explain_2.html?v=$COMMIT_HASH';
document.getElementById("restart").disabled = false;
document.getElementById("previous").disabled = false;
document.getElementById("next").disabled = false;
document.getElementById("skip").disabled = false;
document.getElementById("progressBar").value = 2;
setupCompleted = false;
break;
case 3: // Alignment marker
document.getElementById('maincontent').src = 'edit_alignment.html?v=$COMMIT_HASH#description';
document.getElementById('h_iframe_explain').style.display = "";
document.getElementById('h_iframe_explain').style="height:45px;"
document.getElementById('explaincontent').style="height:45px;"
document.getElementById('explaincontent').scrolling="no"
document.getElementById('explaincontent').src = 'explain_3.html?v=$COMMIT_HASH';
document.getElementById("restart").disabled = false;
document.getElementById("previous").disabled = false;
document.getElementById("next").disabled = false;
document.getElementById("skip").disabled = false;
document.getElementById("progressBar").value = 3;
setupCompleted = false;
break;
case 4: // Digit ROIs
document.getElementById('maincontent').src = 'edit_digits.html?v=$COMMIT_HASH#description';
document.getElementById('h_iframe_explain').style.display = "";
document.getElementById('h_iframe_explain').style="height:45px;"
document.getElementById('explaincontent').style="height:45px;"
document.getElementById('explaincontent').scrolling="no"
document.getElementById('explaincontent').src = 'explain_4.html?v=$COMMIT_HASH';
document.getElementById("restart").disabled = false;
document.getElementById("previous").disabled = false;
document.getElementById("next").disabled = false;
document.getElementById("skip").disabled = false;
document.getElementById("progressBar").value = 4;
setupCompleted = false;
break;
case 5: // Analog ROIs
document.getElementById('maincontent').src = 'edit_analog.html?v=$COMMIT_HASH#description';
document.getElementById('h_iframe_explain').style.display = "";
document.getElementById('h_iframe_explain').style="height:45px;"
document.getElementById('explaincontent').style="height:45px;"
document.getElementById('explaincontent').scrolling="no"
document.getElementById('explaincontent').src = 'explain_5.html?v=$COMMIT_HASH';
document.getElementById("restart").disabled = false;
document.getElementById("previous").disabled = false;
document.getElementById("next").disabled = false;
document.getElementById("skip").disabled = false;
document.getElementById("progressBar").value = 5;
setupCompleted = false;
break;
case 6: // Config page
document.getElementById('maincontent').src = 'edit_config_param.html?v=$COMMIT_HASH#description';
document.getElementById('h_iframe_explain').style.display = "";
document.getElementById('h_iframe_explain').style="height:100px;"
document.getElementById('explaincontent').style="height:100px;"
document.getElementById('explaincontent').scrolling="no"
document.getElementById('explaincontent').src = 'explain_6.html?v=$COMMIT_HASH';
document.getElementById("restart").disabled = false;
document.getElementById("previous").disabled = false;
document.getElementById("next").disabled = false;
document.getElementById("skip").disabled = false;
document.getElementById("progressBar").value = 6;
setupCompleted = true;
break;
case 7: // Setup completed / aborted
document.getElementById('h_iframe').style="height:660px;"
document.getElementById('maincontent').style="height:660px;"
if (setupCompleted) {
document.getElementById('maincontent').src = 'edit_explain_7.html?v=$COMMIT_HASH';
}
else {
document.getElementById('maincontent').src = 'edit_explain_7_abort.html?v=$COMMIT_HASH';
document.getElementById("previous").disabled = true;
}
document.getElementById('h_iframe_explain').style.display = "none";
document.getElementById("skip").disabled = true;
document.getElementById("restart").disabled = false;
document.getElementById("next").disabled = true;
document.getElementById("progressBar").value = 7;
break;
}
}
function loadRSSI() {
url = getDomainname() + '/rssi';
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var _rsp = xhttp.responseText;
if (_rsp >= -55) {
document.getElementById('rssi').value = ("WIFI Signal: Excellent (" + _rsp + "dBm)");
}
else if (_rsp < -55 && _rsp >= -67) {
document.getElementById('rssi').value = ("WIFI Signal: Good (" + _rsp + "dBm)");
}
else if (_rsp < -67 && _rsp >= -78) {
document.getElementById('rssi').value = ("WIFI Signal: Fair (" + _rsp + "dBm)");
}
else if (_rsp < -78 && _rsp >= -85) {
document.getElementById('rssi').value = ("WIFI Signal: Weak (" + _rsp + "dBm)");
}
else {
document.getElementById('rssi').value = ("WIFI Signal: Unreliable (" + _rsp + "dBm)");
}
}
}
xhttp.open("GET", url, true);
xhttp.send();
}
LoadStep();
}
function LoadStep(){
switch (aktstatu) {
case 0:
document.getElementById('maincontent').src = 'edit_explain_0.html?v=$COMMIT_HASH';
document.getElementById('h_iframe_explain').style.display = "none";
document.getElementById("previous").disabled = true;
document.getElementById("next").disabled = false;
break;
case 1:
document.getElementById('maincontent').src = 'edit_reference.html?v=$COMMIT_HASH';
document.getElementById('explaincontent').src = 'explain_1.html?v=$COMMIT_HASH';
document.getElementById('h_iframe_explain').style.display = "";
document.getElementById("previous").disabled = false;
document.getElementById("next").disabled = false;
break;
case 2:
document.getElementById('maincontent').src = 'edit_alignment.html?v=$COMMIT_HASH';
document.getElementById('explaincontent').src = 'explain_2.html?v=$COMMIT_HASH';
document.getElementById('h_iframe_explain').style.display = "";
document.getElementById("previous").disabled = false;
document.getElementById("next").disabled = false;
break;
case 3:
document.getElementById('maincontent').src = 'edit_digits.html?v=$COMMIT_HASH';
document.getElementById('explaincontent').src = 'explain_3.html?v=$COMMIT_HASH';
document.getElementById('h_iframe_explain').style.display = "";
document.getElementById("previous").disabled = false;
document.getElementById("next").disabled = false;
break;
case 4:
document.getElementById('maincontent').src = 'edit_analog.html?v=$COMMIT_HASH';
document.getElementById('explaincontent').src = 'explain_4.html?v=$COMMIT_HASH';
document.getElementById('h_iframe_explain').style.display = "";
document.getElementById("previous").disabled = false;
document.getElementById("next").disabled = false;
break;
case 5:
document.getElementById('maincontent').src = 'edit_config_param.html?v=$COMMIT_HASH?InitialSetup=true';
document.getElementById('explaincontent').src = 'explain_5.html?v=$COMMIT_HASH';
document.getElementById('h_iframe_explain').style.display = "";
document.getElementById("previous").disabled = false;
document.getElementById("next").disabled = false;
break;
case 6:
document.getElementById('maincontent').src = 'edit_explain_6.html?v=$COMMIT_HASH';
document.getElementById('explaincontent').src = 'explain_6.html?v=$COMMIT_HASH'; // Note: The page never gets shown!
document.getElementById('h_iframe_explain').style.display = "none";
document.getElementById("previous").disabled = false;
document.getElementById("next").disabled = true;
break;
}
}
LoadStep();
</script>
</body>
</html>

View File

@@ -1,26 +1,39 @@
body, html {
width: 100%;
height: 100%;
min-height: 800px;
max-width: 1022px;
min-width: 688px;
height: 100vh;
min-height: 100vh;
margin: 0px 0px 0px 2px;
padding: 0;
font-family: arial;
width: fit-content;
}
@media screen and (max-width:687px) {
body, html {
max-width: 687px;
height: 150vh;
min-height: 100vh;
margin: 0px 0px 0px 2px;
padding: 0;
font-family: arial;
}
}
.main {
display: flex;
width: 100%;
height: 100%;
flex-direction: column;
flex-direction: column;
overflow: hidden;
font-family: arial;
}
.iframe {
flex-grow: 1;
margin: 5px 0px 4px 0px;
flex: 1 1 auto;
margin: 5px 0px 8px 0px;
padding: 0;
border: 2px solid #333; /* black */
border: 0px solid #333; /* black */
font-family: arial;
}
h1 {
@@ -41,20 +54,13 @@ p {
font-size: 1em;
}
.menu {
margin: 0px;
padding: 0px;
font-family: "Arial";
font-size: 18px;
font-weight: bold;
width: 1008px;
width: 100%;
background: #333; /* black */
}
@@ -171,13 +177,6 @@ p {
color: white;
}
.arrow {
border: solid #333; /* black */
border-width: 0 3px 3px 0;
@@ -187,9 +186,8 @@ p {
}
.right {
transform: rotate(-45deg);
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg);
position: absolute;
right: 10px;
top: 20px;
@@ -198,8 +196,8 @@ p {
}
.down {
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
border-bottom: solid white;
border-right: solid white;
margin: 0px 0px 2px 5px;

View File

@@ -1,33 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<link rel="icon" href="favicon.ico?v=$COMMIT_HASH" type="image/x-icon">
<meta charset="utf-8">
</head>
<body style="font-family: arial">
testschrift
<div id="value"></div>
</html>
<script type="text/javascript" src="common.js?v=$COMMIT_HASH"></script>
<script type="text/javascript">
var domainname = getDomainname();
function testinit(){
domainname = getDomainname();
url = domainname + '/value?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 +0,0 @@
<!DOCTYPE html><html><head><meta http-equiv="refresh" content="2"></head><body><tr><td><img src = "/original.jpg"></td></tr><tr><td><img src = "/roi.jpg"></td></tr><tr><td><img src = "/resize.bmp"></td></tr><tr><td><h2>Not-a-Number</h2></td></tr></body></html>

View File

@@ -1,5 +1,5 @@
<!DOCTYPE html>
<html>
<html lang="en" xml:lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>

View File

@@ -1,5 +1,5 @@
<html>
<head>
<html lang="en" xml:lang="en">
<head>
<link href="firework.css?v=$COMMIT_HASH" rel="stylesheet">
<script type="text/javascript" src="jquery-3.6.0.min.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="firework.js?v=$COMMIT_HASH"></script>
@@ -14,15 +14,15 @@
<tr><td>gateway</td><td><input type="text" name="gateway" id="gateway"></td><td>Leave emtpy if set by router</td></tr>
<tr><td>netmask</td><td><input type="text" name="netmask" id="netmask"></td><td>Leave emtpy if set by router</td>
</tr><tr><td>DNS</td><td><input type="text" name="dns" id="dns"></td><td>Leave emtpy if set by router</td></tr>
<tr><td>RSSI Threshold</td><td><input type="number" name="name" id="threshold" min="-100" max="0" step="1" value = "0"></td><td>WLAN Mesh Parameter: Threashold for RSSI value to check for start switching access point in a mesh system.Possible values: -100 to 0, 0 = disabled - Value will be transfered to wlan.ini at next startup)</td></tr>
<tr><td>RSSI Threshold</td><td><input type="number" name="name" id="threshold" min="-100" max="0" step="1" value = "0"></td><td>WLAN Mesh Parameter: Threshold for RSSI value to check for start switching access point in a mesh system.Possible values: -100 to 0, 0 = disabled - Value will be transfered to wlan.ini at next startup)</td></tr>
</table>
<button class="button" type="button" onclick="wr()">Write wlan.ini</button>
<button class="button" type="button" onclick="wr();">Write wlan.ini</button>
<input id="newfile" type="file">
<button class="button" style="width:300px" id="doUpdate" type="button" onclick="upload()">Upload Files</button>
<script language="JavaScript">function wr(){
api = "/config?"+"ssid"+document.getElementById("ssid").value+"&pwd="+document.getElementById("password").value;+"&hn="+document.getElementById("hostname").value;+"&ip="+document.getElementById("ip").value;+"&gw="+document.getElementById("gateway").value;+"&nm="+document.getElementById("netmask").value;+"&dns="+document.getElementById("dns").value;+"&rssi="+document.getElementById("threashold").value;
api = "/config?"+"ssid"+document.getElementById("ssid").value+"&pwd="+document.getElementById("password").value;+"&hn="+document.getElementById("hostname").value;+"&ip="+document.getElementById("ip").value;+"&gw="+document.getElementById("gateway").value;+"&nm="+document.getElementById("netmask").value;+"&dns="+document.getElementById("dns").value;+"&rssi="+document.getElementById("threshold").value;
fetch(api);}
@@ -111,5 +111,5 @@ if (!file.name.includes("remote-setup")){
</script>
</html>
</body>
</html>