This commit is contained in:
Serge NOEL
2026-02-10 11:27:18 +01:00
parent 549c9f388e
commit 4423bb2de1
175 changed files with 238087 additions and 0 deletions

BIN
Railuino/data/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
Railuino/data/image1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

BIN
Railuino/data/image2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
Railuino/data/image3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
Railuino/data/image4.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

48
Railuino/data/index.html Normal file
View File

@@ -0,0 +1,48 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Track Controller</title>
<link rel="stylesheet" href="style.css">
<link rel="icon" href="favicon.ico" type="image/x-icon">
</head>
<body>
<h1>Track Controller</h1>
<div id="logWindow" class="log-window"></div>
<div class="image-buttons">
<img src="image1.jpg" class="address-button" data-address="16391">
<img src="image2.jpg" class="address-button" data-address="11000">
<img src="image3.jpg" class="address-button" data-address="12000">
<img src="image4.jpg" class="address-button" data-address="13000">
</div>
<button id="powerButton" class="toggle-button">Power</button>
<button id="stopButton" class="normal-button">Stop</button>
<button id="systemHaltButton" class="normal-button">System Halt</button>
<button id="directionButton" class="toggle-button">&lt;&lt; / &gt;&gt;</button>
<div class="slider-container">
<span class="slider-label" id="slider-min">0</span>
<input type="range" id="speedSlider" min="0" max="1000" value="0">
<span class="slider-label" id="slider-max">1000</span>
</div>
<div class="speed-percentage">
Speed: <span id="speedValue">0</span>%
</div>
<div class="function-buttons">
<button class="function-button" data-function="0">F0</button>
<button class="function-button" data-function="1">F1</button>
<button class="function-button" data-function="2">F2</button>
<button class="function-button" data-function="3">F3</button>
<button class="function-button" data-function="4">F4</button>
</div>
<div class="function-buttons">
<button class="function-button" data-function="5">F5</button>
<button class="function-button" data-function="6">F6</button>
<button class="function-button" data-function="7">F7</button>
<button class="function-button" data-function="8">F8</button>
<button class="function-button" data-function="9">F9</button>
</div>
<script src="script.js"></script>
</body>
</html>

180
Railuino/data/script.js Normal file
View File

