$(document).ready(function() { var backupFileOpen = document.getElementById('grblBackupFile'); if (backupFileOpen) { backupFileOpen.addEventListener('change', readGrblBackupFile, false); } }); function readGrblBackupFile(evt) { var files = evt.target.files || evt.dataTransfer.files; loadGrblBackupFile(files[0]); document.getElementById('grblBackupFile').value = ''; } function loadGrblBackupFile(f) { if (f) { // Filereader var r = new FileReader(); // if (f.name.match(/.gcode$/i)) { r.readAsText(f); r.onload = function(event) { //var grblsettingsfile = this.result //console.log(this.result) var data = this.result.split("\n"); for (i = 0; i < data.length; i++) { if (data[i].indexOf("$I=") == 0) { setMachineButton(data[i].split('=')[1]) } else { var key = data[i].split('=')[0]; var param = data[i].split('=')[1] $("#val-" + key.substring(1) + "-input").val(parseFloat(param)) fixGrblHALSettings(key.substring(1)); // Fix GrblHAL Defaults } }; checkifchanged(); enableLimits(); // Enable or Disable displayDirInvert(); $("#grblSettingsAdvTab").click(); } } } function populateRestoreMenu() { // Retrieve backups from localStorage const backups = JSON.parse(localStorage.getItem('grblParamsBackups')) || []; // Get the dropdown menu element const backupMenu = document.getElementById('restoreBackupMenu'); // Clear existing menu items (in case you're calling this multiple times) backupMenu.innerHTML = ''; // Loop through each backup and create a list item for it backups.forEach((backup, index) => { const backupItem = document.createElement('li'); // Format the timestamp (you can format it as needed) const formattedTimestamp = new Date(backup.timestamp).toLocaleString(); // Adjust formatting as needed // Create the list item HTML content backupItem.innerHTML = ` Restore AutoBackup: ${formattedTimestamp} (${backup.note || 'No note'}) `; // Append the list item to the dropdown menu backupMenu.appendChild(backupItem); }); } function restoreAutoBackup(index) { const backups = JSON.parse(localStorage.getItem('grblParamsBackups')) || []; const selectedBackup = backups[index]; // You can now access selectedBackup.grblParams and apply it as needed console.log('Restoring backup:', selectedBackup); // Call your function to restore the backup here, e.g., update grblParams // Example: grblParams = selectedBackup.grblParams; // Retrieve grblParams from the backup const grblParamsBackup = selectedBackup.grblParams; // Iterate through the keys in the grblParams object and apply them using jQuery for (const key in grblParamsBackup) { if (grblParamsBackup.hasOwnProperty(key)) { const paramValue = grblParamsBackup[key]; const parsedValue = parseFloat(paramValue); // Check if the parsed value is a valid number if (!isNaN(parsedValue)) { // Update the input field based on the parameter using jQuery const inputElement = $("#val-" + key.substring(1) + "-input"); if (inputElement.length) { inputElement.val(parsedValue); // Apply the value to the input field } } else { console.warn(`Invalid value for ${key}: ${paramValue}`); } // Optionally, fix or apply any GrblHAL-specific settings fixGrblHALSettings(key.substring(1)); // Adjust as needed // Optionally, other functions you might call for updating the machine state // Example: checkifchanged(); enableLimits(); displayDirInvert(); } } // Call any post-restoration functions you need (e.g., re-enable limits, etc.) checkifchanged(); enableLimits(); displayDirInvert(); $("#grblSettingsAdvTab").click(); } function backupGrblSettings() { autoBackup("Manual Backup") var grblBackup = "" for (key in grblParams) { var key2 = key.split('=')[0].substr(1); if (grblSettingsTemplate2[key2] !== undefined) { var descr = grblSettingsTemplate2[key2].title } else { var descr = "unknown" } grblBackup += key + "=" + grblParams[key] + " ; " + descr + "\n" } if (laststatus.machine.name.length > 0) { grblBackup += "$I=" + laststatus.machine.name } var blob = new Blob([grblBackup], { type: "plain/text" }); var date = new Date(); if (laststatus.machine.name.length > 0) { invokeSaveAsDialog(blob, 'grbl-settings-backup-' + laststatus.machine.name + "-" + date.yyyymmdd() + '.txt'); } else { invokeSaveAsDialog(blob, 'grbl-settings-backup-' + date.yyyymmdd() + '.txt'); } } function grblSettings(data) { // console.log(data) var template = `` grblconfig = data.split('\n') for (i = 0; i < grblconfig.length; i++) { var key = grblconfig[i].split('=')[0]; var param = grblconfig[i].split(/[= ;(]/)[1] grblParams[key] = param } // $('#grblconfig').show(); // grblPopulate(); // $('#grblSaveBtn').removeAttr('disabled'); // $('#grblFirmwareBtn').removeAttr('disabled'); $('#grblSettings').show() if (laststatus.machine.firmware.platform == "grblHAL") { $("#grbl-settings-tab-title").html('grblHAL'); } else { $("#grbl-settings-tab-title").html('Grbl'); } if (grblParams['$22'] > 0) { $('#gotozeroMPos').removeClass('disabled') $('#homeBtn').attr('disabled', false) $('#gotoXzeroMpos').removeClass('disabled') $('#gotoYzeroMpos').removeClass('disabled') $('#gotoZzeroMpos').removeClass('disabled') $('.PullOffMPos').html("-" + grblParams['$27']) } else { $('#gotozeroMPos').addClass('disabled') $('#homeBtn').attr('disabled', true) $('#gotoXzeroMpos').addClass('disabled') $('#gotoYzeroMpos').addClass('disabled') $('#gotoZzeroMpos').addClass('disabled') } if (grblParams['$32'] == 1) { $('#enLaser').removeClass('alert').addClass('success').html('ON') } else { $('#enLaser').removeClass('success').addClass('alert').html('OFF') } // grblHAL - enable Servo Buttons if Spindle PWM == 50hz if (grblParams['$33'] == 50) { $('#enServo').removeClass('alert').addClass('success').html('ON') $(".servo-active").show() } else { $('#enServo').removeClass('success').addClass('alert').html('OFF') $(".servo-active").hide() } updateToolOnSValues(); if (localStorage.getItem('jogOverride')) { jogOverride(localStorage.getItem('jogOverride')) } else { jogOverride(100); } } function showBasicSettings() { $("#grbl-settings-basic").show(); $("#grbl-settings-advanced").hide(); } function showAdvSettings() { $("#grbl-settings-basic").hide(); $("#grbl-settings-advanced").show(); } function grblPopulate() { if (!isJogWidget) { $('#grblconfig').show(); $('#grblconfig').empty(); var template = `
` $('#grblconfig').append(template) $('#grblSettingsTable').on('keyup paste click change', 'input, select', function() { checkifchanged() }); // Event Handlers for Switch Checkboxes setTimeout(function() { setup_settings_table(); }, 100) $('#grblSettingsBadge').hide(); if (grblParams['$21'] == 1 && grblParams['$22'] > 0) { $('#limitsinstalled:checkbox').prop('checked', true); $('#gotozeroMPos').removeClass('disabled') $('#homeBtn').attr('disabled', false) } else { $('#limitsinstalled:checkbox').prop('checked', false); $('#gotozeroMPos').addClass('disabled') $('#homeBtn').attr('disabled', true) } // if (grblParams['$33'] == 50 && grblParams['$34'] == 5 && grblParams['$35'] == 5 && grblParams['$36'] == 10) { // setSelectedToolhead('scribe') // } if (isMatchingConfig(grblParams, grblParams_scribe)) { setSelectedToolhead('scribe') } else if (isMatchingConfig(grblParams, grblParams_plasma)) { setSelectedToolhead('plasma') } else if (isMatchingConfig(grblParams, grblParams_router)) { setSelectedToolhead('router11') } else if (isMatchingConfig(grblParams, grblParams_laser)) { setSelectedToolhead('laser') } else if (isMatchingConfig(grblParams, grblParams_vfd)) { setSelectedToolhead('vfd_spindle') } setTimeout(function() { setMachineButton(laststatus.machine.name) }, 500) populateRestoreMenu(); } } // function checkifchanged() { // var hasChanged = false; // for (var key in grblParams) { // if (grblParams.hasOwnProperty(key)) { // var j = key.substring(1) // var newVal = $("#val-" + j + "-input").val(); // // if (newVal !== undefined) { // // Only send values that changed // if (newVal != grblParams[key]) { // hasChanged = true; // console.log("changed: " + key) // console.log("old: " + grblParams[key]) // console.log("new: " + newVal) // if (!$("#val-" + j + "-input").parent().is('td')) { // $("#val-" + j + "-input").parent().addClass('alert') // } else if ($("#val-" + j + "-input").is('select')) { // $("#val-" + j + "-input").addClass('alert') // } else if (j == 3) { // axes // $('#xdirinvert').parent().children('.check').addClass('bd-red') // $('#ydirinvert').parent().children('.check').addClass('bd-red') // $('#zdirinvert').parent().children('.check').addClass('bd-red') // } // } else { // if (!$("#val-" + j + "-input").parent().is('td')) { // $("#val-" + j + "-input").parent().removeClass('alert') // } else if ($("#val-" + j + "-input").is('select')) { // $("#val-" + j + "-input").removeClass('alert') // } else if (j == 3) { // $('#xdirinvert').parent().children('.check').removeClass('bd-red') // $('#ydirinvert').parent().children('.check').removeClass('bd-red') // $('#zdirinvert').parent().children('.check').removeClass('bd-red') // } // } // } // } // } // if (hasChanged) { // $('#grblSettingsBadge').fadeIn('slow'); // $('#saveBtn').attr('disabled', false).removeClass('disabled'); // $('#saveBtnIcon').removeClass('fg-gray').addClass('fg-grayBlue'); // } else { // $('#grblSettingsBadge').fadeOut('slow'); // $('#saveBtn').attr('disabled', true).addClass('disabled'); // $('#saveBtnIcon').removeClass('fg-grayBlue').addClass('fg-gray'); // } // } function checkifchanged() { var hasChanged = false; for (var key in grblParams) { if (grblParams.hasOwnProperty(key)) { var j = key.substring(1); var newVal = $("#val-" + j + "-input").val(); if (newVal !== undefined) { // Determine if the value should be compared as text or number var oldVal = grblParams[key]; var compareAsNumber = !isNaN(parseFloat(oldVal)) && !isNaN(parseFloat(newVal)); // Perform appropriate comparison if ((compareAsNumber && parseFloat(newVal) !== parseFloat(oldVal)) || (!compareAsNumber && newVal !== oldVal)) { hasChanged = true; // console.log("changed: " + key); // console.log("old: " + oldVal); // console.log("new: " + newVal); if (!$("#val-" + j + "-input").parent().is('td')) { $("#val-" + j + "-input").parent().addClass('alert'); } else if ($("#val-" + j + "-input").is('select')) { $("#val-" + j + "-input").addClass('alert'); } else if (j == 3) { // axes $('#xdirinvert').parent().children('.check').addClass('bd-red'); $('#ydirinvert').parent().children('.check').addClass('bd-red'); $('#zdirinvert').parent().children('.check').addClass('bd-red'); } } else { if (!$("#val-" + j + "-input").parent().is('td')) { $("#val-" + j + "-input").parent().removeClass('alert'); } else if ($("#val-" + j + "-input").is('select')) { $("#val-" + j + "-input").removeClass('alert'); } else if (j == 3) { $('#xdirinvert').parent().children('.check').removeClass('bd-red'); $('#ydirinvert').parent().children('.check').removeClass('bd-red'); $('#zdirinvert').parent().children('.check').removeClass('bd-red'); } } } } } if (hasChanged) { $('#grblSettingsBadge').fadeIn('slow'); $('#saveBtn').attr('disabled', false).removeClass('disabled'); $('#saveBtnIcon').removeClass('fg-gray').addClass('fg-grayBlue'); } else { $('#grblSettingsBadge').fadeOut('slow'); $('#saveBtn').attr('disabled', true).addClass('disabled'); $('#saveBtnIcon').removeClass('fg-grayBlue').addClass('fg-gray'); } } function autoBackup(note) { const timestamp = new Date().toISOString(); // Generate current timestamp const currentParams = { machinetype: laststatus.machine.name, note: note, timestamp: timestamp, grblParams: { ...grblParams // Spread Operator copy } }; // Add timestamp to the current parameters // Retrieve existing backups from localStorage or initialize an empty array let backups = JSON.parse(localStorage.getItem('grblParamsBackups')) || []; // Add the current backup to the beginning of the array backups.unshift(currentParams); // Trim backups to keep only the last 20 if (backups.length > 20) { backups = backups.slice(0, 20); } // Save the updated backups array back to localStorage localStorage.setItem('grblParamsBackups', JSON.stringify(backups)); // Optionally, add your existing save functionality here console.log('Settings saved and backup created.'); } function grblSaveSettings() { autoBackup("Updated Grbl Settings") var toSaveCommands = []; var saveProgressBar = $("#grblSaveProgress").data("progress"); for (var key in grblParams) { if (grblParams.hasOwnProperty(key)) { var j = key.substring(1) var newVal = $("#val-" + j + "-input").val(); // Only send values that changed if (newVal !== undefined) { if (parseFloat(newVal) != parseFloat(grblParams[key]) && newVal != grblParams[key]) { // console.log(key + ' was ' + grblParams[key] + ' but now, its ' + newVal); toSaveCommands.push(key + '=' + newVal); } } } } if (toSaveCommands.length > 0) { //console.log("commands", toSaveCommands) let counter = 0; // Blank the dialog if (saveProgressBar) { saveProgressBar.val(0); } $("#grblNewParam").html("") $("#grblNewParamVal").html("") // Open Dialog savingGrblSettingsProgress Metro.dialog.open('#savingGrblSettingsProgress') const i = setInterval(function() { //console.log(counter, toSaveCommands[counter]); var newParam = toSaveCommands[counter].split("=")[0]; var newParamKey = newParam.substr(1); if (grblSettingsTemplate2[newParamKey] !== undefined) { var newParamName = grblSettingsTemplate2[newParamKey].title } else { var newParamName = "unknown" } var newParamVal = toSaveCommands[counter].split("=")[1]; $("#grblNewParam").html("" + newParam + " : " + newParamName + "")
$("#grblNewParamVal").html("" + newParamVal + "")
if (saveProgressBar) {
saveProgressBar.val(counter / toSaveCommands.length * 100);
}
//
sendGcode(toSaveCommands[counter] + "\n");;
counter++;
if (counter === toSaveCommands.length) {
// Finished running
clearInterval(i);
grblParams = {};
toSaveCommands = [];
askToResetOnGrblSettingsChange();
}
}, 400); // send another command every 400ms
}
}
function askToResetOnGrblSettingsChange() {
setTimeout(function() {
Metro.dialog.close('#savingGrblSettingsProgress')
Metro.dialog.create({
title: "Configuration Updated. Reset Grbl?",
content: "