Origin Rfid.js

This commit is contained in:
2025-03-23 18:58:33 +01:00
parent b75be0ac06
commit f869bcc0c1
+141 -197
View File
@@ -11,7 +11,7 @@ let reconnectTimer = null;
// WebSocket Funktionen // WebSocket Funktionen
function startHeartbeat() { function startHeartbeat() {
if (heartbeatTimer) clearInterval(heartbeatTimer); if (heartbeatTimer) clearInterval(heartbeatTimer);
heartbeatTimer = setInterval(() => { heartbeatTimer = setInterval(() => {
// Prüfe ob zu lange keine Antwort kam // Prüfe ob zu lange keine Antwort kam
if (Date.now() - lastHeartbeatResponse > HEARTBEAT_TIMEOUT) { if (Date.now() - lastHeartbeatResponse > HEARTBEAT_TIMEOUT) {
@@ -29,7 +29,7 @@ function startHeartbeat() {
updateConnectionStatus(); updateConnectionStatus();
return; return;
} }
try { try {
// Sende Heartbeat // Sende Heartbeat
socket.send(JSON.stringify({ type: 'heartbeat' })); socket.send(JSON.stringify({ type: 'heartbeat' }));
@@ -53,94 +53,118 @@ function initWebSocket() {
// Wenn eine existierende Verbindung besteht, diese erst schließen // Wenn eine existierende Verbindung besteht, diese erst schließen
if (socket) { if (socket) {
try { socket.close();
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 = null; socket = null;
} }
try { try {
socket = new WebSocket('ws://' + window.location.host + '/ws'); socket = new WebSocket('ws://' + window.location.host + '/ws');
socket.onopen = function() { socket.onopen = function () {
console.log('WebSocket connection established');
isConnected = true; isConnected = true;
updateConnectionStatus(); updateConnectionStatus();
startHeartbeat(); // Starte Heartbeat nach erfolgreicher Verbindung startHeartbeat(); // Starte Heartbeat nach erfolgreicher Verbindung
}; };
socket.onclose = function(event) { socket.onclose = function () {
console.log('WebSocket connection closed:', event.code, event.reason);
isConnected = false; isConnected = false;
updateConnectionStatus(); updateConnectionStatus();
if (heartbeatTimer) { if (heartbeatTimer) clearInterval(heartbeatTimer);
clearInterval(heartbeatTimer);
heartbeatTimer = null;
}
// Nur neue Verbindung versuchen, wenn kein Timer läuft // Nur neue Verbindung versuchen, wenn kein Timer läuft
if (!reconnectTimer) { if (!reconnectTimer) {
reconnectTimer = setTimeout(() => { reconnectTimer = setTimeout(() => {
console.log('Attempting to reconnect...');
initWebSocket(); initWebSocket();
}, RECONNECT_INTERVAL); }, RECONNECT_INTERVAL);
} }
}; };
socket.onerror = function(error) { socket.onerror = function (error) {
console.error('WebSocket error occurred:', error);
isConnected = false; isConnected = false;
updateConnectionStatus(); updateConnectionStatus();
if (heartbeatTimer) { if (heartbeatTimer) clearInterval(heartbeatTimer);
clearInterval(heartbeatTimer);
heartbeatTimer = null; // Bei Fehler Verbindung schließen und neu aufbauen
if (socket) {
socket.close();
socket = null;
} }
}; };
socket.onmessage = function(event) { socket.onmessage = function (event) {
try { lastHeartbeatResponse = Date.now(); // Aktualisiere Zeitstempel bei jeder Server-Antwort
lastHeartbeatResponse = Date.now();
const data = JSON.parse(event.data); const data = JSON.parse(event.data);
if (data.type === 'amsData') {
// Handle different message types displayAmsData(data.payload);
switch(data.type) { } else if (data.type === 'nfcTag') {
case 'amsData': updateNfcStatusIndicator(data.payload);
displayAmsData(data.payload); } else if (data.type === 'nfcData') {
break; updateNfcData(data.payload);
case 'nfcTag': } else if (data.type === 'writeNfcTag') {
updateNfcStatusIndicator(data.payload); handleWriteNfcTagResponse(data.success);
break; } else if (data.type === 'heartbeat') {
case 'nfcData': // Optional: Spezifische Behandlung von Heartbeat-Antworten
updateNfcData(data.payload); // Update status dots
break; const bambuDot = document.getElementById('bambuDot');
case 'writeNfcTag': const spoolmanDot = document.getElementById('spoolmanDot');
handleWriteNfcTagResponse(data.success); const ramStatus = document.getElementById('ramStatus');
break;
case 'heartbeat': if (bambuDot) {
handleHeartbeatResponse(data); bambuDot.className = 'status-dot ' + (data.bambu_connected ? 'online' : 'offline');
break; // Add click handler only when offline
case 'setSpoolmanSettings': if (!data.bambu_connected) {
handleSpoolmanSettingsResponse(data); bambuDot.style.cursor = 'pointer';
break; bambuDot.onclick = function () {
default: if (socket && socket.readyState === WebSocket.OPEN) {
console.warn('Unknown message type:', data.type); 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) { } catch (error) {
console.error('Error initializing WebSocket:', error);
isConnected = false; isConnected = false;
updateConnectionStatus(); updateConnectionStatus();
// Nur neue Verbindung versuchen, wenn kein Timer läuft
if (!reconnectTimer) { if (!reconnectTimer) {
reconnectTimer = setTimeout(() => { reconnectTimer = setTimeout(() => {
console.log('Attempting to reconnect after error...');
initWebSocket(); initWebSocket();
}, RECONNECT_INTERVAL); }, RECONNECT_INTERVAL);
} }
@@ -165,26 +189,26 @@ function updateConnectionStatus() {
} }
// Event Listeners // Event Listeners
document.addEventListener("DOMContentLoaded", function() { document.addEventListener("DOMContentLoaded", function () {
initWebSocket(); initWebSocket();
// Event Listener für Checkbox // Event Listener für Checkbox
document.getElementById("onlyWithoutSmId").addEventListener("change", function() { document.getElementById("onlyWithoutSmId").addEventListener("change", function () {
const spoolsData = window.getSpoolData(); const spoolsData = window.getSpoolData();
window.populateVendorDropdown(spoolsData); window.populateVendorDropdown(spoolsData);
}); });
}); });
// Event Listener für Spoolman Events // Event Listener für Spoolman Events
document.addEventListener('spoolDataLoaded', function(event) { document.addEventListener('spoolDataLoaded', function (event) {
window.populateVendorDropdown(event.detail); window.populateVendorDropdown(event.detail);
}); });
document.addEventListener('spoolmanError', function(event) { document.addEventListener('spoolmanError', function (event) {
showNotification(`Spoolman Error: ${event.detail.message}`, false); showNotification(`Spoolman Error: ${event.detail.message}`, false);
}); });
document.addEventListener('filamentSelected', function(event) { document.addEventListener('filamentSelected', function (event) {
updateNfcInfo(); updateNfcInfo();
// Zeige Spool-Buttons wenn ein Filament ausgewählt wurde // Zeige Spool-Buttons wenn ein Filament ausgewählt wurde
const selectedText = document.getElementById("selected-filament").textContent; const selectedText = document.getElementById("selected-filament").textContent;
@@ -194,13 +218,13 @@ document.addEventListener('filamentSelected', function(event) {
// Hilfsfunktion für kontrastreiche Textfarbe // Hilfsfunktion für kontrastreiche Textfarbe
function getContrastColor(hexcolor) { function getContrastColor(hexcolor) {
// Konvertiere Hex zu RGB // Konvertiere Hex zu RGB
const r = parseInt(hexcolor.substr(0,2),16); const r = parseInt(hexcolor.substr(0, 2), 16);
const g = parseInt(hexcolor.substr(2,2),16); const g = parseInt(hexcolor.substr(2, 2), 16);
const b = parseInt(hexcolor.substr(4,2),16); const b = parseInt(hexcolor.substr(4, 2), 16);
// Berechne Helligkeit (YIQ Formel) // 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 schwarz oder weiß basierend auf Helligkeit
return (yiq >= 128) ? '#000000' : '#FFFFFF'; return (yiq >= 128) ? '#000000' : '#FFFFFF';
} }
@@ -218,7 +242,7 @@ function updateNfcInfo() {
} }
// Finde die ausgewählte Spule in den Daten // 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 `${spool.id} | ${spool.filament.name} (${spool.filament.material})` === selectedText
); );
@@ -231,18 +255,18 @@ function updateNfcInfo() {
function displayAmsData(amsData) { function displayAmsData(amsData) {
const amsDataContainer = document.getElementById('amsData'); const amsDataContainer = document.getElementById('amsData');
amsDataContainer.innerHTML = ''; amsDataContainer.innerHTML = '';
amsData.forEach((ams) => { amsData.forEach((ams) => {
// Bestimme den Anzeigenamen für das AMS // Bestimme den Anzeigenamen für das AMS
const amsDisplayName = ams.ams_id === 255 ? 'External Spool' : `AMS ${ams.ams_id}`; const amsDisplayName = ams.ams_id === 255 ? 'External Spool' : `AMS ${ams.ams_id}`;
const trayHTML = ams.tray.map(tray => { const trayHTML = ams.tray.map(tray => {
// Prüfe ob überhaupt Daten vorhanden sind // Prüfe ob überhaupt Daten vorhanden sind
const relevantFields = ['tray_type', 'tray_sub_brands', 'tray_info_idx', 'setting_id', 'cali_idx']; const relevantFields = ['tray_type', 'tray_sub_brands', 'tray_info_idx', 'setting_id', 'cali_idx'];
const hasAnyContent = relevantFields.some(field => const hasAnyContent = relevantFields.some(field =>
tray[field] !== null && tray[field] !== null &&
tray[field] !== undefined && tray[field] !== undefined &&
tray[field] !== '' && tray[field] !== '' &&
tray[field] !== 'null' tray[field] !== 'null'
); );
@@ -258,8 +282,8 @@ function displayAmsData(amsData) {
cursor: pointer; display: none;"> cursor: pointer; display: none;">
<img src="spool_in.png" alt="Spool In" style="width: 48px; height: 48px;"> <img src="spool_in.png" alt="Spool In" style="width: 48px; height: 48px;">
</button>`; </button>`;
// Nur für nicht-leere Trays den Button-HTML erstellen // Nur für nicht-leere Trays den Button-HTML erstellen
const outButtonHtml = ` const outButtonHtml = `
<button class="spool-button" onclick="handleSpoolOut()" <button class="spool-button" onclick="handleSpoolOut()"
style="position: absolute; top: -35px; right: -15px; style="position: absolute; top: -35px; right: -15px;
@@ -289,7 +313,7 @@ function displayAmsData(amsData) {
} }
// Generiere den Type mit Color-Box zusammen // Generiere den Type mit Color-Box zusammen
const typeWithColor = tray.tray_type ? const typeWithColor = tray.tray_type ?
`<p>Typ: ${tray.tray_type} ${tray.tray_color ? `<span style=" `<p>Typ: ${tray.tray_type} ${tray.tray_color ? `<span style="
background-color: #${tray.tray_color}; background-color: #${tray.tray_color};
width: 20px; width: 20px;
@@ -310,9 +334,9 @@ function displayAmsData(amsData) {
// Nur gültige Felder anzeigen // Nur gültige Felder anzeigen
const trayDetails = trayProperties const trayDetails = trayProperties
.filter(prop => .filter(prop =>
tray[prop.key] !== null && tray[prop.key] !== null &&
tray[prop.key] !== undefined && tray[prop.key] !== undefined &&
tray[prop.key] !== '' && tray[prop.key] !== '' &&
tray[prop.key] !== 'null' tray[prop.key] !== 'null'
) )
@@ -326,7 +350,7 @@ function displayAmsData(amsData) {
.join(''); .join('');
// Temperaturen nur anzeigen, wenn beide nicht 0 sind // Temperaturen nur anzeigen, wenn beide nicht 0 sind
const tempHTML = (tray.nozzle_temp_min > 0 && tray.nozzle_temp_max > 0) const tempHTML = (tray.nozzle_temp_min > 0 && tray.nozzle_temp_max > 0)
? `<p>Nozzle Temp: ${tray.nozzle_temp_min}°C - ${tray.nozzle_temp_max}°C</p>` ? `<p>Nozzle Temp: ${tray.nozzle_temp_min}°C - ${tray.nozzle_temp_max}°C</p>`
: ''; : '';
@@ -352,7 +376,7 @@ function displayAmsData(amsData) {
${trayHTML} ${trayHTML}
</div> </div>
</div>`; </div>`;
amsDataContainer.innerHTML += amsInfo; amsDataContainer.innerHTML += amsInfo;
}); });
} }
@@ -365,13 +389,12 @@ function updateSpoolButtons(show) {
}); });
} }
// Verbesserte Funktion zum Behandeln von Spoolman Settings
function handleSpoolmanSettings(tray_info_idx, setting_id, cali_idx, nozzle_temp_min, nozzle_temp_max) { function handleSpoolmanSettings(tray_info_idx, setting_id, cali_idx, nozzle_temp_min, nozzle_temp_max) {
// Hole das ausgewählte Filament // Hole das ausgewählte Filament
const selectedText = document.getElementById("selected-filament").textContent; const selectedText = document.getElementById("selected-filament").textContent;
// Finde die ausgewählte Spule in den Daten // 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 `${spool.id} | ${spool.filament.name} (${spool.filament.material})` === selectedText
); );
@@ -396,7 +419,6 @@ function handleSpoolmanSettings(tray_info_idx, setting_id, cali_idx, nozzle_temp
} }
} }
// Verbesserte Funktion zum Behandeln von Spool Out
function handleSpoolOut() { function handleSpoolOut() {
// Erstelle Payload // Erstelle Payload
const payload = { const payload = {
@@ -421,88 +443,82 @@ function handleSpoolOut() {
} }
} }
// Verbesserte Funktion zum Behandeln des Spool-In-Klicks // Neue Funktion zum Behandeln des Spool-In-Klicks
function handleSpoolIn(amsId, trayId) { function handleSpoolIn(amsId, trayId) {
console.log("handleSpoolIn called with amsId:", amsId, "trayId:", trayId);
// Prüfe WebSocket Verbindung zuerst // Prüfe WebSocket Verbindung zuerst
if (!socket || socket.readyState !== WebSocket.OPEN) { if (!socket || socket.readyState !== WebSocket.OPEN) {
showNotification("No active WebSocket connection!", false); showNotification("No active WebSocket connection!", false);
console.error("WebSocket not connected, state:", socket ? socket.readyState : "no socket"); console.error("WebSocket not connected");
return; return;
} }
// Hole das ausgewählte Filament // Hole das ausgewählte Filament
const selectedText = document.getElementById("selected-filament").textContent; const selectedText = document.getElementById("selected-filament").textContent;
console.log("Selected filament:", selectedText);
if (selectedText === "Please choose...") { if (selectedText === "Please choose...") {
showNotification("Choose Filament first", false); showNotification("Choose Filament first", false);
return; return;
} }
// Finde die ausgewählte Spule in den Daten // 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 `${spool.id} | ${spool.filament.name} (${spool.filament.material})` === selectedText
); );
if (!selectedSpool) { if (!selectedSpool) {
showNotification("Selected Spool not found", false); showNotification("Selected Spool not found", false);
console.error("Selected spool not found in spoolsData");
return; return;
} }
console.log("Found spool data:", selectedSpool);
// Temperaturwerte extrahieren // Temperaturwerte extrahieren
let minTemp = "175"; let minTemp = "175";
let maxTemp = "275"; let maxTemp = "275";
if (selectedSpool.filament && if (Array.isArray(selectedSpool.filament.nozzle_temperature) &&
Array.isArray(selectedSpool.filament.nozzle_temperature) &&
selectedSpool.filament.nozzle_temperature.length >= 2) { selectedSpool.filament.nozzle_temperature.length >= 2) {
minTemp = selectedSpool.filament.nozzle_temperature[0]; minTemp = selectedSpool.filament.nozzle_temperature[0];
maxTemp = selectedSpool.filament.nozzle_temperature[1]; maxTemp = selectedSpool.filament.nozzle_temperature[1];
} }
// Extrahiere bambu_idx
let bambuIdx = "GFL99"; // Default zu Generic PLA
if (selectedSpool.filament?.extra?.bambu_idx) {
bambuIdx = selectedSpool.filament.extra.bambu_idx.replace(/['"]/g, '');
} else if (selectedSpool.extra?.bambu_idx) {
bambuIdx = selectedSpool.extra.bambu_idx.replace(/['"]/g, '');
}
// Erstelle Payload // Erstelle Payload
const payload = { const payload = {
type: 'setBambuSpool', type: 'setBambuSpool',
payload: { payload: {
amsId: amsId, amsId: amsId,
trayId: trayId, trayId: trayId,
color: selectedSpool.filament && selectedSpool.filament.color_hex ? selectedSpool.filament.color_hex : "FFFFFF", color: selectedSpool.filament.color_hex || "FFFFFF",
nozzle_temp_min: parseInt(minTemp), nozzle_temp_min: parseInt(minTemp),
nozzle_temp_max: parseInt(maxTemp), nozzle_temp_max: parseInt(maxTemp),
type: selectedSpool.filament && selectedSpool.filament.material ? selectedSpool.filament.material : "PLA", type: selectedSpool.filament.material,
brand: selectedSpool.filament && selectedSpool.filament.vendor ? selectedSpool.filament.vendor.name : "", brand: selectedSpool.filament.vendor.name,
tray_info_idx: bambuIdx, tray_info_idx: selectedSpool.filament.extra.bambu_idx?.replace(/['"]+/g, '').trim() || '',
cali_idx: "-1" // Default-Wert setzen cali_idx: "-1" // Default-Wert setzen
} }
}; };
console.log("Sending payload:", payload); // Prüfe, ob der Key cali_idx vorhanden ist und setze ihn
if (selectedSpool.filament.extra.bambu_cali_id) {
payload.payload.cali_idx = selectedSpool.filament.extra.bambu_cali_id.replace(/['"]+/g, '').trim();
}
// Prüfe, ob der Key bambu_setting_id vorhanden ist
if (selectedSpool.filament.extra.bambu_setting_id) {
payload.payload.bambu_setting_id = selectedSpool.filament.extra.bambu_setting_id.replace(/['"]+/g, '').trim();
}
console.log("Spool-In Payload:", payload);
try { try {
socket.send(JSON.stringify(payload)); socket.send(JSON.stringify(payload));
showNotification(`Spool settings sent to printer. Please wait...`, true); showNotification(`Spool set in AMS ${amsId} Tray ${trayId}. Pls wait`, true);
} catch (error) { } catch (error) {
console.error("Error sending WebSocket message:", error); console.error("Fehler beim Senden der WebSocket Nachricht:", error);
showNotification("Error sending spool settings!", false); showNotification("Error while sending", false);
} }
} }
function updateNfcStatusIndicator(data) { function updateNfcStatusIndicator(data) {
const indicator = document.getElementById('nfcStatusIndicator'); const indicator = document.getElementById('nfcStatusIndicator');
if (data.found === 0) { if (data.found === 0) {
// Kein NFC Tag gefunden // Kein NFC Tag gefunden
indicator.className = 'status-circle'; indicator.className = 'status-circle';
@@ -518,7 +534,7 @@ function updateNfcStatusIndicator(data) {
function updateNfcData(data) { function updateNfcData(data) {
// Den Container für den NFC Status finden // Den Container für den NFC Status finden
const nfcStatusContainer = document.querySelector('.nfc-status-display'); const nfcStatusContainer = document.querySelector('.nfc-status-display');
// Bestehende Daten-Anzeige entfernen falls vorhanden // Bestehende Daten-Anzeige entfernen falls vorhanden
const existingData = nfcStatusContainer.querySelector('.nfc-data'); const existingData = nfcStatusContainer.querySelector('.nfc-data');
if (existingData) { if (existingData) {
@@ -577,7 +593,7 @@ function updateNfcData(data) {
if (matchingSpool) { if (matchingSpool) {
// Zuerst Hersteller-Dropdown aktualisieren // Zuerst Hersteller-Dropdown aktualisieren
document.getElementById("vendorSelect").value = matchingSpool.filament.vendor.id; document.getElementById("vendorSelect").value = matchingSpool.filament.vendor.id;
// Dann Filament-Dropdown aktualisieren und Spule auswählen // Dann Filament-Dropdown aktualisieren und Spule auswählen
updateFilamentDropdown(); updateFilamentDropdown();
setTimeout(() => { setTimeout(() => {
@@ -590,7 +606,7 @@ function updateNfcData(data) {
html += '</div>'; html += '</div>';
nfcDataDiv.innerHTML = html; nfcDataDiv.innerHTML = html;
// Neues div zum Container hinzufügen // Neues div zum Container hinzufügen
nfcStatusContainer.appendChild(nfcDataDiv); nfcStatusContainer.appendChild(nfcDataDiv);
} }
@@ -603,7 +619,7 @@ function writeNfcTag() {
} }
const spoolsData = window.getSpoolData(); const spoolsData = window.getSpoolData();
const selectedSpool = spoolsData.find(spool => const selectedSpool = spoolsData.find(spool =>
`${spool.id} | ${spool.filament.name} (${spool.filament.material})` === selectedText `${spool.id} | ${spool.filament.name} (${spool.filament.material})` === selectedText
); );
@@ -615,8 +631,8 @@ function writeNfcTag() {
// Temperaturwerte korrekt extrahieren // Temperaturwerte korrekt extrahieren
let minTemp = "175"; let minTemp = "175";
let maxTemp = "275"; let maxTemp = "275";
if (Array.isArray(selectedSpool.filament.nozzle_temperature) && if (Array.isArray(selectedSpool.filament.nozzle_temperature) &&
selectedSpool.filament.nozzle_temperature.length >= 2) { selectedSpool.filament.nozzle_temperature.length >= 2) {
minTemp = String(selectedSpool.filament.nozzle_temperature[0]); minTemp = String(selectedSpool.filament.nozzle_temperature[0]);
maxTemp = String(selectedSpool.filament.nozzle_temperature[1]); maxTemp = String(selectedSpool.filament.nozzle_temperature[1]);
@@ -670,76 +686,4 @@ function showNotification(message, isSuccess) {
notification.remove(); notification.remove();
}, 300); }, 300);
}, 3000); }, 3000);
} }
// Neue Handler-Funktionen für bessere Modularität
function handleHeartbeatResponse(data) {
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');
if (!data.bambu_connected) {
bambuDot.style.cursor = 'pointer';
bambuDot.onclick = function() {
sendReconnectRequest('bambu');
};
} else {
bambuDot.style.cursor = 'default';
bambuDot.onclick = null;
}
}
if (spoolmanDot) {
spoolmanDot.className = 'status-dot ' + (data.spoolman_connected ? 'online' : 'offline');
if (!data.spoolman_connected) {
spoolmanDot.style.cursor = 'pointer';
spoolmanDot.onclick = function() {
sendReconnectRequest('spoolman');
};
} else {
spoolmanDot.style.cursor = 'default';
spoolmanDot.onclick = null;
}
}
if (ramStatus) {
ramStatus.textContent = `${data.freeHeap}k`;
}
}
function handleSpoolmanSettingsResponse(data) {
if (data.payload === 'success') {
showNotification(`Spoolman Settings set successfully`, true);
} else {
showNotification(`Error setting Spoolman Settings`, false);
}
}
function sendReconnectRequest(target) {
if (socket?.readyState === WebSocket.OPEN) {
socket.send(JSON.stringify({
type: 'reconnect',
payload: target
}));
}
}
// Verbesserte Funktion zum Senden von WebSocket-Nachrichten
function sendWebSocketMessage(message) {
if (!socket || socket.readyState !== WebSocket.OPEN) {
console.error('WebSocket is not connected');
showNotification("Connection error - please try again", false);
return;
}
try {
const jsonString = JSON.stringify(message);
console.log('Sending WebSocket message:', jsonString);
socket.send(jsonString);
} catch (error) {
console.error('Error sending WebSocket message:', error);
showNotification("Error sending message", false);
}
}