/** @file WebPage.h @brief Here is saved root WEB page @author Miroslav Pivovarsky Contact: miroslav.pivovarsky@gmail.com https://codebeautify.org/remove-extra-spaces @bug: no know bug */ #pragma once #define MSG_REBOOT_MCU "Reboot process started, wait several seconds for mcu to boot up. You can close this window now" #define MSG_SAVE_OK_REBOOT "Save OK. Please reboot MCU" ///< WEB app msg save OK #define MSG_SAVE_OK_WIFI "Save OK. Connecting to Wi-Fi. Please wait several second" #define MSG_SAVE_OK "Save cfg OK" ///< WEB app msg save OK #define MSG_SAVE_NOTOK "Save cfg NOT OK!" ///< WEB app msg save NOT OK #define MSG_SCANNING "Scanning Wi-Fi networks. Wait 8s..." ///< WEB app msg Scanning wifi #define MSG_UPDATE_START "Start updating" /* ------------------------------------------------------------------------------------------------------------ */ const char index_html[] PROGMEM = R"rawliteral(

Trigger interval: s


















Prusa Connect ESP32 cam

Author

Miroslav Pivovarsky

Licence | General Terms and Conditions | Privacy Policy | Cookie Preferences
)rawliteral"; /* ------------------------------------------------------------------------------------------------------------ */ const char page_auth_html[] PROGMEM = R"rawliteral(
Set web authentication
WEB authentication
Username
Password Show Password
Confirm Password Show Password
)rawliteral"; /* ------------------------------------------------------------------------------------------------------------ */ const char page_wifi_html[] PROGMEM = R"rawliteral(

Connection status

Status:

SSID:

Signal: % / dBm

IP Address:

mDNS: http://.local


Available networks

Network name (SSID) Signal strength (RSSI) Channel Encryption


Connect to Wi-Fi network
Wi-Fi network name (SSID)
Password


Advanced Wi-Fi settings
Enable service AP
Wi-Fi client IPv4 Method
IP address
Subnet mask
Default gateway
DNS server
)rawliteral"; /* ------------------------------------------------------------------------------------------------------------ */ const char page_config_html[] PROGMEM = R"rawliteral(
Basic settings
Connect Token 
Fingerprint
Trigger Interval [s] 
Image qualityLow High
Resolution pixels
BrightnessLow High
ContrastLow High
SaturationLow High
Image Rotation
Horizontal mirror
Vertical flip
LED light
LED flash
Flash durationLow High
Flash duration ms
Save images to micro SD
Advanced settings
Automatic white balancing
Automatic white balancing gain
Automatic white balancing mode
Automatic Exposure Control
Second Level Automatic Exposure Control
Automatic exposure levelLow High
Automatic exposure timeLow High
Automatic exposure time ms
Automatic gain control
Automatic gain control levelLow High
Bad pixel correction
White pixel correction
Raw gamma correction
Lens correction
)rawliteral"; /* ------------------------------------------------------------------------------------------------------------ */ const char page_system_html[] PROGMEM = R"rawliteral(
Status
Prusa Connect Status
Wi-Fi mode
Wi-Fi service AP SSID
Uptime
ESP32 Temperature
Firmware
Version
Build
Configuration
Camera name & mDNS record.local 
Log level
Get logs
Micro SD card
Card status
Capacity MB
Available
0%
Used
0%

Firmware update
Available from cloud  
StatusReady
Progress
0%
)rawliteral"; /* ------------------------------------------------------------------------------------------------------------ */ const char page_temperature_html[] PROGMEM = R"rawliteral(
External temperature sensor DHT22/DHT11
Enable sensors
Sensor status:
Temperature Unit
Temperature
Humidity
)rawliteral"; /* ------------------------------------------------------------------------------------------------------------ */ const char styles_css[] PROGMEM = R"rawliteral( body { font-family: sans-serif; } /* index styles */ .p1 { color: #797979; font: normal normal normal 18px/5px sans-serif; letter-spacing: 0px; } .p2 { text-align: left; font: normal normal bold 14px/20px sans-serif; letter-spacing: 0px; color: #808080; opacity: 1; display: inline-block; } .p3 { text-align: left; font: normal normal normal 14px/20px sans-serif; letter-spacing: 0px; color: #808080; opacity: 1; display: inline-block; } .p4 { text-align: left; font: normal normal normal 14px/20px sans-serif; letter-spacing: 0px; color: #808080; opacity: 1; } .p5 { text-align: center; font: normal normal bold 14px/20px sans-serif; letter-spacing: 0px; color: #000000; opacity: 1; } /* NAVIGATION BAR */ nav { display: flex; background-color: transparent; } .top_bar { display: flex; width: 100%; } .top_bar li { display: inline-block; padding: 5px; } .top_bar li a { text-decoration: none; cursor: pointer; display: flex; align-items: center; } .top_bar li a:hover { text-decoration: underline #fa6831; text-underline-position: under; text-underline-offset: 8px; text-decoration-thickness: 2px; } #links li a.active { text-decoration: underline #fa6831; text-underline-position: under; text-underline-offset: 8px; text-decoration-thickness: 2px; } /* CFG BAR */ #cfg { display: flex; flex-direction: column; text-align: center; font: normal normal bold 14px/20px sans-serif; letter-spacing: 0px; color: #2A2A2A; opacity: 1; } #cfg_bar li { display: inline-block; padding: 14px; font-size: 16px; left: 50%; } #cfg_bar li a { text-decoration: none; cursor: pointer; color: #212529; } #cfg_bar li a:hover { color: #fa6831; } /* CONTAINER */ .container { display: table; height: 100%; width: 100%; } .container_left-half { grid-column: 1; display: table-cell; vertical-align: middle; width: 50%; text-align: center; } .container_right-half { grid-column: 2; display: table-cell; vertical-align: middle; width: 50%; } /* CHECKBOX SLIDER */ .switch { position: relative; display: inline-block; width: 30px; height: 17px; vertical-align: middle; } .switch input { opacity: 0; width: 0; height: 0; } .checkbox_slider { position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; background-color: #ccc; -webkit-transition: .4s; transition: .4s; } .checkbox_slider:before { position: absolute; content: ""; height: 13px; width: 13px; left: 2px; bottom: 2px; background-color: white; -webkit-transition: .4s; transition: .4s; } input:checked+.checkbox_slider { background-color: #797979; } input:focus+.checkbox_slider { box-shadow: 0 0 1px #797979; } input:checked+.checkbox_slider:before { -webkit-transform: translateX(13px); -ms-transform: translateX(13px); transform: translateX(13px); } .checkbox_slider.round { border-radius: 13px; } .checkbox_slider.round:before { border-radius: 50%; } /* BUTTON */ .btn { width: 306px; height: 30px; text-align: center; font: normal normal bold 14px/5px sans-serif; color: #000000; background-color: white; border-radius: 5px; border: 1px solid #343a40; } .btn:hover { background-color: #FA6831; color: white; } /* BOTTON table */ #botton { width: 100%; text-align: center; background: #F5F5F5 0% 0% no-repeat padding-box; opacity: 1; bottom: 0; } /* ----- styles config ----- */ .pc1 { text-align: right; font: normal normal normal 11px/5px sans-serif; letter-spacing: 0px; color: #797979; opacity: 1; } .pc2 { text-align: left; font: normal normal normal 12px/5px sans-serif; letter-spacing: 0px; color: #000000; opacity: 1; } .pc3 { text-align: right; font: normal normal normal bold 12px/17px sans-serif; letter-spacing: 0px; color: #2A2A2A; opacity: 1; } /* data table */ #data { font-family: Arial, Helvetica, sans-serif; border-collapse: collapse; width: 100%; table-layout: fixed; } #data td, #data th { padding: 8px; } #data th { padding-top: 12px; padding-bottom: 12px; text-align: left; } /* BUTTON */ .btn_save { width: 69px; height: 24px; text-align: center; font: normal normal bold 14px/5px sans-serif; color: #000000; background-color: white; border-radius: 5px; border: 1px solid #343a40; } .btn_save:hover { background-color: #FA6831; color: white; } /* RANGE */ .slider { -webkit-appearance: none; width: 133px; height: 10px; border-radius: 5px; background: linear-gradient(to right, #d3d3d3 50%, #FA6831 50%); outline: none; } .slider::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 16px; height: 16px; border-radius: 50%; background: #FA6831; cursor: pointer; } .slider::-moz-range-thumb { width: 16px; height: 16px; border-radius: 50%; background: #FA6831; cursor: pointer; } /* ----- styles wifi ----- */ .w1 { text-align: left; font: normal normal bold 12px/17px sans-serif; letter-spacing: 0px; color: #2A2A2A; opacity: 1; } .w2 { font: normal normal normal 11px/5px sans-serif; letter-spacing: 0px; color: #797979; opacity: 1; } .w2 span { vertical-align: middle; } #center_tb { border-collapse: collapse; width: 100%; table-layout: fixed; text-align: left; } #wificfg_tb { margin-left: 30%; } /* wifi_ntw table */ #wifi_ntw { font: normal normal normal 12px/5px sans-serif; border-collapse: collapse; width: 100%; table-layout: fixed; text-align: left; } #wifi_ntw td { border-bottom: 1px solid #ddd; padding: 8px; } #wifi_ntw tr:nth-child(even) { background: #F8F8F8 0% 0% no-repeat padding-box; } #wifi_ntw tr:hover { background-color: #ddd; } #wifi_ntw th { background-color: transparent; text-align: left; font: normal normal bold 13px/11px sans-serif; letter-spacing: 0px; color: #2A2A2A; opacity: 1; } #wifi_ntw tr { border-bottom: 1px solid #ccc; } #wifi_ntw img { width: 19px; height: 12px; } /* BUTTON */ .btn_save_w { width: 178px; height: 24px; text-align: center; font: normal normal bold 14px/5px sans-serif; color: #000000; background-color: white; border-radius: 5px; border: 1px solid #343a40; } .btn_save_w:hover { background-color: #FA6831; color: white; } /* ----- styles auth ----- */ .pa1 { text-align: right; font: normal normal normal 11px/5px sans-serif; letter-spacing: 0px; color: #797979; opacity: 1; } .pa2 { text-align: left; font: normal normal bold 12px/17px sans-serif; letter-spacing: 0px; color: #2A2A2A; opacity: 1; } .pa3 { text-align: right; font: normal normal normal bold 12px/17px sans-serif; letter-spacing: 0px; color: #2A2A2A; opacity: 1; } /* BUTTON */ .btn_save_a { width: 178px; height: 24px; text-align: center; font: normal normal bold 14px/5px sans-serif; color: #000000; background-color: white; border-radius: 5px; border: 1px solid #343a40; } .btn_save_a:hover { background-color: #FA6831; color: white; } .toggle-password { position: relative; cursor: pointer; } .toggle-password img { position: absolute; top: 50%; right: 0; transform: translateY(-50%); } .password-container { display: flex; align-items: center; } #auth_password.reveal { -webkit-text-security: none; } #auth_password { -webkit-text-security: disc; } /* ----- styles system ----- */ .ps1 { text-align: right; font: normal normal normal 11px/5px sans-serif; letter-spacing: 0px; color: #797979; opacity: 1; } .ps2 { text-align: left; font: normal normal normal 12px/5px sans-serif; letter-spacing: 0px; color: #000000; opacity: 1; } .ps3 { text-align: right; font: normal normal normal bold 12px/17px sans-serif; letter-spacing: 0px; color: #2A2A2A; opacity: 1; } /* update table */ #update { font-family: Arial, Helvetica, sans-serif; border-collapse: collapse; width: 100%; table-layout: fixed; } #update td, #update th { padding: 8px; } #update th { padding-top: 12px; padding-bottom: 12px; text-align: left; } /* BUTTON */ .btn_update { width: 178px; height: 24px; text-align: center; font: normal normal bold 14px/5px sans-serif; color: #000000; background-color: white; border-radius: 5px; border: 1px solid #343a40; } .btn_update:hover { background-color: #FA6831; color: white; } .underlined-text { text-decoration: underline; color: blue; cursor: pointer; } /* progress bar*/ .progress-container { width: 30%; background-color: #ccc; } .progress-bar { width: 0px; height: 15px; background-color: #FA6831; text-align: center; line-height: 15px; color: white; padding-left: 3px; } /* advanced cam cfg */ .content { display: none; } .btn_collapsible { width: 300px; height: 24px; text-align: center; font: normal normal bold 14px/5px sans-serif; color: #000000; background-color: white; border-radius: 5px; border: 1px solid #343a40; } .btn_collapsible:hover { background-color: #FA6831; color: white; } /* advanced wifi cfg */ .content_wifi { display: none; } .btn_collapsible_wifi { width: 300px; height: 24px; text-align: center; font: normal normal bold 14px/5px sans-serif; color: #000000; background-color: white; border-radius: 5px; border: 1px solid #343a40; } .btn_collapsible_wifi:hover { background-color: #FA6831; color: white; } )rawliteral"; /* ------------------------------------------------------------------------------------------------------------ */ const char scripts_js[] PROGMEM = R"rawliteral( function get_data(val) { jQuery.ajax({ url: 'json_input', type: 'GET', timeout: 5000, success: function(data) { console.log("Incommming data: "); console.log(data); var obj = JSON.parse(data); console.log(obj); if (!document.querySelector('#light-icon img')) { var img = document.createElement('img'); img.src = (obj.led == "true") ? 'light-on-icon.svg' : 'light-off-icon.svg'; document.getElementById('light-icon').appendChild(img); } document.title = obj.mdns; if (val == "config") { $("#fingerprint").text(obj.fingerprint); $("#refreshInterval").text(obj.refreshInterval); document.getElementById('tokenid').value = obj.token; document.getElementById('refreshid').value = obj.refreshInterval; document.getElementById('photo_qualityid').value = obj.photoquality; document.getElementById('framesizeid').value = obj.framesize; document.getElementById('brightnessid').value = obj.brightness; document.getElementById('contrastid').value = obj.contrast; document.getElementById('saturationid').value = obj.saturation; document.getElementById('image_rotationid').value = obj.image_rotation; document.getElementById('hmirrorid').checked = obj.hmirror; document.getElementById('vflipid').checked = obj.vflip; document.getElementById('lencid').checked = obj.lensc; document.getElementById('exposure_ctrlid').checked = obj.exposure_ctrl; document.getElementById('awbid').checked = obj.awb; document.getElementById('awb_gainid').checked = obj.awb_gain; document.getElementById('wb_modeid').value = obj.wb_mode; document.getElementById('ledid').checked = obj.led; document.getElementById('flashid').checked = obj.flash; document.getElementById('flash_timeid').value = obj.flash_time; document.getElementById('bpcid').checked = obj.bpc; document.getElementById('wpcid').checked = obj.wpc; document.getElementById('raw_gamaid').checked = obj.raw_gama; document.getElementById('aec2id').checked = obj.aec2; document.getElementById('ae_levelid').value = obj.ae_level; document.getElementById('aec_valueid').value = obj.aec_value; document.getElementById('gain_ctrlid').checked = obj.gain_ctrl; document.getElementById('agc_gainid').value = obj.agc_gain; document.getElementById("flash_time_value").innerText = obj.flash_time; document.getElementById("aec_value_value").innerText = obj.aec_value; document.getElementById('timelapsid').checked = obj.timelaps; $("#status_hmirror").text((obj.hmirror == "true") ? "On" : "Off"); $("#status_vflip").text((obj.vflip == "true") ? "On" : "Off"); $("#status_lensc").text((obj.lensc == "true") ? "On" : "Off"); $("#status_exposure_ctrl").text((obj.exposure_ctrl == "true") ? "On" : "Off"); $("#status_awb").text((obj.awb == "true") ? "On" : "Off"); $("#status_awb_gain").text((obj.awb_gain == "true") ? "On" : "Off"); $("#status_led").text((obj.led == "true") ? "On" : "Off"); $("#status_flash").text((obj.flash == "true") ? "On" : "Off"); $("#status_bpc").text((obj.bpc == "true") ? "On" : "Off"); $("#status_wpc").text((obj.wpc == "true") ? "On" : "Off"); $("#status_raw_gama").text((obj.raw_gama == "true") ? "On" : "Off"); $("#status_aec2").text((obj.aec2 == "true") ? "On" : "Off"); $("#status_gain_ctrl").text((obj.gain_ctrl == "true") ? "On" : "Off"); $("#status_timelaps").text((obj.timelaps == "true") ? "On" : "Off"); sliderCheck(); } if (val == "auth") { document.getElementById('authid').checked = obj.auth; $("#status_auth").text((obj.auth == "true") ? "On" : "Off"); document.getElementById('auth_username').value = obj.auth_username; } if (val == "wifi") { document.getElementById('serviceapid').checked = obj.serviceap; $("#status_serviceap").text((obj.serviceap == "true") ? "On" : "Off"); $("#ssid").text(obj.ssid); $("#rssi").text(obj.rssi); $("#rssi_percentage").text(obj.rssi_percentage); $("#ip").text(obj.ip); $("#mdns").text(obj.mdns); $("#wifi_network_status").text(obj.wifi_network_status); document.getElementById('ipcfgid').value = obj.ip_cfg; document.getElementById('net_ip_id').value = obj.net_ip; document.getElementById('net_mask_id').value = obj.net_mask; document.getElementById('net_gw_id').value = obj.net_gw; document.getElementById('net_dns_id').value = obj.net_dns; if (!document.querySelector('#main-wifi-signal wifi_img')) { var wifi_img = document.createElement('wifi_img'); wifi_img.width = 19; wifi_img.height = 12; wifi_img.src = getIconPath(obj.rssi); document.getElementById('main-wifi-signal').appendChild(wifi_img); } } if (val == "system") { $("#uptime").text(obj.uptime); $("#sw_ver").text(obj.sw_ver); $("#sw_build").text(obj.sw_build); $("#last_upload_status").text(obj.last_upload_status); $("#wifi_mode").text(obj.wifi_mode); $("#sw_new_ver").text(obj.sw_new_ver); $("#service_ap_ssid").text(obj.service_ap_ssid); $("#sd_status").text(obj.sd_status); $("#sd_total").text(obj.sd_total); $("#sd_free_p").text(obj.sd_free_p); $("#sd_used_p").text(obj.sd_used_p); $("#mcu_temp").text(obj.mcu_temp); var sd_free_prog = document.getElementById("progress_bar_sd_free"); sd_free_prog.style.width = obj.sd_free_p + "%"; sd_free_prog.innerHTML = obj.sd_free_p + "%"; var sd_free_prog = document.getElementById("progress_bar_sd_used"); sd_free_prog.style.width = obj.sd_used_p + "%"; sd_free_prog.innerHTML = obj.sd_used_p + "%"; document.getElementById('mdnsid').value = obj.mdns; document.getElementById('loglevelid').value = obj.log_level; } if (val == "temp") { $("#extsens_stat").text(obj.extsens_stat); document.getElementById('extsetsid').checked = obj.extsen_en; document.getElementById('temp_unitid').value = obj.exttemp_unit; $("#ext_temp").text(obj.ext_temp); $("#ext_hum").text(obj.ext_hum); } }, error: function(html) { console.log("json Timeout or error"); //alert("jquery timeout or comunication error"); } }); } function sliderCheck() { var ranges = document.querySelectorAll(".slider"); ranges.forEach(function(range) { var percent = (range.value - range.min) / (range.max - range.min) * 100; var gradient = "linear-gradient(to right, #FA6831 " + percent + "%, #d3d3d3 " + percent + "%)"; range.style.background = gradient; range.oninput = function() { var percent = (this.value - this.min) / (this.max - this.min) * 100; var gradient = "linear-gradient(to right, #FA6831 " + percent + "%, #d3d3d3 " + percent + "%)"; this.style.background = gradient; } }); } function getIconPath(rssi) { let path; if (rssi == 0) { path = 'wifi-icon-0.svg'; } else if (rssi <= -70) { path = 'wifi-icon-1.svg'; } else if (rssi > -70 && rssi <= -60) { path = 'wifi-icon-2.svg'; } else if (rssi > -60 && rssi <= -50) { path = 'wifi-icon-3.svg'; } else { path = 'wifi-icon-4.svg'; } return path; } var OpenImageclickCount = 0; function openImage() { var img = document.getElementById("photo"); if (OpenImageclickCount % 2 == 0) { img.style.position = "fixed"; img.style.top = "5%"; img.style.left = "5%"; img.style.width = "auto"; img.style.height = "auto"; img.style.maxWidth = "100%"; img.style.maxHeight = "90%"; img.style.zIndex = "9999"; } else { img.style.position = ""; img.style.top = ""; img.style.left = ""; img.style.width = ""; img.style.height = ""; img.style.zIndex = ""; } OpenImageclickCount++; } function actionButton(url, reload, msg) { var xhr = new XMLHttpRequest(); if (msg != '') { alert(msg); } xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { if (reload == true) { setTimeout(function() { location.reload(); }, 200); } } }; xhr.open('GET', url, true); xhr.send(); } function setActive(link) { var links = document.querySelectorAll('#links li a'); links.forEach(function(item) { item.classList.remove('active'); }); link.classList.add('active'); } var links = document.querySelectorAll('#links li a'); links.forEach(function(link) { link.addEventListener('click', function() { setActive(link); }); }); function addClickListener(id) { var link = document.getElementById(id); if (!link.hasOwnProperty('clickListener')) { link.addEventListener('click', function(event) { event.preventDefault(); window.open(link.href, '_blank'); }); link.clickListener = true; } } /* wifi page */ function setWifi(val_ssid, val_pass) { var xmlHttp = new XMLHttpRequest(); xmlHttp.open("GET", "wifi_cfg?wifi_ssid=" + encodeURIComponent(val_ssid) + "&wifi_pass=" + encodeURIComponent(val_pass), false); xmlHttp.send(null); alert(xmlHttp.responseText); get_data("wifi"); } function setWifiNet(val_ip, val_mask, val_gw, val_dns) { var xmlHttp = new XMLHttpRequest(); xmlHttp.open("GET", "wifi_net_cfg?ip=" + encodeURIComponent(val_ip) + "&mask=" + encodeURIComponent(val_mask) + "&gw=" + encodeURIComponent(val_gw) + "&dns=" + encodeURIComponent(val_dns), false); xmlHttp.send(null); alert(xmlHttp.responseText); get_data("wifi"); } function scanWifi() { var xmlHttp = new XMLHttpRequest(); xmlHttp.open("GET", "wifi_scan?", false); xmlHttp.send(null); alert(xmlHttp.responseText); get_data("wifi"); setTimeout(function() { GetDataAndPrintTableWiFi(); }, 8000); } function GetDataAndPrintTableWiFi() { $("#wifi_ntw").find("tr:gt(0)").remove(); $.ajax({ url: 'json_wifi', type: 'GET', timeout: 15000, dataType: 'json', data: {}, success: function(data) { for (var i = 0; i < data.length; i++) { const IconName = "wifi-icon-" + i; var row = $('' + data[i].ssid + '
' + data[i].channel + '' + data[i].encryption + ''); $('#wifi_ntw').append(row); if (!document.querySelector('#' + IconName + ' img')) { var img = document.createElement('img'); img.src = getIconPath(data[i].rssi); document.getElementById(IconName).prepend(img); document.getElementById(IconName).append(data[i].rssi_percentage); document.getElementById(IconName).append("% / "); document.getElementById(IconName).append(data[i].rssi); document.getElementById(IconName).append("dBm"); } } }, error: function(jqXHR, textStatus, errorThrown) { console.log('Error:' + textStatus + '-' + errorThrown); } }); } /* auth page */ function setAuth(val_name, val_pass) { var xmlHttp = new XMLHttpRequest(); xmlHttp.open("GET", "basicauth_cfg?" + "auth_username=" + encodeURIComponent(val_name) + "&auth_password=" + encodeURIComponent(val_pass), false); xmlHttp.send(null); alert(xmlHttp.responseText); get_data("auth"); } function changeValue(val, url, reload, msg) { var xmlHttp = new XMLHttpRequest(); xmlHttp.open("GET", url + val, false); xmlHttp.send(null); if ((url == "set_int?refresh=") || (url == "set_token?token=") || (url == "set_mdns?mdns=") || (url == "set_int?ipcfg=")) { alert(xmlHttp.responseText); } if (url == "set_flash_time?flash_time=") { document.getElementById("flash_time_value").innerText = val; } get_data(reload); } function togglePasswordVisibility() { const passwordInput = document.getElementById("auth_password"); const eyeIcon = document.getElementById("eye-icon"); if (passwordInput.getAttribute("type") === "password") { passwordInput.setAttribute("type", "text"); passwordInput.classList.add("reveal"); eyeIcon.src = "eye-slash.svg"; eyeIcon.alt = "Hide Password"; } else { passwordInput.setAttribute("type", "password"); passwordInput.classList.remove("reveal"); eyeIcon.src = "eye.svg"; eyeIcon.alt = "Show Password"; } } /* system page */ if (typeof uploadingFirmware === 'undefined') { var uploadingFirmware = false; } if (typeof FileSize === 'undefined') { var FileSize = 0; } function uploadFile() { alert("Started updating..."); const firmwareInput = document.getElementById('firmwareInput'); const statusDiv = document.getElementById('status'); const file = firmwareInput.files[0]; FileSize = file.size; SetFirmwareSize(file.size); if (file) { statusDiv.innerText = 'Updating...'; const formData = new FormData(); formData.append('firmware', file); uploadingFirmware = true; fetch('/upload', { method: 'POST', body: formData, }) .then((response) => { if (response.ok) { response.text().then((data) => { const jsonData = JSON.parse(data); updateProgress(); uploadingFirmware = false; if (jsonData.errorMessage) { alert(`Error message: ${jsonData.errorMessage}`); } }); } else { uploadingFirmware = false; response.text().then((errorMessage) => { alert(`Error message: ${errorMessage}`); }); } }) .catch((error) => { console.error('Error:', error); uploadingFirmware = false; }); } else { statusDiv.innerText = 'No file selected'; } } function SetFirmwareSize(val) { var xmlHttp = new XMLHttpRequest(); xmlHttp.open("GET", "set_firmware_size?size=" + val, false); xmlHttp.send(null); } function updateProgress() { if (!uploadingFirmware) { return; } fetch('/UpdateProcessing', { method: 'GET', }) .then((response) => { if (response.ok) { return response.json(); } else { throw new Error('Failed to fetch progress'); } }) .then((data) => { const statusDiv = document.getElementById('status'); var progressBar = document.getElementById("myProgressBar"); progressBar.style.width = data.processed_percent + "%"; progressBar.innerHTML = data.processed_percent + "%"; statusDiv.innerText = data.message; uploadingFirmware = data.updating; if (data.updating == false && !updateCompleted) { alert('Operation done. Please reboot MCU.'); uploadingFirmware = false; updateCompleted = true; clearInterval(updateInterval); } }) .catch((error) => { console.error('Error:', error); var progressBar = document.getElementById("myProgressBar"); progressBar.innerHTML = "Error"; clearInterval(updateInterval); }); } function checkUpdate() { var xmlHttp = new XMLHttpRequest(); alert("Connecting to server... Please wait several seconds"); xmlHttp.open("GET", "/check_web_ota_update", false); xmlHttp.send(null); alert(xmlHttp.responseText); get_data("system"); } function updateWeb() { alert("Started updating from cloud."); var xmlHttp = new XMLHttpRequest(); xmlHttp.open("GET", "web_ota_update?update=true", false); xmlHttp.send(null); uploadingFirmware = true; } function validatePasswords() { var password = document.getElementById("auth_password").value; var confirmPassword = document.getElementById("auth_password_confirm").value; var saveButton = document.querySelector(".btn_save_a"); var passwordStatus = document.getElementById("pass_match"); if (password === confirmPassword) { passwordStatus.innerHTML = "✔️"; saveButton.disabled = false; } else { passwordStatus.innerHTML = "❌"; saveButton.disabled = true; } } if (document.getElementById("auth_password")) { document.getElementById("auth_password").addEventListener("input", validatePasswords); } if (document.getElementById("auth_password_confirm")) { document.getElementById("auth_password_confirm").addEventListener("input", validatePasswords); } if ((document.getElementById("auth_password")) && (document.getElementById("auth_password_confirm"))) { validatePasswords(); } function setupCollapsibleButtons() { $(".btn_collapsible").click(function(){ $(this).toggleClass("active"); var content = $(this).parent().next(); if (content.css("display") === "block") { content.css("display", "none"); } else { content.css("display", "block"); } }); } function setupCollapsibleButtonsWiFi() { $(".btn_collapsible_wifi").click(function(){ $(this).toggleClass("active"); var content_wifi = $(this).parent().next(); if (content_wifi.css("display") === "block") { content_wifi.css("display", "none"); } else { content_wifi.css("display", "block"); } }); } )rawliteral"; /* ------------------------------------------------------------------------------------------------------------ */ const char license_html[] PROGMEM = R"rawliteral(

The software for device falls under the GPL-3.0 license terms. To read the license terms please visit this page.

)rawliteral"; /* ------------------------------------------------------------------------------------------------------------ */ const char gtac_html[] PROGMEM = R"rawliteral(

To read the General Terms and Conditions, please visit this page.

)rawliteral"; /* ------------------------------------------------------------------------------------------------------------ */ const char privacypolicy_html[] PROGMEM = R"rawliteral(

To read the Privacy Policy, please visit this page.

)rawliteral"; /* ------------------------------------------------------------------------------------------------------------ */ const char cookies_html[] PROGMEM = R"rawliteral(

To read the Cookie policy, please visit this page.

)rawliteral"; /* EOF */