mirror of
https://github.com/jomjol/AI-on-the-edge-device.git
synced 2025-12-10 13:36:54 +03:00
Merge branch 'rolling'
This commit is contained in:
106
.github/workflows/build.yaml
vendored
Normal file
106
.github/workflows/build.yaml
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
name: Build and Pack
|
||||
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Cache PlatformIO
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.platformio
|
||||
key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }}
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v2
|
||||
- name: Install PlatformIO
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install --upgrade platformio
|
||||
|
||||
- name: Set Variables
|
||||
id: vars
|
||||
run: |
|
||||
echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"
|
||||
echo "::set-output name=date_time::$(git log -1 --format="%at" | xargs -I{} date -d @{} '+%Y-%m-%d %H:%M:%S')"
|
||||
echo "::set-output name=date_time_filename::$(git log -1 --format="%at" | xargs -I{} date -d @{} '+%Y-%m-%d_%H-%M-%S')"
|
||||
#echo "::set-output name=version_string::${{ steps.vars.outputs.date_time_filename }}__${{ github.ref_name }}_(${{ steps.vars.outputs.sha_short }})"
|
||||
#echo "Version String: ${{ steps.vars.outputs.version_string }}"
|
||||
|
||||
|
||||
- name: Set Version used in HTML Info page
|
||||
run: echo "${{ steps.vars.outputs.date_time }}, ${{ github.ref_name }} (${{ steps.vars.outputs.sha_short }})" > "sd-card/html/version.txt"
|
||||
|
||||
|
||||
- name: Build Firmware
|
||||
# run: mkdir -p ./code/.pio/build/esp32cam/; touch ./code/.pio/build/esp32cam/firmware.bin # Testing
|
||||
run: cd code; platformio run --environment esp32cam
|
||||
|
||||
|
||||
|
||||
# Old OTA concept
|
||||
# firmware__*.zip needs to be unpacked before attaching to the release!
|
||||
# The bin filename can contain versioning.
|
||||
- name: Rename firmware file to contain versioning (old ota)
|
||||
run: |
|
||||
mkdir -p ./dist_old_ota
|
||||
cp "./code/.pio/build/esp32cam/firmware.bin" "./dist_old_ota/firmware__${{ steps.vars.outputs.date_time_filename }}__${{ github.ref_name }}_(${{ steps.vars.outputs.sha_short }}).bin"
|
||||
ls -l ./dist_old_ota
|
||||
|
||||
- name: Upload Firmware artifact (old OTA concept)
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: "firmware__extract_before_upload__only_needed_for_migration_from_11.2.0"
|
||||
path: ./dist_old_ota/*
|
||||
|
||||
- name: Upload Web interface artifact (old OTA concept)
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: "html__only_needed_for_migration_from_11.2.0__${{ steps.vars.outputs.date_time_filename }}__${{ github.ref_name }}_(${{ steps.vars.outputs.sha_short }})"
|
||||
path: ./sd-card/html/*
|
||||
|
||||
|
||||
|
||||
# New OTA concept
|
||||
# update__version.zip file with following content:
|
||||
# - /firmware.bin
|
||||
# - (optional) /html/*
|
||||
# - (optional) /config/*.tfl
|
||||
- name: Prepare update.zip artifact
|
||||
run: |
|
||||
mkdir -p ./dist
|
||||
cp "./code/.pio/build/esp32cam/firmware.bin" "dist/firmware.bin"
|
||||
|
||||
- name: Upload update.zip Artifact (Firmware only)
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: "update_firmware_only__${{ steps.vars.outputs.date_time_filename }}__${{ github.ref_name }}_(${{ steps.vars.outputs.sha_short }})"
|
||||
path: ./dist/*
|
||||
|
||||
|
||||
- name: Prepare update.zip artifact (Firmware + Web UI)
|
||||
run: cp -r ./sd-card/html ./dist/
|
||||
|
||||
- name: Upload update.zip artifact (Firmware + Web UI)
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: "update_firmware+web_ui__${{ steps.vars.outputs.date_time_filename }}__${{ github.ref_name }}_(${{ steps.vars.outputs.sha_short }})"
|
||||
path: ./dist/*
|
||||
|
||||
|
||||
- name: Prepare update.zip artifact (Firmware + Web UI + CNN)
|
||||
run: |
|
||||
mkdir ./dist/config/
|
||||
cp ./sd-card/config/*.tfl ./dist/config/ 2>/dev/null || true
|
||||
cp ./sd-card/config/*.tflite ./dist/config/ 2>/dev/null || true
|
||||
|
||||
- name: Upload update.zip artifact (Firmware + Web UI + CNN)
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: "update_firmware+web_ui+cnn__${{ steps.vars.outputs.date_time_filename }}__${{ github.ref_name }}_(${{ steps.vars.outputs.sha_short }})"
|
||||
path: ./dist/*
|
||||
21
README.md
21
README.md
@@ -40,6 +40,27 @@ In other cases you can contact the developer via email: <img src="https://raw.gi
|
||||
|
||||
------
|
||||
|
||||
##### 11.3.0 - Intermediate Digits (2022-09-17)
|
||||
|
||||
- **ATTENTION**:
|
||||
- first update the 'firmware.bin' and ensure that the new version is running
|
||||
|
||||
- Only afterwards update the 'html.zip'
|
||||
|
||||
- Otherwise the downwards compatibility of the new counter clockwise feature is not given and you end in a reboot loop, that needs manual flashing!
|
||||
|
||||
|
||||
|
||||
- Increased precision (more than 6-7 digits)
|
||||
- Implements Counter Clockwise Analog Pointers
|
||||
- Improved post processing algorithm
|
||||
- Debugging: intensive use of testcases
|
||||
- MQTT: improved handling, extended logging, automated reconnect
|
||||
- HTML: Backup Option for Configuration
|
||||
- HTML: Improved Reboot
|
||||
- HTML: Update WebUI (Reboot, Infos, CPU Temp, RSSI)
|
||||
- This version is largely also based on the work of **[caco3](https://github.com/caco3)**, **[adellafave](https://github.com/adellafave)**, **[haverland](https://github.com/haverland)**, **[stefanbode](https://github.com/stefanbode)**, **[PLCHome](https://github.com/PLCHome)**
|
||||
|
||||
##### 11.2.0 - Intermediate Digits (2022-08-28)
|
||||
|
||||
- Updated Tensorflow / TFlite to newest tflite (version as of 2022-07-27)
|
||||
|
||||
@@ -120,16 +120,6 @@ esp_err_t get_tflite_file_handler(httpd_req_t *req)
|
||||
}
|
||||
|
||||
|
||||
/* Handler to redirect incoming GET request for /index.html to /
|
||||
* This can be overridden by uploading file with same name */
|
||||
// static esp_err_t index_html_get_handler(httpd_req_t *req)
|
||||
// {
|
||||
// httpd_resp_set_status(req, "307 Temporary Redirect");
|
||||
// httpd_resp_set_hdr(req, "Location", "/");
|
||||
// httpd_resp_send(req, NULL, 0); // Response body can be empty
|
||||
// return ESP_OK;
|
||||
// }
|
||||
|
||||
/* Send HTTP response with a run-time generated html consisting of
|
||||
* a list of all files and folders under the requested path.
|
||||
* In case of SPIFFS this returns empty list when path is any
|
||||
@@ -716,6 +706,101 @@ void delete_all_in_directory(std::string _directory)
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
std::string unzip_new(std::string _in_zip_file, std::string _target_zip, std::string _target_bin, std::string _main)
|
||||
{
|
||||
int i, sort_iter;
|
||||
mz_bool status;
|
||||
size_t uncomp_size;
|
||||
mz_zip_archive zip_archive;
|
||||
void* p;
|
||||
char archive_filename[64];
|
||||
std::string zw, ret = "";
|
||||
// static const char* s_Test_archive_filename = "testhtml.zip";
|
||||
|
||||
printf("miniz.c version: %s\n", MZ_VERSION);
|
||||
printf("Zipfile: %s\n", _in_zip_file.c_str());
|
||||
printf("Target Dir ZIP: %s\n", _target_zip.c_str());
|
||||
printf("Target Dir BIN: %s\n", _target_bin.c_str());
|
||||
|
||||
// Now try to open the archive.
|
||||
memset(&zip_archive, 0, sizeof(zip_archive));
|
||||
status = mz_zip_reader_init_file(&zip_archive, _in_zip_file.c_str(), 0);
|
||||
if (!status)
|
||||
{
|
||||
printf("mz_zip_reader_init_file() failed!\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Get and print information about each file in the archive.
|
||||
int numberoffiles = (int)mz_zip_reader_get_num_files(&zip_archive);
|
||||
for (sort_iter = 0; sort_iter < 2; sort_iter++)
|
||||
{
|
||||
memset(&zip_archive, 0, sizeof(zip_archive));
|
||||
status = mz_zip_reader_init_file(&zip_archive, _in_zip_file.c_str(), sort_iter ? MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY : 0);
|
||||
if (!status)
|
||||
{
|
||||
printf("mz_zip_reader_init_file() failed!\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (i = 0; i < numberoffiles; i++)
|
||||
{
|
||||
mz_zip_archive_file_stat file_stat;
|
||||
mz_zip_reader_file_stat(&zip_archive, i, &file_stat);
|
||||
sprintf(archive_filename, file_stat.m_filename);
|
||||
|
||||
// Try to extract all the files to the heap.
|
||||
p = mz_zip_reader_extract_file_to_heap(&zip_archive, archive_filename, &uncomp_size, 0);
|
||||
if (!p)
|
||||
{
|
||||
printf("mz_zip_reader_extract_file_to_heap() failed!\n");
|
||||
mz_zip_reader_end(&zip_archive);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Save to File.
|
||||
zw = std::string(archive_filename);
|
||||
if (toUpper(zw) == "FIRMWARE.BIN")
|
||||
{
|
||||
zw = _target_bin + zw;
|
||||
ret = zw;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string _dir = getDirectory(zw);
|
||||
|
||||
if (_dir.length() > 0)
|
||||
{
|
||||
zw = _main + zw;
|
||||
}
|
||||
else
|
||||
{
|
||||
zw = _target_zip + zw;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
printf("Filename to extract: %s", zw.c_str());
|
||||
DeleteFile(zw);
|
||||
FILE* fpTargetFile = OpenFileAndWait(zw.c_str(), "wb");
|
||||
fwrite(p, 1, (uint)uncomp_size, fpTargetFile);
|
||||
fclose(fpTargetFile);
|
||||
|
||||
printf("Successfully extracted file \"%s\", size %u\n", archive_filename, (uint)uncomp_size);
|
||||
// printf("File data: \"%s\"\n", (const char*)p);
|
||||
|
||||
// We're done.
|
||||
mz_free(p);
|
||||
}
|
||||
|
||||
// Close the archive, freeing any resources it was using
|
||||
mz_zip_reader_end(&zip_archive);
|
||||
}
|
||||
|
||||
printf("Success.\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
void unzip(std::string _in_zip_file, std::string _target_directory){
|
||||
int i, sort_iter;
|
||||
mz_bool status;
|
||||
@@ -860,15 +945,4 @@ void register_server_file_uri(httpd_handle_t server, const char *base_path)
|
||||
};
|
||||
httpd_register_uri_handler(server, &file_delete);
|
||||
|
||||
|
||||
/* URI handler for getting tflite files from server */
|
||||
/*
|
||||
httpd_uri_t file_tflite = {
|
||||
.uri = "/tflite", // Match all URIs of type /delete/path/to/file
|
||||
.method = HTTP_GET,
|
||||
.handler = get_tflite_file_handler,
|
||||
.user_ctx = server_data // Pass server data as context
|
||||
};
|
||||
httpd_register_uri_handler(server, &file_tflite);
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
void register_server_file_uri(httpd_handle_t server, const char *base_path);
|
||||
|
||||
void unzip(std::string _in_zip_file, std::string _target_directory);
|
||||
std::string unzip_new(std::string _in_zip_file, std::string _target_zip, std::string _target_bin, std::string _main = "/sdcard/");
|
||||
|
||||
|
||||
void delete_all_in_directory(std::string _directory);
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ esp_err_t send_file(httpd_req_t *req, std::string filename)
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Sending file : %s ...", filename.c_str());
|
||||
// httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
set_content_type_from_file(req, filename.c_str());
|
||||
|
||||
/* Retrieve the pointer to scratch buffer for temporary storage */
|
||||
@@ -120,6 +121,8 @@ esp_err_t set_content_type_from_file(httpd_req_t *req, const char *filename)
|
||||
return httpd_resp_set_type(req, "image/x-icon");
|
||||
} else if (IS_FILE_EXT(filename, ".js")) {
|
||||
return httpd_resp_set_type(req, "text/javascript");
|
||||
} else if (IS_FILE_EXT(filename, ".css")) {
|
||||
return httpd_resp_set_type(req, "text/css");
|
||||
}
|
||||
/* This is a limited set only */
|
||||
/* For any other type always set as plain text */
|
||||
|
||||
@@ -50,6 +50,8 @@ static char ota_write_data[BUFFSIZE + 1] = { 0 };
|
||||
#define OTA_URL_SIZE 256
|
||||
static const char *TAGPARTOTA = "server_ota";
|
||||
|
||||
esp_err_t handler_reboot(httpd_req_t *req);
|
||||
|
||||
|
||||
static void infinite_loop(void)
|
||||
{
|
||||
@@ -207,24 +209,6 @@ static void print_sha256 (const uint8_t *image_hash, const char *label)
|
||||
|
||||
static bool diagnostic(void)
|
||||
{
|
||||
/*
|
||||
gpio_config_t io_conf;
|
||||
io_conf.intr_type = (gpio_int_type_t) GPIO_PIN_INTR_DISABLE;
|
||||
io_conf.mode = GPIO_MODE_INPUT;
|
||||
io_conf.pin_bit_mask = (1ULL << CONFIG_EXAMPLE_GPIO_DIAGNOSTIC);
|
||||
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
|
||||
io_conf.pull_up_en = GPIO_PULLUP_ENABLE;
|
||||
gpio_config(&io_conf);
|
||||
|
||||
ESP_LOGI(TAGPARTOTA, "Diagnostics (5 sec)...");
|
||||
vTaskDelay(5000 / portTICK_PERIOD_MS);
|
||||
|
||||
bool diagnostic_is_ok = gpio_get_level(CONFIG_EXAMPLE_GPIO_DIAGNOSTIC);
|
||||
|
||||
gpio_reset_pin(CONFIG_EXAMPLE_GPIO_DIAGNOSTIC);
|
||||
|
||||
return diagnostic_is_ok;
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -326,7 +310,7 @@ esp_err_t handler_ota_update(httpd_req_t *req)
|
||||
|
||||
if (httpd_query_key_value(_query, "task", _valuechar, 30) == ESP_OK)
|
||||
{
|
||||
printf("task is found"); printf(_valuechar); printf("\n");
|
||||
printf("task is found: "); printf(_valuechar); printf("\n");
|
||||
_task = std::string(_valuechar);
|
||||
}
|
||||
|
||||
@@ -344,16 +328,105 @@ esp_err_t handler_ota_update(httpd_req_t *req)
|
||||
|
||||
};
|
||||
|
||||
if (_task.compare("update") == 0)
|
||||
{
|
||||
std::string filetype = toUpper(getFileType(fn));
|
||||
if (filetype.length() == 0)
|
||||
{
|
||||
std::string zw = "Update failed - no file specified (zip, bin, tfl, tlite)";
|
||||
httpd_resp_sendstr_chunk(req, zw.c_str());
|
||||
httpd_resp_sendstr_chunk(req, NULL);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
if ((filetype == "TFLITE") || (filetype == "TFL"))
|
||||
{
|
||||
std::string out = "/sdcard/config/" + getFileFullFileName(fn);
|
||||
DeleteFile(out);
|
||||
CopyFile(fn, out);
|
||||
DeleteFile(fn);
|
||||
|
||||
const char* resp_str = "Neural Network File copied.";
|
||||
httpd_resp_sendstr_chunk(req, resp_str);
|
||||
httpd_resp_sendstr_chunk(req, NULL);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
if (filetype == "ZIP")
|
||||
{
|
||||
std::string in, out, outbin, zw, retfirmware;
|
||||
|
||||
// in = "/sdcard/firmware/html.zip";
|
||||
out = "/sdcard/html";
|
||||
outbin = "/sdcard/firmware";
|
||||
|
||||
// delete_all_in_directory(out);
|
||||
|
||||
retfirmware = unzip_new(fn, out+"/", outbin+"/");
|
||||
|
||||
if (retfirmware.length() > 0)
|
||||
{
|
||||
filetype = "BIN";
|
||||
fn = retfirmware;
|
||||
zw = "HTML Update Successfull!<br><br>Additioal firmware found in ZIP file.\n";
|
||||
httpd_resp_sendstr_chunk(req, zw.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
zw = "HTML Update Successfull!<br><br>No reboot necessary.\n";
|
||||
httpd_resp_sendstr_chunk(req, zw.c_str());
|
||||
httpd_resp_sendstr_chunk(req, NULL);
|
||||
return ESP_OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (filetype == "BIN")
|
||||
{
|
||||
const char* resp_str;
|
||||
KillTFliteTasks();
|
||||
gpio_handler_deinit();
|
||||
if (ota_update_task(fn))
|
||||
{
|
||||
// resp_str = "rebooting - Firmware Update Successfull!<br><br>You can restart now.";
|
||||
// httpd_resp_send(req, resp_str, strlen(resp_str));
|
||||
// httpd_resp_sendstr_chunk(req, NULL);
|
||||
return handler_reboot(req);
|
||||
}
|
||||
else
|
||||
{
|
||||
resp_str = "Error during Firmware Update!!!<br><br>Please check output of console.";
|
||||
}
|
||||
|
||||
httpd_resp_send(req, resp_str, strlen(resp_str));
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_ota_update - Done");
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
std::string zw = "Update failed - no valid file specified (zip, bin, tfl, tlite)";
|
||||
httpd_resp_sendstr_chunk(req, zw.c_str());
|
||||
httpd_resp_sendstr_chunk(req, NULL);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
if (_task.compare("unziphtml") == 0)
|
||||
{
|
||||
std::string in, out, zw;
|
||||
|
||||
in = "/sdcard/firmware/html.zip";
|
||||
out = "/sdcard/html/";
|
||||
out = "/sdcard/html";
|
||||
|
||||
delete_all_in_directory(out);
|
||||
|
||||
unzip(in, out);
|
||||
unzip(in, out+"/");
|
||||
zw = "HTML Update Successfull!<br><br>No reboot necessary";
|
||||
httpd_resp_sendstr_chunk(req, zw.c_str());
|
||||
httpd_resp_sendstr_chunk(req, NULL);
|
||||
@@ -371,6 +444,8 @@ esp_err_t handler_ota_update(httpd_req_t *req)
|
||||
unlink(fn.c_str());
|
||||
}
|
||||
/* Respond with an empty chunk to signal HTTP response completion */
|
||||
std::string zw = "file deleted!\n";
|
||||
httpd_resp_sendstr_chunk(req, zw.c_str());
|
||||
httpd_resp_send_chunk(req, NULL, 0);
|
||||
return ESP_OK;
|
||||
}
|
||||
@@ -437,7 +512,7 @@ esp_err_t handler_reboot(httpd_req_t *req)
|
||||
|
||||
LogFile.WriteToFile("handler_reboot");
|
||||
ESP_LOGI(TAGPARTOTA, "!!! System will restart within 5 sec!!!");
|
||||
const char* resp_str = "<body style='font-family: arial'> <h3 id=t></h3></body><script>var h='Rebooting!<br>The page will automatically reload.<br>'; document.getElementById('t').innerHTML=h; setInterval(function (){h +='.'; document.getElementById('t').innerHTML=h; fetch(window.location.hostname,{mode: 'no-cors'}).then(r=>{window.location.replace('/wasserzaehler_roi.html');})}, 1000);</script>";
|
||||
const char* resp_str = "<body style='font-family: arial'> <h3 id=t></h3></body><script>var h='Rebooting!<br>The page will automatically reload after around 25s.<br>'; document.getElementById('t').innerHTML=h; setInterval(function (){h +='.'; document.getElementById('t').innerHTML=h; fetch(window.location.hostname,{mode: 'no-cors'}).then(r=>{parent.location.href=('/index.html');})}, 1000);</script>";
|
||||
httpd_resp_send(req, resp_str, strlen(resp_str));
|
||||
|
||||
doReboot();
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
static const char* TAG = "flow_analog";
|
||||
|
||||
bool debugdetailgeneral = false;
|
||||
bool debugdetailgeneral = true;
|
||||
|
||||
ClassFlowCNNGeneral::ClassFlowCNNGeneral(ClassFlowAlignment *_flowalign, t_CNNType _cnntype) : ClassFlowImage(NULL, TAG)
|
||||
{
|
||||
@@ -201,7 +201,7 @@ int ClassFlowCNNGeneral::ZeigerEvalHybridNeu(float zahl, float zahl_vorgaenger,
|
||||
if (AnalogerVorgaenger)
|
||||
{
|
||||
// result = ZeigerEvalAnalogToDigitNeu(zahl, eval_vorgaenger);
|
||||
result = ZeigerEvalAnalogToDigitNeu(zahl, zahl_vorgaenger);
|
||||
result = ZeigerEvalAnalogToDigitNeu(zahl, zahl_vorgaenger, eval_vorgaenger);
|
||||
if (debugdetailgeneral) LogFile.WriteToFile("ClassFlowCNNGeneral::ZeigerEvalHybridNeu - Analoger Vorgänger, Bewertung über ZeigerEvalAnalogNeu = " + std::to_string(result) +
|
||||
" zahl: " + std::to_string(zahl) + " zahl_vorgaenger = " + std::to_string(zahl_vorgaenger)+ " eval_vorgaenger = " + std::to_string(eval_vorgaenger) + " DigitalUnschaerfe = " + std::to_string(DigitalUnschaerfe));
|
||||
return result;
|
||||
@@ -232,20 +232,20 @@ int ClassFlowCNNGeneral::ZeigerEvalHybridNeu(float zahl, float zahl_vorgaenger,
|
||||
}
|
||||
|
||||
// bleibt nur >= 9.5 --> noch kein Nulldurchgang --> 2.8 --> 2, und 3.1 --> 2
|
||||
// hier auf 4 reduziert, da erst ab Vorgänder 9 anfängt umzustellen. Bei 9.5 Vorgänger kann die aktuelle
|
||||
// Zahl noch x.4 - x.5 sein.
|
||||
// alles >=x.4 kann als aktuelle Zahl gelten im Übergang. Bei 9.5 Vorgänger kann die aktuelle
|
||||
// Zahl noch x.6 - x.7 sein.
|
||||
if (ergebnis_nachkomma >= 4)
|
||||
result = ergebnis_vorkomma;
|
||||
else
|
||||
result = (ergebnis_vorkomma - 1 + 10) % 10;
|
||||
|
||||
if (debugdetailgeneral) LogFile.WriteToFile("ClassFlowCNNGeneral::ZeigerEvalHybridNeu - KEIN Analoger Vorgänger, >= 9.5 --> noch kein Nulldurchgang = " + std::to_string(result) +
|
||||
" zahl: " + std::to_string(zahl) + " zahl_vorgaenger = " + std::to_string(zahl_vorgaenger)+ " eval_vorgaenger = " + std::to_string(eval_vorgaenger) + " DigitalUnschaerfe = " + std::to_string(DigitalUnschaerfe));
|
||||
" zahl: " + std::to_string(zahl) + " zahl_vorgaenger = " + std::to_string(zahl_vorgaenger)+ " eval_vorgaenger = " + std::to_string(eval_vorgaenger) + " DigitalUnschaerfe = " + std::to_string(DigitalUnschaerfe) + " ergebnis_nachkomma = " + std::to_string(ergebnis_nachkomma));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int ClassFlowCNNGeneral::ZeigerEvalAnalogToDigitNeu(float zahl, float ziffer_vorgaenger)
|
||||
int ClassFlowCNNGeneral::ZeigerEvalAnalogToDigitNeu(float zahl, float ziffer_vorgaenger, int eval_vorgaenger)
|
||||
{
|
||||
int result;
|
||||
int ergebnis_nachkomma = ((int) floor(zahl * 10)) % 10;
|
||||
@@ -272,7 +272,8 @@ int ClassFlowCNNGeneral::ZeigerEvalAnalogToDigitNeu(float zahl, float ziffer_vor
|
||||
return result;
|
||||
}
|
||||
|
||||
if (ziffer_vorgaenger <= 1) // Nulldurchgang hat stattgefunden (!Bewertung über Prev_value und nicht Zahl!) --> hier aufrunden (2.8 --> 3, aber auch 3.1 --> 3)
|
||||
if (ziffer_vorgaenger <= 1 && eval_vorgaenger<9) // Nulldurchgang hat stattgefunden (!Bewertung über Prev_value und nicht Zahl!) --> hier aufrunden (2.8 --> 3, aber auch 3.1 --> 3)
|
||||
// aber Sonderfall ziffer_vorgaeger = 0.1 vor_vorgaenger 9.9 => eval_vorgaenger ist 9, damit hat Nulldurchgang nicht stattgefunden.
|
||||
{
|
||||
if (ergebnis_nachkomma > 5)
|
||||
result = (ergebnis_vorkomma + 1) % 10;
|
||||
@@ -339,38 +340,6 @@ int ClassFlowCNNGeneral::ZeigerEvalAnalogNeu(float zahl, int ziffer_vorgaenger)
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
int ClassFlowCNNGeneral::ZeigerEval(float zahl, int ziffer_vorgaenger)
|
||||
{
|
||||
int ergebnis_nachkomma = ((int) floor(zahl * 10) + 10) % 10;
|
||||
int ergebnis_vorkomma = ((int) floor(zahl) + 10) % 10;
|
||||
int ergebnis;
|
||||
float ergebnis_rating;
|
||||
if (debugdetailgeneral) LogFile.WriteToFile("ClassFlowCNNGeneral::ZeigerEval erg_v=" + std::to_string(ergebnis_vorkomma) + ", erg_n=" + std::to_string(ergebnis_nachkomma) + ", ziff_v=" + std::to_string(ziffer_vorgaenger));
|
||||
|
||||
if (ziffer_vorgaenger == -1)
|
||||
return ergebnis_vorkomma % 10;
|
||||
|
||||
// Ist die aktuelle Stelle schon umgesprungen und die Vorstelle noch nicht?
|
||||
// Akt.: 2.1, Vorstelle = 0.9 => 1.9
|
||||
// Problem sind mehrere Rundungen
|
||||
// Bsp. zahl=4.5, Vorgänger= 9.6 (ziffer_vorgaenger=0)
|
||||
// Tritt nur auf bei Übergang von analog auf digit
|
||||
ergebnis_rating = ergebnis_nachkomma - ziffer_vorgaenger;
|
||||
if (ergebnis_nachkomma >= 5)
|
||||
ergebnis_rating-=5.1;
|
||||
else
|
||||
ergebnis_rating+=5;
|
||||
ergebnis = (int) round(zahl);
|
||||
if (ergebnis_rating < 0)
|
||||
ergebnis-=1;
|
||||
if (ergebnis == -1)
|
||||
ergebnis+=10;
|
||||
|
||||
ergebnis = (ergebnis + 10) % 10;
|
||||
return ergebnis;
|
||||
}
|
||||
*/
|
||||
|
||||
bool ClassFlowCNNGeneral::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
{
|
||||
@@ -416,11 +385,6 @@ bool ClassFlowCNNGeneral::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
{
|
||||
this->logfileRetentionInDays = std::stoi(zerlegt[1]);
|
||||
}
|
||||
// if ((toUpper(zerlegt[0]) == "MODELTYPE") && (zerlegt.size() > 1))
|
||||
// {
|
||||
// if (toUpper(zerlegt[1]) == "DIGITHYPRID")
|
||||
// CNNType = DigitalHyprid;
|
||||
// }
|
||||
|
||||
if ((toUpper(zerlegt[0]) == "MODEL") && (zerlegt.size() > 1))
|
||||
{
|
||||
@@ -439,6 +403,11 @@ bool ClassFlowCNNGeneral::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
neuroi->posy = std::stoi(zerlegt[2]);
|
||||
neuroi->deltax = std::stoi(zerlegt[3]);
|
||||
neuroi->deltay = std::stoi(zerlegt[4]);
|
||||
neuroi->CCW = false;
|
||||
if (zerlegt.size() >= 6)
|
||||
{
|
||||
neuroi->CCW = toUpper(zerlegt[5]) == "TRUE";
|
||||
}
|
||||
neuroi->result_float = -1;
|
||||
neuroi->image = NULL;
|
||||
neuroi->image_org = NULL;
|
||||
@@ -511,7 +480,7 @@ general* ClassFlowCNNGeneral::GetGENERAL(string _name, bool _create = true)
|
||||
|
||||
_ret->ROI.push_back(neuroi);
|
||||
|
||||
printf("GetGENERAL - GENERAL %s - roi %s\n", _analog.c_str(), _roi.c_str());
|
||||
printf("GetGENERAL - GENERAL %s - roi %s - CCW: %d\n", _analog.c_str(), _roi.c_str(), neuroi->CCW);
|
||||
|
||||
return _ret;
|
||||
}
|
||||
@@ -658,10 +627,11 @@ bool ClassFlowCNNGeneral::getNetworkParameter()
|
||||
CNNType = Digital;
|
||||
printf("TFlite-Type set to Digital\n");
|
||||
break;
|
||||
case 20:
|
||||
/* case 20:
|
||||
CNNType = DigitalHyprid10;
|
||||
printf("TFlite-Type set to DigitalHyprid10\n");
|
||||
break;
|
||||
*/
|
||||
// case 22:
|
||||
// CNNType = DigitalHyprid;
|
||||
// printf("TFlite-Type set to DigitalHyprid\n");
|
||||
@@ -724,8 +694,13 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time)
|
||||
f1 = tflite->GetOutputValue(0);
|
||||
f2 = tflite->GetOutputValue(1);
|
||||
float result = fmod(atan2(f1, f2) / (M_PI * 2) + 2, 1);
|
||||
GENERAL[_ana]->ROI[i]->result_float = result * 10;
|
||||
printf("Result General(Analog)%i: %f\n", i, GENERAL[_ana]->ROI[i]->result_float);
|
||||
|
||||
if(GENERAL[_ana]->ROI[i]->CCW)
|
||||
GENERAL[_ana]->ROI[i]->result_float = 10 - (result * 10);
|
||||
else
|
||||
GENERAL[_ana]->ROI[i]->result_float = result * 10;
|
||||
|
||||
printf("Result General(Analog)%i - CCW: %d - %f\n", i, GENERAL[_ana]->ROI[i]->CCW, GENERAL[_ana]->ROI[i]->result_float);
|
||||
if (isLogImage)
|
||||
LogImage(logPath, GENERAL[_ana]->ROI[i]->name, &GENERAL[_ana]->ROI[i]->result_float, NULL, time, GENERAL[_ana]->ROI[i]->image_org);
|
||||
} break;
|
||||
@@ -790,6 +765,7 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time)
|
||||
}
|
||||
} break;
|
||||
*/
|
||||
/*
|
||||
case DigitalHyprid10:
|
||||
{
|
||||
int _num, _nachkomma;
|
||||
@@ -825,6 +801,7 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time)
|
||||
}
|
||||
}
|
||||
} break;
|
||||
*/
|
||||
|
||||
case DoubleHyprid10:
|
||||
{
|
||||
@@ -858,7 +835,7 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time)
|
||||
_fit = _val + _valminus;
|
||||
|
||||
}
|
||||
if (result > 10)
|
||||
if (result >= 10)
|
||||
result = result - 10;
|
||||
if (result < 0)
|
||||
result = result + 10;
|
||||
@@ -916,15 +893,17 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time)
|
||||
|
||||
_num = tflite->GetOutClassification();
|
||||
|
||||
GENERAL[_ana]->ROI[i]->result_float = (float)_num / 10.0;
|
||||
if(GENERAL[_ana]->ROI[i]->CCW)
|
||||
GENERAL[_ana]->ROI[i]->result_float = 10 - ((float)_num / 10.0);
|
||||
else
|
||||
GENERAL[_ana]->ROI[i]->result_float = (float)_num / 10.0;
|
||||
|
||||
|
||||
_result_save_file = GENERAL[_ana]->ROI[i]->result_float;
|
||||
|
||||
|
||||
GENERAL[_ana]->ROI[i]->isReject = false;
|
||||
|
||||
printf("Result General(Analog)%i: %f\n", i, GENERAL[_ana]->ROI[i]->result_float);
|
||||
printf("Result General(Analog)%i - CCW: %d - %f\n", i, GENERAL[_ana]->ROI[i]->CCW, GENERAL[_ana]->ROI[i]->result_float);
|
||||
|
||||
if (isLogImage)
|
||||
{
|
||||
|
||||
@@ -10,7 +10,6 @@ enum t_CNNType {
|
||||
Analogue,
|
||||
Analogue100,
|
||||
Digital,
|
||||
// DigitalHyprid,
|
||||
DigitalHyprid10,
|
||||
DoubleHyprid10,
|
||||
Digital100,
|
||||
@@ -30,21 +29,18 @@ protected:
|
||||
int DigitalBand = 3;
|
||||
float DigitalAnalogerVorgaengerUebergangsbereich = 2;
|
||||
float DigitalUebergangsbereichVorgaengerAnalogToDigit = 1; // war vorher 2
|
||||
float DigitalUebergangsbereichVorgaenger = 0.9;
|
||||
float DigitalUebergangsbereichVorgaenger = 0.7; // 9.3 - 0.7
|
||||
|
||||
string cnnmodelfile;
|
||||
int modelxsize, modelysize, modelchannel;
|
||||
bool isLogImageSelect;
|
||||
string LogImageSelect;
|
||||
ClassFlowAlignment* flowpostalignment;
|
||||
// ClassFlowPostProcessing *flowpostprocessing = NULL;
|
||||
bool SaveAllFiles;
|
||||
// bool extendedResolution;
|
||||
|
||||
// int ZeigerEval(float zahl, int ziffer_vorgaenger);
|
||||
// int ZeigerEvalHybrid(float zahl, float zahl_vorgaenger, int eval_vorgaenger);
|
||||
bool SaveAllFiles;
|
||||
|
||||
int ZeigerEvalAnalogNeu(float zahl, int ziffer_vorgaenger);
|
||||
int ZeigerEvalAnalogToDigitNeu(float zahl, float ziffer_vorgaenger);
|
||||
int ZeigerEvalAnalogToDigitNeu(float zahl, float ziffer_vorgaenger, int eval_vorgaenger);
|
||||
int ZeigerEvalHybridNeu(float zahl, float zahl_vorgaenger, int eval_vorgaenger, bool AnalogerVorgaenger = false);
|
||||
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ struct roi {
|
||||
int posx, posy, deltax, deltay;
|
||||
float result_float;
|
||||
int result_klasse;
|
||||
bool isReject;
|
||||
bool isReject, CCW;
|
||||
string name;
|
||||
CImageBasis *image, *image_org;
|
||||
};
|
||||
@@ -33,9 +33,9 @@ struct NumberPost {
|
||||
bool checkDigitIncreaseConsistency;
|
||||
time_t lastvalue;
|
||||
string timeStamp;
|
||||
float FlowRateAct; // m3 / min
|
||||
float PreValue; // letzter Wert, der gut ausgelesen wurde
|
||||
float Value; // letzer ausgelesener Wert, inkl. Korrekturen
|
||||
double FlowRateAct; // m3 / min
|
||||
double PreValue; // letzter Wert, der gut ausgelesen wurde
|
||||
double Value; // letzer ausgelesener Wert, inkl. Korrekturen
|
||||
string ReturnRateValue; // RückgabewertRate
|
||||
string ReturnChangeAbsolute; // RückgabewertRate
|
||||
string ReturnRawValue; // Rohwert (mit N & führenden 0)
|
||||
|
||||
@@ -63,7 +63,12 @@ void ClassFlowImage::LogImage(string logPath, string name, float *resultFloat, i
|
||||
if (*resultFloat < 0)
|
||||
sprintf(buf, "N.N_");
|
||||
else
|
||||
{
|
||||
sprintf(buf, "%.1f_", *resultFloat);
|
||||
if (strcmp(buf, "10.0_"))
|
||||
sprintf(buf, "0.0_");
|
||||
}
|
||||
|
||||
} else if (resultInt != NULL) {
|
||||
sprintf(buf, "%d_", *resultInt);
|
||||
} else {
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "time_sntp.h"
|
||||
#include "interface_mqtt.h"
|
||||
#include "ClassFlowPostProcessing.h"
|
||||
#include "ClassLogFile.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
@@ -31,9 +32,7 @@ void ClassFlowMQTT::SetInitialParameter(void)
|
||||
ListFlowControll = NULL;
|
||||
disabled = false;
|
||||
MQTTenable = false;
|
||||
|
||||
|
||||
|
||||
keepAlive = 600; // TODO This must be greater than the Flow Interval!
|
||||
}
|
||||
|
||||
ClassFlowMQTT::ClassFlowMQTT()
|
||||
@@ -124,11 +123,50 @@ bool ClassFlowMQTT::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
printf("InitMQTTInit\n");
|
||||
mainerrortopic = maintopic + "/connection";
|
||||
printf("Init MQTT with uri: %s, clientname: %s, user: %s, password: %s, maintopic: %s\n", uri.c_str(), clientname.c_str(), user.c_str(), password.c_str(), mainerrortopic.c_str());
|
||||
MQTTInit(uri, clientname, user, password, mainerrortopic, 60);
|
||||
MQTTPublish(mainerrortopic, "connected", SetRetainFlag);
|
||||
MQTTenable = true;
|
||||
if (!MQTTInit(uri, clientname, user, password, mainerrortopic, keepAlive))
|
||||
{ // Failed
|
||||
MQTTenable = false;
|
||||
return true; // We need to return true despite we failed, else it will retry 5x and then reboot!
|
||||
}
|
||||
}
|
||||
|
||||
// Try sending mainerrortopic. If it fails, re-run init
|
||||
if (!MQTTPublish(mainerrortopic, "connected", SetRetainFlag))
|
||||
{ // Failed
|
||||
LogFile.WriteToFile("MQTT - Re-running init...!");
|
||||
if (!MQTTInit(this->uri, this->clientname, this->user, this->password, this->mainerrortopic, keepAlive))
|
||||
{ // Failed
|
||||
MQTTenable = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Try again and quit if it fails
|
||||
if (!MQTTPublish(mainerrortopic, "connected", SetRetainFlag))
|
||||
{ // Failed
|
||||
MQTTenable = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* if (!MQTTPublish(mainerrortopic, "connected", SetRetainFlag))
|
||||
{ // Failed
|
||||
LogFile.WriteToFile("MQTT - Could not publish connection status!");
|
||||
MQTTenable = false;
|
||||
return true; // We need to return true despite we failed, else it will retry 5x and then reboot!
|
||||
}*/
|
||||
|
||||
/* if(!MQTTPublish(_LWTContext, "", 1))
|
||||
{
|
||||
LogFile.WriteToFile("MQTT - Could not publish LWT!");
|
||||
MQTTenable = false;
|
||||
return true; // We need to return true despite we failed, else it will retry 5x and then reboot!
|
||||
}*/
|
||||
|
||||
|
||||
MQTTenable = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -141,8 +179,44 @@ string ClassFlowMQTT::GetMQTTMainTopic()
|
||||
|
||||
bool ClassFlowMQTT::doFlow(string zwtime)
|
||||
{
|
||||
if (!MQTTenable)
|
||||
return true;
|
||||
// if (!MQTTenable) {
|
||||
// LogFile.WriteToFile("MQTT not enabled!");
|
||||
//
|
||||
// // Try again to init it
|
||||
// if (!MQTTInit(this->uri, this->clientname, this->user, this->password, this->mainerrortopic, keepAlive))
|
||||
// { // Failed
|
||||
// MQTTenable = false;
|
||||
// return true; // We need to return true despite we failed, else it will retry 5x and then reboot!
|
||||
// }
|
||||
//
|
||||
// if (!MQTTPublish(mainerrortopic, "connected", SetRetainFlag))
|
||||
// { // Failed
|
||||
// MQTTenable = false;
|
||||
// return true; // We need to return true despite we failed, else it will retry 5x and then reboot!
|
||||
// }
|
||||
//
|
||||
// LogFile.WriteToFile("MQTT is now enabled");
|
||||
// MQTTenable = true;
|
||||
// }
|
||||
|
||||
|
||||
// Try sending mainerrortopic. If it fails, re-run init
|
||||
if (!MQTTPublish(mainerrortopic, "connected", SetRetainFlag))
|
||||
{ // Failed
|
||||
LogFile.WriteToFile("MQTT - Re-running init...!");
|
||||
if (!MQTTInit(this->uri, this->clientname, this->user, this->password, this->mainerrortopic, keepAlive))
|
||||
{ // Failed
|
||||
MQTTenable = false;
|
||||
return true; // We need to return true despite we failed, else it will retry 5x and then reboot!
|
||||
}
|
||||
}
|
||||
|
||||
// Try again and quit if it fails
|
||||
if (!MQTTPublish(mainerrortopic, "connected", SetRetainFlag))
|
||||
{ // Failed
|
||||
MQTTenable = false;
|
||||
return true; // We need to return true despite we failed, else it will retry 5x and then reboot!
|
||||
}
|
||||
|
||||
std::string result;
|
||||
std::string resulterror = "";
|
||||
@@ -153,7 +227,10 @@ bool ClassFlowMQTT::doFlow(string zwtime)
|
||||
string zw = "";
|
||||
string namenumber = "";
|
||||
|
||||
MQTTPublish(mainerrortopic, "connected");
|
||||
// if (!MQTTPublish(mainerrortopic, "connected", SetRetainFlag))
|
||||
//{ // Failed, skip other topics
|
||||
// return true; // We need to return true despite we failed, else it will retry 5x and then reboot!
|
||||
//}
|
||||
|
||||
zw = maintopic + "/" + "uptime";
|
||||
char uptimeStr[11];
|
||||
@@ -163,13 +240,19 @@ bool ClassFlowMQTT::doFlow(string zwtime)
|
||||
zw = maintopic + "/" + "freeMem";
|
||||
char freeheapmem[11];
|
||||
sprintf(freeheapmem, "%zu", esp_get_free_heap_size());
|
||||
MQTTPublish(zw, freeheapmem, SetRetainFlag);
|
||||
if (!MQTTPublish(zw, freeheapmem, SetRetainFlag))
|
||||
{ // Failed, skip other topics
|
||||
return true; // We need to return true despite we failed, else it will retry 5x and then reboot!
|
||||
}
|
||||
|
||||
zw = maintopic + "/" + "wifiRSSI";
|
||||
char rssi[11];
|
||||
sprintf(rssi, "%d", get_WIFI_RSSI());
|
||||
MQTTPublish(zw, rssi, SetRetainFlag);
|
||||
|
||||
zw = maintopic + "/" + "CPUtemp";
|
||||
std::string cputemp = std::to_string(temperatureRead());
|
||||
MQTTPublish(zw, cputemp, SetRetainFlag);
|
||||
|
||||
if (flowpostprocessing)
|
||||
{
|
||||
|
||||
@@ -15,6 +15,7 @@ protected:
|
||||
std::string user, password;
|
||||
int SetRetainFlag;
|
||||
bool MQTTenable;
|
||||
int keepAlive;
|
||||
|
||||
std::string maintopic, mainerrortopic;
|
||||
void SetInitialParameter(void);
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <time.h>
|
||||
|
||||
#include "time_sntp.h"
|
||||
//#define SERIAL_DEBUG // testing debug on serial enabled
|
||||
|
||||
|
||||
#define PREVALUE_TIME_FORMAT_OUTPUT "%Y-%m-%dT%H:%M:%S"
|
||||
@@ -68,7 +69,7 @@ string ClassFlowPostProcessing::GetPreValue(std::string _number)
|
||||
return result;
|
||||
}
|
||||
|
||||
void ClassFlowPostProcessing::SetPreValue(float zw, string _numbers, bool _extern)
|
||||
void ClassFlowPostProcessing::SetPreValue(double zw, string _numbers, bool _extern)
|
||||
{
|
||||
printf("SetPrevalue: %f, %s\n", zw, _numbers.c_str());
|
||||
for (int j = 0; j < NUMBERS.size(); ++j)
|
||||
@@ -126,7 +127,7 @@ bool ClassFlowPostProcessing::LoadPreValue(void)
|
||||
{
|
||||
if (NUMBERS[j]->name == name)
|
||||
{
|
||||
NUMBERS[j]->PreValue = stof(zwvalue.c_str());
|
||||
NUMBERS[j]->PreValue = stod(zwvalue.c_str());
|
||||
NUMBERS[j]->ReturnPreValue = RundeOutput(NUMBERS[j]->PreValue, NUMBERS[j]->Nachkomma + 1); // SIcherheitshalber 1 Stelle mehr, da ggf. Exgtended Resolution an ist (wird erst beim ersten Durchlauf gesetzt)
|
||||
|
||||
time_t tStart;
|
||||
@@ -177,7 +178,7 @@ bool ClassFlowPostProcessing::LoadPreValue(void)
|
||||
fclose(pFile);
|
||||
printf("%s", zw);
|
||||
zwvalue = trim(std::string(zw));
|
||||
NUMBERS[0]->PreValue = stof(zwvalue.c_str());
|
||||
NUMBERS[0]->PreValue = stod(zwvalue.c_str());
|
||||
|
||||
time_t tStart;
|
||||
int yy, month, dd, hh, mm, ss;
|
||||
@@ -663,7 +664,9 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
|
||||
previous_value = zw - 48;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SERIAL_DEBUG
|
||||
printf("After analog->getReadout: ReturnRaw %s\n", NUMBERS[j]->ReturnRawValue.c_str());
|
||||
#endif
|
||||
if (NUMBERS[j]->digit_roi && NUMBERS[j]->analog_roi)
|
||||
NUMBERS[j]->ReturnRawValue = "." + NUMBERS[j]->ReturnRawValue;
|
||||
|
||||
@@ -674,16 +677,22 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
|
||||
else
|
||||
NUMBERS[j]->ReturnRawValue = flowDigit->getReadout(j, NUMBERS[j]->isExtendedResolution, previous_value); // Extended Resolution nur falls es keine analogen Ziffern gibt
|
||||
}
|
||||
|
||||
#ifdef SERIAL_DEBUG
|
||||
printf("After digital->getReadout: ReturnRaw %s\n", NUMBERS[j]->ReturnRawValue.c_str());
|
||||
#endif
|
||||
NUMBERS[j]->ReturnRawValue = ShiftDecimal(NUMBERS[j]->ReturnRawValue, NUMBERS[j]->DecimalShift);
|
||||
|
||||
printf("ReturnRaw %s", NUMBERS[j]->ReturnRawValue.c_str());
|
||||
|
||||
#ifdef SERIAL_DEBUG
|
||||
printf("After ShiftDecimal: ReturnRaw %s\n", NUMBERS[j]->ReturnRawValue.c_str());
|
||||
#endif
|
||||
|
||||
if (IgnoreLeadingNaN)
|
||||
while ((NUMBERS[j]->ReturnRawValue.length() > 1) && (NUMBERS[j]->ReturnRawValue[0] == 'N'))
|
||||
NUMBERS[j]->ReturnRawValue.erase(0, 1);
|
||||
|
||||
#ifdef SERIAL_DEBUG
|
||||
printf("After IgnoreLeadingNaN: ReturnRaw %s\n", NUMBERS[j]->ReturnRawValue.c_str());
|
||||
#endif
|
||||
NUMBERS[j]->ReturnValue = NUMBERS[j]->ReturnRawValue;
|
||||
|
||||
if (findDelimiterPos(NUMBERS[j]->ReturnValue, "N") != std::string::npos)
|
||||
@@ -693,18 +702,38 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
|
||||
else
|
||||
continue; // es gibt keinen Zahl, da noch ein N vorhanden ist.
|
||||
}
|
||||
|
||||
#ifdef SERIAL_DEBUG
|
||||
printf("After findDelimiterPos: ReturnValue %s\n", NUMBERS[j]->ReturnRawValue.c_str());
|
||||
#endif
|
||||
// Lösche führende Nullen (außer es ist nur noch einen 0)
|
||||
while ((NUMBERS[j]->ReturnValue.length() > 1) && (NUMBERS[j]->ReturnValue[0] == '0'))
|
||||
NUMBERS[j]->ReturnValue.erase(0, 1);
|
||||
|
||||
NUMBERS[j]->Value = std::stof(NUMBERS[j]->ReturnValue);
|
||||
#ifdef SERIAL_DEBUG
|
||||
printf("After removeLeadingZeros: ReturnValue %s\n", NUMBERS[j]->ReturnRawValue.c_str());
|
||||
#endif
|
||||
NUMBERS[j]->Value = std::stod(NUMBERS[j]->ReturnValue);
|
||||
#ifdef SERIAL_DEBUG
|
||||
printf("After setting the Value: Value %f and as double is %f\n", NUMBERS[j]->Value, std::stod(NUMBERS[j]->ReturnValue));
|
||||
#endif
|
||||
|
||||
if (NUMBERS[j]->checkDigitIncreaseConsistency)
|
||||
{
|
||||
NUMBERS[j]->Value = checkDigitConsistency(NUMBERS[j]->Value, NUMBERS[j]->DecimalShift, NUMBERS[j]->analog_roi != NULL, NUMBERS[j]->PreValue);
|
||||
if (flowDigit)
|
||||
{
|
||||
if (flowDigit->getCNNType() != Digital)
|
||||
printf("checkDigitIncreaseConsistency = true - ignored due to wrong CNN-Type (not Digital Classification)\n");
|
||||
else
|
||||
NUMBERS[j]->Value = checkDigitConsistency(NUMBERS[j]->Value, NUMBERS[j]->DecimalShift, NUMBERS[j]->analog_roi != NULL, NUMBERS[j]->PreValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("checkDigitIncreaseConsistency = true - no digital numbers defined!\n");
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SERIAL_DEBUG
|
||||
printf("After checkDigitIncreaseConsistency: Value %f\n", NUMBERS[j]->Value);
|
||||
#endif
|
||||
|
||||
|
||||
if (!NUMBERS[j]->AllowNegativeRates)
|
||||
@@ -717,7 +746,9 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SERIAL_DEBUG
|
||||
printf("After AllowNegativeRates: Value %f\n", NUMBERS[j]->Value);
|
||||
#endif
|
||||
double difference = difftime(imagetime, NUMBERS[j]->lastvalue); // in Sekunden
|
||||
difference /= 60;
|
||||
NUMBERS[j]->FlowRateAct = (NUMBERS[j]->Value - NUMBERS[j]->PreValue) / difference;
|
||||
@@ -725,7 +756,7 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
|
||||
|
||||
if (NUMBERS[j]->useMaxRateValue && PreValueUse && NUMBERS[j]->PreValueOkay)
|
||||
{
|
||||
float _ratedifference;
|
||||
double _ratedifference;
|
||||
if (NUMBERS[j]->RateType == RateChange)
|
||||
_ratedifference = NUMBERS[j]->FlowRateAct;
|
||||
else
|
||||
@@ -740,7 +771,9 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SERIAL_DEBUG
|
||||
printf("After MaxRateCheck: Value %f\n", NUMBERS[j]->Value);
|
||||
#endif
|
||||
NUMBERS[j]->ReturnChangeAbsolute = RundeOutput(NUMBERS[j]->Value - NUMBERS[j]->PreValue, NUMBERS[j]->Nachkomma);
|
||||
NUMBERS[j]->lastvalue = imagetime;
|
||||
NUMBERS[j]->PreValue = NUMBERS[j]->Value;
|
||||
@@ -818,7 +851,7 @@ string ClassFlowPostProcessing::getReadoutParam(bool _rawValue, bool _noerror, i
|
||||
return NUMBERS[_number]->ReturnValue;
|
||||
}
|
||||
|
||||
string ClassFlowPostProcessing::RundeOutput(float _in, int _anzNachkomma){
|
||||
string ClassFlowPostProcessing::RundeOutput(double _in, int _anzNachkomma){
|
||||
std::stringstream stream;
|
||||
int _zw = _in;
|
||||
// printf("AnzNachkomma: %d\n", _anzNachkomma);
|
||||
@@ -842,7 +875,7 @@ string ClassFlowPostProcessing::RundeOutput(float _in, int _anzNachkomma){
|
||||
}
|
||||
|
||||
|
||||
string ClassFlowPostProcessing::ErsetzteN(string input, float _prevalue)
|
||||
string ClassFlowPostProcessing::ErsetzteN(string input, double _prevalue)
|
||||
{
|
||||
int posN, posPunkt;
|
||||
int pot, ziffer;
|
||||
@@ -873,7 +906,7 @@ string ClassFlowPostProcessing::ErsetzteN(string input, float _prevalue)
|
||||
return input;
|
||||
}
|
||||
|
||||
float ClassFlowPostProcessing::checkDigitConsistency(float input, int _decilamshift, bool _isanalog, float _preValue){
|
||||
float ClassFlowPostProcessing::checkDigitConsistency(double input, int _decilamshift, bool _isanalog, double _preValue){
|
||||
int aktdigit, olddigit;
|
||||
int aktdigit_before, olddigit_before;
|
||||
int pot, pot_max;
|
||||
@@ -885,8 +918,14 @@ float ClassFlowPostProcessing::checkDigitConsistency(float input, int _decilamsh
|
||||
{
|
||||
pot++;
|
||||
}
|
||||
#ifdef SERIAL_DEBUG
|
||||
printf("checkDigitConsistency: pot=%d, decimalshift=%d\n", pot, _decilamshift);
|
||||
#endif
|
||||
pot_max = ((int) log10(input)) + 1;
|
||||
|
||||
float not_checked_input = floorf(input * pow(10, pot)) / pow(10, pot);
|
||||
#ifdef SERIAL_DEBUG
|
||||
printf("checkDigitConsistency: not_checked_input=%f\n", not_checked_input);
|
||||
#endif
|
||||
while (pot <= pot_max)
|
||||
{
|
||||
zw = input / pow(10, pot-1);
|
||||
@@ -915,11 +954,13 @@ float ClassFlowPostProcessing::checkDigitConsistency(float input, int _decilamsh
|
||||
input = input + ((float) (1)) * pow(10, pot); // addiere 1 an der Stelle
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SERIAL_DEBUG
|
||||
printf("checkDigitConsistency: input=%f", input);
|
||||
#endif
|
||||
pot++;
|
||||
}
|
||||
|
||||
return input;
|
||||
return not_checked_input + input;
|
||||
}
|
||||
|
||||
string ClassFlowPostProcessing::getReadoutRate(int _number)
|
||||
|
||||
@@ -32,9 +32,9 @@ protected:
|
||||
bool LoadPreValue(void);
|
||||
string ShiftDecimal(string in, int _decShift);
|
||||
|
||||
string ErsetzteN(string, float _prevalue);
|
||||
float checkDigitConsistency(float input, int _decilamshift, bool _isanalog, float _preValue);
|
||||
string RundeOutput(float _in, int _anzNachkomma);
|
||||
string ErsetzteN(string, double _prevalue);
|
||||
float checkDigitConsistency(double input, int _decilamshift, bool _isanalog, double _preValue);
|
||||
string RundeOutput(double _in, int _anzNachkomma);
|
||||
|
||||
void InitNUMBERS();
|
||||
void handleDecimalSeparator(string _decsep, string _value);
|
||||
@@ -58,7 +58,7 @@ public:
|
||||
string getReadoutTimeStamp(int _number = 0);
|
||||
void SavePreValue();
|
||||
string GetPreValue(std::string _number = "");
|
||||
void SetPreValue(float zw, string _numbers, bool _extern = false);
|
||||
void SetPreValue(double zw, string _numbers, bool _extern = false);
|
||||
|
||||
std::string GetJSON(std::string _id = "", std::string _mac = "", std::string _lineend = "\n");
|
||||
|
||||
|
||||
@@ -209,6 +209,21 @@ size_t findDelimiterPos(string input, string delimiter)
|
||||
return pos;
|
||||
}
|
||||
|
||||
void DeleteFile(string fn)
|
||||
{
|
||||
// ESP_LOGI(logTag, "Deleting file : %s", fn.c_str());
|
||||
/* Delete file */
|
||||
FILE* fpSourceFile = OpenFileAndWait(fn.c_str(), "rb");
|
||||
if (!fpSourceFile) // Sourcefile existiert nicht sonst gibt es einen Fehler beim Kopierversuch!
|
||||
{
|
||||
printf("DeleteFile: File %s existiert nicht!\n", fn.c_str());
|
||||
return;
|
||||
}
|
||||
fclose(fpSourceFile);
|
||||
|
||||
unlink(fn.c_str());
|
||||
}
|
||||
|
||||
|
||||
void CopyFile(string input, string output)
|
||||
{
|
||||
@@ -243,18 +258,48 @@ void CopyFile(string input, string output)
|
||||
// Close The Files
|
||||
fclose(fpSourceFile);
|
||||
fclose(fpTargetFile);
|
||||
printf("File copied: %s to %s", input.c_str(), output.c_str());
|
||||
}
|
||||
|
||||
string getFileFullFileName(string filename)
|
||||
{
|
||||
size_t lastpos = filename.find_last_of('/');
|
||||
|
||||
if (lastpos == string::npos)
|
||||
return "";
|
||||
|
||||
// printf("Last position: %d\n", lastpos);
|
||||
|
||||
string zw = filename.substr(lastpos + 1, filename.size() - lastpos);
|
||||
|
||||
return zw;
|
||||
}
|
||||
|
||||
string getDirectory(string filename)
|
||||
{
|
||||
size_t lastpos = filename.find('/');
|
||||
|
||||
if (lastpos == string::npos)
|
||||
return "";
|
||||
|
||||
// printf("Directory: %d\n", lastpos);
|
||||
|
||||
string zw = filename.substr(0, lastpos - 1);
|
||||
return zw;
|
||||
}
|
||||
|
||||
string getFileType(string filename)
|
||||
{
|
||||
int lastpos = filename.find(".", 0);
|
||||
int neu_pos;
|
||||
size_t lastpos = filename.find(".", 0);
|
||||
size_t neu_pos;
|
||||
while ((neu_pos = filename.find(".", lastpos + 1)) > -1)
|
||||
{
|
||||
lastpos = neu_pos;
|
||||
}
|
||||
|
||||
if (lastpos == string::npos)
|
||||
return "";
|
||||
|
||||
string zw = filename.substr(lastpos + 1, filename.size() - lastpos);
|
||||
zw = toUpper(zw);
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ std::string FormatFileName(std::string input);
|
||||
void FindReplace(std::string& line, std::string& oldString, std::string& newString);
|
||||
|
||||
void CopyFile(string input, string output);
|
||||
void DeleteFile(string fn);
|
||||
|
||||
FILE* OpenFileAndWait(const char* nm, const char* _mode, int _waitsec = 1);
|
||||
|
||||
@@ -19,6 +20,8 @@ string trim(string istring, string adddelimiter = "");
|
||||
bool ctype_space(const char c, string adddelimiter);
|
||||
|
||||
string getFileType(string filename);
|
||||
string getFileFullFileName(string filename);
|
||||
string getDirectory(string filename);
|
||||
|
||||
int mkdir_r(const char *dir, const mode_t mode);
|
||||
int removeFolder(const char* folderPath, const char* logTag);
|
||||
|
||||
@@ -129,6 +129,7 @@ void ClassLogFile::WriteToFile(std::string info, bool _time)
|
||||
std::string logpath = logroot + "/" + buffer;
|
||||
|
||||
WriteToDedicatedFile(logpath, info, _time);
|
||||
printf((info + "\n").c_str());
|
||||
}
|
||||
|
||||
std::string ClassLogFile::GetCurrentFileName()
|
||||
|
||||
@@ -19,18 +19,43 @@ esp_mqtt_event_id_t esp_mmqtt_ID = MQTT_EVENT_ANY;
|
||||
bool mqtt_connected = false;
|
||||
esp_mqtt_client_handle_t client = NULL;
|
||||
|
||||
void MQTTPublish(std::string _key, std::string _content, int retained_flag){
|
||||
if (client && mqtt_connected) {
|
||||
int msg_id;
|
||||
std::string zw;
|
||||
msg_id = esp_mqtt_client_publish(client, _key.c_str(), _content.c_str(), 0, 1, retained_flag);
|
||||
zw = "sent publish successful in MQTTPublish, msg_id=" + std::to_string(msg_id) + ", " + _key + ", " + _content;
|
||||
if (debugdetail) LogFile.WriteToFile(zw);
|
||||
ESP_LOGD(TAG_INTERFACEMQTT, "sent publish successful in MQTTPublish, msg_id=%d, %s, %s", msg_id, _key.c_str(), _content.c_str());
|
||||
bool MQTTPublish(std::string _key, std::string _content, int retained_flag){
|
||||
|
||||
// if (!client) {
|
||||
// LogFile.WriteToFile("MQTT - client not initialized!");
|
||||
// return false;
|
||||
// }
|
||||
// LogFile.WriteToFile("MQTT - client initialized!"); // Debug
|
||||
//
|
||||
// if (!mqtt_connected) {
|
||||
// LogFile.WriteToFile("MQTT - Can not publish, not connected!");
|
||||
// ESP_LOGW(TAG_INTERFACEMQTT, "Problem with Publish, client=%d, mqtt_connected %d", (int) client, (int) mqtt_connected);
|
||||
// return false;
|
||||
// }
|
||||
// LogFile.WriteToFile("MQTT - connected!"); // Debug
|
||||
|
||||
/* if (client && mqtt_connected) {
|
||||
LogFile.WriteToFile("MQTT - connected!"); // Debug
|
||||
}
|
||||
else {
|
||||
ESP_LOGW(TAG_INTERFACEMQTT, "Problem with Publish, client=%d, mqtt_connected %d", (int) client, (int) mqtt_connected);
|
||||
else { // init needed
|
||||
if (!MQTTInit(this->uri, this->clientname, this->user, password, mainerrortopic, keepAlive)) // validate{
|
||||
{ // Failed
|
||||
return false;
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
int msg_id;
|
||||
std::string zw;
|
||||
msg_id = esp_mqtt_client_publish(client, _key.c_str(), _content.c_str(), 0, 1, retained_flag);
|
||||
if (msg_id < 0) {
|
||||
LogFile.WriteToFile("MQTT - Failed to publish '" + _key + "'!");
|
||||
return false;
|
||||
}
|
||||
zw = "MQTT - sent publish successful in MQTTPublish, msg_id=" + std::to_string(msg_id) + ", " + _key + ", " + _content;
|
||||
if (debugdetail) LogFile.WriteToFile(zw);
|
||||
ESP_LOGD(TAG_INTERFACEMQTT, "sent publish successful in MQTTPublish, msg_id=%d, %s, %s", msg_id, _key.c_str(), _content.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -90,11 +115,23 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_
|
||||
mqtt_event_handler_cb((esp_mqtt_event_handle_t) event_data);
|
||||
}
|
||||
|
||||
void MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user, std::string _password, std::string _LWTContext, int _keepalive){
|
||||
|
||||
bool MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user, std::string _password, std::string _LWTContext, int _keepalive){
|
||||
std::string _zwmessage = "connection lost";
|
||||
|
||||
int _lzw = _zwmessage.length();
|
||||
|
||||
/* LWTContext = _LWTContext;
|
||||
|
||||
mqtt_cfg.uri = _mqttURI.c_str();
|
||||
mqtt_cfg.client_id = _clientid.c_str();
|
||||
mqtt_cfg.lwt_topic = _LWTContext.c_str();
|
||||
mqtt_cfg.lwt_msg = _zwmessage.c_str();
|
||||
mqtt_cfg.lwt_retain = 1;
|
||||
mqtt_cfg.lwt_msg_len = _lzw;
|
||||
mqtt_cfg.keepalive = _keepalive;
|
||||
*/
|
||||
|
||||
esp_mqtt_client_config_t mqtt_cfg = {
|
||||
.uri = _mqttURI.c_str(),
|
||||
.client_id = _clientid.c_str(),
|
||||
@@ -105,12 +142,51 @@ void MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user, st
|
||||
.keepalive = _keepalive
|
||||
};
|
||||
|
||||
LogFile.WriteToFile("MQTT - Init");
|
||||
|
||||
if (_user.length() && _password.length()){
|
||||
mqtt_cfg.username = _user.c_str();
|
||||
mqtt_cfg.password = _password.c_str();
|
||||
ESP_LOGI(TAG_INTERFACEMQTT, "Connect to MQTT: %s, %s", mqtt_cfg.username, mqtt_cfg.password);
|
||||
};
|
||||
|
||||
MQTTdestroy();
|
||||
client = esp_mqtt_client_init(&mqtt_cfg);
|
||||
if (client)
|
||||
{
|
||||
if (esp_mqtt_client_register_event(client, esp_mmqtt_ID, mqtt_event_handler, client) != ESP_OK)
|
||||
{
|
||||
LogFile.WriteToFile("MQTT - Could not register event!");
|
||||
return false;
|
||||
}
|
||||
if (esp_mqtt_client_start(client) != ESP_OK)
|
||||
{
|
||||
LogFile.WriteToFile("MQTT - Could not start client!");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* if(!MQTTPublish(_LWTContext, "", 1))
|
||||
{
|
||||
LogFile.WriteToFile("MQTT - Could not publish LWT!");
|
||||
return false;
|
||||
}*/
|
||||
}
|
||||
else
|
||||
{
|
||||
LogFile.WriteToFile("MQTT - Could not Init client!");
|
||||
return false;
|
||||
}
|
||||
|
||||
LogFile.WriteToFile("MQTT - Init successful");
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
void MQTTReConnect(){
|
||||
std::string _zwmessage = "connection lost";
|
||||
int _lzw = _zwmessage.length();
|
||||
|
||||
>>>>>>> Stashed changes
|
||||
client = esp_mqtt_client_init(&mqtt_cfg);
|
||||
if (client)
|
||||
{
|
||||
@@ -119,14 +195,25 @@ void MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user, st
|
||||
if (esp_mqtt_client_start(client) != ESP_OK)
|
||||
LogFile.WriteToFile("MQTT - Could not start client!");
|
||||
|
||||
MQTTPublish(_LWTContext, "", 1);
|
||||
<<<<<<< Updated upstream
|
||||
if(MQTTPublish(_LWTContext, "", 1)) {
|
||||
LogFile.WriteToFile("MQTT - Client init successful");
|
||||
}
|
||||
=======
|
||||
if (mqtt_connected)
|
||||
MQTTPublish(LWTContext, "", 1);
|
||||
else
|
||||
LogFile.WriteToFile("Problem with (Re)Connection not successful!");
|
||||
|
||||
>>>>>>> Stashed changes
|
||||
}
|
||||
else
|
||||
{
|
||||
LogFile.WriteToFile("MQTT - Could not Init MQTT Client!");
|
||||
LogFile.WriteToFile("MQTT - Could not Init client!");
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
void MQTTdestroy() {
|
||||
if (client != NULL) {
|
||||
@@ -185,6 +272,7 @@ void MQTTregisterSubscribeFunction(std::string topic, std::function<bool(std::st
|
||||
|
||||
void MQTTconnected(){
|
||||
if (mqtt_connected) {
|
||||
LogFile.WriteToFile("MQTT - Connected");
|
||||
if (connectFunktionMap != NULL) {
|
||||
for(std::map<std::string, std::function<void()>>::iterator it = connectFunktionMap->begin(); it != connectFunktionMap->end(); ++it) {
|
||||
it->second();
|
||||
@@ -192,10 +280,11 @@ void MQTTconnected(){
|
||||
}
|
||||
}
|
||||
|
||||
if (subscribeFunktionMap != NULL) {
|
||||
if (subscribeFunktionMap != NULL) {
|
||||
for(std::map<std::string, std::function<bool(std::string, char*, int)>>::iterator it = subscribeFunktionMap->begin(); it != subscribeFunktionMap->end(); ++it) {
|
||||
int msg_id = esp_mqtt_client_subscribe(client, it->first.c_str(), 0);
|
||||
ESP_LOGD(TAG_INTERFACEMQTT, "topic %s subscribe successful, msg_id=%d", it->first.c_str(), msg_id);
|
||||
LogFile.WriteToFile("MQTT - topic " + it->first + " subscribe successful, msg_id=" + std::to_string(msg_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
#include <map>
|
||||
#include <functional>
|
||||
|
||||
void MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user, std::string _password, std::string _LWTContext, int _keepalive);
|
||||
bool MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user, std::string _password, std::string _LWTContext, int _keepalive);
|
||||
void MQTTdestroy();
|
||||
|
||||
//void MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user = "", std::string _password = "");
|
||||
|
||||
void MQTTPublish(std::string _key, std::string _content, int retained_flag = 1); // retained Flag as Standart
|
||||
bool MQTTPublish(std::string _key, std::string _content, int retained_flag = 1); // retained Flag as Standart
|
||||
|
||||
bool MQTTisConnected();
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "server_GPIO.h"
|
||||
|
||||
#include "server_file.h"
|
||||
#include "connect_wlan.h"
|
||||
|
||||
#define DEBUG_DETAIL_ON
|
||||
|
||||
@@ -590,6 +591,55 @@ esp_err_t handler_statusflow(httpd_req_t *req)
|
||||
return ESP_OK;
|
||||
};
|
||||
|
||||
esp_err_t handler_cputemp(httpd_req_t *req)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_cputemp - Start");
|
||||
#endif
|
||||
|
||||
const char* resp_str;
|
||||
char cputemp[20];
|
||||
|
||||
sprintf(cputemp, "CPU Temp: %4.1f°C", temperatureRead());
|
||||
|
||||
resp_str = cputemp;
|
||||
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
httpd_resp_send(req, resp_str, strlen(resp_str));
|
||||
/* Respond with an empty chunk to signal HTTP response completion */
|
||||
httpd_resp_send_chunk(req, NULL, 0);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_cputemp - End");
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
};
|
||||
|
||||
esp_err_t handler_rssi(httpd_req_t *req)
|
||||
{
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_rssi - Start");
|
||||
#endif
|
||||
|
||||
const char* resp_str;
|
||||
char rssi[20];
|
||||
|
||||
sprintf(rssi, "RSSI: %idBm", get_WIFI_RSSI());
|
||||
|
||||
resp_str = rssi;
|
||||
|
||||
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
|
||||
httpd_resp_send(req, resp_str, strlen(resp_str));
|
||||
/* Respond with an empty chunk to signal HTTP response completion */
|
||||
httpd_resp_send_chunk(req, NULL, 0);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_rssi - End");
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
};
|
||||
|
||||
esp_err_t handler_prevalue(httpd_req_t *req)
|
||||
{
|
||||
@@ -643,7 +693,7 @@ esp_err_t handler_prevalue(httpd_req_t *req)
|
||||
httpd_resp_send_chunk(req, NULL, 0);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("handler_prevalue - Start");
|
||||
LogFile.WriteHeapInfo("handler_prevalue - End");
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
@@ -766,11 +816,26 @@ void register_server_tflite_uri(httpd_handle_t server)
|
||||
camuri.user_ctx = (void*) "Light Off";
|
||||
httpd_register_uri_handler(server, &camuri);
|
||||
|
||||
camuri.uri = "/cputemp.html";
|
||||
camuri.handler = handler_cputemp;
|
||||
camuri.user_ctx = (void*) "Light Off";
|
||||
httpd_register_uri_handler(server, &camuri);
|
||||
|
||||
camuri.uri = "/rssi.html";
|
||||
camuri.handler = handler_rssi;
|
||||
camuri.user_ctx = (void*) "Light Off";
|
||||
httpd_register_uri_handler(server, &camuri);
|
||||
|
||||
camuri.uri = "/editflow.html";
|
||||
camuri.handler = handler_editflow;
|
||||
camuri.user_ctx = (void*) "EditFlow";
|
||||
httpd_register_uri_handler(server, &camuri);
|
||||
|
||||
camuri.uri = "/value.html";
|
||||
camuri.handler = handler_wasserzaehler;
|
||||
camuri.user_ctx = (void*) "Value";
|
||||
httpd_register_uri_handler(server, &camuri);
|
||||
|
||||
camuri.uri = "/wasserzaehler.html";
|
||||
camuri.handler = handler_wasserzaehler;
|
||||
camuri.user_ctx = (void*) "Wasserzaehler";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const char* GIT_REV="234925c";
|
||||
const char* GIT_TAG="";
|
||||
const char* GIT_BRANCH="master";
|
||||
const char* BUILD_TIME="2022-08-28 19:59";
|
||||
const char* GIT_REV="N/A";
|
||||
const char* GIT_TAG="N/A";
|
||||
const char* GIT_BRANCH="N/A";
|
||||
const char* BUILD_TIME="2022-09-17 09:00";
|
||||
@@ -13,7 +13,7 @@ extern "C"
|
||||
#include "Helper.h"
|
||||
#include <fstream>
|
||||
|
||||
const char* GIT_BASE_BRANCH = "master - v11.2.0 - 2022-08-28";
|
||||
const char* GIT_BASE_BRANCH = "master - v11.3.0 - 2022-09-16";
|
||||
|
||||
|
||||
const char* git_base_branch(void)
|
||||
|
||||
@@ -12,12 +12,12 @@
|
||||
[platformio]
|
||||
src_dir = main
|
||||
|
||||
|
||||
[env:esp32cam]
|
||||
platform = espressif32@4.4.0
|
||||
;platform = espressif32@5.1.0
|
||||
;platform = espressif32
|
||||
board = esp32cam
|
||||
;board = m5stack-core-esp32
|
||||
framework = espidf
|
||||
|
||||
;board_build.partitions = partitions_singleapp.csv
|
||||
@@ -45,3 +45,6 @@ monitor_rts = 0
|
||||
monitor_dtr = 0
|
||||
|
||||
debug_tool = esp-prog
|
||||
|
||||
; Enable and adapt for logging over USB
|
||||
;upload_port = /dev/ttyUSB0
|
||||
@@ -1028,7 +1028,7 @@ CONFIG_MQTT_TRANSPORT_SSL=y
|
||||
CONFIG_MQTT_TRANSPORT_WEBSOCKET=y
|
||||
CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y
|
||||
# CONFIG_MQTT_MSG_ID_INCREMENTAL is not set
|
||||
# CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set
|
||||
CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set
|
||||
# CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set
|
||||
# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set
|
||||
# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set
|
||||
|
||||
@@ -1036,7 +1036,7 @@ CONFIG_MQTT_TRANSPORT_SSL=y
|
||||
CONFIG_MQTT_TRANSPORT_WEBSOCKET=y
|
||||
CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y
|
||||
# CONFIG_MQTT_MSG_ID_INCREMENTAL is not set
|
||||
# CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set
|
||||
CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED=y
|
||||
# CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set
|
||||
# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set
|
||||
# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
#include <ClassFlowMakeImage.h>
|
||||
|
||||
void setUpClassFlowPostprocessing(void);
|
||||
string process_doFlow(std::vector<float> analog, std::vector<float> digits);
|
||||
string process_doFlow(std::vector<float> analog, std::vector<float> digits, t_CNNType digType = Digital100,
|
||||
bool checkConsistency=false, bool extendedResolution=false, int decimal_shift=0);
|
||||
|
||||
ClassFlowCNNGeneral* _analog;
|
||||
ClassFlowCNNGeneral* _digit;
|
||||
@@ -43,13 +44,14 @@ void test_doFlow() {
|
||||
std::vector<float> digits = { 1.2, 6.7};
|
||||
std::vector<float> analogs = { 9.5, 8.4};
|
||||
const char* expected = "16.98";
|
||||
const char* expected_extended = "16.984";
|
||||
std::string result = process_doFlow(analogs, digits);
|
||||
TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
|
||||
/*
|
||||
* https://github.com/jomjol/AI-on-the-edge-device/issues/921
|
||||
*
|
||||
* Das Ergebnis sollte "376529.6" sein. Bzw. 16.98 ohne Extended true
|
||||
* Das Ergebnis sollte "376529.6" sein.
|
||||
*/
|
||||
digits = { 3.0, 7.0, 6.0, 5.0, 2.5, 9.6};
|
||||
analogs = { 6.4};
|
||||
@@ -158,11 +160,154 @@ void test_doFlow() {
|
||||
expected = "194.9089";
|
||||
result = process_doFlow(analogs, digits);
|
||||
TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
|
||||
// Fehler bei V11.2.0
|
||||
// https://github.com/jomjol/AI-on-the-edge-device/issues/921#issuecomment-1229552041
|
||||
digits = { 2.9, 7.0, 7.0, 9.1, 8.1, 8.5}; // 376.9884(1) als falsches Ergebnis
|
||||
analogs = { 4.1 };
|
||||
expected = "377988.4";
|
||||
result = process_doFlow(analogs, digits);
|
||||
TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
|
||||
// Fehler bei V11.2.0
|
||||
// https://github.com/jomjol/AI-on-the-edge-device/issues/921#issuecomment-1233149877
|
||||
digits = { 0.0, 0.0, 7.0, 8.9}; // 79.9999(6) als falsches Ergebnis
|
||||
analogs = { 0.1, 0.1, 0.1, 9.6};
|
||||
expected = "78.9999";
|
||||
result = process_doFlow(analogs, digits);
|
||||
TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
|
||||
// Fehler bei V11.2.0
|
||||
// https://github.com/jomjol/AI-on-the-edge-device/issues/921#issuecomment-1236119370
|
||||
digits = { 3.1, 9.1, 5.7}; // 9.1 führt zu falscher Erkennung eines unvollständigen Übergangs
|
||||
analogs = { 8.8, 6.1, 3.0, 2.0};
|
||||
expected = "395.8632";
|
||||
result = process_doFlow(analogs, digits);
|
||||
TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
|
||||
// Fehler bei V11.2.0
|
||||
// https://github.com/jomjol/AI-on-the-edge-device/discussions/950#discussion-4338615
|
||||
digits = { 1.0, 9.0, 9.0}; // Übergang wurde um 1 erhöht (200, statt 199)
|
||||
analogs = { 7.1, 4.8, 8.3};
|
||||
expected = "199.748";
|
||||
result = process_doFlow(analogs, digits, Digital);
|
||||
TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
|
||||
// Fehler bei Rolling (2002-09-09)
|
||||
// https://github.com/jomjol/AI-on-the-edge-device/issues/921#issuecomment-1242730397
|
||||
digits = { 3.0, 2.0, 2.0, 8.0, 9.0, 4.0, 1.7, 9.8}; // falscher Wert 32290.420
|
||||
analogs = { };
|
||||
expected = "32289.420";
|
||||
expected_extended= "32289.4198";
|
||||
// FALSCH! wegen ungenügender Präzision von NUMBERS->Value
|
||||
// expected_extended= "32289.4198";
|
||||
|
||||
// extendResolution=false, checkConsistency=false
|
||||
result = process_doFlow(analogs, digits, Digital100, false, false, -3);
|
||||
TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
|
||||
// extendResolution=true
|
||||
result = process_doFlow(analogs, digits, Digital100, false, true, -3);
|
||||
TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str());
|
||||
|
||||
// checkConsistency=true und extendResolution=true
|
||||
result = process_doFlow(analogs, digits, Digital100, false, true, -3);
|
||||
TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str());
|
||||
|
||||
// Fehler Rolling (2022-09-10)
|
||||
// not documented as issue
|
||||
digits = { 0.0, 0.0, 7.9, 3.8}; // 84.99401 als falsches Ergebnis
|
||||
analogs = { 0.0, 9.4, 4.1, 0.1};
|
||||
expected = "83.9940";
|
||||
expected_extended= "83.99401";
|
||||
|
||||
// checkConsistency=false
|
||||
result = process_doFlow(analogs, digits, Digital100, false);
|
||||
TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
|
||||
|
||||
// checkConsistency=true
|
||||
result = process_doFlow(analogs, digits, Digital100, true);
|
||||
TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
|
||||
// extendResolution=true
|
||||
result = process_doFlow(analogs, digits, Digital100, false, true);
|
||||
TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str());
|
||||
|
||||
// checkConsistency=true und extendResolution=true
|
||||
result = process_doFlow(analogs, digits, Digital100, false, true);
|
||||
TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str());
|
||||
|
||||
// Fehler Rolling (2022-09-10)
|
||||
// https://github.com/jomjol/AI-on-the-edge-device/issues/994#issue-1368570945
|
||||
digits = { 0.0, 0.0, 1.0, 2.0, 2.8, 1.9, 2.8, 5.6}; // 123245.6 als falsches Ergebnis
|
||||
analogs = { };
|
||||
expected = "123236";
|
||||
expected_extended= "123235.6";
|
||||
|
||||
// checkConsistency=true
|
||||
result = process_doFlow(analogs, digits, Digital100, false, false);
|
||||
TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
|
||||
|
||||
// checkConsistency=true
|
||||
result = process_doFlow(analogs, digits, Digital100, true, false);
|
||||
TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
|
||||
// extendResolution=true
|
||||
result = process_doFlow(analogs, digits, Digital100, false, true);
|
||||
TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str());
|
||||
|
||||
// Fehler bei V11.2.0
|
||||
// https://github.com/jomjol/AI-on-the-edge-device/discussions/950#discussioncomment-3661982
|
||||
digits = { 3.0, 2.0, 4.1, 9.0, 4.0, 6.3, 9.2}; // 3249.459 als falsches Ergebnis
|
||||
analogs = { };
|
||||
expected = "3249.469";
|
||||
expected_extended= "3249.4692";
|
||||
|
||||
// checkConsistency=true
|
||||
result = process_doFlow(analogs, digits, Digital100, false, false, -3);
|
||||
TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
|
||||
|
||||
// checkConsistency=true
|
||||
// checkConsistency NOT working correctly
|
||||
//result = process_doFlow(analogs, digits, Digital100, true, false, -3);
|
||||
//TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
|
||||
// extendResolution=true
|
||||
result = process_doFlow(analogs, digits, Digital100, false, true, -3);
|
||||
TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str());
|
||||
|
||||
// Fehler bei V11.2.0
|
||||
// https://github.com/jomjol/AI-on-the-edge-device/issues/1020#issue-1375648891
|
||||
digits = { 0.0, 2.0, 6.1, 9.2}; // 259.9227 als falsches Ergebnis
|
||||
analogs = { 9.0, 2.5, 2.9, 7.2};
|
||||
expected = "269.9227";
|
||||
expected_extended= "269.92272";
|
||||
// Float Value reduziert die Genauigkeit hier. Korrekt wäre
|
||||
// expected_extended= "269.92272";
|
||||
|
||||
// checkConsistency=true
|
||||
result = process_doFlow(analogs, digits, Digital100, false, false);
|
||||
TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
|
||||
|
||||
// checkConsistency=true
|
||||
// checkConsistency NOT working correctly
|
||||
//result = process_doFlow(analogs, digits, Digital100, true, false, -3);
|
||||
//TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
|
||||
|
||||
// checkConsistency=true und extendResolution=true
|
||||
result = process_doFlow(analogs, digits, Digital100, false, true);
|
||||
TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void setUpClassFlowPostprocessing(void)
|
||||
void setUpClassFlowPostprocessing(t_CNNType digType, t_CNNType anaType)
|
||||
{
|
||||
|
||||
// wird im doFlow verwendet
|
||||
@@ -170,18 +315,19 @@ void setUpClassFlowPostprocessing(void)
|
||||
FlowControll.push_back(flowmakeimage);
|
||||
|
||||
// Die Modeltypen werden gesetzt, da keine Modelle verwendet werden.
|
||||
_analog = new ClassFlowCNNGeneral(nullptr, Analogue100);
|
||||
_analog = new ClassFlowCNNGeneral(nullptr, anaType);
|
||||
|
||||
_digit = new ClassFlowCNNGeneral(nullptr, Digital100);
|
||||
_digit = new ClassFlowCNNGeneral(nullptr, digType);
|
||||
|
||||
undertestPost = new UnderTestPost(&FlowControll, _analog, _digit);
|
||||
|
||||
}
|
||||
|
||||
|
||||
std::string process_doFlow(std::vector<float> analog, std::vector<float> digits) {
|
||||
std::string process_doFlow(std::vector<float> analog, std::vector<float> digits, t_CNNType digType,
|
||||
bool checkConsistency, bool extendedResolution, int decimal_shift) {
|
||||
// setup the classundertest
|
||||
setUpClassFlowPostprocessing();
|
||||
setUpClassFlowPostprocessing(digType, Analogue100);
|
||||
|
||||
printf("SetupClassFlowPostprocessing completed.\n");
|
||||
|
||||
@@ -189,11 +335,11 @@ std::string process_doFlow(std::vector<float> analog, std::vector<float> digits)
|
||||
if (digits.size()>0) {
|
||||
general* gen_digit = _digit->GetGENERAL("default", true);
|
||||
gen_digit->ROI.clear();
|
||||
|
||||
for (int i = 0; i<digits.size(); i++) {
|
||||
roi* digitROI = new roi();
|
||||
string name = "digit_" + std::to_string(i);
|
||||
digitROI->name = name;
|
||||
digitROI->result_klasse = (int) digits[i];
|
||||
digitROI->result_float = digits[i];
|
||||
gen_digit->ROI.push_back(digitROI);
|
||||
}
|
||||
@@ -215,6 +361,30 @@ std::string process_doFlow(std::vector<float> analog, std::vector<float> digits)
|
||||
printf("Setup ROIs completed.\n");
|
||||
|
||||
undertestPost->InitNUMBERS();
|
||||
if (checkConsistency) {
|
||||
printf("checkConsistency=true\n");
|
||||
std::vector<NumberPost*>* NUMBERS = undertestPost->GetNumbers();
|
||||
for (int _n = 0; _n < (*NUMBERS).size(); ++_n) {
|
||||
printf("Set checkConsistency on number: %d\n", _n);
|
||||
(*NUMBERS)[_n]->checkDigitIncreaseConsistency = true;
|
||||
}
|
||||
}
|
||||
if (extendedResolution ) {
|
||||
std::vector<NumberPost*>* NUMBERS = undertestPost->GetNumbers();
|
||||
for (int _n = 0; _n < (*NUMBERS).size(); ++_n) {
|
||||
printf("Set extendedResolution on number: %d\n", _n);
|
||||
(*NUMBERS)[_n]->isExtendedResolution = true;
|
||||
}
|
||||
|
||||
}
|
||||
if (decimal_shift!=0) {
|
||||
std::vector<NumberPost*>* NUMBERS = undertestPost->GetNumbers();
|
||||
for (int _n = 0; _n < (*NUMBERS).size(); ++_n) {
|
||||
printf("Set decimalshif on number: %d to %d\n", _n, decimal_shift);
|
||||
(*NUMBERS)[_n]->DecimalShift = decimal_shift;
|
||||
(*NUMBERS)[_n]->DecimalShiftInitial = decimal_shift;
|
||||
}
|
||||
}
|
||||
|
||||
string time;
|
||||
// run test
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const char* GIT_REV="234925c";
|
||||
const char* GIT_TAG="";
|
||||
const char* GIT_BRANCH="master";
|
||||
const char* BUILD_TIME="2022-08-28 19:59";
|
||||
const char* GIT_REV="N/A";
|
||||
const char* GIT_TAG="N/A";
|
||||
const char* GIT_BRANCH="N/A";
|
||||
const char* BUILD_TIME="2022-09-17 09:00";
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
sd-card/config/ana-class100_0130_s1_q.tflite
Normal file
BIN
sd-card/config/ana-class100_0130_s1_q.tflite
Normal file
Binary file not shown.
@@ -25,9 +25,9 @@ Model = /config/dig-cont_0570_s3.tflite
|
||||
CNNGoodThreshold = 0.5
|
||||
;LogImageLocation = /log/digit
|
||||
;LogfileRetentionInDays = 3
|
||||
main.dig1 294 126 30 54
|
||||
main.dig2 343 126 30 54
|
||||
main.dig3 391 126 30 54
|
||||
main.dig1 294 126 30 54 false
|
||||
main.dig2 343 126 30 54 false
|
||||
main.dig3 391 126 30 54 false
|
||||
|
||||
[Analog]
|
||||
Model = /config/ana-cont_11.3.0_s2.tflite
|
||||
@@ -35,10 +35,10 @@ CNNGoodThreshold = 0.5
|
||||
;LogImageLocation = /log/analog
|
||||
;LogfileRetentionInDays = 3
|
||||
ExtendedResolution = true
|
||||
main.ana1 432 230 92 92
|
||||
main.ana2 379 332 92 92
|
||||
main.ana3 283 374 92 92
|
||||
main.ana4 155 328 92 92
|
||||
main.ana1 432 230 92 92 false
|
||||
main.ana2 379 332 92 92 false
|
||||
main.ana3 283 374 92 92 false
|
||||
main.ana4 155 328 92 92 false
|
||||
|
||||
[PostProcessing]
|
||||
main.DecimalShift = 0
|
||||
|
||||
BIN
sd-card/config/dig-class100-0130_s2_q.tflite
Normal file
BIN
sd-card/config/dig-class100-0130_s2_q.tflite
Normal file
Binary file not shown.
Binary file not shown.
3
sd-card/html/FileSaver.min.js
vendored
Normal file
3
sd-card/html/FileSaver.min.js
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
(function(a,b){if("function"==typeof define&&define.amd)define([],b);else if("undefined"!=typeof exports)b();else{b(),a.FileSaver={exports:{}}.exports}})(this,function(){"use strict";function b(a,b){return"undefined"==typeof b?b={autoBom:!1}:"object"!=typeof b&&(console.warn("Deprecated: Expected third argument to be a object"),b={autoBom:!b}),b.autoBom&&/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(a.type)?new Blob(["\uFEFF",a],{type:a.type}):a}function c(a,b,c){var d=new XMLHttpRequest;d.open("GET",a),d.responseType="blob",d.onload=function(){g(d.response,b,c)},d.onerror=function(){console.error("could not download file")},d.send()}function d(a){var b=new XMLHttpRequest;b.open("HEAD",a,!1);try{b.send()}catch(a){}return 200<=b.status&&299>=b.status}function e(a){try{a.dispatchEvent(new MouseEvent("click"))}catch(c){var b=document.createEvent("MouseEvents");b.initMouseEvent("click",!0,!0,window,0,0,0,80,20,!1,!1,!1,!1,0,null),a.dispatchEvent(b)}}var f="object"==typeof window&&window.window===window?window:"object"==typeof self&&self.self===self?self:"object"==typeof global&&global.global===global?global:void 0,a=/Macintosh/.test(navigator.userAgent)&&/AppleWebKit/.test(navigator.userAgent)&&!/Safari/.test(navigator.userAgent),g=f.saveAs||("object"!=typeof window||window!==f?function(){}:"download"in HTMLAnchorElement.prototype&&!a?function(b,g,h){var i=f.URL||f.webkitURL,j=document.createElement("a");g=g||b.name||"download",j.download=g,j.rel="noopener","string"==typeof b?(j.href=b,j.origin===location.origin?e(j):d(j.href)?c(b,g,h):e(j,j.target="_blank")):(j.href=i.createObjectURL(b),setTimeout(function(){i.revokeObjectURL(j.href)},4E4),setTimeout(function(){e(j)},0))}:"msSaveOrOpenBlob"in navigator?function(f,g,h){if(g=g||f.name||"download","string"!=typeof f)navigator.msSaveOrOpenBlob(b(f,h),g);else if(d(f))c(f,g,h);else{var i=document.createElement("a");i.href=f,i.target="_blank",setTimeout(function(){e(i)})}}:function(b,d,e,g){if(g=g||open("","_blank"),g&&(g.document.title=g.document.body.innerText="downloading..."),"string"==typeof b)return c(b,d,e);var h="application/octet-stream"===b.type,i=/constructor/i.test(f.HTMLElement)||f.safari,j=/CriOS\/[\d]+/.test(navigator.userAgent);if((j||h&&i||a)&&"undefined"!=typeof FileReader){var k=new FileReader;k.onloadend=function(){var a=k.result;a=j?a:a.replace(/^data:[^;]*;/,"data:attachment/file;"),g?g.location.href=a:location=a,g=null},k.readAsDataURL(b)}else{var l=f.URL||f.webkitURL,m=l.createObjectURL(b);g?g.location=m:location.href=m,g=null,setTimeout(function(){l.revokeObjectURL(m)},4E4)}});f.saveAs=g.saveAs=g,"undefined"!=typeof module&&(module.exports=g)});
|
||||
|
||||
//# sourceMappingURL=FileSaver.min.js.map
|
||||
1
sd-card/html/FileSaver.min.js.map
Normal file
1
sd-card/html/FileSaver.min.js.map
Normal file
File diff suppressed because one or more lines are too long
140
sd-card/html/backup.html
Normal file
140
sd-card/html/backup.html
Normal file
@@ -0,0 +1,140 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="icon" href="favicon.ico" type="image/x-icon">
|
||||
<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;}
|
||||
|
||||
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>
|
||||
|
||||
</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>
|
||||
|
||||
<table border="0">
|
||||
</tr>
|
||||
<td>
|
||||
<button class="button" id="doBackup" type="button" onclick="doBackup()">Create Config backup</button>
|
||||
</td>
|
||||
<td>
|
||||
<p id=progress></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<h2>Restore Configuration</h2>
|
||||
<p>Use the <a href="/fileserver/config/" target="_self">File Server</a> to upload individual files.</p>
|
||||
</body>
|
||||
|
||||
|
||||
<script src="jszip.min.js"></script>
|
||||
<script src="FileSaver.min.js"></script>
|
||||
<script>
|
||||
|
||||
function doBackup() {
|
||||
document.getElementById("progress").innerHTML = "Creating backup...";
|
||||
|
||||
// Get hostname
|
||||
try {
|
||||
var xhttp = new XMLHttpRequest();
|
||||
xhttp.open("GET", "/version?type=Hostname", false);
|
||||
xhttp.send();
|
||||
hostname = xhttp.responseText;
|
||||
}
|
||||
catch(err) {
|
||||
alert("Failed to fetch hostname: " + err.message);
|
||||
return;
|
||||
}
|
||||
|
||||
// get date/time
|
||||
var dateTime = new Date().toJSON().slice(0,10) + "_" + new Date().toJSON().slice(11,19).replaceAll(":", "-");
|
||||
|
||||
zipFilename = hostname + "_" + dateTime + ".zip";
|
||||
console.log(zipFilename);
|
||||
|
||||
// Get files list
|
||||
try {
|
||||
var xhttp = new XMLHttpRequest();
|
||||
xhttp.open("GET", "/fileserver/config/", false);
|
||||
xhttp.send();
|
||||
|
||||
var parser = new DOMParser();
|
||||
var content = parser.parseFromString(xhttp.responseText, 'text/html'); }
|
||||
catch(err) {
|
||||
alert("Failed to fetch files list: " + err.message);
|
||||
return;
|
||||
}
|
||||
|
||||
const list = content.querySelectorAll("a");
|
||||
|
||||
var urls = [];
|
||||
|
||||
for (a of list) {
|
||||
url = a.getAttribute("href");
|
||||
urls.push(url);
|
||||
}
|
||||
|
||||
// Pack as zip and download
|
||||
try {
|
||||
saveZip(zipFilename, urls);
|
||||
}
|
||||
catch(err) {
|
||||
alert("Failed to zip files: " + err.message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const saveZip = (filename, urls) => {
|
||||
if(!urls) return;
|
||||
|
||||
const zip = new JSZip();
|
||||
const folder = zip.folder("");
|
||||
|
||||
var i = 0;
|
||||
urls.forEach((url) => {
|
||||
const blobPromise = fetch(url).then((r) => {
|
||||
if (r.status === 200) return r.blob();
|
||||
return Promise.reject(new Error(r.statusText));
|
||||
});
|
||||
const name = url.substring(url.lastIndexOf("/") + 1);
|
||||
folder.file(name, blobPromise);
|
||||
});
|
||||
|
||||
zip.generateAsync({ type: "blob" },
|
||||
function updateCallback(metadata) {
|
||||
var msg = "Progress: " + metadata.percent.toFixed(0) + "%";
|
||||
if(metadata.currentFile) {
|
||||
msg += ", " + metadata.currentFile;
|
||||
}
|
||||
|
||||
console.log(msg);
|
||||
document.getElementById("progress").innerHTML = msg;
|
||||
}
|
||||
).then((blob) => saveAs(blob, filename));
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
</html>
|
||||
31
sd-card/html/common.js
Normal file
31
sd-card/html/common.js
Normal file
@@ -0,0 +1,31 @@
|
||||
|
||||
var basepath = "http://192.168.178.22";
|
||||
|
||||
function LoadHostname() {
|
||||
_basepath = getbasepath();
|
||||
|
||||
|
||||
var xhttp = new XMLHttpRequest();
|
||||
xhttp.addEventListener('load', function(event) {
|
||||
if (xhttp.status >= 200 && xhttp.status < 300) {
|
||||
hostname = xhttp.responseText;
|
||||
document.title = hostname + " - AI on the edge";
|
||||
document.getElementById("id_title").innerHTML = "Digitizer - AI on the edge - " + hostname;
|
||||
}
|
||||
else {
|
||||
console.warn(request.statusText, request.responseText);
|
||||
}
|
||||
});
|
||||
|
||||
// var xhttp = new XMLHttpRequest();
|
||||
try {
|
||||
url = _basepath + '/version?type=Hostname';
|
||||
xhttp.open("GET", url, true);
|
||||
xhttp.send();
|
||||
|
||||
}
|
||||
catch (error)
|
||||
{
|
||||
// alert("Loading Hostname failed");
|
||||
}
|
||||
}
|
||||
@@ -86,7 +86,10 @@ select {
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td colspan="2"><input class="button" type="submit" name="saveroi" onclick="SaveToConfig()" value="Save all to Config.ini"></td>
|
||||
<td><input class="button" type="submit" name="saveroi" onclick="SaveToConfig()" value="Save all to Config.ini"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><button class="button" id="reboot" type="button" onclick="doReboot()">Reboot to activate saved config</button></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@@ -107,7 +110,17 @@ select {
|
||||
basepath = "http://192.168.178.26";
|
||||
basepath = "",
|
||||
param;
|
||||
|
||||
|
||||
function doReboot() {
|
||||
if (confirm("Are you sure you want to reboot? Did you save the config?")) {
|
||||
var stringota = "/reboot";
|
||||
window.location = stringota;
|
||||
window.location.href = stringota;
|
||||
window.location.assign(stringota);
|
||||
window.location.replace(stringota);
|
||||
}
|
||||
}
|
||||
|
||||
function ChangeSelection(){
|
||||
aktindex = parseInt(document.getElementById("index").value);
|
||||
UpdateReference();
|
||||
|
||||
@@ -116,18 +116,22 @@ th, td {
|
||||
<tr>
|
||||
<td>x: <input type="number" name="refx" id="refx" step=1 onchange="valuemanualchanged()" tabindex=2></td>
|
||||
<td>dx: <input type="number" name="refdx" id="refdx" step=1 onchange="valuemanualchangeddx()" tabindex=4></td>
|
||||
<td rowspan="2"><label for="lockAR"> Lock aspect ratio: </label><input type="checkbox" id="lockAR" name="lockAR" value="1" onclick="changelockAR()" checked tabindex=6></td>
|
||||
<td rowspan="1"><label for="lockAR"> Lock aspect ratio: </label><input type="checkbox" id="lockAR" name="lockAR" value="1" onclick="changelockAR()" checked tabindex=6></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>y: <input type="number" name="refy" id="refy" step=1 onchange="valuemanualchanged()" tabindex=3></td>
|
||||
<td>dy: <input type="number" name="refdy" id="refdy" step=1 onchange="valuemanualchanged()" tabindex=5></td>
|
||||
<td rowspan="1"><label for="CCW"> Counter-Clockwise Rotation: </label><input type="checkbox" id="CCW" name="CCW" value="0" onclick="changeCCW()" unchecked tabindex=7></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td><input class="button" type="submit" id="saveroi" name="saveroi" onclick="SaveToConfig()" value="Save all to Config.ini" tabindex=7></td>
|
||||
<td><input class="button" type="submit" id="saveroi" name="saveroi" onclick="SaveToConfig()" value="Save all to Config.ini" tabindex=8></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><button class="button" id="reboot" type="button" onclick="doReboot()">Reboot to activate saved config</button></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@@ -147,8 +151,17 @@ th, td {
|
||||
enhanceCon = false;
|
||||
lockAR = true;
|
||||
basepath = "http://192.168.178.26";
|
||||
|
||||
|
||||
|
||||
function doReboot() {
|
||||
if (confirm("Are you sure you want to reboot? Did you save the config?")) {
|
||||
var stringota = "/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;
|
||||
|
||||
@@ -204,9 +217,9 @@ function newROI(){
|
||||
var _roinew = prompt("Please enter name of new ROI", "name");
|
||||
|
||||
if (ROIInfo.length > 0)
|
||||
erg = CreateROI(_number, "analog", sel.selectedIndex, _roinew, 1, 1, ROIInfo[aktindex]["dx"], ROIInfo[aktindex]["dy"]);
|
||||
erg = CreateROI(_number, "analog", sel.selectedIndex, _roinew, 1, 1, ROIInfo[aktindex]["dx"], ROIInfo[aktindex]["dy"], ROIInfo[aktindex]["CCW"]=="true");
|
||||
else
|
||||
erg = CreateROI(_number, "analog", sel.selectedIndex, _roinew, 1, 1, 30, 30);
|
||||
erg = CreateROI(_number, "analog", sel.selectedIndex, _roinew, 1, 1, 30, 30, false);
|
||||
|
||||
if (erg != "")
|
||||
alert(erg);
|
||||
@@ -234,6 +247,20 @@ function changelockAR(){
|
||||
lockAR = document.getElementById("lockAR").checked;
|
||||
}
|
||||
|
||||
function changeCCW(){
|
||||
var sel = document.getElementById("Numbers_value1");
|
||||
var _number = sel.options[sel.selectedIndex].text;
|
||||
|
||||
ROIInfo = getROIInfo("analog", _number);
|
||||
aktindex = parseInt(document.getElementById("index").value);
|
||||
|
||||
if (document.getElementById("CCW").checked)
|
||||
ROIInfo[aktindex]["CCW"] = "true";
|
||||
else
|
||||
ROIInfo[aktindex]["CCW"] = "false";
|
||||
UpdateROIs();
|
||||
}
|
||||
|
||||
function ChangeSelection(){
|
||||
aktindex = parseInt(document.getElementById("index").value);
|
||||
// lockAR = true;
|
||||
@@ -249,7 +276,7 @@ function SaveToConfig(){
|
||||
}
|
||||
|
||||
|
||||
function UpdateROIs(){
|
||||
function UpdateROIs(_sel){
|
||||
document.getElementById("Category_Analog_enabled").checked = true;
|
||||
var sel = document.getElementById("Numbers_value1");
|
||||
var _number = sel.options[sel.selectedIndex].text;
|
||||
@@ -320,6 +347,8 @@ function UpdateROIs(){
|
||||
document.getElementById("refy").value = ROIInfo[aktindex]["y"];
|
||||
document.getElementById("refdx").value = ROIInfo[aktindex]["dx"];
|
||||
document.getElementById("refdy").value = ROIInfo[aktindex]["dy"];
|
||||
document.getElementById("CCW").checked = ROIInfo[aktindex]["CCW"] == "true";
|
||||
|
||||
rect.startX = ROIInfo[aktindex]["x"];
|
||||
rect.startY = ROIInfo[aktindex]["y"];
|
||||
rect.w = ROIInfo[aktindex]["dx"];
|
||||
|
||||
@@ -611,8 +611,12 @@ textarea {
|
||||
<input type="text" id="MQTT_MainTopic_value1">
|
||||
</td>
|
||||
<td style="font-size: 80%;">
|
||||
MQTT main topic, under which the counters are published. The single value will be published with the following key: MAINTOPIC/VALUE_NAME/PARAMETER <br>
|
||||
where parameters are: value, rate, timestamp, error<br>
|
||||
MQTT main topic, under which the counters are published. <br>
|
||||
The single value will be published with the following key: MAINTOPIC/VALUE_NAME/PARAMETER where
|
||||
<ul>
|
||||
<li> VALUE_NAME is the name of the value (a meter might have more than one value) as defined during analog and digital ROI configuration (defaults to "main")</li>
|
||||
<li> and PARAMETERS are: value, rate, timestamp, error</li>
|
||||
</ul>
|
||||
The general connection status can be found in MAINTOPIC/CONNECTION
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -119,6 +119,9 @@ th, td {
|
||||
<table>
|
||||
<tr>
|
||||
<td><input class="button" type="submit" id="saveroi" name="saveroi" onclick="SaveToConfig()" value="Save all to Config.ini" tabindex=7></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><button class="button" id="reboot" type="button" onclick="doReboot()">Reboot to activate saved config</button></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@@ -140,6 +143,15 @@ th, td {
|
||||
lockAR = true;
|
||||
basepath = "http://192.168.178.26";
|
||||
|
||||
function doReboot() {
|
||||
if (confirm("Are you sure you want to reboot? Did you save the config?")) {
|
||||
var stringota = "/reboot";
|
||||
window.location = stringota;
|
||||
window.location.href = stringota;
|
||||
window.location.assign(stringota);
|
||||
window.location.replace(stringota);
|
||||
}
|
||||
}
|
||||
|
||||
function EnDisableDigits() {
|
||||
isEnabled = document.getElementById("Category_Digits_enabled").checked;
|
||||
@@ -197,9 +209,9 @@ function newROI() {
|
||||
var _roinew = prompt("Please enter name of new ROI", "name");
|
||||
|
||||
if (ROIInfo.length > 0)
|
||||
erg = CreateROI(_number, "digit", sel.selectedIndex, _roinew, 1, 1, ROIInfo[aktindex]["dx"], ROIInfo[aktindex]["dy"]);
|
||||
erg = CreateROI(_number, "digit", sel.selectedIndex, _roinew, 1, 1, ROIInfo[aktindex]["dx"], ROIInfo[aktindex]["dy"], 0);
|
||||
else
|
||||
erg = CreateROI(_number, "digit", sel.selectedIndex, _roinew, 1, 1, 30, 51);
|
||||
erg = CreateROI(_number, "digit", sel.selectedIndex, _roinew, 1, 1, 30, 51, 0);
|
||||
|
||||
if (erg != "")
|
||||
alert(erg);
|
||||
|
||||
@@ -2,14 +2,11 @@
|
||||
<html style="width: fit-content">
|
||||
<head>
|
||||
<link rel="icon" href="favicon.ico" type="image/x-icon">
|
||||
<title>jomjol - AI on the edge</title>
|
||||
<title>AI on the edge</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<style>
|
||||
.h_iframe iframe {width:995px;height:605px;}
|
||||
.h_iframe {width:995px;height:605px;}
|
||||
|
||||
h1 {font-size: 2em; margin-block-end: 0.3em;}
|
||||
h2 {font-size: 1.5em;margin-block-start: 0.3em;}
|
||||
h3 {font-size: 1.2em;}
|
||||
|
||||
@@ -2,14 +2,11 @@
|
||||
<html style="width: fit-content">
|
||||
<head>
|
||||
<link rel="icon" href="favicon.ico" type="image/x-icon">
|
||||
<title>jomjol - AI on the edge</title>
|
||||
<title>AI on the edge</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<style>
|
||||
.h_iframe iframe {width:995px;height:605px;}
|
||||
.h_iframe {width:995px;height:605px;}
|
||||
|
||||
h1 {font-size: 2em; margin-block-end: 0.3em;}
|
||||
h2 {font-size: 1.5em;margin-block-start: 0.3em;}
|
||||
h3 {font-size: 1.2em;}
|
||||
|
||||
@@ -35,6 +35,7 @@ table {
|
||||
|
||||
<body style="font-family: arial; padding: 0px 10px;">
|
||||
<h2>Create Reference out of Raw Image</h2>
|
||||
<p><b>Note: After saving a new Reference Image, make sure to update the Alignment Marks and the ROI's and reboot once!</b></p>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
@@ -85,6 +86,9 @@ table {
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input class="button" type="button" id="updatereferenceimage" value="Update Reference Image" onclick="SaveReference()"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><button class="button" id="reboot" type="button" onclick="doReboot()">Reboot to activate saved Reference</button></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@@ -102,6 +106,16 @@ table {
|
||||
basepath = "http://192.168.178.26";
|
||||
isActReference = false;
|
||||
param;
|
||||
|
||||
function doReboot() {
|
||||
if (confirm("Are you sure you want to reboot? Did you save the config?")) {
|
||||
var stringota = "/reboot";
|
||||
window.location = stringota;
|
||||
window.location.href = stringota;
|
||||
window.location.assign(stringota);
|
||||
window.location.replace(stringota);
|
||||
}
|
||||
}
|
||||
|
||||
function doTake(){
|
||||
var xhttp = new XMLHttpRequest();
|
||||
|
||||
@@ -2,14 +2,11 @@
|
||||
<html style="width: fit-content">
|
||||
<head>
|
||||
<link rel="icon" href="favicon.ico" type="image/x-icon">
|
||||
<title>jomjol - AI on the edge</title>
|
||||
<title>AI on the edge</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<style>
|
||||
.h_iframe iframe {width:995px;height:605px;}
|
||||
.h_iframe {width:995px;height:605px;}
|
||||
|
||||
h1 {font-size: 2em; margin-block-end: 0.3em;}
|
||||
h2 {font-size: 1.5em;margin-block-start: 0.3em;}
|
||||
h3 {font-size: 1.2em;}
|
||||
|
||||
@@ -2,13 +2,11 @@
|
||||
<html style="width: fit-content">
|
||||
<head>
|
||||
<link rel="icon" href="favicon.ico" type="image/x-icon">
|
||||
<title>jomjol - AI on the edge</title>
|
||||
<title>AI on the edge</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<style>
|
||||
.h_iframe iframe {width:995px;height:605px;}
|
||||
.h_iframe {width:995px;height:605px;}
|
||||
|
||||
h1 {font-size: 2em; margin-block-end: 0.3em;}
|
||||
h2 {font-size: 1.5em;margin-block-start: 0.3em;}
|
||||
|
||||
@@ -2,14 +2,11 @@
|
||||
<html style="width: fit-content">
|
||||
<head>
|
||||
<link rel="icon" href="favicon.ico" type="image/x-icon">
|
||||
<title>jomjol - AI on the edge</title>
|
||||
<title>AI on the edge</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<style>
|
||||
.h_iframe iframe {width:995px;height:605px;}
|
||||
.h_iframe {width:995px;height:605px;}
|
||||
|
||||
h1 {font-size: 2em; margin-block-end: 0.3em;}
|
||||
h2 {font-size: 1.5em;margin-block-start: 0.3em;}
|
||||
h3 {font-size: 1.2em;}
|
||||
|
||||
@@ -2,13 +2,11 @@
|
||||
<html style="width: fit-content">
|
||||
<head>
|
||||
<link rel="icon" href="favicon.ico" type="image/x-icon">
|
||||
<title>jomjol - AI on the edge</title>
|
||||
<title>AI on the edge</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<style>
|
||||
.h_iframe iframe {width:995px;height:605px;}
|
||||
.h_iframe {width:995px;height:605px;}
|
||||
|
||||
h1 {font-size: 2em; margin-block-end: 0.3em;}
|
||||
h2 {font-size: 1.5em;margin-block-start: 0.3em;}
|
||||
|
||||
@@ -2,14 +2,11 @@
|
||||
<html style="width: fit-content">
|
||||
<head>
|
||||
<link rel="icon" href="favicon.ico" type="image/x-icon">
|
||||
<title>jomjol - AI on the edge</title>
|
||||
<title>AI on the edge</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<style>
|
||||
.h_iframe iframe {width:995px;height:605px;}
|
||||
.h_iframe {width:995px;height:605px;}
|
||||
|
||||
h1 {font-size: 2em; margin-block-end: 0.3em;}
|
||||
h2 {font-size: 1.5em;margin-block-start: 0.3em;}
|
||||
h3 {font-size: 1.2em;}
|
||||
|
||||
@@ -2,14 +2,11 @@
|
||||
<html style="width: fit-content">
|
||||
<head>
|
||||
<link rel="icon" href="favicon.ico" type="image/x-icon">
|
||||
<title>jomjol - AI on the edge</title>
|
||||
<title>AI on the edge</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<style>
|
||||
.h_iframe iframe {width:995px;height:605px;}
|
||||
.h_iframe {width:995px;height:605px;}
|
||||
|
||||
h1 {font-size: 2em; margin-block-end: 0.3em;}
|
||||
h2 {font-size: 1.5em;margin-block-start: 0.3em;}
|
||||
h3 {font-size: 1.2em;}
|
||||
|
||||
@@ -2,13 +2,11 @@
|
||||
<html style="width: fit-content">
|
||||
<head>
|
||||
<link rel="icon" href="favicon.ico" type="image/x-icon">
|
||||
<title>jomjol - AI on the edge</title>
|
||||
<title>AI on the edge</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<style>
|
||||
.h_iframe iframe {width:995px;height:605px;}
|
||||
.h_iframe {width:995px;height:605px;}
|
||||
|
||||
h1 {font-size: 2em; margin-block-end: 0.3em;}
|
||||
h2 {font-size: 1.5em;margin-block-start: 0.3em;}
|
||||
|
||||
@@ -1,78 +1,123 @@
|
||||
<!DOCTYPE html>
|
||||
<html style="width: fit-content">
|
||||
<html>
|
||||
<head>
|
||||
<link rel="icon" href="favicon.ico" type="image/x-icon">
|
||||
<title>jomjol - AI on the edge</title>
|
||||
<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" type="text/css" > -->
|
||||
<style>
|
||||
.h_iframe iframe {width:995px;height:605px;}
|
||||
.h_iframe {width:995px;height:605px;}
|
||||
/* Older Firmware versions (11.2.0 and older) do not support css files, therefore we need to keep it integrated for now! */
|
||||
body, html {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-height: 800px;
|
||||
margin: 0px 0px 0px 2px;
|
||||
padding: 0;
|
||||
font-family: arial;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
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;}
|
||||
.main {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.iframe {
|
||||
flex-grow: 1;
|
||||
margin: 5px 7px 4px 0px;
|
||||
padding: 0;
|
||||
border: 2px solid black;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
background-color: #333;
|
||||
width:1000px;
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
background-color: #333;
|
||||
width:1000px;
|
||||
}
|
||||
|
||||
li {
|
||||
float: left;
|
||||
font-family: arial;
|
||||
font-size: 18px;
|
||||
float: left;
|
||||
font-family: arial;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
li a, .dropbtn {
|
||||
display: inline-block;
|
||||
color: white;
|
||||
text-align: center;
|
||||
padding: 14px 16px;
|
||||
text-decoration: none;
|
||||
display: inline-block;
|
||||
color: white;
|
||||
text-align: center;
|
||||
padding: 14px 16px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
li a:hover, .dropdown:hover .dropbtn {
|
||||
background-color: red;
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
li.dropdown {
|
||||
display: inline-block;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.dropdown-content {
|
||||
display: none;
|
||||
position: absolute;
|
||||
background-color: #f9f9f9;
|
||||
min-width: 160px;
|
||||
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
|
||||
z-index: 1;
|
||||
font-family: arial;
|
||||
display: none;
|
||||
position: absolute;
|
||||
background-color: #f9f9f9;
|
||||
min-width: 160px;
|
||||
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
|
||||
z-index: 1;
|
||||
font-family: arial;
|
||||
}
|
||||
|
||||
.dropdown-content a {
|
||||
color: black;
|
||||
padding: 12px 16px;
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
text-align: left;
|
||||
color: black;
|
||||
padding: 12px 16px;
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.dropdown-content a:hover {background-color: #f1f1f1;}
|
||||
.dropdown-content a:hover {
|
||||
color: white;
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
.dropdown:hover .dropdown-content {
|
||||
display: block;
|
||||
}
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type="text/javascript" src="common.js"></script>
|
||||
<script type="text/javascript" src="gethost.js"></script>
|
||||
<script type="text/javascript" src="readconfigcommon.js"></script>
|
||||
<script type="text/javascript" src="readconfigparam.js"></script>
|
||||
</head>
|
||||
|
||||
<body style="font-family: arial">
|
||||
<body>
|
||||
<div class="main">
|
||||
|
||||
<table style="border: none">
|
||||
<tr><td style="padding-right: 10px;"><img src="favicon.ico"></td>
|
||||
@@ -82,71 +127,35 @@ li.dropdown {
|
||||
</table>
|
||||
|
||||
<ul>
|
||||
<li><a href="#"onclick="document.getElementById('maincontent').src = '/wasserzaehler_roi.html';">Overview</a></li>
|
||||
<li class="dropdown">
|
||||
<li><a href="#"onclick="document.getElementById('maincontent').src = '/wasserzaehler_roi.html';">Overview</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="javascript:void(0)" class="dropbtn">Configuration</a>
|
||||
<div class="dropdown-content">
|
||||
<a href="#"onclick="document.getElementById('maincontent').src = '/prevalue_set.html';">Set preValue</a>
|
||||
<a href="index_configure.html">Edit Configuration</a>
|
||||
<a href="#"onclick="document.getElementById('maincontent').src = '/prevalue_set.html';">Set Previous Value</a>
|
||||
<a href="index_configure.html">Edit Configuration</a>
|
||||
</div>
|
||||
</li>
|
||||
<li><a href="#"onclick="document.getElementById('maincontent').src = '/wasserzaehler.html?full';">Recognition</a></li>
|
||||
<li><a href="#"onclick="document.getElementById('maincontent').src = '/fileserver/';">File Server</a></li>
|
||||
<li class="dropdown">
|
||||
</li>
|
||||
<li><a href="#"onclick="document.getElementById('maincontent').src = '/wasserzaehler.html?full';">Recognition</a></li>
|
||||
<li><a href="#"onclick="document.getElementById('maincontent').src = '/fileserver/';">File Server</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="javascript:void(0)" class="dropbtn">System</a>
|
||||
<div class="dropdown-content">
|
||||
<a href="#"onclick="document.getElementById('maincontent').src = '/ota_page.html';">OTA Update</a>
|
||||
<a href="#"onclick="document.getElementById('maincontent').src = '/fileserver/log/message/?readonly=true';">Log Viewer</a>
|
||||
<a href="#"onclick="document.getElementById('maincontent').src = '/reboot_page.html';">Reboot</a>
|
||||
<a href="#"onclick="document.getElementById('maincontent').src = '/info.html';">Info</a>
|
||||
<a href="#"onclick="document.getElementById('maincontent').src = '/backup.html';">Backup/Restore</a>
|
||||
<a href="#"onclick="document.getElementById('maincontent').src = '/ota_page.html';">OTA Update</a>
|
||||
<a href="#"onclick="document.getElementById('maincontent').src = '/fileserver/log/message/?readonly=true';">Log Viewer</a>
|
||||
<a href="#"onclick="document.getElementById('maincontent').src = '/reboot_page.html';">Reboot</a>
|
||||
<a href="#"onclick="document.getElementById('maincontent').src = '/info.html';">Info</a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
|
||||
<div class="h_iframe">
|
||||
<iframe name="maincontent" id ="maincontent" src="/wasserzaehler_roi.html" title="fileserver" allowfullscreen></iframe>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" src="./gethost.js"></script>
|
||||
<script type="text/javascript" src="./readconfigcommon.js"></script>
|
||||
<script type="text/javascript" src="./readconfigparam.js"></script>
|
||||
|
||||
<iframe name="maincontent" class="iframe" id="maincontent" src="wasserzaehler_roi.html"></iframe>
|
||||
|
||||
<script type="text/javascript">
|
||||
var basepath = "http://192.168.178.22";
|
||||
|
||||
|
||||
function LoadHostname() {
|
||||
_basepath = getbasepath();
|
||||
|
||||
|
||||
var xhttp = new XMLHttpRequest();
|
||||
xhttp.addEventListener('load', function(event) {
|
||||
if (xhttp.status >= 200 && xhttp.status < 300) {
|
||||
hostname = xhttp.responseText;
|
||||
document.title = hostname + " - jomjol - AI on the edge";
|
||||
document.getElementById("id_title").innerHTML = "Digitizer - AI on the edge - " + hostname;
|
||||
} else {
|
||||
console.warn(request.statusText, request.responseText);
|
||||
}
|
||||
});
|
||||
|
||||
// var xhttp = new XMLHttpRequest();
|
||||
try {
|
||||
url = _basepath + '/version?type=Hostname';
|
||||
xhttp.open("GET", url, true);
|
||||
xhttp.send();
|
||||
|
||||
}
|
||||
catch (error)
|
||||
{
|
||||
// alert("Loading Hostname failed");
|
||||
}
|
||||
}
|
||||
|
||||
LoadHostname();
|
||||
|
||||
</script>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -2,76 +2,117 @@
|
||||
<html>
|
||||
<head>
|
||||
<link rel="icon" href="favicon.ico" type="image/x-icon">
|
||||
<title>jomjol - AI on the edge</title>
|
||||
<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" type="text/css" > -->
|
||||
<style>
|
||||
.h_iframe iframe {width:995px;height:765px;}
|
||||
.h_iframe {width:995px;height:765px;}
|
||||
/* Older Firmware versions (11.2.0 and older) do not support css files, therefore we need to keep it integrated for now! */
|
||||
body, html {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-height: 800px;
|
||||
margin: 0px 0px 0px 2px;
|
||||
padding: 0;
|
||||
font-family: arial;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
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;}
|
||||
.main {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.iframe {
|
||||
flex-grow: 1;
|
||||
margin: 5px 7px 4px 0px;
|
||||
padding: 0;
|
||||
border: 2px solid black;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
background-color: #333;
|
||||
width:1000px;
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
background-color: #333;
|
||||
width:1000px;
|
||||
}
|
||||
|
||||
li {
|
||||
float: left;
|
||||
font-family: arial;
|
||||
font-size: 18px;
|
||||
float: left;
|
||||
font-family: arial;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
li a, .dropbtn {
|
||||
display: inline-block;
|
||||
color: white;
|
||||
text-align: center;
|
||||
padding: 14px 16px;
|
||||
text-decoration: none;
|
||||
display: inline-block;
|
||||
color: white;
|
||||
text-align: center;
|
||||
padding: 14px 16px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
li a:hover, .dropdown:hover .dropbtn {
|
||||
background-color: red;
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
li.dropdown {
|
||||
display: inline-block;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.dropdown-content {
|
||||
display: none;
|
||||
position: absolute;
|
||||
background-color: #f9f9f9;
|
||||
min-width: 160px;
|
||||
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
|
||||
z-index: 1;
|
||||
font-family: arial;
|
||||
display: none;
|
||||
position: absolute;
|
||||
background-color: #f9f9f9;
|
||||
min-width: 160px;
|
||||
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
|
||||
z-index: 1;
|
||||
font-family: arial;
|
||||
}
|
||||
|
||||
.dropdown-content a {
|
||||
color: black;
|
||||
padding: 12px 16px;
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
text-align: left;
|
||||
color: black;
|
||||
padding: 12px 16px;
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.dropdown-content a:hover {background-color: #f1f1f1;}
|
||||
.dropdown-content a:hover {
|
||||
color: white;
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
.dropdown:hover .dropdown-content {
|
||||
display: block;
|
||||
}
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body style="font-family: arial">
|
||||
<body>
|
||||
<div class="main">
|
||||
|
||||
<table style="border: none">
|
||||
<tr><td style="padding-right: 10px;"><img src="favicon.ico"></td>
|
||||
@@ -81,62 +122,44 @@ li.dropdown {
|
||||
</table>
|
||||
|
||||
<ul>
|
||||
<li aria-current="page"><a href="index.html">Main Page</a>
|
||||
<li><a href="#"onclick="document.getElementById('maincontent').src = 'edit_config_param.html';">Configuration</a></li>
|
||||
<li aria-current="page"><a href="index.html">Main Page</a>
|
||||
<li><a href="#"onclick="document.getElementById('maincontent').src = 'edit_config_param.html';">Configuration</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="javascript:void(0)" class="dropbtn">Alignment</a>
|
||||
<div class="dropdown-content">
|
||||
<a href="#"onclick="document.getElementById('maincontent').src = 'edit_reference.html';">Reference Image</a>
|
||||
<a href="#"onclick="document.getElementById('maincontent').src = 'edit_alignment.html';">Alignment Marks</a>
|
||||
</div>
|
||||
</li>
|
||||
<a href="javascript:void(0)" class="dropbtn">Alignment</a>
|
||||
<div class="dropdown-content">
|
||||
<a href="#"onclick="document.getElementById('maincontent').src = 'edit_reference.html';">Reference Image</a>
|
||||
<a href="#"onclick="document.getElementById('maincontent').src = 'edit_alignment.html';">Alignment Marks</a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
<a href="javascript:void(0)" class="dropbtn">Regions Of Interest (ROI)</a>
|
||||
<div class="dropdown-content">
|
||||
<a href="#"onclick="document.getElementById('maincontent').src = 'edit_digits.html';">Digital ROIs</a>
|
||||
<a href="#"onclick="document.getElementById('maincontent').src = 'edit_analog.html';">Analog ROIs</a>
|
||||
</div>
|
||||
</li>
|
||||
<a href="javascript:void(0)" class="dropbtn">Regions Of Interest (ROI)</a>
|
||||
<div class="dropdown-content">
|
||||
<a href="#"onclick="document.getElementById('maincontent').src = 'edit_digits.html';">Digital ROIs</a>
|
||||
<a href="#"onclick="document.getElementById('maincontent').src = 'edit_analog.html';">Analog ROIs</a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
<a href="javascript:void(0)" class="dropbtn">System</a>
|
||||
<div class="dropdown-content">
|
||||
<a href="#"onclick="document.getElementById('maincontent').src = '/backup.html';">Backup/Restore</a>
|
||||
<a href="#"onclick="document.getElementById('maincontent').src = '/ota_page.html';">OTA Update</a>
|
||||
<a href="#"onclick="document.getElementById('maincontent').src = '/fileserver/log/message/?readonly=true';">Log Viewer</a>
|
||||
<a href="#"onclick="document.getElementById('maincontent').src = '/reboot_page.html';">Reboot</a>
|
||||
<a href="#"onclick="document.getElementById('maincontent').src = '/info.html';">Info</a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
<div class="h_iframe">
|
||||
<iframe width="1020px" height="650px" name="maincontent" id ="maincontent" src="edit_config_param.html" title="fileserver"></iframe>
|
||||
</div>
|
||||
<script type="text/javascript" src="./gethost.js"></script>
|
||||
|
||||
<iframe name="maincontent" class="iframe" id="maincontent" src="edit_config_param.html"></iframe>
|
||||
|
||||
<script type="text/javascript" src="common.js"></script>
|
||||
<script type="text/javascript" src="gethost.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
var basepath = "http://192.168.178.22";
|
||||
|
||||
|
||||
function LoadHostname() {
|
||||
_basepath = getbasepath();
|
||||
|
||||
var xhttp = new XMLHttpRequest();
|
||||
xhttp.addEventListener('load', function(event) {
|
||||
if (xhttp.status >= 200 && xhttp.status < 300) {
|
||||
hostname = xhttp.responseText;
|
||||
document.title = hostname + " - Configure";
|
||||
document.getElementById("id_title").innerHTML = "Configure - " + hostname;
|
||||
} else {
|
||||
console.warn(request.statusText, request.responseText);
|
||||
}
|
||||
});
|
||||
|
||||
// var xhttp = new XMLHttpRequest();
|
||||
try {
|
||||
url = _basepath + '/version?type=Hostname';
|
||||
xhttp.open("GET", url, true);
|
||||
xhttp.send();
|
||||
|
||||
}
|
||||
catch (error)
|
||||
{
|
||||
// alert("Loading Hostname failed");
|
||||
}
|
||||
}
|
||||
|
||||
LoadHostname();
|
||||
|
||||
</script>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<link rel="icon" href="favicon.ico" type="image/x-icon">
|
||||
<title>Set PreValue</title>
|
||||
<title>Info</title>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<style>
|
||||
@@ -136,6 +136,8 @@ div {
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h3>Copyright</h3>
|
||||
Copyright © 2020 - 2022 by <a href="https://github.com/jomjol/AI-on-the-edge-device" target=_blank>Jomjol</a> and others.
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
13
sd-card/html/jszip.min.js
vendored
Normal file
13
sd-card/html/jszip.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -29,7 +29,9 @@ input[type=number] {
|
||||
</head>
|
||||
|
||||
<body style="font-family: arial; padding: 0px 10px;">
|
||||
<h3>It is strongly recommended to update firmware and content of /html directory on SD-card at the same time!</h3>
|
||||
Check at <a href="https://github.com/jomjol/AI-on-the-edge-device/releases" target=_blank>https://github.com/jomjol/AI-on-the-edge-device/releases</a> to see if there is an update available.
|
||||
<h3>It is strongly recommended to update firmware and web interface (stored separately in the html directory on SD-card) at the same time!</h3>
|
||||
<hr>
|
||||
<h2>1. Firmware Update</h2>
|
||||
<table class="fixed" border="0">
|
||||
<tr>
|
||||
@@ -37,18 +39,21 @@ input[type=number] {
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td style="width: 230px">
|
||||
<label for="newfile">Select the firmware file:</label>
|
||||
<label for="newfile">Select the firmware file (firmware.bin):</label>
|
||||
</td>
|
||||
<td colspan="2">
|
||||
<input id="newfile" type="file" onchange="setpath()" style="width:100%;">
|
||||
</td>
|
||||
<td rowspan="2" style="padding-left:50px">
|
||||
<button class="button" id="doUpdate" type="button" onclick="doUpdate()">Flash the firmware<br>(Takes about 60s)</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="filepath">Set path on server:</label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="filepath" type="text" style="width:100%;" readonly>
|
||||
<input id="filepath" type="text" style="width:100%; border: 0" readonly>
|
||||
</td>
|
||||
<td>
|
||||
<button id="upload" type="button" onclick="upload()">Upload</button>
|
||||
@@ -57,41 +62,29 @@ input[type=number] {
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td style="width: 230px">
|
||||
<button class="button" id="doUpdate" type="button" onclick="doUpdate()">Flash the firmware</button>
|
||||
</td>
|
||||
<td>
|
||||
(Takes about 60s)
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>2. Update "/html" directory</h2>
|
||||
<h2>2. Web Interface Update</h2>
|
||||
<table class="fixed" border="0">
|
||||
<tr>
|
||||
<td>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td style="width: 230px">
|
||||
<label for="newfilehtml">Select the zipped /html content:</label>
|
||||
<label for="newfilehtml">Select the Web Interface file (html.zip):</label>
|
||||
</td>
|
||||
<td colspan="2">
|
||||
<input id="newfilehtml" type="file" onchange="setpathhtml()" style="width:100%;">
|
||||
</td>
|
||||
<td rowspan="2" style="padding-left:50px">
|
||||
<button class="button" id="doUpdatehtml" type="button" onclick="doUpdatehtml()">Update Web Interface</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="filepathhtml">Set path on server:</label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="filepathhtml" type="text" style="width:100%;" readonly>
|
||||
<input id="filepathhtml" type="text" style="width:100%; border: 0" readonly>
|
||||
</td>
|
||||
<td>
|
||||
<button id="uploadhtml" type="button" onclick="uploadhtml()">Upload</button>
|
||||
@@ -100,21 +93,12 @@ input[type=number] {
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<button class="button" id="doUpdatehtml" type="button" onclick="doUpdatehtml()">Update "/html" directory</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h2>3. Reboot</h2>
|
||||
<table class="fixed" border="0">
|
||||
<tr>
|
||||
<td>
|
||||
<button class="button" id="reboot" type="button" onclick="doReboot()">Reboot to activate updates</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h2>4. Upload neural network definition (tfl/tflite file)</h2>
|
||||
<hr>
|
||||
<h2>Upload Neural Network Definition (tfl/tflite file)</h2>
|
||||
<b>The file must be set active afterwards on the <a href="index_configure.html" target="_parent">Config</a> page</b>!
|
||||
<table class="fixed" border="0">
|
||||
<tr>
|
||||
<td>
|
||||
@@ -132,7 +116,7 @@ input[type=number] {
|
||||
<label for="filepathtfl">Set path on server</label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="filepathtfl" type="text" style="width:100%;" readonly>
|
||||
<input id="filepathtfl" type="text" style="width:100%; border: 0" readonly>
|
||||
</td>
|
||||
<td>
|
||||
<button id="uploadtfl" type="button" onclick="uploadtfl()" disabled>Upload</button>
|
||||
@@ -141,7 +125,6 @@ input[type=number] {
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
The file must be activated in the config.ini file.
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
207
sd-card/html/ota_page_new.html
Normal file
207
sd-card/html/ota_page_new.html
Normal file
@@ -0,0 +1,207 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="icon" href="favicon.ico" type="image/x-icon">
|
||||
<title>OTA Update</title>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<style>
|
||||
h1 {font-size: 2em;}
|
||||
h2 {font-size: 1.5em;}
|
||||
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;
|
||||
}
|
||||
|
||||
.button {
|
||||
padding: 10px 20px;
|
||||
width: 211px;
|
||||
font-size: 16px;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
<body style="font-family: arial; padding: 0px 10px;">
|
||||
Check at <a href="https://github.com/jomjol/AI-on-the-edge-device/releases" target=_blank>https://github.com/jomjol/AI-on-the-edge-device/releases</a> to see if there is an update available.
|
||||
<h3>It is strongly recommended to update firmware and web interface (stored separately in the html directory on SD-card) at the same time!</h3>
|
||||
<hr>
|
||||
<h2>Update</h2>
|
||||
<table class="fixed" border="0">
|
||||
<tr>
|
||||
<td>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td style="width: 230px">
|
||||
<label for="newfile">Select the update file (update.zip, firmware.bin, html.zip, *.tfl/tflite):</label>
|
||||
</td>
|
||||
<td colspan="2">
|
||||
<input id="newfile" type="file" onchange="setpath()" style="width:100%;">
|
||||
</td>
|
||||
<td rowspan="2" style="padding-left:50px">
|
||||
<button class="button" id="doUpdate" type="button" onclick="doUpdate()">Flash the firmware<br>(Takes about 60s)</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="filepath">Selected upload file:</label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="filepath" type="text" style="width:100%; border: 0" readonly>
|
||||
</td>
|
||||
<td>
|
||||
<button id="upload" type="button" onclick="upload()">Upload</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h2>Reboot</h2>
|
||||
<button class="button" id="reboot" type="button" onclick="doReboot()">Reboot to activate updates</button>
|
||||
<hr>
|
||||
|
||||
<script type="text/javascript" src="./gethost.js"></script>
|
||||
|
||||
|
||||
<script language="JavaScript">
|
||||
|
||||
var basepath = "http://192.168.178.26";
|
||||
|
||||
|
||||
function init(){
|
||||
basepath = getbasepath();
|
||||
|
||||
document.getElementById("reboot").disabled = true;
|
||||
document.getElementById("upload").disabled = true;
|
||||
document.getElementById("doUpdate").disabled = true;
|
||||
}
|
||||
|
||||
function doUpdate() {
|
||||
if (confirm("Are you sure to update the firmware?")) {
|
||||
var stringota = "/ota?file=firmware.bin";
|
||||
document.getElementById("doUpdate").disabled = true;
|
||||
|
||||
var xhttp = new XMLHttpRequest();
|
||||
|
||||
xhttp.onreadystatechange = function() {
|
||||
if (xhttp.readyState == 4) {
|
||||
if (xhttp.status == 200) {
|
||||
document.getElementById("reboot").disabled = false;
|
||||
alert("Flash successfull - Reboot necessary to make changes active.");
|
||||
/* keine Reaktion, damit sich das Dokument nicht ändert */
|
||||
} else if (xhttp.status == 0) {
|
||||
alert("Server closed the connection abruptly!");
|
||||
UpdatePage();
|
||||
} else {
|
||||
alert(xhttp.status + " Error!\n" + xhttp.responseText);
|
||||
UpdatePage();
|
||||
}
|
||||
}
|
||||
};
|
||||
xhttp.open("GET", stringota, true);
|
||||
xhttp.send();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
function setpath() {
|
||||
var nameneu = document.getElementById("newfile").value;
|
||||
nameneu = nameneu.split(/[\\\/]/).pop();
|
||||
document.getElementById("filepath").value = nameneu;
|
||||
document.getElementById("upload").disabled = false;
|
||||
}
|
||||
|
||||
|
||||
function upload() {
|
||||
var xhttp = new XMLHttpRequest();
|
||||
|
||||
var filePath = document.getElementById("filepath").value;
|
||||
var upload_path = "/upload/firmware/" + filePath;
|
||||
var fileInput = document.getElementById("newfile").files;
|
||||
|
||||
/* first delete the old firmware */
|
||||
xhttp.onreadystatechange = function() {
|
||||
if (xhttp.readyState == 4) {
|
||||
if (xhttp.status == 200) {
|
||||
/* keine Reaktion, damit sich das Dokument nicht ändert */
|
||||
} else if (xhttp.status == 0) {
|
||||
alert("Server closed the connection abruptly!");
|
||||
UpdatePage();
|
||||
} else {
|
||||
alert(xhttp.status + " Error!\n" + xhttp.responseText);
|
||||
UpdatePage();
|
||||
}
|
||||
}
|
||||
};
|
||||
var _toDo = basepath + "/ota?delete=" + filePath;
|
||||
xhttp.open("GET", _toDo, false);
|
||||
xhttp.send();
|
||||
/* ----------------------------- */
|
||||
|
||||
|
||||
/* Max size of an individual file. Make sure this
|
||||
* value is same as that set in file_server.c */
|
||||
var MAX_FILE_SIZE = 6000*1024;
|
||||
var MAX_FILE_SIZE_STR = "6MB";
|
||||
|
||||
if (fileInput.length == 0) {
|
||||
alert("No file selected!");
|
||||
} else if (filePath.length == 0) {
|
||||
alert("File path on server is not set!");
|
||||
} else if (filePath.indexOf(' ') >= 0) {
|
||||
alert("File path on server cannot have spaces!");
|
||||
} else if (filePath[filePath.length-1] == '/') {
|
||||
alert("File name not specified after path!");
|
||||
} else if (fileInput[0].size > MAX_FILE_SIZE) {
|
||||
alert("File size must be less than " + MAX_FILE_SIZE_STR + "!");
|
||||
} else {
|
||||
document.getElementById("newfile").disabled = true;
|
||||
document.getElementById("filepath").disabled = true;
|
||||
document.getElementById("upload").disabled = true;
|
||||
|
||||
xhttp.onreadystatechange = function() {
|
||||
if (xhttp.readyState == 4) {
|
||||
if (xhttp.status == 200) {
|
||||
alert("Upload successfull!")
|
||||
// document.reload();
|
||||
document.getElementById("reboot").disabled = false;
|
||||
document.getElementById("doUpdate").disabled = false;
|
||||
} else if (xhttp.status == 0) {
|
||||
alert("Server closed the connection abruptly!");
|
||||
UpdatePage();
|
||||
} else {
|
||||
alert(xhttp.status + " Error!\n" + xhttp.responseText);
|
||||
UpdatePage();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var file = fileInput[0];
|
||||
xhttp.open("POST", upload_path, true);
|
||||
xhttp.send(file);
|
||||
}
|
||||
}
|
||||
|
||||
init();
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,7 +1,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<link rel="icon" href="data:,">
|
||||
<title>jomjol - AI on the edge</title>
|
||||
<title>AI on the edge</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<script type="text/javascript">
|
||||
|
||||
@@ -86,8 +86,6 @@ function ParseConfig() {
|
||||
ParamAddValue(param, catname, "CNNGoodThreshold", 1);
|
||||
ParamAddValue(param, catname, "LogImageLocation");
|
||||
ParamAddValue(param, catname, "LogfileRetentionInDays");
|
||||
// ParamAddValue(param, catname, "ModelInputSize", 2);
|
||||
|
||||
|
||||
var catname = "Analog";
|
||||
category[catname] = new Object();
|
||||
@@ -97,7 +95,6 @@ function ParseConfig() {
|
||||
ParamAddValue(param, catname, "Model");
|
||||
ParamAddValue(param, catname, "LogImageLocation");
|
||||
ParamAddValue(param, catname, "LogfileRetentionInDays");
|
||||
// ParamAddValue(param, catname, "ModelInputSize", 2);
|
||||
|
||||
var catname = "PostProcessing";
|
||||
category[catname] = new Object();
|
||||
@@ -236,9 +233,9 @@ function ParseConfigParamAll(_aktline, _catname){
|
||||
let [isCom, input] = isCommented(_input);
|
||||
var linesplit = ZerlegeZeile(input);
|
||||
ParamExtractValueAll(param, linesplit, _catname, _aktline, isCom);
|
||||
if (!isCom && (linesplit.length == 5) && (_catname == 'Digits'))
|
||||
if (!isCom && (linesplit.length >= 5) && (_catname == 'Digits'))
|
||||
ExtractROIs(input, "digit");
|
||||
if (!isCom && (linesplit.length == 5) && (_catname == 'Analog'))
|
||||
if (!isCom && (linesplit.length >= 5) && (_catname == 'Analog'))
|
||||
ExtractROIs(input, "analog");
|
||||
if (!isCom && (linesplit.length == 3) && (_catname == 'Alignment'))
|
||||
{
|
||||
@@ -398,6 +395,7 @@ function WriteConfigININew()
|
||||
text = text + " " + NUMBERS[_roi]["digit"][_roiddet]["y"];
|
||||
text = text + " " + NUMBERS[_roi]["digit"][_roiddet]["dx"];
|
||||
text = text + " " + NUMBERS[_roi]["digit"][_roiddet]["dy"];
|
||||
text = text + " " + NUMBERS[_roi]["digit"][_roiddet]["CCW"];
|
||||
config_split.push(text);
|
||||
}
|
||||
}
|
||||
@@ -416,6 +414,7 @@ function WriteConfigININew()
|
||||
text = text + " " + NUMBERS[_roi]["analog"][_roiddet]["y"];
|
||||
text = text + " " + NUMBERS[_roi]["analog"][_roiddet]["dx"];
|
||||
text = text + " " + NUMBERS[_roi]["analog"][_roiddet]["dy"];
|
||||
text = text + " " + NUMBERS[_roi]["analog"][_roiddet]["CCW"];
|
||||
config_split.push(text);
|
||||
}
|
||||
}
|
||||
@@ -484,6 +483,9 @@ function ExtractROIs(_aktline, _type){
|
||||
abc["dx"] = linesplit[3];
|
||||
abc["dy"] = linesplit[4];
|
||||
abc["ar"] = parseFloat(linesplit[3]) / parseFloat(linesplit[4]);
|
||||
abc["CCW"] = "false";
|
||||
if (linesplit.length >= 6)
|
||||
abc["CCW"] = linesplit[5];
|
||||
}
|
||||
|
||||
|
||||
@@ -712,7 +714,7 @@ function DeleteNUMBER(_delte){
|
||||
return "";
|
||||
}
|
||||
|
||||
function CreateROI(_number, _type, _pos, _roinew, _x, _y, _dx, _dy){
|
||||
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)
|
||||
@@ -735,6 +737,7 @@ function CreateROI(_number, _type, _pos, _roinew, _x, _y, _dx, _dy){
|
||||
_ret["dx"] = _dx;
|
||||
_ret["dy"] = _dy;
|
||||
_ret["ar"] = _dx / _dy;
|
||||
_ret["CCW"] = _CCW;
|
||||
|
||||
NUMBERS[_indexnumber][_type].splice(_pos+1, 0, _ret);
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<html style="width: fit-content">
|
||||
<head>
|
||||
<link rel="icon" href="favicon.ico" type="image/x-icon">
|
||||
<title>jomjol - AI on the edge</title>
|
||||
<title>AI on the edge</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
|
||||
100
sd-card/html/style.css
Normal file
100
sd-card/html/style.css
Normal file
@@ -0,0 +1,100 @@
|
||||
body, html {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-height: 800px;
|
||||
margin: 0px 0px 0px 2px;
|
||||
padding: 0;
|
||||
font-family: arial;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.main {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.iframe {
|
||||
flex-grow: 1;
|
||||
margin: 5px 7px 4px 0px;
|
||||
padding: 0;
|
||||
border: 2px solid black;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
background-color: #333;
|
||||
width:1000px;
|
||||
}
|
||||
|
||||
li {
|
||||
float: left;
|
||||
font-family: arial;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
li a, .dropbtn {
|
||||
display: inline-block;
|
||||
color: white;
|
||||
text-align: center;
|
||||
padding: 14px 16px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
li a:hover, .dropdown:hover .dropbtn {
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
li.dropdown {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.dropdown-content {
|
||||
display: none;
|
||||
position: absolute;
|
||||
background-color: #f9f9f9;
|
||||
min-width: 160px;
|
||||
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
|
||||
z-index: 1;
|
||||
font-family: arial;
|
||||
}
|
||||
|
||||
.dropdown-content a {
|
||||
color: black;
|
||||
padding: 12px 16px;
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.dropdown-content a:hover {
|
||||
color: white;
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
.dropdown:hover .dropdown-content {
|
||||
display: block;
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
15.1.0
|
||||
16.4.1
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
<table class="tg">
|
||||
<tr>
|
||||
<td class="tg-1" rowspan="9"><div id="img"></div></td>
|
||||
<td class="tg-1" rowspan="9" style="vertical-align: top"><div id="img"></div></td>
|
||||
<th class="th">Value:</th>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -57,6 +57,8 @@
|
||||
<td class="tg-3">
|
||||
<div id="timestamp" ></div>
|
||||
<div id="statusflow" ></div>
|
||||
<div id="cputemp" ></div>
|
||||
<div id="rssi" ></div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -83,6 +85,8 @@ function addZero(i) {
|
||||
$('#img').html('<img src="/img_tmp/alg_roi.jpg" style="max-height:555px; display:block; margin-left:auto; margin-right:auto;"></img>');
|
||||
$('#timestamp').html("Last Page Refresh:" + (h + ":" + m + ":" + s));
|
||||
loadStatus();
|
||||
loadCPUTemp();
|
||||
loadRSSI();
|
||||
refresh();
|
||||
});
|
||||
|
||||
@@ -94,10 +98,10 @@ function refresh() {
|
||||
var h = addZero(d.getHours());
|
||||
var m = addZero(d.getMinutes());
|
||||
var s = addZero(d.getSeconds());
|
||||
|
||||
// reassign the url to be like alg_roi.jpg?timestamp=456784512 based on timestamp
|
||||
$('#img').html('<img src="/img_tmp/alg_roi.jpg?timestamp='+ timestamp +'"max-height:555px; display:block; margin-left:auto; margin-right:auto;"></img>');
|
||||
$('#timestamp').html("Last Page Refresh:" + (h + ":" + m + ":" + s));
|
||||
loadStatus();
|
||||
init();
|
||||
refresh();
|
||||
}, 300000);
|
||||
@@ -120,6 +124,32 @@ function refresh() {
|
||||
xhttp.send();
|
||||
}
|
||||
|
||||
function loadCPUTemp() {
|
||||
url = basepath + '/cputemp.html';
|
||||
var xhttp = new XMLHttpRequest();
|
||||
xhttp.onreadystatechange = function() {
|
||||
if (this.readyState == 4 && this.status == 200) {
|
||||
var _rsp = xhttp.responseText;
|
||||
$('#cputemp').html(_rsp);
|
||||
}
|
||||
}
|
||||
xhttp.open("GET", url, true);
|
||||
xhttp.send();
|
||||
}
|
||||
|
||||
function loadRSSI() {
|
||||
url = basepath + '/rssi.html';
|
||||
var xhttp = new XMLHttpRequest();
|
||||
xhttp.onreadystatechange = function() {
|
||||
if (this.readyState == 4 && this.status == 200) {
|
||||
var _rsp = xhttp.responseText;
|
||||
$('#rssi').html(_rsp);
|
||||
}
|
||||
}
|
||||
xhttp.open("GET", url, true);
|
||||
xhttp.send();
|
||||
}
|
||||
|
||||
function loadValue(_type, _div, _style) {
|
||||
url = basepath + '/wasserzaehler.html?all=true&type=' + _type;
|
||||
var xhttp = new XMLHttpRequest();
|
||||
@@ -167,6 +197,8 @@ function refresh() {
|
||||
loadValue("prevalue", "prevalue");
|
||||
loadValue("error", "error", "font-size:8px");
|
||||
loadStatus();
|
||||
loadCPUTemp();
|
||||
loadRSSI();
|
||||
}
|
||||
|
||||
init();
|
||||
|
||||
Reference in New Issue
Block a user