This commit is contained in:
Your Name
2025-06-30 15:37:24 +01:00
parent acdc736a38
commit 3b8b51172c
2 changed files with 146 additions and 1 deletions

View File

@@ -155,7 +155,34 @@
<div class="col-lg-4 col-12"> <div class="col-lg-4 col-12">
<h3 class="mt-4">Updates</h3> <h3 class="mt-4">Updates</h3>
<button type="submit" class="btn btn-primary" onclick="updateGitPull()">Update firmware</button> <button type="submit" class="btn btn-primary" onclick="updateGitPull()">Update firmware (v1)</button>
<button type="submit" class="btn btn-primary" onclick="updateFirmware()" id="updateBtn">
<span id="updateBtnText">Update firmware (v2)</span>
<span id="updateSpinner" class="spinner-border spinner-border-sm ms-2" style="display: none;"></span>
</button>
<!-- Update Output Console -->
<div id="updateOutput" class="mt-3" style="display: none;">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<span class="fw-bold">Update Log</span>
<div>
<button type="button" class="btn btn-sm btn-success me-2" onclick="location.reload()" id="reloadBtn" style="display: none;">
<svg width="14" height="14" fill="currentColor" class="bi bi-arrow-clockwise me-1" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M8 3a5 5 0 1 0 4.546 2.914.5.5 0 0 1 .908-.417A6 6 0 1 1 8 2v1z"/>
<path d="M8 4.466V.534a.25.25 0 0 1 .41-.192l2.36 1.966c.12.1.12.284 0 .384L8.41 4.658A.25.25 0 0 1 8 4.466z"/>
</svg>
Reload Page
</button>
<button type="button" class="btn btn-sm btn-outline-secondary" onclick="clearUpdateOutput()">
Clear
</button>
</div>
</div>
<div class="card-body">
<pre id="updateOutputContent" class="mb-0" style="max-height: 400px; overflow-y: auto; font-size: 0.85rem; background-color: #f8f9fa; padding: 1rem; border-radius: 0.375rem;"></pre>
</div>
</div>
</div>
</div> </div>
</div> </div>
@@ -285,11 +312,13 @@ window.onload = function() {
const checkbox_bme = document.getElementById("check_bme280"); const checkbox_bme = document.getElementById("check_bme280");
const checkbox_CO2 = document.getElementById("check_CO2"); const checkbox_CO2 = document.getElementById("check_CO2");
const checkbox_SFA30 = document.getElementById("check_sensirionSFA30"); const checkbox_SFA30 = document.getElementById("check_sensirionSFA30");
const checkbox_uSpot = document.getElementById("check_uSpot");
checkbox_nmp5channels.checked = response.npm_5channel; checkbox_nmp5channels.checked = response.npm_5channel;
checkbox_bme.checked = response["BME280"]; checkbox_bme.checked = response["BME280"];
checkbox_SFA30.checked = response["SFA30"]; checkbox_SFA30.checked = response["SFA30"];
checkbox_CO2.checked = response["MHZ19"]; checkbox_CO2.checked = response["MHZ19"];
checkbox_uSpot.checked = response["send_uSpot"];
//si sonde envea is true //si sonde envea is true
if (response["envea"]) { if (response["envea"]) {
@@ -439,6 +468,108 @@ function updateGitPull(){
}); });
} }
function updateFirmware() {
console.log("Starting comprehensive firmware update...");
// Show loading state
const updateBtn = document.getElementById('updateBtn');
const updateBtnText = document.getElementById('updateBtnText');
const updateSpinner = document.getElementById('updateSpinner');
const updateOutput = document.getElementById('updateOutput');
const updateOutputContent = document.getElementById('updateOutputContent');
// Disable button and show spinner
updateBtn.disabled = true;
updateBtnText.textContent = 'Updating...';
updateSpinner.style.display = 'inline-block';
// Show output console
updateOutput.style.display = 'block';
updateOutputContent.textContent = 'Starting update process...\n';
$.ajax({
url: 'launcher.php?type=update_firmware',
method: 'GET',
dataType: 'json',
timeout: 120000, // 2 minutes timeout
success: function(response) {
console.log('Update completed:', response);
// Display formatted output
if (response.success && response.output) {
// Format the output for better readability
const formattedOutput = response.output
.replace(/\[\d{2}:\d{2}:\d{2}\]/g, function(match) {
return `<span style="color: #007bff; font-weight: bold;">${match}</span>`;
})
.replace(/✓/g, '<span style="color: #28a745;">✓</span>')
.replace(/✗/g, '<span style="color: #dc3545;">✗</span>')
.replace(/⚠/g, '<span style="color: #ffc107;">⚠</span>')
.replace(//g, '<span style="color: #17a2b8;"></span>');
updateOutputContent.innerHTML = formattedOutput;
// Show success toast and reload button
showToast('Update completed successfully!', 'success');
document.getElementById('reloadBtn').style.display = 'inline-block';
} else {
updateOutputContent.textContent = 'Update completed but no output received.';
showToast('Update may have completed with issues', 'warning');
}
},
error: function(xhr, status, error) {
console.error('Update failed:', status, error);
updateOutputContent.textContent = `Update failed: ${error}\n\nStatus: ${status}\nResponse: ${xhr.responseText || 'No response'}`;
showToast('Update failed! Check the output for details.', 'error');
},
complete: function() {
// Reset button state
updateBtn.disabled = false;
updateBtnText.textContent = 'Update firmware';
updateSpinner.style.display = 'none';
}
});
}
function clearUpdateOutput() {
const updateOutput = document.getElementById('updateOutput');
const updateOutputContent = document.getElementById('updateOutputContent');
const reloadBtn = document.getElementById('reloadBtn');
updateOutputContent.textContent = '';
updateOutput.style.display = 'none';
reloadBtn.style.display = 'none';
}
function showToast(message, type) {
const toastLiveExample = document.getElementById('liveToast');
const toastBody = toastLiveExample.querySelector('.toast-body');
// Set toast color based on type
toastLiveExample.classList.remove('text-bg-primary', 'text-bg-success', 'text-bg-danger', 'text-bg-warning');
switch(type) {
case 'success':
toastLiveExample.classList.add('text-bg-success');
break;
case 'error':
toastLiveExample.classList.add('text-bg-danger');
break;
case 'warning':
toastLiveExample.classList.add('text-bg-warning');
break;
default:
toastLiveExample.classList.add('text-bg-primary');
}
toastBody.textContent = message;
const toastBootstrap = bootstrap.Toast.getOrCreateInstance(toastLiveExample);
toastBootstrap.show();
}
function set_RTC_withNTP(){ function set_RTC_withNTP(){
console.log("Set RTC module with WIFI (NTP server)"); console.log("Set RTC module with WIFI (NTP server)");

View File

@@ -255,6 +255,20 @@ if ($type == "git_pull") {
echo $output; echo $output;
} }
if ($type == "update_firmware") {
// Execute the comprehensive update script
$command = 'sudo /var/www/moduleair_pro_4g/update_firmware.sh 2>&1';
$output = shell_exec($command);
// Return the output as JSON for better web display
header('Content-Type: application/json');
echo json_encode([
'success' => true,
'output' => $output,
'timestamp' => date('Y-m-d H:i:s')
]);
}
if ($type == "set_RTC_withNTP") { if ($type == "set_RTC_withNTP") {
$command = 'sudo /usr/bin/python3 /var/www/moduleair_pro_4g/RTC/set_with_NTP.py'; $command = 'sudo /usr/bin/python3 /var/www/moduleair_pro_4g/RTC/set_with_NTP.py';
$output = shell_exec($command); $output = shell_exec($command);