@@ -0,0 +1,180 @@
let isPowerOn = false;
const locos = {};
let selectedLoco = null;
// Classe Loco
class Loco {
constructor(address) {
this.address = address;
this.speed = 0;
this.direction = 0;
this.functions = Array(10).fill(false);
}
setSpeed(speed) {
this.speed = speed;
}
setDirection(direction) {
this.direction = direction;
}
setFunction(index, state) {
this.functions[index] = state;
}
}
// Créer des instances de Loco pour chaque bouton image
document.querySelectorAll('.address-button').forEach(button => {
const address = button.getAttribute('data-address');
locos[address] = new Loco(address);
});
// Fonction pour mettre à jour l'affichage avec les valeurs de la locomotive sélectionnée
function updateUI() {
if (selectedLoco) {
document.getElementById('speedSlider').value = selectedLoco.speed;
updateSpeedValue(selectedLoco.speed);
document.querySelectorAll('.function-button').forEach((button, index) => {
if (selectedLoco.functions[index]) {
button.classList.add('active');
} else {
button.classList.remove('active');
}
});
}
}
// Fonction pour ajouter un message au log
// function addLogMessage(message) {
// const logWindow = document.getElementById('logWindow');
// const newMessage = document.createElement('div');
// newMessage.textContent = message;
// logWindow.appendChild(newMessage);
// logWindow.scrollTop = logWindow.scrollHeight;
// }
function addLogMessage(message) {
const logWindow = document.getElementById('logWindow');
logWindow.textContent = message; // Remplace le contenu du log par le nouveau message
}
// Gestionnaire d'événement pour le bouton d'alimentation
document.getElementById('powerButton').addEventListener('click', () => {
fetch('/setPower', { method: 'POST' })
.then(response => response.text())
.then(state => {
isPowerOn = state === 'true';
const powerButton = document.getElementById('powerButton');
if (isPowerOn == true) {
powerButton.classList.remove('power-off');
powerButton.classList.add('power-on');
addLogMessage('Power ON');
} else if (isPowerOn == false) {
powerButton.classList.remove('power-on');
powerButton.classList.add('power-off');
addLogMessage('Power OFF');
} else {
addLogMessage('Error for power function');
}
});
});
document.getElementById('systemHaltButton').addEventListener('click', () => {
if (selectedLoco) {
fetch(`/setSystemHalt?address=0x0000`, { method: 'POST' })
.then(() => {
document.getElementById('speedSlider').value = 0;
updateSpeedValue(0);
selectedLoco.setSpeed(0);
addLogMessage(`System Halt`);
});
}
});
document.getElementById('stopButton').addEventListener('click', () => {
if (selectedLoco) {
fetch(`/setStop?address=${selectedLoco.address}`, { method: 'POST' })
.then(() => {
document.getElementById('speedSlider').value = 0;
updateSpeedValue(0);
selectedLoco.setSpeed(0);
addLogMessage(`Stop for address ${selectedLoco.address}`);
});
}
});
document.getElementById('directionButton').addEventListener('click', () => {
if (selectedLoco) {
selectedLoco.direction = 1 - selectedLoco.direction; // Change de direction
fetch(`/setDirection?address=${selectedLoco.address}`, { method: 'POST' })
.then(() => {
document.getElementById('speedSlider').value = 0;
updateSpeedValue(0);
addLogMessage(`Direction change for address ${selectedLoco.address}`);
});
}
});
document.getElementById('speedSlider').addEventListener('input', (event) => {
if (!isPowerOn) {
addLogMessage('Power is off');
event.target.value = 0; // Réinitialiser le curseur à 0
updateSpeedValue(0);
return;
}
if (!selectedLoco) {
addLogMessage('Select a locomotive');
event.target.value = 0; // Réinitialiser le curseur à 0
updateSpeedValue(0);
return;
}
const speed = event.target.value;
fetch(`/setSpeed?address=${selectedLoco.address}&speed=${speed}`, { method: 'POST' });
selectedLoco.setSpeed(speed);
updateSpeedValue(speed);
addLogMessage(`Speed set to ${speed} for address ${selectedLoco.address}`);
});
document.querySelectorAll('.address-button').forEach(button => {
button.addEventListener('click', () => {
// Supprimer la classe 'selected' de tous les boutons
document.querySelectorAll('.address-button').forEach(btn => btn.classList.remove('selected'));
// Ajouter la classe 'selected' au bouton cliqué
button.classList.add('selected');
// Mettre à jour la locomotive sélectionnée
const address = button.getAttribute('data-address');
selectedLoco = locos[address];
// Envoyer l'adresse au serveur
fetch(`/setAddress?address=${address}`, { method: 'POST' });
// Mettre à jour l'interface utilisateur avec les valeurs de la locomotive sélectionnée
updateUI();
addLogMessage(`Locomotive selected with address ${address}`);
});
});
document.querySelectorAll('.function-button').forEach(button => {
button.addEventListener('click', () => {
if (selectedLoco) {
const functionId = button.getAttribute('data-function');
const newState = !selectedLoco.functions[functionId];
fetch(`/setFunction?address=${selectedLoco.address}&function=${functionId}&power=${newState ? 1 : 0}`, { method: 'POST' })
.then(() => {
selectedLoco.setFunction(functionId, newState);
if (newState) {
button.classList.add('active');
addLogMessage(`Function F ${functionId} activated for address ${selectedLoco.address}`);
} else {
button.classList.remove('active');
addLogMessage(`Function F ${functionId} deactivated for address ${selectedLoco.address}`);
}
});
}
});
});
function updateSpeedValue(speed) {
const speedValue = document.getElementById('speedValue');
const percentage = (speed / 1000) * 100;
speedValue.textContent = Math.round(percentage);
}

105
Railuino/data/style.css Normal file
View File

@@ -0,0 +1,105 @@
body {
font-family: Arial, sans-serif;
}
h1 {
text-align: center;
}
.log-window {
border: 1px solid #ccc;
padding: 10px;
margin-top: 20px;
margin-bottom: 20px;
max-height: 150px;
overflow-y: scroll;
background-color: #f9f9f9;
font-family: monospace;
font-size: 12px;
}
.toggle-button {
color: white;
border: none;
padding: 10px 20px;
margin: 10px;
cursor: pointer;
background-color: green;
}
.normal-button {
color: white;
border: none;
padding: 10px 20px;
margin: 10px;
cursor: pointer;
background-color: #a81b9c;
}
.toggle-button.power-on {
background-color: red;
}
.toggle-button.power-off {
background-color: green;
}
.slider-container {
display: flex;
align-items: center;
justify-content: center;
margin-top: 20px;
}
#speedSlider {
width: 70%;
margin: 0 10px;
}
.slider-label {
font-weight: bold;
margin: 0 10px;
}
.speed-percentage {
text-align: center;
margin-top: 10px;
font-size: 1.2em;
margin-bottom: 20px;
}
.image-buttons {
display: flex;
justify-content: center;
}
.address-button {
margin: 0 10px;
width: 90px;
height: 60px;
cursor: pointer;
}
.address-button.selected {
border: 1px solid black;
}
.function-buttons {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.function-button {
margin: 5px;
padding: 10px 20px;
cursor: pointer;
background-color: lightgray;
border: 1px solid #ccc;
border-radius: 5px;
}
.function-button.active {
background-color: rgb(74, 72, 72);
color: white;
}