Преглед на файлове

release 15.1.0 (#2172)

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

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

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

* Fix timezone config parser (#2169)

* make sure to parse the whole config line

* fix crash on empty timezone parameter

---------

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

* Enhance ROI pages (#2161)

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

* renaming

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

* only allow editing space when box is checked

* fix sync check

* show inner frame on all ROIs

* cleanup

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

* checkbox position

* renaming

* renaming

* show inner frame and cross hairs on all ROIs

* update ROIs on ticking checkboxes

* show timezone hint

* fix deleting last ROI

* cleanup

---------

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

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

* restart timeout on progress, catch error

* .

---------

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

* BugFix #2167

* Release 15.1 preparations (#2171)

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update changelog

* Fix links to PR

* Formating

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

---------

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

---------

Co-authored-by: Frank Haverland <fspapaping@googlemail.com>
Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>
Co-authored-by: Slider0007 <jobbelle@gmx.net>
Co-authored-by: Slider0007 <115730895+Slider0007@users.noreply.github.com>
CaCO3 преди 2 години
родител
ревизия
7d33c3ee5f

+ 45 - 36
Changelog.md

@@ -1,59 +1,67 @@
-## [Unreleased]
-
-xxx
+## [15.1.0] - 2023-03-12
 
 
 ### Update Procedure
 ### Update Procedure
 
 
 Update Procedure see [online documentation](https://jomjol.github.io/AI-on-the-edge-device-docs/Installation/#update-ota-over-the-air)
 Update Procedure see [online documentation](https://jomjol.github.io/AI-on-the-edge-device-docs/Installation/#update-ota-over-the-air)
 
 
-:bangbang: Afterwards you should force-reload the Web Interface (usually Ctrl-F5 will do it).
-
-### Changes
+:bangbang: Afterwards you should force-reload the Web Interface (usually Ctrl-F5 will do it)!
 
 
-This release only migrates some parameters, see #2023 for details and a list of all parameter changes.
-The parameter migration happens automatically on the next startup. No user interaction is required.
-A backup of the config is stored on the SD-card as `config.bak`.
+:bangbang: Afterwards you should check your configuration for errors!
 
 
-Beside of the parameter change and the bugfix listed below, no changes are contained in this release!
+### Changes
 
 
-If you want to revert back to `v14` or earlier, you will have to revert the migration changes in `config.ini` manually!
+For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/v15.0.3...v15.1.0)
 
 
 #### Added
 #### Added
+- The Configuration page has now tooltips with enhanced documentation
+- MQTT:
+    - Added `GJ` (`gigajoule`) as an energy meter unit
+    - Removed State Class and unit from `raw` topic
+    - Various Improvements (Only send Homeassistant Discovery the first time we connect, ...) (https://github.com/jomjol/AI-on-the-edge-device/pull/2091
+- Added Expert Parameter to change CPU Clock from `160` to `240 Mhz`
+- SD card basic read/write check and a folder/file presence check at boot to indicate SD card issues or missing folders / files ([#2085](https://github.com/jomjol/AI-on-the-edge-device/pull/2085))
+- Simplified "WIFI roaming" by client triggered channel scan (AP switching at low RSSI) -> using expert parameter "RSSIThreshold" ([#2120](https://github.com/jomjol/AI-on-the-edge-device/pull/2120))
+- Log WLAN disconnect reason codes (see [WLAN disconnect reasons](https://jomjol.github.io/AI-on-the-edge-device-docs/WLAN-disconnect-reason))
+- Support of InfluxDB v2 ([#2004](https://github.com/jomjol/AI-on-the-edge-device/pull/2004))
 
 
--   Additional interface to InfluxDB Version 2 upwards
--   Updated the network and corrected problems with quantized version:
-  -   Hybrid CNN network to `dig-cont_0611_s3` 
-  -   Analog CNN network to `ana-cont-11.0.5` and `ana-clas100-1.5.7`
-  -   Digital CNN network to `dig-class100-1.6.0`
-
--   :bangbang:  Update Camera driver: contrast, brightness and saturation now working
-   
-    :bangbang:  **Attention**: this can effect old version as well, because there not all settings were effective!
-    
-- Option to change the CPU frequency (stability vs. speed)
-- Homeassistant: add GJ (giga joule)
-- Implementes "poor mans" wifi roaming to connect to the nearest access point
-- Additional startup checks (sd card, folder / file prescence, boot phase)
-- Internal updates (log file handling, boot phase)
 
 
 #### Changed
 #### Changed
-
--   [#2023](https://github.com/jomjol/AI-on-the-edge-device/pull/2023) Migrated Parameters
--   Removed old `Topic` parameter, it is not used anymore
--   Internal optimization of memory usage to enable new features
--   Improve MQTT
+- Updated models (tflite files), removed old versions (https://github.com/jomjol/AI-on-the-edge-device/pull/2089, https://github.com/jomjol/AI-on-the-edge-device/pull/2133)
+  :bangbang: **Attention:** Update your configuration!
+    -   Hybrid CNN network to `dig-cont_0611_s3` 
+    -   Analog CNN network to `ana-cont-11.0.5` and `ana-clas100-1.5.7`
+    -   Digital CNN network to `dig-class100-1.6.0`
+-   Various Web interface Improvements/Enhancements:
+    - Restructured Menu (Needs cache clearing to be applied)
+    - Enhanced `Previous Value` page
+    - Improved/faster Graph page
+    - Various minor improvements
+    - ROI config pages improvements
+    - Improved Backup Functionality
+- Added log file logs for Firmware Update
+- Improved memory management (moved various stuff to external PSRAM, https://github.com/jomjol/AI-on-the-edge-device/pull/2117)
+- Camera driver update: Support of contrast and saturation ([#2048](https://github.com/jomjol/AI-on-the-edge-device/pull/2048))   
+  :bangbang:  **Attention**: This could have impact to old configurations. Please check your configuration and potentially adapt parametrization, if detection is negativly affected.
+- Improved error handling and provide more verbose output in error cases during boot phase ([#2020](https://github.com/jomjol/AI-on-the-edge-device/pull/2020))
+- Red board LED is indicating more different errors and states (see [Status LED Blink Codes](https://jomjol.github.io/AI-on-the-edge-device-docs/StatusLED-BlinkCodes))
+- Logfile: Print start indication block after time is synced to indicate start in logfile after a cold boot
+- `Image Quality Index`: Limit lower input range to 8 to avoid system instabilities
 
 
 #### Fixed
 #### Fixed
+- Various minor fixes
+- Added State Class "measurement" to rate_per_time_unit
+- GPIO: Avoid MQTT publishing to empty topic when "MQTT enable" flag is not set
+- Fix timezone config parser
+- Remote Setup truncated long passwords (https://github.com/jomjol/AI-on-the-edge-device/issues/2167)
 -  Problem with timestamp in InfluxDB interface
 -  Problem with timestamp in InfluxDB interface
 
 
 #### Removed
 #### Removed
-
 -   n.a.
 -   n.a.
 
 
 
 
 ## [15.0.3] - 2023-02-28
 ## [15.0.3] - 2023-02-28
 
 
-**Parameter Migration**
+**Name: Parameter Migration**
 
 
 ### Update Procedure
 ### Update Procedure
 
 
@@ -93,7 +101,7 @@ If you want to revert back to `v14` or earlier, you will have to revert the migr
 
 
 ## [14.0.3] -2023-02-05
 ## [14.0.3] -2023-02-05
 
 
-**Stabilization and Improved User Experience**
+**Name: Stabilization and Improved User Experience**
 
 
 Thanks to over 80 Pull Requests from 6 contributors, we can anounce another great release with many many improvements and new features:
 Thanks to over 80 Pull Requests from 6 contributors, we can anounce another great release with many many improvements and new features:
 
 
@@ -147,7 +155,7 @@ For a full list of changes see [Full list of changes](https://github.com/jomjol/
 
 
 ## [13.0.8] - 2022-12-19
 ## [13.0.8] - 2022-12-19
 
 
-**Home Assistant MQTT Discovery Support**
+**Name: Home Assistant MQTT Discovery Support**
 
 
 ### Update Procedure see [online documentation](https://jomjol.github.io/AI-on-the-edge-device-docs/Installation/#update-ota-over-the-air)
 ### Update Procedure see [online documentation](https://jomjol.github.io/AI-on-the-edge-device-docs/Installation/#update-ota-over-the-air)
 
 
@@ -227,7 +235,7 @@ For a full list of changes see [Full list of changes](https://github.com/jomjol/
 
 
 ## [12.0.1] 2022-09-29
 ## [12.0.1] 2022-09-29
 
 
-Improve **u**ser e**x**perience 
+Name: Improve **u**ser e**x**perience 
 
 
 :bangbang: The release breaks a few things in ota update :bangbang:
 :bangbang: The release breaks a few things in ota update :bangbang:
 
 
@@ -895,6 +903,7 @@ External Illumination
 -   Initial Version
 -   Initial Version
 
 
 
 
+[15.1.0]: https://github.com/jomjol/AI-on-the-edge-device/compare/v15.0.3...v15.1.0
 [15.0.3]: https://github.com/jomjol/AI-on-the-edge-device/compare/v14.0.3...v15.0.3
 [15.0.3]: https://github.com/jomjol/AI-on-the-edge-device/compare/v14.0.3...v15.0.3
 [14.0.3]: https://github.com/jomjol/AI-on-the-edge-device/compare/v13.0.8...v14.0.3
 [14.0.3]: https://github.com/jomjol/AI-on-the-edge-device/compare/v13.0.8...v14.0.3
 [13.0.8]: https://github.com/jomjol/AI-on-the-edge-device/compare/v12.0.1...v13.0.8
 [13.0.8]: https://github.com/jomjol/AI-on-the-edge-device/compare/v12.0.1...v13.0.8

+ 3 - 1
code/components/jomjol_flowcontroll/ClassFlowPostProcessing.cpp

@@ -402,7 +402,7 @@ void ClassFlowPostProcessing::handleAllowNegativeRate(string _decsep, string _va
         _digit = _decsep.substr(0, _pospunkt);
         _digit = _decsep.substr(0, _pospunkt);
     else
     else
         _digit = "default";
         _digit = "default";
-
+  
     for (int j = 0; j < NUMBERS.size(); ++j)
     for (int j = 0; j < NUMBERS.size(); ++j)
     {
     {
         bool _rt = false;
         bool _rt = false;
@@ -841,6 +841,7 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
 
 
         if (!NUMBERS[j]->AllowNegativeRates)
         if (!NUMBERS[j]->AllowNegativeRates)
         {
         {
+            LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "handleAllowNegativeRate for device: " + NUMBERS[j]->name);
             if ((NUMBERS[j]->Value < NUMBERS[j]->PreValue))
             if ((NUMBERS[j]->Value < NUMBERS[j]->PreValue))
             {
             {
                 #ifdef SERIAL_DEBUG
                 #ifdef SERIAL_DEBUG
@@ -848,6 +849,7 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
                      NUMBERS[j]->PreValue-(2/pow(10, NUMBERS[j]->Nachkomma))
                      NUMBERS[j]->PreValue-(2/pow(10, NUMBERS[j]->Nachkomma))
                       ) ;
                       ) ;
                 #endif
                 #endif
+            
                 // Include inaccuracy of 0.2 for isExtendedResolution.
                 // Include inaccuracy of 0.2 for isExtendedResolution.
                 if (NUMBERS[j]->Value >= (NUMBERS[j]->PreValue-(2/pow(10, NUMBERS[j]->Nachkomma))) && NUMBERS[j]->isExtendedResolution) {
                 if (NUMBERS[j]->Value >= (NUMBERS[j]->PreValue-(2/pow(10, NUMBERS[j]->Nachkomma))) && NUMBERS[j]->isExtendedResolution) {
                     NUMBERS[j]->Value = NUMBERS[j]->PreValue;
                     NUMBERS[j]->Value = NUMBERS[j]->PreValue;

+ 7 - 2
code/components/jomjol_time_sntp/time_sntp.cpp

@@ -175,10 +175,15 @@ bool setupTime() {
 
 
     while (configFile.getNextLine(&line, disabledLine, eof) && 
     while (configFile.getNextLine(&line, disabledLine, eof) && 
             !configFile.isNewParagraph(line)) {
             !configFile.isNewParagraph(line)) {
-        splitted = ZerlegeZeile(line);
+        splitted = ZerlegeZeile(line, "=");
 
 
         if (toUpper(splitted[0]) == "TIMEZONE") {
         if (toUpper(splitted[0]) == "TIMEZONE") {
-            timeZone = splitted[1];
+            if (splitted.size() <= 1) { // parameter part is empty
+                timeZone = "";
+            }
+            else {
+                timeZone = splitted[1];
+            }
         }
         }
 
 
         if (toUpper(splitted[0]) == "TIMESERVER") {
         if (toUpper(splitted[0]) == "TIMESERVER") {

+ 9 - 9
code/main/softAP.cpp

@@ -212,55 +212,55 @@ esp_err_t config_ini_handler(httpd_req_t *req)
     {
     {
         ESP_LOGD(TAG, "Query: %s", _query);
         ESP_LOGD(TAG, "Query: %s", _query);
         
         
-        if (httpd_query_key_value(_query, "ssid", _valuechar, 30) == ESP_OK)
+        if (httpd_query_key_value(_query, "ssid", _valuechar, 100) == ESP_OK)
         {
         {
             ESP_LOGD(TAG, "ssid is found: %s", _valuechar);
             ESP_LOGD(TAG, "ssid is found: %s", _valuechar);
             ssid = UrlDecode(std::string(_valuechar));
             ssid = UrlDecode(std::string(_valuechar));
         }
         }
 
 
-        if (httpd_query_key_value(_query, "pwd", _valuechar, 30) == ESP_OK)
+        if (httpd_query_key_value(_query, "pwd", _valuechar, 100) == ESP_OK)
         {
         {
             ESP_LOGD(TAG, "pwd is found: %s", _valuechar);
             ESP_LOGD(TAG, "pwd is found: %s", _valuechar);
             pwd = UrlDecode(std::string(_valuechar));
             pwd = UrlDecode(std::string(_valuechar));
         }
         }
 
 
-        if (httpd_query_key_value(_query, "ssid", _valuechar, 30) == ESP_OK)
+        if (httpd_query_key_value(_query, "ssid", _valuechar, 100) == ESP_OK)
         {
         {
             ESP_LOGD(TAG, "ssid is found: %s", _valuechar);
             ESP_LOGD(TAG, "ssid is found: %s", _valuechar);
             ssid = UrlDecode(std::string(_valuechar));
             ssid = UrlDecode(std::string(_valuechar));
         }
         }
 
 
-        if (httpd_query_key_value(_query, "hn", _valuechar, 30) == ESP_OK)
+        if (httpd_query_key_value(_query, "hn", _valuechar, 100) == ESP_OK)
         {
         {
             ESP_LOGD(TAG, "hostname is found: %s", _valuechar);
             ESP_LOGD(TAG, "hostname is found: %s", _valuechar);
             hn = UrlDecode(std::string(_valuechar));
             hn = UrlDecode(std::string(_valuechar));
         }
         }
 
 
-        if (httpd_query_key_value(_query, "ip", _valuechar, 30) == ESP_OK)
+        if (httpd_query_key_value(_query, "ip", _valuechar, 100) == ESP_OK)
         {
         {
             ESP_LOGD(TAG, "ip is found: %s", _valuechar);
             ESP_LOGD(TAG, "ip is found: %s", _valuechar);
             ip = UrlDecode(std::string(_valuechar));
             ip = UrlDecode(std::string(_valuechar));
         }
         }
 
 
-        if (httpd_query_key_value(_query, "gw", _valuechar, 30) == ESP_OK)
+        if (httpd_query_key_value(_query, "gw", _valuechar, 100) == ESP_OK)
         {
         {
             ESP_LOGD(TAG, "gateway is found: %s", _valuechar);
             ESP_LOGD(TAG, "gateway is found: %s", _valuechar);
             gw = UrlDecode(std::string(_valuechar));
             gw = UrlDecode(std::string(_valuechar));
         }
         }
 
 
-        if (httpd_query_key_value(_query, "nm", _valuechar, 30) == ESP_OK)
+        if (httpd_query_key_value(_query, "nm", _valuechar, 100) == ESP_OK)
         {
         {
             ESP_LOGD(TAG, "netmask is found: %s", _valuechar);
             ESP_LOGD(TAG, "netmask is found: %s", _valuechar);
             nm = UrlDecode(std::string(_valuechar));
             nm = UrlDecode(std::string(_valuechar));
         }
         }
 
 
-        if (httpd_query_key_value(_query, "dns", _valuechar, 30) == ESP_OK)
+        if (httpd_query_key_value(_query, "dns", _valuechar, 100) == ESP_OK)
         {
         {
             ESP_LOGD(TAG, "dns is found: %s", _valuechar);
             ESP_LOGD(TAG, "dns is found: %s", _valuechar);
             dns = UrlDecode(std::string(_valuechar));
             dns = UrlDecode(std::string(_valuechar));
         }
         }
 
 
-        if (httpd_query_key_value(_query, "rssithreshold", _valuechar, 30) == ESP_OK)
+        if (httpd_query_key_value(_query, "rssithreshold", _valuechar, 100) == ESP_OK)
         {
         {
             ESP_LOGD(TAG, "rssithreshold is found: %s", _valuechar);
             ESP_LOGD(TAG, "rssithreshold is found: %s", _valuechar);
             rssithreshold = UrlDecode(std::string(_valuechar));
             rssithreshold = UrlDecode(std::string(_valuechar));

+ 27 - 0
code/test/components/jomjol-flowcontroll/test_flow_pp_negative.cpp

@@ -76,3 +76,30 @@ void testNegative() {
 
 
 }
 }
 
 
+/**
+ * @brief Fehlerberichte aus Issues
+ * 
+ */
+void testNegative_Issues() {
+        // Ohne decimal_shift
+        std::vector<float> digits = { 2.0, 2.0, 0.0, 1.0, 7.2, 9.0, 8.0};
+        std::vector<float> analogs = { };
+        double preValue_extended = 22018.080;
+        double preValue = 22018.08;
+        
+        const char* expected = "22017.98";
+
+        // https://github.com/jomjol/AI-on-the-edge-device/issues/2145#issuecomment-1461899094
+        // extendResolution=false
+        // value < preValue
+        // Prüfung eingeschaltet => Fehler
+        preValue = 22018.08; // zu groß
+        UnderTestPost* underTestPost = init_do_flow(analogs, digits, Digital100, false, false, -2);
+        setAllowNegatives(underTestPost, false);
+        setPreValue(underTestPost, preValue_extended);
+        std::string result = process_doFlow(underTestPost);
+        TEST_ASSERT_EQUAL_STRING("Neg. Rate - Read:  - Raw: 22017.98 - Pre: 22018.08 ", underTestPost->getReadoutError().c_str());
+        TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
+        delete underTestPost;
+
+}

+ 4 - 4
code/test/test_suite_flowcontroll.cpp

@@ -108,9 +108,9 @@ extern "C" void app_main()
   esp_log_level_set("*", ESP_LOG_DEBUG);        // set all components to ERROR level
   esp_log_level_set("*", ESP_LOG_DEBUG);        // set all components to ERROR level
 
 
   UNITY_BEGIN();
   UNITY_BEGIN();
-  
-    RUN_TEST(testNegative);
-  
+    RUN_TEST(testNegative_Issues);
+  /* RUN_TEST(testNegative);
+   
     RUN_TEST(test_analogToDigit_Standard);
     RUN_TEST(test_analogToDigit_Standard);
     RUN_TEST(test_analogToDigit_Transition);
     RUN_TEST(test_analogToDigit_Transition);
     RUN_TEST(test_doFlowPP);
     RUN_TEST(test_doFlowPP);
@@ -121,6 +121,6 @@ extern "C" void app_main()
 
 
     // getReadoutRawString test
     // getReadoutRawString test
     RUN_TEST(test_getReadoutRawString);
     RUN_TEST(test_getReadoutRawString);
-  
+  */
   UNITY_END();
   UNITY_END();
 }
 }

BIN
sd-card/config/dig-class100_0160_s2_q.tflite


+ 17 - 3
sd-card/html/backup.html

@@ -122,13 +122,13 @@ function fetchFiles(urls, filesData, index, retry, zipFilename) {
         xhr.timeout = 5000; // time in milliseconds
         xhr.timeout = 5000; // time in milliseconds
     }
     }
     else if (retry == 2) { // longer timeout
     else if (retry == 2) { // longer timeout
-        xhr.timeout = 20000; // time in milliseconds
+        xhr.timeout = 10000; // time in milliseconds
     }
     }
     else if (retry == 3) { // longer timeout
     else if (retry == 3) { // longer timeout
-        xhr.timeout = 30000; // time in milliseconds
+        xhr.timeout = 20000; // time in milliseconds
     }
     }
     else { // very long timeout
     else { // very long timeout
-        xhr.timeout = 60000; // time in milliseconds
+        xhr.timeout = 30000; // time in milliseconds
     }
     }
 
 
     xhr.onload = () => { // Request finished
     xhr.onload = () => { // Request finished
@@ -146,6 +146,20 @@ function fetchFiles(urls, filesData, index, retry, zipFilename) {
         }
         }
     };
     };
 
 
+    xhr.onprogress = (e) => { // XMLHttpRequest progress ... extend timeout
+        xhr.timeout = xhr.timeout + 500;
+    };
+
+    xhr.onerror = (e) => { // XMLHttpRequest error loading
+        console.log("Error on fetching " + url + "!");
+        if (retry > 5) {
+            setStatus("<span style=\"color: red\">Backup failed, please restart the device and try again!</span>");
+        }
+        else {
+            fetchFiles(urls, filesData, index, retry+1, zipFilename);
+        }
+    };
+
     xhr.ontimeout = (e) => { // XMLHttpRequest timed out
     xhr.ontimeout = (e) => { // XMLHttpRequest timed out
         console.log("Timeout on fetching " + url + "!");
         console.log("Timeout on fetching " + url + "!");
         if (retry > 5) {
         if (retry > 5) {

+ 1 - 1
sd-card/html/common.js

@@ -1,7 +1,7 @@
  
  
 /* The UI can also be run locally, but you have to set the IP of your devide accordingly.
 /* The UI can also be run locally, but you have to set the IP of your devide accordingly.
  * And you also might have to disable CORS in your webbrowser! */
  * And you also might have to disable CORS in your webbrowser! */
-var domainname_for_testing = "192.168.178.62";
+var domainname_for_testing = "192.168.1.153";
 
 
 
 
 
 

+ 60 - 21
sd-card/html/edit_analog.html

@@ -85,9 +85,6 @@ th, td {
             <tr>
             <tr>
                 <class id="Numbers_text" style="color:black;"><b>Number: </b></class>
                 <class id="Numbers_text" style="color:black;"><b>Number: </b></class>
                 <select id="Numbers_value1" onchange="numberChanged()">
                 <select id="Numbers_value1" onchange="numberChanged()">
-                    <option value="0" selected>default</option>
-                    <option value="1" >NT</option>
-                    <option value="2" >HT</option>
                 </select>
                 </select>
                 <input class="move" type="submit" id="renameNumber" name="renameNumber" onclick="renameNumber()" value="Rename">  
                 <input class="move" type="submit" id="renameNumber" name="renameNumber" onclick="renameNumber()" value="Rename">  
                 <input class="move" type="submit" id="newNumber" name="newNumber" onclick="newNumber()" value="New">  
                 <input class="move" type="submit" id="newNumber" name="newNumber" onclick="newNumber()" value="New">  
@@ -105,8 +102,6 @@ th, td {
 	  <tr>
 	  <tr>
 		<td>
 		<td>
 			<select id="index" name="index" onchange="ChangeSelection()" tabindex=1>
 			<select id="index" name="index" onchange="ChangeSelection()" tabindex=1>
-			  <option value="0" selected>ROI 0</option>
-			  <option value="1" >ROI 1</option>
             </select>
             </select>
 		</td>
 		</td>
 		<td>                
 		<td>                
@@ -120,16 +115,16 @@ th, td {
 	  <tr>
 	  <tr>
         <td>x: <input type="number" name="refx" id="refx" step=1 onchange="valuemanualchanged()" tabindex=2></td>	  
         <td>x: <input type="number" name="refx" id="refx" step=1 onchange="valuemanualchanged()" tabindex=2></td>	  
 		<td>Δx: <input type="number" name="refdx" id="refdx" step=1 onchange="valuemanualchangeddx()" tabindex=4></td>
 		<td>Δx: <input type="number" name="refdx" id="refdx" step=1 onchange="valuemanualchangeddx()" tabindex=4></td>
-		<td><label for="lockAR"> Lock aspect ratio: </label><input type="checkbox" id="lockAR" name="lockAR" value="1" onclick="changelockAR()" checked tabindex=6></td>
+		<td><input type="checkbox" id="lockAspectRatio" name="lockAspectRatio" value="1" onclick="changelockAspectRatio()" checked tabindex=6><label for="lockAspectRatio"> Lock aspect ratio</label></td>
 	  </tr>
 	  </tr>
 	  <tr>
 	  <tr>
 		<td>y: <input type="number" name="refy" id="refy" step=1 onchange="valuemanualchanged()" tabindex=3></td>	
 		<td>y: <input type="number" name="refy" id="refy" step=1 onchange="valuemanualchanged()" tabindex=3></td>	
 		<td>Δy: <input type="number" name="refdy" id="refdy" step=1 onchange="valuemanualchanged()" tabindex=5></td>
 		<td>Δy: <input type="number" name="refdy" id="refdy" step=1 onchange="valuemanualchanged()" tabindex=5></td>
-		<td><label for="lockSizes"> Synchronize Δx and Δy between ROIs</label><input type="checkbox" id="lockSizes" name="lockSizes" value="1" onclick="changelockSizes()" checked tabindex=7></td>
+		<td><input type="checkbox" id="lockSizes" name="lockSizes" value="1" onclick="changelockSizes()" checked tabindex=7><label for="lockSizes"> Synchronize Δx and Δy between ROIs</label></td>
 	  </tr>
 	  </tr>
       <tr>
       <tr>
         <td colspan="2"></td>
         <td colspan="2"></td>
-        <td><label for="CCW"> Counter-Clockwise Rotation: </label><input type="checkbox" id="CCW" name="CCW" value="0" onclick="changeCCW()" unchecked tabindex=8></td>
+        <td><input type="checkbox" id="CCW" name="CCW" value="0" onclick="changeCCW()" unchecked tabindex=8><label for="CCW"> Counter-Clockwise Rotation: </label></td>
       </tr>
       </tr>
 	</table>			 
 	</table>			 
 </div>	 
 </div>	 
@@ -159,8 +154,8 @@ th, td {
             cofcat,
             cofcat,
             param,
             param,
             enhanceCon = false;
             enhanceCon = false;
-            lockAR = true;
-            lockSizes = true;
+            lockAspectRatio = true;
+            lockSizes = false;
             domainname = getDomainname();
             domainname = getDomainname();
 
 
     
     
@@ -222,6 +217,7 @@ function deleteROI(){
         aktindex = ROIInfo.length - 1;
         aktindex = ROIInfo.length - 1;
     }
     }
     UpdateROIs();
     UpdateROIs();
+    draw();
 }
 }
 
 
 function newROI(){
 function newROI(){
@@ -259,12 +255,13 @@ function moveNext(){
     UpdateROIs();    
     UpdateROIs();    
 }
 }
 
 
-function changelockAR(){
-    lockAR = document.getElementById("lockAR").checked;
+function changelockAspectRatio(){
+    lockAspectRatio = document.getElementById("lockAspectRatio").checked;
 }
 }
 
 
 function changelockSizes(){
 function changelockSizes(){
     lockSizes = document.getElementById("lockSizes").checked;
     lockSizes = document.getElementById("lockSizes").checked;
+    UpdateROIs(); 
 }
 }
 
 
 function changeCCW(){
 function changeCCW(){
@@ -283,7 +280,7 @@ function changeCCW(){
 
 
 function ChangeSelection(){
 function ChangeSelection(){
     aktindex = parseInt(document.getElementById("index").value);
     aktindex = parseInt(document.getElementById("index").value);
-//    lockAR = true;
+//    lockAspectRatio = true;
     UpdateROIs();
     UpdateROIs();
 }
 }
 
 
@@ -317,6 +314,7 @@ function UpdateROIs(_sel){
         document.getElementById("newROI").disabled = false;
         document.getElementById("newROI").disabled = false;
         document.getElementById("deleteROI").disabled = true;
         document.getElementById("deleteROI").disabled = true;
         document.getElementById("index").disabled = true;
         document.getElementById("index").disabled = true;
+        document.getElementById("saveroi").disabled = true;
         document.getElementById("renameROI").disabled = true;
         document.getElementById("renameROI").disabled = true;
         document.getElementById("moveNext").disabled = true;
         document.getElementById("moveNext").disabled = true;
         document.getElementById("movePrevious").disabled = true;
         document.getElementById("movePrevious").disabled = true;
@@ -361,7 +359,7 @@ function UpdateROIs(_sel){
         document.getElementById("moveNext").disabled = true;
         document.getElementById("moveNext").disabled = true;
     }  
     }  
     
     
-    document.getElementById("lockAR").checked = lockAR;
+    document.getElementById("lockAspectRatio").checked = lockAspectRatio;
     document.getElementById("lockSizes").checked = lockSizes;
     document.getElementById("lockSizes").checked = lockSizes;
        
        
     document.getElementById("refx").value = ROIInfo[aktindex]["x"];
     document.getElementById("refx").value = ROIInfo[aktindex]["x"];
@@ -419,6 +417,29 @@ function UpdateROIs(_sel){
             param = getConfigParameters(); 
             param = getConfigParameters(); 
             cofcat = getConfigCategory();
             cofcat = getConfigCategory();
             UpdateNUMBERS();
             UpdateNUMBERS();
+
+			/* Check if the ROIs have same dy and dx. If so, tick the sync checkbox */
+            var all_dx_dy_Identical = true;
+            if (ROIInfo.length > 1) {
+                for (var i = 1; i < (ROIInfo.length); ++i) { // 2nd .. last ROI
+                    if (parseInt(ROIInfo[i].dx) != parseInt(ROIInfo[0].dx) ||
+                        parseInt(ROIInfo[i].dy) != parseInt(ROIInfo[0].dy)) { 
+                        all_dx_dy_Identical = false;
+						break;
+                    }
+                }
+			}
+
+            if (all_dx_dy_Identical) {
+                lockSizes = true;
+                console.log("All ROI have the same dX and dY, ticking the sync checkbox!");
+                document.getElementById("lockSizes").checked = lockSizes;
+            }
+            else {
+                console.log("Not all ROI have the same dX and dY, unticking the sync checkbox!");
+            }
+
+
             drawImage();
             drawImage();
             draw();
             draw();
         }
         }
@@ -510,11 +531,17 @@ function drawTextBG(context, txt, x, y, padding) {
     if (typeof ROIInfo === 'undefined') { // During init, ROIInfo is not defined yet
     if (typeof ROIInfo === 'undefined') { // During init, ROIInfo is not defined yet
         return;
         return;
     }
     }
+
+
     
     
         var canvas = document.getElementById('canvas');
         var canvas = document.getElementById('canvas');
         var context = canvas.getContext('2d');
         var context = canvas.getContext('2d');
         context.drawImage(imageObj, 0, 0);
         context.drawImage(imageObj, 0, 0);
 
 
+        if (ROIInfo.length == 0) {
+            return;
+        } 
+
         context.font = "15px Arial";
         context.font = "15px Arial";
         context.fillStyle = "red";
         context.fillStyle = "red";
         context.textAlign = "center";
         context.textAlign = "center";
@@ -540,7 +567,7 @@ function drawTextBG(context, txt, x, y, padding) {
             {
             {
                 if (_nb != _number)
                 if (_nb != _number)
                 {
                 {
-                    lw = 1;
+                    lw = 2;
                     context.lineWidth = lw;
                     context.lineWidth = lw;
                     context.strokeStyle = "#990000";
                     context.strokeStyle = "#990000";
                     var x0 = parseInt(ROIInfo[_nb].x) - parseInt(lw/2);
                     var x0 = parseInt(ROIInfo[_nb].x) - parseInt(lw/2);
@@ -549,12 +576,24 @@ function drawTextBG(context, txt, x, y, padding) {
                     var dy = parseInt(ROIInfo[_nb].dy) + parseInt(lw);
                     var dy = parseInt(ROIInfo[_nb].dy) + parseInt(lw);
                     context.strokeRect(x0, y0, dx, dy);
                     context.strokeRect(x0, y0, dx, dy);
                     drawTextBG(context, ROIInfo[_nb]["name"], x0+dx/2-0.5, y0-13, 5);
                     drawTextBG(context, ROIInfo[_nb]["name"], x0+dx/2-0.5, y0-13, 5);
-                }
 
 
+                    lw = 1;
+                    var x0 = parseInt(ROIInfo[_nb].x) - parseInt(lw/2);
+                    var y0 = parseInt(ROIInfo[_nb].y) - parseInt(lw/2);
+                    var dx = parseInt(ROIInfo[_nb].dx) + parseInt(lw);
+                    var dy = parseInt(ROIInfo[_nb].dy) + parseInt(lw);
+                    context.strokeRect(x0, y0, dx, dy); 
+                    context.lineWidth = lw;
+                    context.beginPath();
+                    context.arc(x0+dx/2, y0+dy/2, dx/2, 0, 2 * Math.PI);
+                    context.moveTo(x0+dx/2, y0);
+                    context.lineTo(x0+dx/2, y0+dy);
+                    context.moveTo(x0, y0+dy/2);
+                    context.lineTo(x0+dx, y0+dy/2);
+                    context.stroke();  
+                }
             }
             }
 
 
-
-
             lw = 4
             lw = 4
             context.lineWidth = lw;
             context.lineWidth = lw;
             context.strokeStyle = "#FF0000";
             context.strokeStyle = "#FF0000";
@@ -622,7 +661,7 @@ function drawTextBG(context, txt, x, y, padding) {
             zw = getCoords(this)        
             zw = getCoords(this)        
 
 
 
 
-            if (lockAR) {
+            if (lockAspectRatio) {
                 rect.h = (e.pageY - zw.top) - rect.startY;
                 rect.h = (e.pageY - zw.top) - rect.startY;
                 rect.w = Math.round(rect.h * ROIInfo[aktindex]["ar"]);            }
                 rect.w = Math.round(rect.h * ROIInfo[aktindex]["ar"]);            }
             else {
             else {
@@ -657,7 +696,7 @@ function drawTextBG(context, txt, x, y, padding) {
         if (!drag) {
         if (!drag) {
             rect.w = document.getElementById("refdx").value;
             rect.w = document.getElementById("refdx").value;
             rect.h = document.getElementById("refdy").value;
             rect.h = document.getElementById("refdy").value;
-            if (lockAR) {
+            if (lockAspectRatio) {
                 rect.w = Math.round(rect.h * ROIInfo[aktindex]["ar"]);
                 rect.w = Math.round(rect.h * ROIInfo[aktindex]["ar"]);
                 document.getElementById("refdx").value = rect.w;
                 document.getElementById("refdx").value = rect.w;
             }
             }
@@ -672,7 +711,7 @@ function drawTextBG(context, txt, x, y, padding) {
         if (!drag) {
         if (!drag) {
             rect.w = document.getElementById("refdx").value;
             rect.w = document.getElementById("refdx").value;
             rect.h = document.getElementById("refdy").value;
             rect.h = document.getElementById("refdy").value;
-            if (lockAR) {
+            if (lockAspectRatio) {
                 rect.h = Math.round(rect.w / ROIInfo[aktindex]["ar"]);
                 rect.h = Math.round(rect.w / ROIInfo[aktindex]["ar"]);
                 document.getElementById("refdy").value = rect.h;
                 document.getElementById("refdy").value = rect.h;
             }
             }

+ 1 - 0
sd-card/html/edit_config_param.html

@@ -1309,6 +1309,7 @@ textarea {
 			</td>
 			</td>
 			<td>
 			<td>
 				<input type="text" id="System_TimeZone_value1">
 				<input type="text" id="System_TimeZone_value1">
+				<p>Use <a href="timezones.html" target="_blank">timezones.html</a> to find your correct settings.</p>
 			</td>
 			</td>
 			<td>$TOOLTIP_System_TimeZone</td>
 			<td>$TOOLTIP_System_TimeZone</td>
 		</tr>
 		</tr>

+ 84 - 18
sd-card/html/edit_digits.html

@@ -81,9 +81,6 @@ th, td {
             <tr>
             <tr>
                 <class id="Numbers_text" style="color:black;"><b>Number:</b> </class>
                 <class id="Numbers_text" style="color:black;"><b>Number:</b> </class>
                 <select id="Numbers_value1" onchange="numberChanged()">
                 <select id="Numbers_value1" onchange="numberChanged()">
-                    <option value="0" selected>default</option>
-                    <option value="1" >NT</option>
-                    <option value="2" >HT</option>
                 </select>
                 </select>
                 <input class="move" type="submit" id="renameNumber" name="renameNumber" onclick="renameNumber()" value="Rename">  
                 <input class="move" type="submit" id="renameNumber" name="renameNumber" onclick="renameNumber()" value="Rename">  
                 <input class="move" type="submit" id="newNumber" name="newNumber" onclick="newNumber()" value="New">  
                 <input class="move" type="submit" id="newNumber" name="newNumber" onclick="newNumber()" value="New">  
@@ -101,8 +98,6 @@ th, td {
 	  <tr>
 	  <tr>
 		<td>
 		<td>
 			<select id="index" name="index" onchange="ChangeSelection()" tabindex=1>
 			<select id="index" name="index" onchange="ChangeSelection()" tabindex=1>
-			  <option value="0" selected>ROI 0</option>
-			  <option value="1" >ROI 1</option>
 			</select>
 			</select>
 		</td>
 		</td>
 		<td>                
 		<td>                
@@ -115,7 +110,7 @@ th, td {
 	  <tr>
 	  <tr>
         <td>x: <input type="number" name="refx" id="refx" step=1 onchange="valuemanualchanged()" tabindex=2></td>	  
         <td>x: <input type="number" name="refx" id="refx" step=1 onchange="valuemanualchanged()" tabindex=2></td>	  
 		<td>Δx: <input type="number" name="refdx" id="refdx" step=1 onchange="valuemanualchangeddx()" tabindex=4></td>
 		<td>Δx: <input type="number" name="refdx" id="refdx" step=1 onchange="valuemanualchangeddx()" tabindex=4></td>
-		<td><input type="checkbox" id="lockAR" name="lockAR" value="1" onclick="changelockAR()" checked tabindex=6><label for="lockAR"> Lock aspect ratio </label></td>
+		<td><input type="checkbox" id="lockAspectRatio" name="lockAspectRatio" value="1" onclick="changelockAspectRatio()" checked tabindex=6><label for="lockAspectRatio"> Lock aspect ratio </label></td>
 	  </tr>
 	  </tr>
 	  <tr>
 	  <tr>
 		<td>y: <input type="number" name="refy" id="refy" step=1 onchange="valuemanualchanged()" tabindex=3></td>	
 		<td>y: <input type="number" name="refy" id="refy" step=1 onchange="valuemanualchanged()" tabindex=3></td>	
@@ -154,8 +149,8 @@ th, td {
             cofcat,
             cofcat,
             param,
             param,
             enhanceCon = false;
             enhanceCon = false;
-            lockAR = true;
-            lockSizes = true;
+            lockAspectRatio = true;
+            lockSizes = false;
             lockSpaceEquidistant = true;
             lockSpaceEquidistant = true;
             space = 3;
             space = 3;
             domainname = getDomainname();
             domainname = getDomainname();
@@ -269,12 +264,14 @@ function moveNext(){
     valuemanualchanged();
     valuemanualchanged();
 }
 }
 
 
-function changelockAR(){
-    lockAR = document.getElementById("lockAR").checked;
+function changelockAspectRatio(){
+    lockAspectRatio = document.getElementById("lockAspectRatio").checked;
 }
 }
 
 
 function changelockSizes(){
 function changelockSizes(){
     lockSizes = document.getElementById("lockSizes").checked;
     lockSizes = document.getElementById("lockSizes").checked;
+    UpdateROIs(); 
+    valuemanualchangedspace();
 
 
     if (!lockSizes) {
     if (!lockSizes) {
         firework.launch("For best results it is in most cases advised to keep the y, Δx and Δy identical!", 'warning', 10000);
         firework.launch("For best results it is in most cases advised to keep the y, Δx and Δy identical!", 'warning', 10000);
@@ -283,11 +280,18 @@ function changelockSizes(){
 
 
 function changeLockSpaceEquidistant(){
 function changeLockSpaceEquidistant(){
     lockSpaceEquidistant = document.getElementById("lockSpaceEquidistant").checked;
     lockSpaceEquidistant = document.getElementById("lockSpaceEquidistant").checked;
+    if (!lockSpaceEquidistant) {
+        document.getElementById("space").disabled = true;
+    }
+    else {
+        document.getElementById("space").disabled = false;
+    }
+    UpdateROIs(); 
 }
 }
 
 
 function ChangeSelection(){
 function ChangeSelection(){
     aktindex = parseInt(document.getElementById("index").value);
     aktindex = parseInt(document.getElementById("index").value);
-//    lockAR = true;
+//    lockAspectRatio = true;
     UpdateROIs();
     UpdateROIs();
 }
 }
 
 
@@ -367,10 +371,16 @@ function UpdateROIs(_sel){
         document.getElementById("moveNext").disabled = true;
         document.getElementById("moveNext").disabled = true;
     }  
     }  
     
     
-    document.getElementById("lockAR").checked = lockAR;
+    document.getElementById("lockAspectRatio").checked = lockAspectRatio;
     document.getElementById("lockSizes").checked = lockSizes;
     document.getElementById("lockSizes").checked = lockSizes;
     document.getElementById("lockSpaceEquidistant").checked = lockSpaceEquidistant;
     document.getElementById("lockSpaceEquidistant").checked = lockSpaceEquidistant;
     document.getElementById("space").value = space;
     document.getElementById("space").value = space;
+    if (!lockSpaceEquidistant) {
+        document.getElementById("space").disabled = true;
+    }
+    else {
+        document.getElementById("space").disabled = false;
+    }
        
        
     document.getElementById("refx").value = ROIInfo[aktindex]["x"];
     document.getElementById("refx").value = ROIInfo[aktindex]["x"];
     document.getElementById("refy").value = ROIInfo[aktindex]["y"];  
     document.getElementById("refy").value = ROIInfo[aktindex]["y"];  
@@ -423,8 +433,53 @@ function UpdateROIs(_sel){
             cofcat = getConfigCategory();
             cofcat = getConfigCategory();
             UpdateNUMBERS();
             UpdateNUMBERS();
 
 
-            space = ROIInfo[1].x - parseInt(ROIInfo[0].x) - parseInt(ROIInfo[0].dx);
-            document.getElementById("space").value = space;
+
+            /* Check if the ROIs are equidistant. Only if not, untick the checkbox */
+            if (ROIInfo.length > 1) {
+				var distanceROI0_to_ROI1 = parseInt(ROIInfo[1].x) - (parseInt(ROIInfo[0].x) + parseInt(ROIInfo[0].dx)); // Distance between 1st and 2nd ROI
+				//console.log("0->1: " + distanceROI0_to_ROI1);
+				for (var i = 1; i < (ROIInfo.length - 1); ++i) { // 2nd .. 2nd-last ROI
+					//console.log(i + "->" + i+1 + ": " + (parseInt(ROIInfo[i+1].x) - (parseInt(ROIInfo[i].x) + parseInt(ROIInfo[i].dx))));
+					if (distanceROI0_to_ROI1 != (parseInt(ROIInfo[i+1].x) - (parseInt(ROIInfo[i].x) + parseInt(ROIInfo[i].dx)))) {
+						console.log("Not equidistant, unticking the checkbox!");
+						lockSpaceEquidistant = false;
+    					document.getElementById("lockSpaceEquidistant").checked = lockSpaceEquidistant;
+                        if (!lockSpaceEquidistant) {
+                            document.getElementById("space").disabled = true;
+                        }
+                        else {
+                            document.getElementById("space").disabled = false;
+                        }
+						break;
+					}
+				}
+			}
+			/* Check if the ROIs have same y, dy and dx. If so, tick the sync checkbox */
+           var all_y_dx_dy_Identical = true;
+            if (ROIInfo.length > 1) {
+                for (var i = 1; i < (ROIInfo.length); ++i) { // 2nd .. last ROI
+                    if (parseInt(ROIInfo[i].y) != parseInt(ROIInfo[0].y) ||
+                        parseInt(ROIInfo[i].dx) != parseInt(ROIInfo[0].dx) ||
+                        parseInt(ROIInfo[i].dy) != parseInt(ROIInfo[0].dy)) { 
+                        all_y_dx_dy_Identical = false;
+						break;
+                    }
+                }
+			}
+
+            if (all_y_dx_dy_Identical) {
+                lockSizes = true;
+                console.log("All ROI have the same Y, dX and dY, ticking the sync checkbox!");
+                document.getElementById("lockSizes").checked = lockSizes;
+            }
+            else {
+                console.log("Not all ROI have the same Y, dX and dY, unticking the sync checkbox!");
+            }
+
+            if (ROIInfo.length > 1) {
+                space = ROIInfo[1].x - parseInt(ROIInfo[0].x) - parseInt(ROIInfo[0].dx);
+                document.getElementById("space").value = space;
+            }
 
 
             drawImage();
             drawImage();
             draw();
             draw();
@@ -558,8 +613,19 @@ function draw() {
                     var dy = parseInt(ROIInfo[_nb].dy) + parseInt(lw);
                     var dy = parseInt(ROIInfo[_nb].dy) + parseInt(lw);
                     context.strokeRect(x0, y0, dx, dy);
                     context.strokeRect(x0, y0, dx, dy);
                     drawTextBG(context, ROIInfo[_nb]["name"], x0+dx/2, y0-12, 5);
                     drawTextBG(context, ROIInfo[_nb]["name"], x0+dx/2, y0-12, 5);
-                }
 
 
+                    lw = 1
+                    var x0 = parseInt(ROIInfo[_nb].x) - parseInt(lw/2);
+                    var y0 = parseInt(ROIInfo[_nb].y) - parseInt(lw/2);
+                    var dx = parseInt(ROIInfo[_nb].dx) + parseInt(lw);
+                    var dy = parseInt(ROIInfo[_nb].dy) + parseInt(lw);
+                    context.lineWidth = lw;
+                    context.beginPath();
+                    context.moveTo(x0, y0+dy/2);
+                    context.lineTo(x0+dx, y0+dy/2);
+                    context.stroke();   
+                    context.strokeRect(x0+dx*0.2, y0+dy*0.2, dx*0.6, dy*0.6);
+                }
             }
             }
 
 
             lw = 4
             lw = 4
@@ -635,7 +701,7 @@ function draw() {
                 return;
                 return;
             }
             }
 
 
-            if (lockAR) {
+            if (lockAspectRatio) {
                 rect.h = (e.pageY - zw.top) - rect.startY;
                 rect.h = (e.pageY - zw.top) - rect.startY;
                 rect.w = Math.round(rect.h * ROIInfo[aktindex]["ar"]);            }
                 rect.w = Math.round(rect.h * ROIInfo[aktindex]["ar"]);            }
             else {
             else {
@@ -675,7 +741,7 @@ function draw() {
             rect.w = document.getElementById("refdx").value;
             rect.w = document.getElementById("refdx").value;
             rect.h = document.getElementById("refdy").value;
             rect.h = document.getElementById("refdy").value;
 
 
-            if (lockAR) {
+            if (lockAspectRatio) {
                 rect.w = Math.round(rect.h * ROIInfo[aktindex]["ar"]);
                 rect.w = Math.round(rect.h * ROIInfo[aktindex]["ar"]);
                 document.getElementById("refdx").value = rect.w;
                 document.getElementById("refdx").value = rect.w;
             }
             }
@@ -700,7 +766,7 @@ function draw() {
             rect.w = document.getElementById("refdx").value;
             rect.w = document.getElementById("refdx").value;
             rect.h = document.getElementById("refdy").value;
             rect.h = document.getElementById("refdy").value;
 
 
-            if (lockAR) {
+            if (lockAspectRatio) {
                 rect.h = Math.round(rect.w / ROIInfo[aktindex]["ar"]);
                 rect.h = Math.round(rect.w / ROIInfo[aktindex]["ar"]);
                 document.getElementById("refdy").value = rect.h;
                 document.getElementById("refdy").value = rect.h;
             }
             }