- X1C MQTT Fix

- Spoolman Settings Fix
- Spoolman Out Fix
- Spoolman In Fix
This commit is contained in:
2025-03-23 18:09:25 +01:00
parent 15d0bfd8e9
commit 1c01bfb2da
2 changed files with 311 additions and 149 deletions
+149 -93
View File
@@ -53,7 +53,13 @@ function initWebSocket() {
// Wenn eine existierende Verbindung besteht, diese erst schließen
if (socket) {
socket.close();
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 = null;
}
@@ -61,110 +67,80 @@ function initWebSocket() {
socket = new WebSocket('ws://' + window.location.host + '/ws');
socket.onopen = function() {
console.log('WebSocket connection established');
isConnected = true;
updateConnectionStatus();
startHeartbeat(); // Starte Heartbeat nach erfolgreicher Verbindung
};
socket.onclose = function() {
socket.onclose = function(event) {
console.log('WebSocket connection closed:', event.code, event.reason);
isConnected = false;
updateConnectionStatus();
if (heartbeatTimer) clearInterval(heartbeatTimer);
if (heartbeatTimer) {
clearInterval(heartbeatTimer);
heartbeatTimer = null;
}
// 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);
isConnected = false;
updateConnectionStatus();
if (heartbeatTimer) clearInterval(heartbeatTimer);
// Bei Fehler Verbindung schließen und neu aufbauen
if (socket) {
socket.close();
socket = null;
if (heartbeatTimer) {
clearInterval(heartbeatTimer);
heartbeatTimer = null;
}
};
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');
try {
lastHeartbeatResponse = Date.now();
const data = JSON.parse(event.data);
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);
// 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);
}
} 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);
}
@@ -389,6 +365,7 @@ 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) {
// Hole das ausgewählte Filament
const selectedText = document.getElementById("selected-filament").textContent;
@@ -419,6 +396,7 @@ function handleSpoolmanSettings(tray_info_idx, setting_id, cali_idx, nozzle_temp
}
}
// Verbesserte Funktion zum Behandeln von Spool Out
function handleSpoolOut() {
// Erstelle Payload
const payload = {
@@ -443,17 +421,21 @@ function handleSpoolOut() {
}
}
// Neue Funktion zum Behandeln des Spool-In-Klicks
// Verbesserte Funktion zum Behandeln des Spool-In-Klicks
function handleSpoolIn(amsId, trayId) {
console.log("handleSpoolIn called with amsId:", amsId, "trayId:", trayId);
// Prüfe WebSocket Verbindung zuerst
if (!socket || socket.readyState !== WebSocket.OPEN) {
showNotification("No active WebSocket connection!", false);
console.error("WebSocket not connected");
console.error("WebSocket not connected, state:", socket ? socket.readyState : "no socket");
return;
}
// Hole das ausgewählte Filament
const selectedText = document.getElementById("selected-filament").textContent;
console.log("Selected filament:", selectedText);
if (selectedText === "Please choose...") {
showNotification("Choose Filament first", false);
return;
@@ -466,53 +448,55 @@ function handleSpoolIn(amsId, trayId) {
if (!selectedSpool) {
showNotification("Selected Spool not found", false);
console.error("Selected spool not found in spoolsData");
return;
}
console.log("Found spool data:", selectedSpool);
// Temperaturwerte extrahieren
let minTemp = "175";
let maxTemp = "275";
if (Array.isArray(selectedSpool.filament.nozzle_temperature) &&
if (selectedSpool.filament &&
Array.isArray(selectedSpool.filament.nozzle_temperature) &&
selectedSpool.filament.nozzle_temperature.length >= 2) {
minTemp = selectedSpool.filament.nozzle_temperature[0];
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
const payload = {
type: 'setBambuSpool',
payload: {
amsId: amsId,
trayId: trayId,
color: selectedSpool.filament.color_hex || "FFFFFF",
color: selectedSpool.filament && selectedSpool.filament.color_hex ? selectedSpool.filament.color_hex : "FFFFFF",
nozzle_temp_min: parseInt(minTemp),
nozzle_temp_max: parseInt(maxTemp),
type: selectedSpool.filament.material,
brand: selectedSpool.filament.vendor.name,
tray_info_idx: selectedSpool.filament.extra.bambu_idx.replace(/['"]+/g, '').trim(),
type: selectedSpool.filament && selectedSpool.filament.material ? selectedSpool.filament.material : "PLA",
brand: selectedSpool.filament && selectedSpool.filament.vendor ? selectedSpool.filament.vendor.name : "",
tray_info_idx: bambuIdx,
cali_idx: "-1" // Default-Wert setzen
}
};
// 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);
console.log("Sending payload:", payload);
try {
socket.send(JSON.stringify(payload));
showNotification(`Spool set in AMS ${amsId} Tray ${trayId}. Pls wait`, true);
showNotification(`Spool settings sent to printer. Please wait...`, true);
} catch (error) {
console.error("Fehler beim Senden der WebSocket Nachricht:", error);
showNotification("Error while sending", false);
console.error("Error sending WebSocket message:", error);
showNotification("Error sending spool settings!", false);
}
}
@@ -687,3 +671,75 @@ function showNotification(message, isSuccess) {
}, 300);
}, 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);
}
}