diff --git a/html/rfid.js b/html/rfid.js
index 12b3d82..960c9a7 100644
--- a/html/rfid.js
+++ b/html/rfid.js
@@ -11,7 +11,7 @@ let reconnectTimer = null;
// WebSocket Funktionen
function startHeartbeat() {
if (heartbeatTimer) clearInterval(heartbeatTimer);
-
+
heartbeatTimer = setInterval(() => {
// Prüfe ob zu lange keine Antwort kam
if (Date.now() - lastHeartbeatResponse > HEARTBEAT_TIMEOUT) {
@@ -29,7 +29,7 @@ function startHeartbeat() {
updateConnectionStatus();
return;
}
-
+
try {
// Sende Heartbeat
socket.send(JSON.stringify({ type: 'heartbeat' }));
@@ -53,94 +53,118 @@ function initWebSocket() {
// Wenn eine existierende Verbindung besteht, diese erst schließen
if (socket) {
- try {
- socket.onclose = null; // Remove onclose handler before closing
- socket.onerror = null; // Remove error handler
- socket.close();
- } catch (e) {
- console.error('Error closing existing socket:', e);
- }
+ socket.close();
socket = null;
}
try {
socket = new WebSocket('ws://' + window.location.host + '/ws');
-
- socket.onopen = function() {
- console.log('WebSocket connection established');
+
+ socket.onopen = function () {
isConnected = true;
updateConnectionStatus();
startHeartbeat(); // Starte Heartbeat nach erfolgreicher Verbindung
};
-
- socket.onclose = function(event) {
- console.log('WebSocket connection closed:', event.code, event.reason);
+
+ socket.onclose = function () {
isConnected = false;
updateConnectionStatus();
- if (heartbeatTimer) {
- clearInterval(heartbeatTimer);
- heartbeatTimer = null;
- }
-
+ if (heartbeatTimer) clearInterval(heartbeatTimer);
+
// Nur neue Verbindung versuchen, wenn kein Timer läuft
if (!reconnectTimer) {
reconnectTimer = setTimeout(() => {
- console.log('Attempting to reconnect...');
initWebSocket();
}, RECONNECT_INTERVAL);
}
};
-
- socket.onerror = function(error) {
- console.error('WebSocket error occurred:', error);
+
+ socket.onerror = function (error) {
isConnected = false;
updateConnectionStatus();
- if (heartbeatTimer) {
- clearInterval(heartbeatTimer);
- heartbeatTimer = null;
+ if (heartbeatTimer) clearInterval(heartbeatTimer);
+
+ // Bei Fehler Verbindung schließen und neu aufbauen
+ if (socket) {
+ socket.close();
+ socket = null;
}
};
-
- socket.onmessage = function(event) {
- try {
- lastHeartbeatResponse = Date.now();
- const data = JSON.parse(event.data);
-
- // Handle different message types
- switch(data.type) {
- case 'amsData':
- displayAmsData(data.payload);
- break;
- case 'nfcTag':
- updateNfcStatusIndicator(data.payload);
- break;
- case 'nfcData':
- updateNfcData(data.payload);
- break;
- case 'writeNfcTag':
- handleWriteNfcTagResponse(data.success);
- break;
- case 'heartbeat':
- handleHeartbeatResponse(data);
- break;
- case 'setSpoolmanSettings':
- handleSpoolmanSettingsResponse(data);
- break;
- default:
- console.warn('Unknown message type:', data.type);
+
+ socket.onmessage = function (event) {
+ lastHeartbeatResponse = Date.now(); // Aktualisiere Zeitstempel bei jeder Server-Antwort
+
+ const data = JSON.parse(event.data);
+ if (data.type === 'amsData') {
+ displayAmsData(data.payload);
+ } else if (data.type === 'nfcTag') {
+ updateNfcStatusIndicator(data.payload);
+ } else if (data.type === 'nfcData') {
+ updateNfcData(data.payload);
+ } else if (data.type === 'writeNfcTag') {
+ handleWriteNfcTagResponse(data.success);
+ } else if (data.type === 'heartbeat') {
+ // Optional: Spezifische Behandlung von Heartbeat-Antworten
+ // Update status dots
+ const bambuDot = document.getElementById('bambuDot');
+ const spoolmanDot = document.getElementById('spoolmanDot');
+ const ramStatus = document.getElementById('ramStatus');
+
+ if (bambuDot) {
+ bambuDot.className = 'status-dot ' + (data.bambu_connected ? 'online' : 'offline');
+ // Add click handler only when offline
+ if (!data.bambu_connected) {
+ bambuDot.style.cursor = 'pointer';
+ bambuDot.onclick = function () {
+ if (socket && socket.readyState === WebSocket.OPEN) {
+ socket.send(JSON.stringify({
+ type: 'reconnect',
+ payload: 'bambu'
+ }));
+ }
+ };
+ } else {
+ bambuDot.style.cursor = 'default';
+ bambuDot.onclick = null;
+ }
+ }
+ if (spoolmanDot) {
+ spoolmanDot.className = 'status-dot ' + (data.spoolman_connected ? 'online' : 'offline');
+ // Add click handler only when offline
+ if (!data.spoolman_connected) {
+ spoolmanDot.style.cursor = 'pointer';
+ spoolmanDot.onclick = function () {
+ if (socket && socket.readyState === WebSocket.OPEN) {
+ socket.send(JSON.stringify({
+ type: 'reconnect',
+ payload: 'spoolman'
+ }));
+ }
+ };
+ } else {
+ spoolmanDot.style.cursor = 'default';
+ spoolmanDot.onclick = null;
+ }
+ }
+ if (ramStatus) {
+ ramStatus.textContent = `${data.freeHeap}k`;
+ }
+ }
+ else if (data.type === 'setSpoolmanSettings') {
+ if (data.payload == 'success') {
+ showNotification(`Spoolman Settings set successfully`, true);
+ } else {
+ showNotification(`Error setting Spoolman Settings`, false);
}
- } catch (error) {
- console.error('Error processing WebSocket message:', error);
}
};
} catch (error) {
- console.error('Error initializing WebSocket:', error);
isConnected = false;
updateConnectionStatus();
-
+
+ // Nur neue Verbindung versuchen, wenn kein Timer läuft
if (!reconnectTimer) {
reconnectTimer = setTimeout(() => {
- console.log('Attempting to reconnect after error...');
initWebSocket();
}, RECONNECT_INTERVAL);
}
@@ -165,26 +189,26 @@ function updateConnectionStatus() {
}
// Event Listeners
-document.addEventListener("DOMContentLoaded", function() {
+document.addEventListener("DOMContentLoaded", function () {
initWebSocket();
-
+
// Event Listener für Checkbox
- document.getElementById("onlyWithoutSmId").addEventListener("change", function() {
+ document.getElementById("onlyWithoutSmId").addEventListener("change", function () {
const spoolsData = window.getSpoolData();
window.populateVendorDropdown(spoolsData);
});
});
// Event Listener für Spoolman Events
-document.addEventListener('spoolDataLoaded', function(event) {
+document.addEventListener('spoolDataLoaded', function (event) {
window.populateVendorDropdown(event.detail);
});
-document.addEventListener('spoolmanError', function(event) {
+document.addEventListener('spoolmanError', function (event) {
showNotification(`Spoolman Error: ${event.detail.message}`, false);
});
-document.addEventListener('filamentSelected', function(event) {
+document.addEventListener('filamentSelected', function (event) {
updateNfcInfo();
// Zeige Spool-Buttons wenn ein Filament ausgewählt wurde
const selectedText = document.getElementById("selected-filament").textContent;
@@ -194,13 +218,13 @@ document.addEventListener('filamentSelected', function(event) {
// Hilfsfunktion für kontrastreiche Textfarbe
function getContrastColor(hexcolor) {
// Konvertiere Hex zu RGB
- const r = parseInt(hexcolor.substr(0,2),16);
- const g = parseInt(hexcolor.substr(2,2),16);
- const b = parseInt(hexcolor.substr(4,2),16);
-
+ const r = parseInt(hexcolor.substr(0, 2), 16);
+ const g = parseInt(hexcolor.substr(2, 2), 16);
+ const b = parseInt(hexcolor.substr(4, 2), 16);
+
// Berechne Helligkeit (YIQ Formel)
- const yiq = ((r*299)+(g*587)+(b*114))/1000;
-
+ const yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000;
+
// Return schwarz oder weiß basierend auf Helligkeit
return (yiq >= 128) ? '#000000' : '#FFFFFF';
}
@@ -218,7 +242,7 @@ function updateNfcInfo() {
}
// Finde die ausgewählte Spule in den Daten
- const selectedSpool = spoolsData.find(spool =>
+ const selectedSpool = spoolsData.find(spool =>
`${spool.id} | ${spool.filament.name} (${spool.filament.material})` === selectedText
);
@@ -231,18 +255,18 @@ function updateNfcInfo() {
function displayAmsData(amsData) {
const amsDataContainer = document.getElementById('amsData');
- amsDataContainer.innerHTML = '';
+ amsDataContainer.innerHTML = '';
amsData.forEach((ams) => {
// Bestimme den Anzeigenamen für das AMS
const amsDisplayName = ams.ams_id === 255 ? 'External Spool' : `AMS ${ams.ams_id}`;
-
+
const trayHTML = ams.tray.map(tray => {
// Prüfe ob überhaupt Daten vorhanden sind
const relevantFields = ['tray_type', 'tray_sub_brands', 'tray_info_idx', 'setting_id', 'cali_idx'];
- const hasAnyContent = relevantFields.some(field =>
- tray[field] !== null &&
- tray[field] !== undefined &&
+ const hasAnyContent = relevantFields.some(field =>
+ tray[field] !== null &&
+ tray[field] !== undefined &&
tray[field] !== '' &&
tray[field] !== 'null'
);
@@ -258,8 +282,8 @@ function displayAmsData(amsData) {
cursor: pointer; display: none;">
`;
-
- // Nur für nicht-leere Trays den Button-HTML erstellen
+
+ // Nur für nicht-leere Trays den Button-HTML erstellen
const outButtonHtml = `