index.html 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. <!DOCTYPE html>
  2. <html lang="en" xml:lang="en">
  3. <head>
  4. <meta charset="UTF-8"/>
  5. <title>AI on the edge</title>
  6. <style>
  7. /* Add these styles to your existing CSS file or in a <style> tag in the head */
  8. .footer {
  9. display: flex;
  10. justify-content: space-between;
  11. align-items: center;
  12. padding: 20px;
  13. background-color: #d8d8d8;
  14. margin-top: 20px;
  15. }
  16. .footer-section {
  17. display: flex;
  18. align-items: center;
  19. }
  20. .footer-section img {
  21. width: 24px;
  22. height: 24px;
  23. margin-left: 10px;
  24. }
  25. .donation-cards img {
  26. height: 20px;
  27. margin-right: 5px;
  28. }
  29. </style>
  30. <link rel="icon" href="favicon.ico?v=$COMMIT_HASH" type="image/x-icon">
  31. <link rel="apple-touch-icon" href="watermeter.svg?v=$COMMIT_HASH" />
  32. <meta name="viewport" content="width=device-width, initial-scale=1">
  33. <link rel="stylesheet" href="style.css?v=$COMMIT_HASH" type="text/css" >
  34. <link href="firework.css?v=$COMMIT_HASH" rel="stylesheet">
  35. <script type="text/javascript" src="common.js?v=$COMMIT_HASH"></script>
  36. <script type="text/javascript" src="readconfigcommon.js?v=$COMMIT_HASH"></script>
  37. <script type="text/javascript" src="readconfigparam.js?v=$COMMIT_HASH"></script>
  38. <script type="text/javascript" src="jquery-3.6.0.min.js?v=$COMMIT_HASH"></script>
  39. <script type="text/javascript" src="firework.js?v=$COMMIT_HASH"></script>
  40. <script type="text/javascript">var domainname = getDomainname();</script>
  41. <script>
  42. var streamPopup;
  43. var streamFlashlight = false;
  44. var streamWindowFeatures =
  45. 'channelmode=no,directories=no,fullscreen=no,' +
  46. 'location=no,dependent=yes,menubar=no,resizable=no,scrollbars=no,' +
  47. 'status=no,toolbar=no,titlebar=no,' +
  48. 'left=10,top=260,width=640px,height=480px';
  49. function loadPage(page) {
  50. console.log("loadPage( " + page + " )");
  51. if (streamPopup) { // Ensure that stream popup is closed because it's blocking web interface
  52. streamPopup.close();
  53. }
  54. asyncPageLoad(page);
  55. }
  56. async function asyncPageLoad(page ) {
  57. console.log(" loading " + page + " ...");
  58. document.cookie = "page="+page + "; path=/";
  59. document.getElementById('maincontent').src = page;
  60. [].forEach.call(document.querySelectorAll('.submenu'), function (el) {
  61. el.style.visibility = 'hidden';
  62. });
  63. }
  64. function resetMenu() {
  65. [].forEach.call(document.querySelectorAll('.submenu'), function (el) {
  66. el.style.visibility = 'visible';
  67. });
  68. }
  69. function getCookie(cname) {
  70. let name = cname + "=";
  71. let decodedCookie = decodeURIComponent(document.cookie);
  72. let ca = decodedCookie.split(';');
  73. for(let i = 0; i <ca.length; i++) {
  74. let c = ca[i];
  75. while (c.charAt(0) == ' ') {
  76. c = c.substring(1);
  77. }
  78. if (c.indexOf(name) == 0) {
  79. return c.substring(name.length, c.length);
  80. }
  81. }
  82. return "";
  83. }
  84. </script>
  85. </head>
  86. <body>
  87. <div class="main">
  88. <table style="border: none; width:100%">
  89. <tr>
  90. <td style="padding-right: 10px;"><img style="width:64px; height:64px" src="favicon.ico?v=$COMMIT_HASH"></td>
  91. <td><h1 id="id_title"> Digitizer - AI on the edge</h1>
  92. <h2>An ESP32 all inclusive neural network recognition system for meter Digitization</h2>
  93. </td>
  94. </tr>
  95. </table>
  96. <div class="menu" onmouseover="resetMenu()">
  97. <ul>
  98. <li><a href="#" onclick="loadPage('overview.html?v=$COMMIT_HASH');">Overview</a></li>
  99. <li><a>Settings <i class="arrow down"></i></a>
  100. <ul class="submenu" style="width: 260px">
  101. <li style="width: 260px"><a href="#" onclick="loadPage('prevalue_set.html?v=$COMMIT_HASH');">Set "Previous Value"</a></li>
  102. <li style="width: 260px"><a>References <i class="arrow right"></i></a>
  103. <ul style="width: 350px">
  104. <li style="width: 350px"><a href="#" onclick="loadPage('edit_reference.html?v=$COMMIT_HASH');">Reference Image and Camera Settings</a></li>
  105. <li style="width: 350px"><a href="#" onclick="loadPage('edit_alignment.html?v=$COMMIT_HASH');">Alignment Markers</a></li>
  106. </ul>
  107. </li>
  108. <li style="width: 260px"><a>Regions of Interest (ROIs)<i class="arrow right"></i></a>
  109. <ul>
  110. <li><a href="#" onclick="loadPage('edit_digits.html?v=$COMMIT_HASH');">Digit ROI</a></li>
  111. <li><a href="#" onclick="loadPage('edit_analog.html?v=$COMMIT_HASH');">Analog ROI</a></li>
  112. </ul>
  113. </li>
  114. <li style="width: 260px"><a href="#" onclick="loadPage('edit_config.html?v=$COMMIT_HASH');">Configuration</a></li>
  115. </ul>
  116. <li><a>Data<i class="arrow down"></i></a>
  117. <ul class="submenu">
  118. <li><a href="#" onclick="loadPage(domainname + '/value?full');">Recognition</a></li>
  119. <li><a>Livestream <i class="arrow right"></i></a>
  120. <ul>
  121. <li><a href="#" onclick="start_livestream(false);">Live Stream (Light off)</a></li>
  122. <li><a href="#" onclick="start_livestream(true);">Live Stream (Light on)</a></li>
  123. </ul>
  124. </li>
  125. <li><a href="#" onclick="loadPage('graph.html?v=$COMMIT_HASH');">Data Graph</a></li>
  126. <li><a href="#" onclick="loadPage('data.html?v=$COMMIT_HASH');">Data Table</a></li>
  127. <li><a href="#" onclick="loadPage(domainname + '/fileserver/log/data/');">Data Files</a></li>
  128. <li><a href="#" onclick="loadPage('data_export.html?v=$COMMIT_HASH');">Data Export</a></li>
  129. </ul>
  130. </li>
  131. <li><a>System <i class="arrow down"></i></a>
  132. <ul class="submenu">
  133. <li><a href="#" onclick="loadPage('backup.html?v=$COMMIT_HASH');">Backup/Restore</a></li>
  134. <li><a href="#" onclick="loadPage('ota_page.html?v=$COMMIT_HASH');">OTA Update</a></li>
  135. <li><a href="#" onclick="loadPage('log.html?v=$COMMIT_HASH');">Log Viewer</a></li>
  136. <li><a href="#" onclick="loadPage(domainname + '/fileserver/');">File Server</a></li>
  137. <li><a href="#" onclick="loadPage('reboot_page.html?v=$COMMIT_HASH');">Reboot</a></li>
  138. <li><a href="#" onclick="loadPage('info.html?v=$COMMIT_HASH');">Info</a></li>
  139. <li><a href="https://jomjol.github.io/AI-on-the-edge-device-docs/" target="_blank">Help</a></li>
  140. </ul>
  141. </li>
  142. <li id="ManualControl" style="display:none;"><a>Manual Control <i class="arrow down"></i></a> <!-- Workaround: Hide menu if no entry is available -->
  143. <ul class="submenu" style="width: 300px">
  144. <li><a href="#" onclick="flow_start()">Start Round</a></li>
  145. <li id="HASendDiscovery" style="width: 300px" style="display:none;"><a href="#" onclick="HA_send_discovery()">Resend Homeassistant Discovery</a></li>
  146. </ul>
  147. </li>
  148. <li style="float: right; padding-right: 10px;">
  149. <div style="font-size: 12px; color: white; padding-top: 20px;" id="system_date"></div>
  150. </li>
  151. </ul>
  152. </div>
  153. <iframe title="maincontent" name="maincontent" class="iframe" id="maincontent"></iframe>
  154. <span id="Version" style="font-size: 10px; margin-top: -5px;padding-left: 10px;">Loading version...</span>
  155. <!-- # Disabled footer, since it wastes a lot of space and the images are broken
  156. <div class="footer">
  157. <div class="footer-section">
  158. <span>Support & Contact Us</span>
  159. <a href="https://github.com/jomjol/AI-on-the-edge-device" target="_blank" title="GitHub">
  160. <img src="https://github.com/jomjol/AI-on-the-edge-device/images/github-logo.png" alt="GitHub">
  161. </a>
  162. <img src="https://github.com/jomjol/AI-on-the-edge-device/images/gmail-logo.png" alt="Email">
  163. </a>
  164. <a href="https://github.com/jomjol/AI-on-the-edge-device/discussions" target="_blank" title="GitHub">
  165. <img src="https://github.com/jomjol/AI-on-the-edge-device/images/discussion-logo" alt="GitHub">
  166. </a>
  167. </div>
  168. <div class="footer-section">
  169. <span>Donations</span>
  170. <a href="https://www.paypal.com/donate?hosted_button_id=8TRSVYNYKDSWL" target="_blank" title="Donate via PayPal">
  171. <img src="https://github.com/jomjol/AI-on-the-edge-device/images/paypal.png" alt="PayPal" style="width: 60px; height: auto;">
  172. </a>
  173. </div>
  174. </div> -->
  175. <script type="text/javascript">
  176. var param, category;
  177. function updateTime() {
  178. var _system_date = new Date();
  179. var _year = _system_date.getFullYear();
  180. var _month = _system_date.getMonth() + 1;
  181. var _day = _system_date.getDate();
  182. var _hours = _system_date.getHours();
  183. var _minutes = _system_date.getMinutes();
  184. var _seconds = _system_date.getSeconds();
  185. if (_month < 10) {_month = '0' + _month;}
  186. if (_day < 10) {_day = '0' + _day;}
  187. if (_hours < 10) {_hours = '0' + _hours;}
  188. if (_minutes < 10) {_minutes = '0' + _minutes;}
  189. if (_seconds < 10) {_seconds = '0' + _seconds;}
  190. var day_in_week = _system_date.getDay();
  191. var weekday = new Array("Sonntag", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday");
  192. var _date = weekday[day_in_week] + ", " + _day + "." + _month + "." + _year + " " + _hours + ":" + _minutes + ":" + _seconds;
  193. document.getElementById('system_date').innerHTML = _date;
  194. setTimeout(updateTime, 1);
  195. }
  196. function flow_start() {
  197. var url = domainname + '/flow_start';
  198. var xhttp = new XMLHttpRequest();
  199. xhttp.onreadystatechange = function() {
  200. if (this.readyState == 4 && this.status == 200) {
  201. firework.launch(xhttp.responseText, 'success', 5000);
  202. /*if (xhttp.responseText.substring(0,3) == "001") {
  203. firework.launch('Flow start triggered', 'success', 5000);
  204. window.location.reload();
  205. }
  206. else if (xhttp.responseText.substring(0,3) == "002") {
  207. firework.launch('Flow start scheduled. Start after round is completed', 'success', 5000);
  208. }
  209. else if (xhttp.responseText.substring(0,3) == "099") {
  210. firework.launch('Flow start triggered, but start not possible (no flow task available)', 'danger', 5000);
  211. }*/
  212. }
  213. }
  214. xhttp.open("GET", url, true);
  215. xhttp.send();
  216. }
  217. function HA_send_discovery_visibility() {
  218. param = getConfigParameters();
  219. category = getConfigCategory();
  220. if (category["MQTT"]["enabled"] && param["MQTT"]["HomeassistantDiscovery"].value1 == "true") {
  221. document.getElementById("ManualControl").style.display="";
  222. document.getElementById("HASendDiscovery").style.display="";
  223. }
  224. }
  225. function HA_send_discovery() {
  226. console.log("Homeassistant Discovery topic sending scheduled");
  227. var url = domainname + '/mqtt_publish_discovery';
  228. var xhttp = new XMLHttpRequest();
  229. xhttp.onreadystatechange = function() {
  230. if (this.readyState == 4 && this.status == 200) {
  231. firework.launch('Sending Homeassistant discovery topics scheduled. It will get sent in the step "Publish to MQTT" of the next digitization round', 'success', 5000);
  232. }
  233. }
  234. xhttp.open("GET", url, true);
  235. xhttp.send();
  236. }
  237. function start_livestream(streamFlashlight) {
  238. if (streamPopup) {
  239. streamPopup.close();
  240. }
  241. if (streamFlashlight) {
  242. streamPopup = window.open(domainname + '/stream?flashlight=true','LivestreamWithlight',streamWindowFeatures);
  243. }
  244. else {
  245. streamPopup = window.open(domainname + '/stream','Livestream',streamWindowFeatures);
  246. }
  247. streamPopup.focus();
  248. }
  249. function init() {
  250. LoadHostname();
  251. LoadFwVersion();
  252. LoadWebUiVersion();
  253. HA_send_discovery_visibility();
  254. if (getCookie("page") == "" || getCookie("page") == "reboot_page.html?v=$COMMIT_HASH") {
  255. document.cookie = "page=overview.html?v=$COMMIT_HASH" + "; path=/";
  256. }
  257. console.log("Loading page: " + getCookie("page"));
  258. document.getElementById('maincontent').src = getCookie("page");
  259. updateTime();
  260. }
  261. init();
  262. </script>
  263. </body>
  264. </html>