Initialisation depot

This commit is contained in:
2025-11-30 09:58:00 +01:00
commit 56d8cd96c8
28 changed files with 3154 additions and 0 deletions

182
data/js/app.js Normal file
View File

@@ -0,0 +1,182 @@
let currentMode = 'analog';
let currentDirection = 1;
let dccFunctions = 0;
// Initialize
document.addEventListener('DOMContentLoaded', function() {
loadStatus();
setupEventListeners();
generateFunctionButtons();
setInterval(loadStatus, 2000);
});
function setupEventListeners() {
document.getElementById('speedSlider').addEventListener('input', function(e) {
updateSpeed(e.target.value);
});
document.querySelectorAll('input[name="mode"]').forEach(radio => {
radio.addEventListener('change', function(e) {
setMode(e.target.value);
});
});
document.getElementById('wifiMode').addEventListener('change', function(e) {
toggleWiFiSettings(e.target.value);
});
}
function generateFunctionButtons() {
const container = document.getElementById('functionButtons');
for (let i = 0; i <= 12; i++) {
const btn = document.createElement('button');
btn.className = 'btn btn-outline-secondary function-btn';
btn.id = 'f' + i;
btn.textContent = 'F' + i;
btn.onclick = () => toggleFunction(i);
container.appendChild(btn);
}
}
async function loadStatus() {
try {
const response = await fetch('/api/status');
const data = await response.json();
document.getElementById('statusIndicator').className = 'status-indicator status-connected';
document.getElementById('statusText').textContent = 'Connected';
document.getElementById('ipAddress').textContent = data.ip || '-';
currentMode = data.mode;
currentDirection = data.direction;
document.getElementById(data.mode === 'dcc' ? 'modeDCC' : 'modeAnalog').checked = true;
document.getElementById('speedSlider').value = data.speed;
document.getElementById('speedValue').textContent = data.speed + '%';
document.getElementById('dccAddress').value = data.dccAddress;
updateUIForMode(data.mode);
updateDirectionIndicator();
} catch (error) {
document.getElementById('statusIndicator').className = 'status-indicator status-disconnected';
document.getElementById('statusText').textContent = 'Disconnected';
}
}
function updateUIForMode(mode) {
currentMode = mode;
document.getElementById('dccSection').style.display = mode === 'dcc' ? 'block' : 'none';
document.getElementById('functionsSection').style.display = mode === 'dcc' ? 'block' : 'none';
}
async function setMode(mode) {
try {
await fetch('/api/mode', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({mode: mode})
});
updateUIForMode(mode);
} catch (error) {
console.error('Error setting mode:', error);
}
}
async function updateSpeed(speed) {
document.getElementById('speedValue').textContent = speed + '%';
try {
await fetch('/api/speed', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
speed: parseInt(speed),
direction: currentDirection
})
});
} catch (error) {
console.error('Error setting speed:', error);
}
}
async function emergencyStop() {
document.getElementById('speedSlider').value = 0;
updateSpeed(0);
}
async function reverseDirection() {
currentDirection = currentDirection === 1 ? 0 : 1;
updateDirectionIndicator();
const speed = document.getElementById('speedSlider').value;
updateSpeed(speed);
}
function updateDirectionIndicator() {
document.getElementById('directionIndicator').textContent = currentDirection === 1 ? '→' : '←';
}
async function setDCCAddress() {
const address = document.getElementById('dccAddress').value;
try {
await fetch('/api/dcc/address', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({address: parseInt(address)})
});
} catch (error) {
console.error('Error setting DCC address:', error);
}
}
async function toggleFunction(fn) {
const btn = document.getElementById('f' + fn);
const isActive = btn.classList.contains('btn-secondary');
if (isActive) {
btn.classList.remove('btn-secondary');
btn.classList.add('btn-outline-secondary');
} else {
btn.classList.remove('btn-outline-secondary');
btn.classList.add('btn-secondary');
}
try {
await fetch('/api/dcc/function', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
function: fn,
state: !isActive
})
});
} catch (error) {
console.error('Error setting function:', error);
}
}
function toggleWiFiSettings(mode) {
document.getElementById('apSettings').style.display = mode === 'ap' ? 'block' : 'none';
document.getElementById('clientSettings').style.display = mode === 'client' ? 'block' : 'none';
}
async function saveWiFiSettings() {
const mode = document.getElementById('wifiMode').value;
const config = {
isAPMode: mode === 'ap',
apSSID: document.getElementById('apSSID').value,
apPassword: document.getElementById('apPassword').value,
ssid: document.getElementById('wifiSSID').value,
password: document.getElementById('wifiPassword').value
};
if (confirm('Save WiFi settings and restart?')) {
try {
await fetch('/api/wifi', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(config)
});
alert('Settings saved. Device will restart...');
} catch (error) {
console.error('Error saving WiFi settings:', error);
}
}
}

7
data/js/bootstrap.bundle.min.js vendored Normal file

File diff suppressed because one or more lines are too long