Update WebUI

This commit is contained in:
Slider0007
2023-05-01 14:19:31 +02:00
parent fc719da0ae
commit d7a507ca05
39 changed files with 3961 additions and 2529 deletions

View File

@@ -1,13 +1,12 @@
<!DOCTYPE html>
<html>
<html lang="en" xml:lang="en">
<head>
<link rel="icon" href="favicon.ico?v=$COMMIT_HASH" type="image/x-icon">
<title>Backup/Restore Configuration</title>
<meta charset="utf-8">
<meta charset="UTF-8" />
<style>
h1 {font-size: 2em;}
h2 {font-size: 1.5em;}
h2 {font-size: 1.5em; margin-block-start: 0.0em; margin-block-end: 0.2em;}
h3 {font-size: 1.2em;}
p {font-size: 1em;}
@@ -20,8 +19,8 @@ input[type=number] {
}
.button {
padding: 10px 20px;
width: 211px;
padding: 5px 10px;
width: 205px;
font-size: 16px;
}
</style>
@@ -32,7 +31,7 @@ input[type=number] {
<h2>Backup Configuration</h2>
<p>With the following action the <a href="/fileserver/config/" target="_self">config</a> folder on the SD-card gets zipped and provided as a download.</p>
<button class="button" id="startBackup" type="button" onclick="startBackup()">Create Config backup</button>
<button class="button" id="startBackup" type="button" onclick="startBackup()">Create Backup</button>
<p id=progress></p>
<hr>
<h2>Restore Configuration</h2>
@@ -105,7 +104,7 @@ function fetchFiles(urls, filesData, index, retry, zipFilename) {
// console.log(url + " started (" + index + "/" + urls.length + ")");
if (retry == 0) {
setStatus("&nbsp;- " + getFilenameFromUrl(urls[index]) + " (" + index + "/" + urls.length + ")...");
setStatus("&nbsp;- " + getFilenameFromUrl(urls[index]) + " (" + (index+1) + "/" + urls.length + ")...");
}
else {
setStatus("<span style=\"color: gray\">&nbsp;&nbsp;&nbsp;Retrying (" + retry + ")...</span>");

View File

@@ -145,8 +145,8 @@ function compareVersions() {
console.log("FW Hash: " + fWGitHash + ", Web UI Hash: " + webUiHash);
if (fWGitHash != webUiHash) {
firework.launch("The Version of the Web Interface (" + webUiHash +
") does not match the Firmware Version (" +
firework.launch("The version of the web interface (" + webUiHash +
") does not match the firmware version (" +
fWGitHash + ")! It is suggested to keep them on the same version!", 'warning', 30000);
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,36 +1,21 @@
<!DOCTYPE html>
<html style="width: fit-content">
<html lang="en" xml:lang="en">
<head>
<link rel="icon" href="favicon.ico?v=$COMMIT_HASH" type="image/x-icon">
<title>AI on the edge</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="UTF-8" />
<style>
h1 {font-size: 2em; margin-block-end: 0.3em;}
h2 {font-size: 1.5em;margin-block-start: 0.3em;}
h3 {font-size: 1.2em;}
p {font-size: 1em;}
</style>
</head>
<body style="font-family: arial">
<h4>Step 3: Define ROI's for your Digits</h4>
Here you define your digits you want to read. If you have more than one number on the reading you can define several numbers with the <b>"Number"</b> selector. There you can also define new numbers.
<p>
With the drop down menue <b>"ROI x"</b> you can change between the different digits. Mark them with the mouse or the coordinates.
<br>
To create new ROIs use <b>"New ROIs"</b>. The order of the ROIs defines the positon within the reading. <br>
You can change it with <b>"move Next" / "move Previous"</b>.
</p>
<p>
Don't forget to save your changes with the <b>"Save"</b> button!
</p>
<h4>Step 3 / 7: Definement Of Alignment Marker</h4>
</body>
</html>

View File

@@ -1,35 +1,21 @@
<!DOCTYPE html>
<html style="width: fit-content">
<html lang="en" xml:lang="en">
<head>
<link rel="icon" href="favicon.ico?v=$COMMIT_HASH" type="image/x-icon">
<title>AI on the edge</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="UTF-8" />
<style>
h1 {font-size: 2em; margin-block-end: 0.3em;}
h2 {font-size: 1.5em;margin-block-start: 0.3em;}
h3 {font-size: 1.2em;}
p {font-size: 1em;}
</style>
</head>
<body style="font-family: arial">
<h4>Step 4: Define ROI's for your Analog Counters</h4>
Here you define your analog counters you want to read. If you have more than one number on the reading you can define several numbers with the <b>"Number"</b> selector. There you can also define new numbers. If you do not have analog counters delete all ROIs.
<p>
With the drop down menue <b>"ROI x"</b> you can change between the different counters. Mark them with the mouse or the coordinates.
<br>
To create new ROIs use <b>"New ROIs"</b>. The order of the ROIs defines the positon within the reading. <br>
You can change it with <b>"move Next" / "move Previous"</b>.
</p>
<p>
Don't forget to save your changes with the <b>"Save"</b> button!
</p>
<h4>Step 4 / 7: Configuration Of ROIs For Digit Numbers</h4>
</body>
</html>

View File

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

View File

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

View File

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

View File

@@ -1,9 +1,15 @@
<html>
<!DOCTYPE html>
<html lang="en" xml:lang="en">
<head>
<link href="/firework.css?v=$COMMIT_HASH" rel="stylesheet">
<script type="text/javascript" src="/jquery-3.6.0.min.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="/firework.js?v=$COMMIT_HASH"></script>
<style>
h1 {font-size: 2em;}
h2 {font-size: 1.5em; margin-block-start: 0.0em; margin-block-end: 0.2em;}
h3 {font-size: 1.2em;}
p {font-size: 1em;}
#files_table {
font-family: Arial, Helvetica, sans-serif;
border-collapse: collapse;
@@ -27,42 +33,67 @@
padding-top: 12px;
padding-bottom: 12px;
text-align: left;
background-color: #0011ff;
color: white;
background-color:lightgrey;
color: black;
}
input[type=file] {
padding: 5px 0px;
display: inline-block;
font-size: 16px;
}
input[type=text] {
padding: 5px 10px;
display: inline-block;
border: 1px solid #ccc;
font-size: 16px;
}
.button {
padding: 4px 10px;
width: 100px;
font-size: 16px;
}
</style>
</head>
</body>
<table class="fixed" border="0" width=100% style="font-family: arial">
<tr><td>
<h2>Content on SD-Card</h2>
</td>
<td rowspan="2" width="500px">
<table border="0">
<tr>
<td>
<label for="newfile">Upload a file</label>
<td style="vertical-align: top;width: 300px;">
<h2>Fileserver</h2>
</td>
<td rowspan="2">
<table border="0" style="width:100%">
<tr>
<td style="width:80px">
<label for="newfile">Source</label>
</td>
<td colspan="2">
<input id="newfile" type="file" onchange="setpath()" style="width:100%;">
</td>
</tr>
<tr>
<td>
<label for="filepath">Set path on server</label>
<label for="filepath">Destination</label>
</td>
<td>
<input id="filepath" type="text" style="width:100%;">
<input id="filepath" type="text" style="width:94%;">
</td>
<td>
<button id="upload" type="button" onclick="upload()">Upload</button>
<button id="upload" type="button" class="button" onclick="upload()">Upload</button>
</td>
</tr>
</table>
</td></tr>
</td>
</tr>
<tr></tr>
<tr>
<td>
<span id="currentpath"></span> &nbsp;&nbsp;&nbsp;&nbsp;<button id="dirup" type="button" onclick="dirup()" disabled>&#129041; Directory up</button>
<td colspan="2">
<button style="font-size:16px; padding: 5px 10px" id="dirup" type="button" onclick="dirup()" disabled>&#129145; Directory up</button>
<span style="padding-left:15px" id="currentpath"></span>
</td>
</tr>
</table>
@@ -129,6 +160,7 @@ function upload() {
document.open();
document.write(xhttp.responseText);
document.close();
firework.launch('File upload completed', 'success', 5000);
} else if (xhttp.status == 0) {
firework.launch('Server closed the connection abruptly!', 'danger', 30000);
UpdatePage(false);
@@ -168,6 +200,5 @@ document.getElementById("currentpath").innerHTML = "Current path: <b>" + getPath
document.cookie = "page=" + getPath() + "; path=/";
</script>
</body>
</html>

View File

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

View File

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

View File

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

View File

@@ -1,10 +1,10 @@
<!DOCTYPE html>
<html>
<html lang="en" xml:lang="en">
<head>
<link rel="icon" href="favicon.ico?v=$COMMIT_HASH" type="image/x-icon">
<title>AI on the edge</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="style.css?v=$COMMIT_HASH" type="text/css" >
<link href="firework.css?v=$COMMIT_HASH" rel="stylesheet">
@@ -13,11 +13,21 @@
<script type="text/javascript" src="readconfigparam.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="jquery-3.6.0.min.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="common.js?v=$COMMIT_HASH"></script>
<script type="text/javascript" src="firework.js?v=$COMMIT_HASH"></script>
<script>
var streamPopup;
var streamFlashlight = false;
var streamWindowFeatures =
'channelmode=no,directories=no,fullscreen=no,' +
'location=no,dependent=yes,menubar=no,resizable=no,scrollbars=no,' +
'status=no,toolbar=no,titlebar=no,' +
'left=10,top=250,width=640px,height=480px';
async function loadPage(page) {
if (streamPopup) // Ensure that stream popup is closed because it's blocking web interface
streamPopup.close();
console.log("loadPage(" + page + ")");
document.cookie = "page="+page + "; path=/";
document.getElementById('maincontent').src = page;
@@ -49,17 +59,18 @@
return "";
}
</script>
</head>
<body>
<div class="main">
<table style="border: none">
<tr><td style="padding-right: 10px;"><img src="favicon.ico?v=$COMMIT_HASH"></td>
<table style="border: none; width:100%">
<tr>
<td style="padding-right: 10px;"><img style="width:64px; height:64px" src="favicon.ico?v=$COMMIT_HASH"></td>
<td><h1 id="id_title"> Digitizer - AI on the edge</h1>
<h2>An ESP32 all inclusive neural network recognition system for meter digitalization</h2>
</td></tr>
</td>
</tr>
</table>
<div class="menu" onmouseover="resetMenu()">
@@ -67,17 +78,17 @@
<li><a href="#" onclick="loadPage('overview.html?v=$COMMIT_HASH');">Overview</a></li>
<li><a>Settings <i class="arrow down"></i></a>
<ul class="submenu">
<li><a href="#" onclick="loadPage('prevalue_set.html?v=$COMMIT_HASH');">Set Previous Value</a></li>
<li><a href="#" onclick="loadPage('prevalue_set.html?v=$COMMIT_HASH');">Set "Previous Value"</a></li>
<li><a href="#" onclick="loadPage('edit_config_param.html?v=$COMMIT_HASH');">Configuration</a></li>
<li><a>Alignment <i class="arrow right"></i></a>
<ul>
<li><a href="#" onclick="loadPage('edit_reference.html?v=$COMMIT_HASH');">Reference Image</a></li>
<li><a href="#" onclick="loadPage('edit_alignment.html?v=$COMMIT_HASH');">Alignment Marks</a></li>
<li><a href="#" onclick="loadPage('edit_alignment.html?v=$COMMIT_HASH');">Alignment Marker</a></li>
</ul>
</li>
<li><a><strong>R</strong>egions <strong>O</strong>f <strong>I</strong>nterest <i class="arrow right"></i></a>
<ul>
<li><a href="#" onclick="loadPage('edit_digits.html?v=$COMMIT_HASH');">Digital ROIs</a></li>
<li><a href="#" onclick="loadPage('edit_digits.html?v=$COMMIT_HASH');">Digit ROIs</a></li>
<li><a href="#" onclick="loadPage('edit_analog.html?v=$COMMIT_HASH');">Analog ROIs</a></li>
</ul>
</li>
@@ -100,30 +111,98 @@
<li><a href="#" onclick="loadPage('ota_page.html?v=$COMMIT_HASH');">OTA Update</a></li>
<li><a href="#" onclick="loadPage('log.html?v=$COMMIT_HASH');">Log Viewer</a></li>
<li><a href="#" onclick="loadPage(getDomainname() + '/fileserver/');">File Server</a></li>
<li><a>Livestream <i class="arrow right"></i></a>
<ul>
<li><a href="#" onclick="start_livestream(false);">Live Stream (Light off)</a></li>
<li><a href="#" onclick="start_livestream(true);">Live Stream (Light on)</a></li>
</ul>
<li><a href="#" onclick="loadPage('reboot_page.html?v=$COMMIT_HASH');">Reboot</a></li>
<li><a href="#" onclick="loadPage('info.html?v=$COMMIT_HASH');">Info</a></li>
</ul>
</li>
<li><a>Manual Control <i class="arrow down"></i></a>
<ul class="submenu">
<li><a href="#" onclick="flow_start()">Start Round</a></li>
<li id="HASendDiscovery" style="display:none;"><a href="#" onclick="HA_send_discovery()">Resend HA Discovery</a></li>
</ul>
</li>
</ul>
</div>
<iframe name="maincontent" class="iframe" id="maincontent"></iframe>
<iframe title="maincontent" name="maincontent" class="iframe" id="maincontent"></iframe>
<span id="Version" style="font-size: 10px; margin-top: -5px">Loading version...</span>
<span id="Version" style="font-size: 10px; margin-top: -5px;padding-left: 10px;">Loading version...</span>
<script type="text/javascript">
LoadHostname();
LoadFwVersion();
LoadWebUiVersion();
HA_send_discovery_visiblilty();
if (getCookie("page") == "" || getCookie("page") == "reboot_page.html?v=$COMMIT_HASH") {
document.cookie = "page=overview.html?v=$COMMIT_HASH" + "; path=/";
}
console.log("Loading page: " + getCookie("page"));
document.getElementById('maincontent').src = getCookie("page");
</script>
</div>
function flow_start() {
var url = getDomainname() + '/flow_start';
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
if (xhttp.responseText.substring(0,3) == "001") {
firework.launch('Flow start triggered', 'success', 5000);
window.location.reload();
}
else if (xhttp.responseText.substring(0,3) == "002") {
firework.launch('Flow start scheduled. Start after round is completed', 'success', 5000);
}
else if (xhttp.responseText.substring(0,3) == "099") {
firework.launch('Flow start triggered, but start not possible (no flow task available)', 'danger', 5000);
}
}
}
xhttp.open("GET", url, true);
xhttp.send();
}
function HA_send_discovery_visiblilty() {
loadConfig(domainname);
ParseConfig();
category = getConfigCategory();
param = getConfigParameters();
if (category["MQTT"]["enabled"] && param["MQTT"]["HomeassistantDiscovery"]["value1"] == "true")
document.getElementById("HASendDiscovery").style.display="";
}
function HA_send_discovery() {
var url = getDomainname() + '/mqtt_publish_discovery';
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
firework.launch('Sending HA discovery topics scheduled. The sending will be processed in state "Publish to MQTT"', 'success', 5000);
}
}
xhttp.open("GET", url, true);
xhttp.send();
}
function start_livestream(streamFlashlight) {
if (streamPopup)
streamPopup.close();
if (streamFlashlight)
streamPopup = window.open(getDomainname() + '/stream?flashlight=true','LivestreamWithlight',streamWindowFeatures);
else
streamPopup = window.open(getDomainname() + '/stream','Livestream',streamWindowFeatures);
streamPopup.focus();
}
</script>
</body>
</html>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,33 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<link rel="icon" href="favicon.ico?v=$COMMIT_HASH" type="image/x-icon">
<meta charset="utf-8">
</head>
<body style="font-family: arial">
testschrift
<div id="value"></div>
</html>
<script type="text/javascript" src="common.js?v=$COMMIT_HASH"></script>
<script type="text/javascript">
var domainname = getDomainname();
function testinit(){
domainname = getDomainname();
url = domainname + '/value?all=true';
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
// Typical action to be performed when the document is ready:
document.getElementById("value").innerHTML = xhttp.responseText;
}
};
xhttp.open("GET", url, true);
xhttp.send();
}
testinit();
</script>
</body>

View File

@@ -1 +0,0 @@
<!DOCTYPE html><html><head><meta http-equiv="refresh" content="2"></head><body><tr><td><img src = "/original.jpg"></td></tr><tr><td><img src = "/roi.jpg"></td></tr><tr><td><img src = "/resize.bmp"></td></tr><tr><td><h2>Not-a-Number</h2></td></tr></body></html>

View File

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

View File

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