|
|
<!DOCTYPE html> |
|
|
<html> |
|
|
<head> |
|
|
<meta charset="UTF-8"> |
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
|
<title>Contrôleur - Mise à jour</title> |
|
|
<style> |
|
|
body { |
|
|
font-family: Arial, sans-serif; |
|
|
max-width: 800px; |
|
|
margin: 50px auto; |
|
|
padding: 20px; |
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
|
|
min-height: 100vh; |
|
|
} |
|
|
|
|
|
.container { |
|
|
background: white; |
|
|
padding: 40px; |
|
|
border-radius: 10px; |
|
|
box-shadow: 0 10px 30px rgba(0,0,0,0.3); |
|
|
} |
|
|
|
|
|
h1 { |
|
|
color: #333; |
|
|
text-align: center; |
|
|
margin-bottom: 30px; |
|
|
} |
|
|
|
|
|
h2 { |
|
|
color: #667eea; |
|
|
border-bottom: none; |
|
|
padding-bottom: 10px; |
|
|
margin-top: 30px; |
|
|
} |
|
|
|
|
|
.nav-links { |
|
|
text-align: center; |
|
|
margin-top: 30px; |
|
|
} |
|
|
|
|
|
.nav-links a { |
|
|
display: inline-block; |
|
|
padding: 10px 20px; |
|
|
background: #95a5a6; |
|
|
color: white; |
|
|
text-decoration: none; |
|
|
border-radius: 5px; |
|
|
margin: 5px; |
|
|
transition: background 0.3s; |
|
|
} |
|
|
|
|
|
.nav-links a:hover { |
|
|
background: #7f8c8d; |
|
|
} |
|
|
|
|
|
input[type="file"] { |
|
|
width: 100%; |
|
|
padding: 10px; |
|
|
border: 2px solid #ddd; |
|
|
border-radius: 5px; |
|
|
font-size: 16px; |
|
|
box-sizing: border-box; |
|
|
} |
|
|
|
|
|
button { |
|
|
width: 100%; |
|
|
padding: 12px 30px; |
|
|
background: #667eea; |
|
|
color: white; |
|
|
border: none; |
|
|
border-radius: 5px; |
|
|
font-size: 16px; |
|
|
font-weight: bold; |
|
|
cursor: pointer; |
|
|
transition: background 0.3s; |
|
|
margin-right: 10px; |
|
|
} |
|
|
|
|
|
button:hover { |
|
|
background: #764ba2; |
|
|
} |
|
|
|
|
|
button:disabled { |
|
|
background: #ccc; |
|
|
cursor: not-allowed; |
|
|
} |
|
|
|
|
|
.message { |
|
|
padding: 15px; |
|
|
border-radius: 5px; |
|
|
margin-bottom: 20px; |
|
|
display: none; |
|
|
} |
|
|
|
|
|
.message.success { |
|
|
background: #d4edda; |
|
|
color: #155724; |
|
|
border: 1px solid #c3e6cb; |
|
|
} |
|
|
|
|
|
.message.error { |
|
|
background: #f8d7da; |
|
|
color: #721c24; |
|
|
border: 1px solid #f5c6cb; |
|
|
} |
|
|
|
|
|
.update-section { |
|
|
margin: 30px 0; |
|
|
padding: 25px; |
|
|
border: 2px solid #667eea; |
|
|
border-radius: 8px; |
|
|
} |
|
|
|
|
|
/* Styles spécifiques à update.html */ |
|
|
button { |
|
|
width: 100%; |
|
|
} |
|
|
.progress { |
|
|
width: 100%; |
|
|
height: 30px; |
|
|
background: #f0f0f0; |
|
|
border-radius: 5px; |
|
|
overflow: hidden; |
|
|
margin: 15px 0; |
|
|
display: none; |
|
|
} |
|
|
|
|
|
.progress-bar { |
|
|
height: 100%; |
|
|
background: linear-gradient(90deg, #667eea 0%, #764ba2 100%); |
|
|
width: 0%; |
|
|
transition: width 0.3s; |
|
|
display: flex; |
|
|
align-items: center; |
|
|
justify-content: center; |
|
|
color: white; |
|
|
font-weight: bold; |
|
|
} |
|
|
</style> |
|
|
</head> |
|
|
<body> |
|
|
<div class="container"> |
|
|
<h1>🔄 Mise à jour OTA</h1> |
|
|
|
|
|
<div class="update-section"> |
|
|
<h2>📱 Mise à jour du Firmware</h2> |
|
|
<p>Sélectionnez un fichier .bin pour mettre à jour le firmware de l'ESP</p> |
|
|
<input type="file" id="firmwareFile" accept=".bin"> |
|
|
<div class="progress" id="firmwareProgress"> |
|
|
<div class="progress-bar" id="firmwareProgressBar">0%</div> |
|
|
</div> |
|
|
<div class="message" id="firmwareMessage"></div> |
|
|
<button onclick="uploadFirmware()" id="firmwareBtn">Envoyer le Firmware</button> |
|
|
</div> |
|
|
|
|
|
<div class="update-section"> |
|
|
<h2>📁 Mise à jour du Filesystem</h2> |
|
|
<p>Sélectionnez un fichier .bin du filesystem LittleFS</p> |
|
|
<input type="file" id="filesystemFile" accept=".bin"> |
|
|
<div class="progress" id="filesystemProgress"> |
|
|
<div class="progress-bar" id="filesystemProgressBar">0%</div> |
|
|
</div> |
|
|
<div class="message" id="filesystemMessage"></div> |
|
|
<button onclick="uploadFilesystem()" id="filesystemBtn">Envoyer le Filesystem</button> |
|
|
</div> |
|
|
|
|
|
<div class="nav-links"> |
|
|
<a href="/">🏠 Accueil</a> |
|
|
<a href="/settings.html">⚙️ Configuration</a> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<script> |
|
|
function showMessage(type, elementId, message) { |
|
|
const msgElement = document.getElementById(elementId); |
|
|
msgElement.className = 'message ' + type; |
|
|
msgElement.textContent = message; |
|
|
msgElement.style.display = 'block'; |
|
|
} |
|
|
|
|
|
function updateProgress(progressBarId, percent) { |
|
|
const bar = document.getElementById(progressBarId); |
|
|
bar.style.width = percent + '%'; |
|
|
bar.textContent = percent + '%'; |
|
|
} |
|
|
|
|
|
function uploadFirmware() { |
|
|
const fileInput = document.getElementById('firmwareFile'); |
|
|
const file = fileInput.files[0]; |
|
|
|
|
|
if (!file) { |
|
|
showMessage('error', 'firmwareMessage', 'Veuillez sélectionner un fichier'); |
|
|
return; |
|
|
} |
|
|
|
|
|
const formData = new FormData(); |
|
|
formData.append('firmware', file); |
|
|
|
|
|
const button = document.getElementById('firmwareBtn'); |
|
|
button.disabled = true; |
|
|
document.getElementById('firmwareProgress').style.display = 'block'; |
|
|
document.getElementById('firmwareMessage').style.display = 'none'; |
|
|
|
|
|
const xhr = new XMLHttpRequest(); |
|
|
|
|
|
xhr.upload.addEventListener('progress', (e) => { |
|
|
if (e.lengthComputable) { |
|
|
const percent = Math.round((e.loaded / e.total) * 100); |
|
|
updateProgress('firmwareProgressBar', percent); |
|
|
} |
|
|
}); |
|
|
|
|
|
xhr.addEventListener('load', () => { |
|
|
button.disabled = false; |
|
|
if (xhr.status === 200) { |
|
|
showMessage('success', 'firmwareMessage', 'Firmware mis à jour avec succès! Redémarrage en cours...'); |
|
|
setTimeout(() => { |
|
|
window.location.href = '/index.html'; |
|
|
}, 10000); |
|
|
} else { |
|
|
showMessage('error', 'firmwareMessage', 'Erreur lors de la mise à jour: ' + xhr.responseText); |
|
|
} |
|
|
}); |
|
|
|
|
|
xhr.addEventListener('error', () => { |
|
|
button.disabled = false; |
|
|
showMessage('error', 'firmwareMessage', 'Erreur de connexion'); |
|
|
}); |
|
|
|
|
|
xhr.open('POST', '/update'); |
|
|
xhr.send(formData); |
|
|
} |
|
|
|
|
|
function uploadFilesystem() { |
|
|
const fileInput = document.getElementById('filesystemFile'); |
|
|
const file = fileInput.files[0]; |
|
|
|
|
|
if (!file) { |
|
|
showMessage('error', 'filesystemMessage', 'Veuillez sélectionner un fichier'); |
|
|
return; |
|
|
} |
|
|
|
|
|
const formData = new FormData(); |
|
|
formData.append('filesystem', file); |
|
|
|
|
|
const button = document.getElementById('filesystemBtn'); |
|
|
button.disabled = true; |
|
|
document.getElementById('filesystemProgress').style.display = 'block'; |
|
|
document.getElementById('filesystemMessage').style.display = 'none'; |
|
|
|
|
|
const xhr = new XMLHttpRequest(); |
|
|
|
|
|
xhr.upload.addEventListener('progress', (e) => { |
|
|
if (e.lengthComputable) { |
|
|
const percent = Math.round((e.loaded / e.total) * 100); |
|
|
updateProgress('filesystemProgressBar', percent); |
|
|
} |
|
|
}); |
|
|
|
|
|
xhr.addEventListener('load', () => { |
|
|
button.disabled = false; |
|
|
if (xhr.status === 200) { |
|
|
showMessage('success', 'filesystemMessage', 'Filesystem mis à jour avec succès! Redémarrage en cours...'); |
|
|
setTimeout(() => { |
|
|
window.location.href = '/index.html'; |
|
|
}, 10000); |
|
|
} else { |
|
|
showMessage('error', 'filesystemMessage', 'Erreur lors de la mise à jour: ' + xhr.responseText); |
|
|
} |
|
|
}); |
|
|
|
|
|
xhr.addEventListener('error', () => { |
|
|
button.disabled = false; |
|
|
showMessage('error', 'filesystemMessage', 'Erreur de connexion'); |
|
|
}); |
|
|
|
|
|
xhr.open('POST', '/update?filesystem=true'); |
|
|
xhr.send(formData); |
|
|
} |
|
|
</script> |
|
|
</body> |
|
|
</html>
|
|
|
|