Files
nebuleair_pro_4g/html/admin.html
Your Name 9d280c6e37 update
2025-04-01 11:57:39 +02:00

929 lines
33 KiB
HTML
Executable File

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>NebuleAir</title>
<link rel="stylesheet" href="assets/css/bootstrap.min.css">
<style>
body {
overflow-x: hidden;
}
#sidebar a.nav-link {
position: relative;
display: flex;
align-items: center;
}
#sidebar a.nav-link:hover {
background-color: rgba(0, 0, 0, 0.5);
}
#sidebar a.nav-link svg {
margin-right: 8px; /* Add spacing between icons and text */
}
#sidebar {
transition: transform 0.3s ease-in-out;
}
.offcanvas-backdrop {
z-index: 1040;
}
</style>
</head>
<body>
<!-- Topbar -->
<span id="topbar"></span>
<!-- Sidebar Offcanvas for Mobile -->
<div class="offcanvas offcanvas-start text-white bg-dark" tabindex="-1" id="sidebarOffcanvas" aria-labelledby="sidebarOffcanvasLabel">
<div class="offcanvas-header">
<h5 class="offcanvas-title" id="sidebarOffcanvasLabel">NebuleAir</h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body" id="sidebar_mobile">
</div>
</div>
<div class="container-fluid mt-5">
<div class="row">
<!-- Side bar -->
<aside class="col-md-2 col-lg-1 d-none d-md-block vh-100 position-fixed bg-dark text-white" id="sidebar">
</aside>
<!-- Main content -->
<main class="col-md-10 ms-sm-auto col-lg-11 offset-md-2 offset-lg-1 px-md-4">
<h1 class="mt-4">Admin</h1>
<div class="row mb-3">
<div class="col-lg-3 col-12">
<h3 class="mt-4">Parameters (config)</h3>
<form>
<div class="mb-3">
<label for="device_name" class="form-label">Device Name</label>
<input type="text" class="form-control" id="device_name" onchange="update_config_sqlite('deviceName', this.value)">
</div>
<div class="mb-3">
<label for="device_ID" class="form-label">Device ID</label>
<input type="text" class="form-control" id="device_ID" disabled>
</div>
<div class="mb-3">
<label for="modem_version" class="form-label">Modem Version</label>
<input type="text" class="form-control" id="modem_version" disabled>
</div>
<!-- config_scripts_table -->
<div class="form-check mb-3">
<input class="form-check-input" type="checkbox" value="" id="check_NPM" onchange="update_config_scripts_sqlite('NPM/get_data_modbus_v3.py', this.checked)">
<label class="form-check-label" for="check_NPM">
Next PM
</label>
</div>
<div class="form-check mb-3">
<input class="form-check-input" type="checkbox" value="" id="check_NPM_5channels" onchange="update_config_sqlite('npm_5channel', this.checked)">
<label class="form-check-label" for="check_NPM_5channels">
Next PM send 5 channels (no script)
</label>
</div>
<div class="form-check mb-3">
<input class="form-check-input" type="checkbox" value="" id="check_bme280" onchange="update_config_scripts_sqlite('BME280/get_data_v2.py', this.checked)">
<label class="form-check-label" for="check_bme280">
Sonde temp/hum (BME280)
</label>
</div>
<div class="form-check mb-3">
<input class="form-check-input" type="checkbox" value="" id="check_envea" onchange="update_config_scripts_sqlite('envea/read_value_v2.py', this.checked)">
<label class="form-check-label" for="check_envea">
Sonde Envea
</label>
</div>
<div class="form-check mb-3">
<input class="form-check-input" type="checkbox" value="" id="check_solarBattery" onchange="update_config_scripts_sqlite('MPPT/read.py', this.checked)">
<label class="form-check-label" for="check_solarBattery">
Solar / Battery MPPT
</label>
</div>
<div class="form-check mb-3">
<input class="form-check-input" type="checkbox" value="" id="check_WindMeter" onchange="update_config_sqlite('windMeter', this.checked)">
<label class="form-check-label" for="check_WindMeter">
Wind Meter (no script -> systemd service)
</label>
</div>
<div class="form-check mb-3">
<input class="form-check-input" type="checkbox" value="" id="check_uSpot" onchange="update_config_sqlite('send_uSpot', this.checked)" disabled>
<label class="form-check-label" for="check_uSpot">
uSpot
</label>
</div>
<div class="input-group mb-3" id="sondes_envea_div"></div>
<div id="envea_table"></div>
<!--<button type="submit" class="btn btn-primary">Submit</button>-->
</form>
</div>
<!-- CLOCK-->
<div class="col-lg-3 col-12">
<h3 class="mt-4">Clock</h3>
<div class="mb-3">
<label for="sys_local_time" class="form-label">System time (local)</label>
<input type="text" class="form-control" id="sys_local_time" disabled>
</div>
<div class="mb-3">
<label for="sys_UTC_time" class="form-label">System time (UTC)</label>
<input type="text" class="form-control" id="sys_UTC_time" disabled>
</div>
<div class="mb-3">
<label for="RTC_utc_time" class="form-label">RTC time (UTC)</label>
<input type="text" class="form-control" id="RTC_utc_time" disabled>
</div>
<div id="alert_container"></div>
<h5 class="mt-4">Set RTC</h5>
<button type="submit" class="btn btn-primary mb-1" onclick="set_RTC_withNTP()">WiFi (NTP) </button>
<button type="submit" class="btn btn-primary mb-1" onclick="set_RTC_withBrowser()">Browser time </button>
<button type="submit" class="btn btn-primary mb-1" onclick="set_RTC_with4G()" disabled>4G (NTP) </button>
</div>
<!-- UPDATE-->
<div class="col-lg-4 col-12">
<h3 class="mt-4">Updates</h3>
<button type="submit" class="btn btn-primary" onclick="updateGitPull()">Update firmware</button>
</div>
</div>
<!-- toast -->
<div class="toast-container position-fixed bottom-0 end-0 p-3">
<div id="liveToast" class="toast align-items-center text-bg-primary border-1" role="alert" aria-live="assertive" aria-atomic="true">
<div class="d-flex">
<div class="toast-body">
Hello, world! This is a toast message.
</div>
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
</div>
</div>
</main>
</div>
</div>
<!-- JAVASCRIPT -->
<!-- Link Ajax locally -->
<script src="assets/jquery/jquery-3.7.1.min.js"></script>
<!-- Link Bootstrap JS and Popper.js locally -->
<script src="assets/js/bootstrap.bundle.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
const elementsToLoad = [
{ id: 'topbar', file: 'topbar.html' },
{ id: 'sidebar', file: 'sidebar.html' },
{ id: 'sidebar_mobile', file: 'sidebar.html' }
];
elementsToLoad.forEach(({ id, file }) => {
fetch(file)
.then(response => response.text())
.then(data => {
const element = document.getElementById(id);
if (element) {
element.innerHTML = data;
}
})
.catch(error => console.error(`Error loading ${file}:`, error));
});
});
//end document.addEventListener
/*
___ _ _
/ _ \ _ __ | | ___ __ _ __| |
| | | | '_ \| | / _ \ / _` |/ _` |
| |_| | | | | |__| (_) | (_| | (_| |
\___/|_| |_|_____\___/ \__,_|\__,_|
*/
window.onload = function() {
//NEW way to get config (SQLite)
$.ajax({
url: 'launcher.php?type=get_config_sqlite',
dataType:'json',
//dataType: 'json', // Specify that you expect a JSON response
method: 'GET', // Use GET or POST depending on your needs
success: function(response) {
console.log("Getting SQLite config table:");
console.log(response);
//device name
const deviceName = document.getElementById("device_name");
deviceName.value = response.deviceName;
//device name_side bar
const elements = document.querySelectorAll('.sideBar_sensorName');
elements.forEach((element) => {
element.innerText = response.deviceName;
});
//device ID
const deviceID = response.deviceID.trim().toUpperCase();
const device_ID = document.getElementById("device_ID");
device_ID.value = response.deviceID.toUpperCase();
//modem_version
const modem_version = document.getElementById("modem_version");
modem_version.value = response.modem_version;
//nextPM send 5 channels
const checkbox_nmp5channels = document.getElementById("check_NPM_5channels");
checkbox_nmp5channels.checked = response.npm_5channel;
//windMeter (as a config not a script -> it's running with a systemd service)
const checkbox_wind = document.getElementById("check_WindMeter");
checkbox_wind.checked = response["windMeter"];
//send uSpot
const checkbox_uSpot = document.getElementById("check_uSpot");
checkbox_uSpot.checked = response["send_uSpot"];
},
error: function(xhr, status, error) {
console.error('AJAX request failed:', status, error);
}
});//end AJAX
//getting config_scripts table
$.ajax({
url: 'launcher.php?type=get_config_scripts_sqlite',
dataType:'json',
//dataType: 'json', // Specify that you expect a JSON response
method: 'GET', // Use GET or POST depending on your needs
success: function(response) {
console.log("Getting SQLite config scripts table:");
console.log(response);
const checkbox_NPM = document.getElementById("check_NPM");
const checkbox_bme = document.getElementById("check_bme280");
const checkbox_envea = document.getElementById("check_envea");
const checkbox_solar = document.getElementById("check_solarBattery");
checkbox_NPM.checked = response["NPM/get_data_modbus_v3.py"];
checkbox_bme.checked = response["BME280/get_data_v2.py"];
checkbox_envea.checked = response["envea/read_value_v2.py"];
checkbox_solar.checked = response["MPPT/read.py"];
//si sonde envea is true
if (response["envea/read_value_v2.py"]) {
add_sondeEnveaContainer();
}
},
error: function(xhr, status, error) {
console.error('AJAX request failed:', status, error);
}
});//end AJAX
//OLD way to get config (JSON)
/*
fetch('../config.json') // Replace 'deviceID.txt' with 'config.json'
.then(response => response.json()) // Parse response as JSON
.then(data => {
console.log("Getting config file (onload)");
//get device ID
//document.getElementById('pageTitle_plus_ID').innerText = 'token: ' + deviceID;
//get device Name
//const deviceName = data.deviceName;
//get BME check
const checkbox = document.getElementById("check_bme280");
checkbox.checked = data["BME280/get_data_v2.py"];
//get NPM-5channels check
const checkbox_NPM_5channels = document.getElementById("check_NPM_5channels");
checkbox_NPM_5channels.checked = data["NextPM_5channels"];
//get sonde Envea check
const checkbox_envea = document.getElementById("check_envea");
checkbox_envea.checked = data["envea/read_value_v2.py"];
//device name
//const device_name = document.getElementById("device_name");
//device_name.value = data.deviceName;
})
.catch(error => console.error('Error loading config.json:', error));
*/
//get system time and RTC module
$.ajax({
url: 'launcher.php?type=sys_RTC_module_time',
dataType: 'json', // Specify that you expect a JSON response
method: 'GET', // Use GET or POST depending on your needs
success: function(response) {
console.log("Getting RTC times");
console.log(response);
// Update the input fields with the received JSON data
document.getElementById("sys_local_time").value = response.system_local_time;
document.getElementById("sys_UTC_time").value = response.system_utc_time;
document.getElementById("RTC_utc_time").value = response.rtc_module_time;
// Get the time difference
const timeDiff = response.time_difference_seconds;
// Reference to the alert container
const alertContainer = document.getElementById("alert_container");
// Remove any previous alert
alertContainer.innerHTML = "";
// Add an alert based on time difference
if (typeof timeDiff === "number") {
if (timeDiff >= 0 && timeDiff <= 10) {
alertContainer.innerHTML = `
<div class="alert alert-success" role="alert">
RTC and system time are in sync (Difference: ${timeDiff} sec).
</div>`;
} else if (timeDiff > 10) {
alertContainer.innerHTML = `
<div class="alert alert-danger" role="alert">
RTC time is out of sync! (Difference: ${timeDiff} sec).
</div>`;
}
}
},
error: function(xhr, status, error) {
console.error('AJAX request failed:', status, error);
}
});//end AJAX
//get local RTC
$.ajax({
url: 'launcher.php?type=RTC_time',
dataType: 'text', // Specify that you expect a JSON response
method: 'GET', // Use GET or POST depending on your needs
success: function(response) {
//console.log("Local RTC: " + response);
const RTC_Element = document.getElementById("RTC_time");
RTC_Element.textContent = response;
},
error: function(xhr, status, error) {
console.error('AJAX request failed:', status, error);
}
}); //end AJAx
} //end window.onload
function update_config_sqlite(param, value){
console.log("Updating sqlite ",param," : ", value);
const toastLiveExample = document.getElementById('liveToast')
const toastBody = toastLiveExample.querySelector('.toast-body');
$.ajax({
url: 'launcher.php?type=update_config_sqlite&param='+param+'&value='+value,
dataType: 'json', // Specify that you expect a JSON response
method: 'GET', // Use GET or POST depending on your needs
cache: false, // Prevent AJAX from caching
success: function(response) {
console.log(response);
// Format the response nicely
let formattedMessage = '';
if (response.success) {
// Success message
toastLiveExample.classList.remove('text-bg-danger');
toastLiveExample.classList.add('text-bg-success');
formattedMessage = `
<strong>Success!</strong><br>
Parameter: ${response.param || param}<br>
Value: ${response.value || checked}<br>
${response.message || ''}
`;
} else {
// Error message
toastLiveExample.classList.remove('text-bg-success');
toastLiveExample.classList.add('text-bg-danger');
formattedMessage = `
<strong>Error!</strong><br>
${response.error || 'Unknown error'}<br>
Parameter: ${response.param || param}
`;
}
// Update the toast body with formatted content
toastBody.innerHTML = formattedMessage;
// Show the toast
const toastBootstrap = bootstrap.Toast.getOrCreateInstance(toastLiveExample)
toastBootstrap.show()
},
error: function(xhr, status, error) {
console.error('AJAX request failed:', status, error);
}
});
}
function update_config_scripts_sqlite(param, value) {
console.log("Updating scripts sqlite ", param, " : ", value);
const toastLiveExample = document.getElementById('liveToast')
const toastBody = toastLiveExample.querySelector('.toast-body');
$.ajax({
url: 'launcher.php?type=update_config_scripts_sqlite&param=' + param + '&value=' + value,
dataType: 'json',
method: 'GET',
cache: false,
success: function(response) {
console.log(response);
// Format the response nicely
let formattedMessage = '';
if (response.success) {
// Success message
toastLiveExample.classList.remove('text-bg-danger');
toastLiveExample.classList.add('text-bg-success');
formattedMessage = `
<strong>Success!</strong><br>
Parameter: ${response.script_path || param}<br>
Value: ${response.enabled !== undefined ? response.enabled : value}<br>
${response.message || ''}
`;
if (response.script_path == "envea/read_value_v2.py") {
console.log("envea sondes activated");
add_sondeEnveaContainer();
}
} else {
// Error message
toastLiveExample.classList.remove('text-bg-success');
toastLiveExample.classList.add('text-bg-danger');
formattedMessage = `
<strong>Error!</strong><br>
${response.error || 'Unknown error'}<br>
Parameter: ${response.script_path || param}
`;
}
// Update the toast body with formatted content
toastBody.innerHTML = formattedMessage;
// Show the toast
const toastBootstrap = bootstrap.Toast.getOrCreateInstance(toastLiveExample)
toastBootstrap.show()
},
error: function(xhr, status, error) {
console.error('AJAX request failed:', status, error);
}
});
}
function update_config(param, value){
console.log("Updating ",param," : ", value);
$.ajax({
url: 'launcher.php?type=update_config&param='+param+'&value='+value,
dataType: 'text', // Specify that you expect a JSON response
method: 'GET', // Use GET or POST depending on your needs
cache: false, // Prevent AJAX from caching
success: function(response) {
console.log(response);
},
error: function(xhr, status, error) {
console.error('AJAX request failed:', status, error);
}
});
}
function updateGitPull(){
console.log("Updating device (git pull)");
$.ajax({
url: 'launcher.php?type=git_pull',
method: 'GET', // Use GET or POST depending on your needs
dataType: 'text', // Specify that you expect a JSON response
success: function(response) {
// Handle success response if needed
console.log(response);
alert(response);
// Reload the page after the device update
location.reload(); // This will reload the page
},
error: function(xhr, status, error) {
console.error('AJAX request failed:', status, error);
}
});
}
function set_RTC_withNTP(){
console.log("Set RTC module with WIFI (NTP server)");
$.ajax({
url: 'launcher.php?type=set_RTC_withNTP',
method: 'GET', // Use GET or POST depending on your needs
dataType: 'text', // Specify that you expect a JSON response
success: function(response) {
// Handle success response if needed
console.log(response);
alert(response);
// Reload the page after the device update
location.reload(); // This will reload the page
},
error: function(xhr, status, error) {
console.error('AJAX request failed:', status, error);
}
}); //end ajax
}
function set_RTC_withBrowser(){
console.log("Set RTC module with browser time");
const browserTime = new Date(); // Get the current time in the browser
const formattedTime = browserTime.toISOString(); // Convert to ISO string (UTC)
console.log(formattedTime);
$.ajax({
url: `launcher.php?type=set_RTC_withBrowser&time=${encodeURIComponent(formattedTime)}`,
method: 'GET', // Use GET or POST depending on your needs
dataType: 'json', // Specify that you expect a JSON response
success: function(response) {
// Handle success response if needed
console.log(response);
if (response.success) {
alert("RTC successfully updated!");
} else {
alert(`Error: ${response.message}`);
} // Reload the page after the device update
location.reload(); // This will reload the page
},
error: function(xhr, status, error) {
console.error('AJAX request failed:', status, error);
}
}); //end ajax
}
/*
____ _ _____
/ ___| ___ _ __ __| | ___ ___ | ____|_ ____ _____ __ _
\___ \ / _ \| '_ \ / _` |/ _ \/ __| | _| | '_ \ \ / / _ \/ _` |
___) | (_) | | | | (_| | __/\__ \ | |___| | | \ V / __/ (_| |
|____/ \___/|_| |_|\__,_|\___||___/ |_____|_| |_|\_/ \___|\__,_|
*/
function add_sondeEnveaContainer() {
console.log("Sonde Envea is true: need to add container!");
// Getting envea_sondes_table data
$.ajax({
url: 'launcher.php?type=get_envea_sondes_table_sqlite',
dataType: 'json',
method: 'GET',
success: function(sondes) {
console.log("Getting SQLite envea sondes table:");
console.log(sondes);
// Create container div if it doesn't exist
if ($('#sondes_envea_div').length === 0) {
$('#advanced_options').append('<div id="sondes_envea_div" class="input-group mt-4 border p-3 rounded"><legend>Sondes Envea</legend><p>Plouf</p></div>');
} else {
// Clear existing content if container exists
$('#sondes_envea_div').html('<legend>Sondes Envea</legend>');
$('#envea_table').html('<table class="table table-striped table-bordered">'+
'<thead><tr><th scope="col">Software</th><th scope="col">Hardware (PCB)</th></tr></thead>'+
'<tbody>' +
'<tr><td>ttyAMA5</td><td>NPM1</td></tr>' +
'<tr><td>ttyAMA4</td><td>NPM2</td></tr>' +
'<tr><td>ttyAMA3</td><td>NPM3</td></tr>' +
'<tr><td>ttyAMA2</td><td>SARA</td></tr>' +
'</tbody></table>');
}
// Loop through each sonde and create UI elements
sondes.forEach(function(sonde) {
// Create a unique ID for this sonde
const sondeId = `sonde_${sonde.id}`;
// Create HTML for this sonde
const sondeHtml = `
<div class="input-group mb-3" id="${sondeId}_container">
<div class="input-group-text">
<input class="form-check-input mt-0" type="checkbox" id="${sondeId}_enabled"
${sonde.connected ? 'checked' : ''}
onchange="updateSondeStatus(${sonde.id}, this.checked)">
</div>
<input type="text" class="form-control" placeholder="Name" value="${sonde.name}"
id="${sondeId}_name" onchange="updateSondeName(${sonde.id}, this.value)">
<input type="text" class="form-control" placeholder="Port" value="${sonde.port}"
id="${sondeId}_port" onchange="updateSondePort(${sonde.id}, this.value)">
<input type="number" class="form-control" placeholder="Coefficient" value="${sonde.coefficient}"
id="${sondeId}_coefficient" onchange="updateSondeCoefficient(${sonde.id}, this.value)">
</div>
`;
// Append this sonde to the container
$('#sondes_envea_div').append(sondeHtml);
});
},
error: function(xhr, status, error) {
console.error('AJAX request failed:', status, error);
}
});
}
// Helper functions for updating sonde properties
function updateSondeStatus(id, connected) {
console.log(`Updating sonde ${id} connected status to: ${connected}`);
const toastLiveExample = document.getElementById('liveToast');
const toastBody = toastLiveExample.querySelector('.toast-body');
$.ajax({
url: `launcher.php?type=update_sonde&id=${id}&field=connected&value=${connected ? 1 : 0}`,
dataType: 'json',
method: 'GET',
cache: false,
success: function(response) {
console.log('Sonde status updated:', response);
// Format the response for toast
let formattedMessage = '';
if (response.success) {
// Success message
toastLiveExample.classList.remove('text-bg-danger');
toastLiveExample.classList.add('text-bg-success');
formattedMessage = `
<strong>Success!</strong><br>
Sonde ID: ${response.id}<br>
Connected: ${connected ? "Yes" : "No"}<br>
${response.message || ''}
`;
} else {
// Error message
toastLiveExample.classList.remove('text-bg-success');
toastLiveExample.classList.add('text-bg-danger');
formattedMessage = `
<strong>Error!</strong><br>
${response.error || 'Unknown error'}<br>
Sonde ID: ${id}
`;
}
// Update and show toast
toastBody.innerHTML = formattedMessage;
const toastBootstrap = bootstrap.Toast.getOrCreateInstance(toastLiveExample);
toastBootstrap.show();
},
error: function(xhr, status, error) {
console.error('Failed to update sonde status:', error);
// Show error toast
toastLiveExample.classList.remove('text-bg-success');
toastLiveExample.classList.add('text-bg-danger');
toastBody.innerHTML = `
<strong>Request Failed!</strong><br>
Error: ${error}<br>
Sonde ID: ${id}
`;
const toastBootstrap = bootstrap.Toast.getOrCreateInstance(toastLiveExample);
toastBootstrap.show();
}
});
}
function updateSondeName(id, name) {
console.log(`Updating sonde ${id} name to: ${name}`);
const toastLiveExample = document.getElementById('liveToast');
const toastBody = toastLiveExample.querySelector('.toast-body');
$.ajax({
url: `launcher.php?type=update_sonde&id=${id}&field=name&value=${encodeURIComponent(name)}`,
dataType: 'json',
method: 'GET',
cache: false,
success: function(response) {
console.log('Sonde name updated:', response);
// Format the response for toast
let formattedMessage = '';
if (response.success) {
// Success message
toastLiveExample.classList.remove('text-bg-danger');
toastLiveExample.classList.add('text-bg-success');
formattedMessage = `
<strong>Success!</strong><br>
Sonde ID: ${response.id}<br>
Name: ${name}<br>
${response.message || ''}
`;
} else {
// Error message
toastLiveExample.classList.remove('text-bg-success');
toastLiveExample.classList.add('text-bg-danger');
formattedMessage = `
<strong>Error!</strong><br>
${response.error || 'Unknown error'}<br>
Sonde ID: ${id}
`;
}
// Update and show toast
toastBody.innerHTML = formattedMessage;
const toastBootstrap = bootstrap.Toast.getOrCreateInstance(toastLiveExample);
toastBootstrap.show();
},
error: function(xhr, status, error) {
console.error('Failed to update sonde name:', error);
// Show error toast
toastLiveExample.classList.remove('text-bg-success');
toastLiveExample.classList.add('text-bg-danger');
toastBody.innerHTML = `
<strong>Request Failed!</strong><br>
Error: ${error}<br>
Sonde ID: ${id}
`;
const toastBootstrap = bootstrap.Toast.getOrCreateInstance(toastLiveExample);
toastBootstrap.show();
}
});
}
function updateSondePort(id, port) {
console.log(`Updating sonde ${id} port to: ${port}`);
const toastLiveExample = document.getElementById('liveToast');
const toastBody = toastLiveExample.querySelector('.toast-body');
$.ajax({
url: `launcher.php?type=update_sonde&id=${id}&field=port&value=${encodeURIComponent(port)}`,
dataType: 'json',
method: 'GET',
cache: false,
success: function(response) {
console.log('Sonde port updated:', response);
// Format the response for toast
let formattedMessage = '';
if (response.success) {
// Success message
toastLiveExample.classList.remove('text-bg-danger');
toastLiveExample.classList.add('text-bg-success');
formattedMessage = `
<strong>Success!</strong><br>
Sonde ID: ${response.id}<br>
Port: ${port}<br>
${response.message || ''}
`;
} else {
// Error message
toastLiveExample.classList.remove('text-bg-success');
toastLiveExample.classList.add('text-bg-danger');
formattedMessage = `
<strong>Error!</strong><br>
${response.error || 'Unknown error'}<br>
Sonde ID: ${id}
`;
}
// Update and show toast
toastBody.innerHTML = formattedMessage;
const toastBootstrap = bootstrap.Toast.getOrCreateInstance(toastLiveExample);
toastBootstrap.show();
},
error: function(xhr, status, error) {
console.error('Failed to update sonde port:', error);
// Show error toast
toastLiveExample.classList.remove('text-bg-success');
toastLiveExample.classList.add('text-bg-danger');
toastBody.innerHTML = `
<strong>Request Failed!</strong><br>
Error: ${error}<br>
Sonde ID: ${id}
`;
const toastBootstrap = bootstrap.Toast.getOrCreateInstance(toastLiveExample);
toastBootstrap.show();
}
});
}
function updateSondeCoefficient(id, coefficient) {
console.log(`Updating sonde ${id} coefficient to: ${coefficient}`);
const toastLiveExample = document.getElementById('liveToast');
const toastBody = toastLiveExample.querySelector('.toast-body');
$.ajax({
url: `launcher.php?type=update_sonde&id=${id}&field=coefficient&value=${coefficient}`,
dataType: 'json',
method: 'GET',
cache: false,
success: function(response) {
console.log('Sonde coefficient updated:', response);
// Format the response for toast
let formattedMessage = '';
if (response.success) {
// Success message
toastLiveExample.classList.remove('text-bg-danger');
toastLiveExample.classList.add('text-bg-success');
formattedMessage = `
<strong>Success!</strong><br>
Sonde ID: ${response.id}<br>
Coefficient: ${coefficient}<br>
${response.message || ''}
`;
} else {
// Error message
toastLiveExample.classList.remove('text-bg-success');
toastLiveExample.classList.add('text-bg-danger');
formattedMessage = `
<strong>Error!</strong><br>
${response.error || 'Unknown error'}<br>
Sonde ID: ${id}
`;
}
// Update and show toast
toastBody.innerHTML = formattedMessage;
const toastBootstrap = bootstrap.Toast.getOrCreateInstance(toastLiveExample);
toastBootstrap.show();
},
error: function(xhr, status, error) {
console.error('Failed to update sonde coefficient:', error);
// Show error toast
toastLiveExample.classList.remove('text-bg-success');
toastLiveExample.classList.add('text-bg-danger');
toastBody.innerHTML = `
<strong>Request Failed!</strong><br>
Error: ${error}<br>
Sonde ID: ${id}
`;
const toastBootstrap = bootstrap.Toast.getOrCreateInstance(toastLiveExample);
toastBootstrap.show();
}
});
}
</script>
</body>
</html>