- X1C MQTT Fix
- Spoolman Settings Fix - Spoolman Out Fix - Spoolman In Fix
This commit is contained in:
+149
-93
@@ -53,7 +53,13 @@ function initWebSocket() {
|
|||||||
|
|
||||||
// Wenn eine existierende Verbindung besteht, diese erst schließen
|
// Wenn eine existierende Verbindung besteht, diese erst schließen
|
||||||
if (socket) {
|
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;
|
socket = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,110 +67,80 @@ function initWebSocket() {
|
|||||||
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() {
|
socket.onclose = function(event) {
|
||||||
|
console.log('WebSocket connection closed:', event.code, event.reason);
|
||||||
isConnected = false;
|
isConnected = false;
|
||||||
updateConnectionStatus();
|
updateConnectionStatus();
|
||||||
if (heartbeatTimer) clearInterval(heartbeatTimer);
|
if (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) clearInterval(heartbeatTimer);
|
if (heartbeatTimer) {
|
||||||
|
clearInterval(heartbeatTimer);
|
||||||
// Bei Fehler Verbindung schließen und neu aufbauen
|
heartbeatTimer = null;
|
||||||
if (socket) {
|
|
||||||
socket.close();
|
|
||||||
socket = null;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
socket.onmessage = function(event) {
|
socket.onmessage = function(event) {
|
||||||
lastHeartbeatResponse = Date.now(); // Aktualisiere Zeitstempel bei jeder Server-Antwort
|
try {
|
||||||
|
lastHeartbeatResponse = Date.now();
|
||||||
const data = JSON.parse(event.data);
|
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) {
|
// Handle different message types
|
||||||
bambuDot.className = 'status-dot ' + (data.bambu_connected ? 'online' : 'offline');
|
switch(data.type) {
|
||||||
// Add click handler only when offline
|
case 'amsData':
|
||||||
if (!data.bambu_connected) {
|
displayAmsData(data.payload);
|
||||||
bambuDot.style.cursor = 'pointer';
|
break;
|
||||||
bambuDot.onclick = function() {
|
case 'nfcTag':
|
||||||
if (socket && socket.readyState === WebSocket.OPEN) {
|
updateNfcStatusIndicator(data.payload);
|
||||||
socket.send(JSON.stringify({
|
break;
|
||||||
type: 'reconnect',
|
case 'nfcData':
|
||||||
payload: 'bambu'
|
updateNfcData(data.payload);
|
||||||
}));
|
break;
|
||||||
}
|
case 'writeNfcTag':
|
||||||
};
|
handleWriteNfcTagResponse(data.success);
|
||||||
} else {
|
break;
|
||||||
bambuDot.style.cursor = 'default';
|
case 'heartbeat':
|
||||||
bambuDot.onclick = null;
|
handleHeartbeatResponse(data);
|
||||||
}
|
break;
|
||||||
}
|
case 'setSpoolmanSettings':
|
||||||
if (spoolmanDot) {
|
handleSpoolmanSettingsResponse(data);
|
||||||
spoolmanDot.className = 'status-dot ' + (data.spoolman_connected ? 'online' : 'offline');
|
break;
|
||||||
// Add click handler only when offline
|
default:
|
||||||
if (!data.spoolman_connected) {
|
console.warn('Unknown message type:', data.type);
|
||||||
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);
|
||||||
}
|
}
|
||||||
@@ -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) {
|
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;
|
||||||
@@ -419,6 +396,7 @@ 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 = {
|
||||||
@@ -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) {
|
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");
|
console.error("WebSocket not connected, state:", socket ? socket.readyState : "no socket");
|
||||||
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;
|
||||||
@@ -466,53 +448,55 @@ function handleSpoolIn(amsId, trayId) {
|
|||||||
|
|
||||||
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 (Array.isArray(selectedSpool.filament.nozzle_temperature) &&
|
if (selectedSpool.filament &&
|
||||||
|
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.color_hex || "FFFFFF",
|
color: selectedSpool.filament && selectedSpool.filament.color_hex ? 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.material,
|
type: selectedSpool.filament && selectedSpool.filament.material ? selectedSpool.filament.material : "PLA",
|
||||||
brand: selectedSpool.filament.vendor.name,
|
brand: selectedSpool.filament && selectedSpool.filament.vendor ? selectedSpool.filament.vendor.name : "",
|
||||||
tray_info_idx: selectedSpool.filament.extra.bambu_idx.replace(/['"]+/g, '').trim(),
|
tray_info_idx: bambuIdx,
|
||||||
cali_idx: "-1" // Default-Wert setzen
|
cali_idx: "-1" // Default-Wert setzen
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Prüfe, ob der Key cali_idx vorhanden ist und setze ihn
|
console.log("Sending payload:", payload);
|
||||||
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 set in AMS ${amsId} Tray ${trayId}. Pls wait`, true);
|
showNotification(`Spool settings sent to printer. Please wait...`, true);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Fehler beim Senden der WebSocket Nachricht:", error);
|
console.error("Error sending WebSocket message:", error);
|
||||||
showNotification("Error while sending", false);
|
showNotification("Error sending spool settings!", false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -687,3 +671,75 @@ function showNotification(message, isSuccess) {
|
|||||||
}, 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+162
-56
@@ -18,7 +18,7 @@ PubSubClient client(sslClient);
|
|||||||
TaskHandle_t BambuMqttTask;
|
TaskHandle_t BambuMqttTask;
|
||||||
|
|
||||||
String report_topic = "";
|
String report_topic = "";
|
||||||
//String request_topic = "";
|
String request_topic = "";
|
||||||
const char* bambu_username = "bblp";
|
const char* bambu_username = "bblp";
|
||||||
const char* bambu_ip = nullptr;
|
const char* bambu_ip = nullptr;
|
||||||
const char* bambu_accesscode = nullptr;
|
const char* bambu_accesscode = nullptr;
|
||||||
@@ -197,18 +197,69 @@ FilamentResult findFilamentIdx(String brand, String type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool sendMqttMessage(const String& payload) {
|
bool sendMqttMessage(const String& payload) {
|
||||||
Serial.println("Sending MQTT message");
|
// Check MQTT client state first
|
||||||
Serial.println(payload);
|
if (!client.connected()) {
|
||||||
if (client.publish(report_topic.c_str(), payload.c_str()))
|
Serial.println("Error: MQTT client not connected when trying to send message");
|
||||||
{
|
Serial.print("MQTT client state: ");
|
||||||
return true;
|
Serial.println(client.state());
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if request_topic is empty
|
||||||
|
if (request_topic.isEmpty()) {
|
||||||
|
Serial.println("Error: request_topic is empty!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check payload
|
||||||
|
if (payload.isEmpty()) {
|
||||||
|
Serial.println("Error: Empty payload!");
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.println("Attempting to send MQTT message:");
|
||||||
|
Serial.println("Topic: " + request_topic);
|
||||||
|
Serial.println("Payload: " + payload);
|
||||||
|
Serial.println("Payload length: " + String(payload.length()));
|
||||||
|
|
||||||
|
// Try to publish with QoS 1 and retain flag false
|
||||||
|
bool published = client.publish(request_topic.c_str(), payload.c_str(), false);
|
||||||
|
|
||||||
|
if (published) {
|
||||||
|
Serial.println("MQTT message published successfully");
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
Serial.println("Failed to publish MQTT message");
|
||||||
|
Serial.print("MQTT client state after publish attempt: ");
|
||||||
|
Serial.println(client.state());
|
||||||
|
|
||||||
|
// Additional error information
|
||||||
|
switch(client.state()) {
|
||||||
|
case -4:
|
||||||
|
Serial.println("Reason: Connection timeout");
|
||||||
|
break;
|
||||||
|
case -3:
|
||||||
|
Serial.println("Reason: Connection lost");
|
||||||
|
break;
|
||||||
|
case -2:
|
||||||
|
Serial.println("Reason: Connect failed");
|
||||||
|
break;
|
||||||
|
case -1:
|
||||||
|
Serial.println("Reason: Disconnected");
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
Serial.println("Reason: Connected but publish failed");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Serial.println("Reason: Unknown error");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool setBambuSpool(String payload) {
|
bool setBambuSpool(String payload) {
|
||||||
Serial.println("Spool settings in");
|
Serial.println("Spool settings received from WebSocket");
|
||||||
Serial.println(payload);
|
Serial.println(payload);
|
||||||
|
|
||||||
// Parse the JSON
|
// Parse the JSON
|
||||||
@@ -220,21 +271,28 @@ bool setBambuSpool(String payload) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int amsId = doc["amsId"];
|
// Check if we have all required fields
|
||||||
int trayId = doc["trayId"];
|
if (!doc["amsId"].is<int>() || !doc["trayId"].is<int>()) {
|
||||||
|
Serial.println("Error: Missing or invalid required fields in payload");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int amsId = doc["amsId"].as<int>();
|
||||||
|
int trayId = doc["trayId"].as<int>();
|
||||||
String color = doc["color"].as<String>();
|
String color = doc["color"].as<String>();
|
||||||
color.toUpperCase();
|
color.toUpperCase();
|
||||||
int minTemp = doc["nozzle_temp_min"];
|
int minTemp = doc["nozzle_temp_min"] | 0; // Default to 0 if not present
|
||||||
int maxTemp = doc["nozzle_temp_max"];
|
int maxTemp = doc["nozzle_temp_max"] | 0; // Default to 0 if not present
|
||||||
String type = doc["type"].as<String>();
|
String type = doc["type"] | ""; // Default to empty string if not present
|
||||||
(type == "PLA+") ? type = "PLA" : type;
|
(type == "PLA+") ? type = "PLA" : type;
|
||||||
String brand = doc["brand"].as<String>();
|
String brand = doc["brand"] | ""; // Default to empty string if not present
|
||||||
String tray_info_idx = (doc["tray_info_idx"].as<String>() != "-1") ? doc["tray_info_idx"].as<String>() : "";
|
String tray_info_idx = (doc["tray_info_idx"].as<String>() != "-1") ? doc["tray_info_idx"].as<String>() : "";
|
||||||
if (tray_info_idx == "") {
|
if (tray_info_idx == "") {
|
||||||
if (brand != "" && type != "") {
|
if (brand != "" && type != "") {
|
||||||
FilamentResult result = findFilamentIdx(brand, type);
|
FilamentResult result = findFilamentIdx(brand, type);
|
||||||
tray_info_idx = result.key;
|
tray_info_idx = result.key;
|
||||||
type = result.type; // Aktualisiere den type mit dem gefundenen Basistyp
|
type = result.type; // Aktualisiere den type mit dem gefundenen Basistyp
|
||||||
|
Serial.println("Found filament idx: " + tray_info_idx + " for type: " + type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String setting_id = doc["bambu_setting_id"].as<String>();
|
String setting_id = doc["bambu_setting_id"].as<String>();
|
||||||
@@ -242,6 +300,7 @@ bool setBambuSpool(String payload) {
|
|||||||
|
|
||||||
doc.clear();
|
doc.clear();
|
||||||
|
|
||||||
|
// Create MQTT message
|
||||||
doc["print"]["sequence_id"] = "0";
|
doc["print"]["sequence_id"] = "0";
|
||||||
doc["print"]["command"] = "ams_filament_setting";
|
doc["print"]["command"] = "ams_filament_setting";
|
||||||
doc["print"]["ams_id"] = amsId < 200 ? amsId : 255;
|
doc["print"]["ams_id"] = amsId < 200 ? amsId : 255;
|
||||||
@@ -250,26 +309,25 @@ bool setBambuSpool(String payload) {
|
|||||||
doc["print"]["nozzle_temp_min"] = minTemp;
|
doc["print"]["nozzle_temp_min"] = minTemp;
|
||||||
doc["print"]["nozzle_temp_max"] = maxTemp;
|
doc["print"]["nozzle_temp_max"] = maxTemp;
|
||||||
doc["print"]["tray_type"] = type;
|
doc["print"]["tray_type"] = type;
|
||||||
//doc["print"]["cali_idx"] = (cali_idx != "") ? cali_idx : "";
|
|
||||||
doc["print"]["tray_info_idx"] = tray_info_idx;
|
doc["print"]["tray_info_idx"] = tray_info_idx;
|
||||||
doc["print"]["setting_id"] = setting_id;
|
doc["print"]["setting_id"] = setting_id;
|
||||||
|
|
||||||
// Serialize the JSON
|
// Serialize and send MQTT message
|
||||||
String output;
|
String output;
|
||||||
serializeJson(doc, output);
|
serializeJson(doc, output);
|
||||||
|
Serial.println("Sending to Bambu printer:");
|
||||||
|
Serial.println(output);
|
||||||
|
|
||||||
if (sendMqttMessage(output)) {
|
if (!sendMqttMessage(output)) {
|
||||||
Serial.println("Spool successfully set");
|
Serial.println("Failed to send filament settings to printer");
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Serial.println("Failed to set spool");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Serial.println("Filament settings sent successfully");
|
||||||
doc.clear();
|
doc.clear();
|
||||||
yield();
|
yield();
|
||||||
|
|
||||||
|
// Send calibration if available
|
||||||
if (cali_idx != "") {
|
if (cali_idx != "") {
|
||||||
yield();
|
yield();
|
||||||
doc["print"]["sequence_id"] = "0";
|
doc["print"]["sequence_id"] = "0";
|
||||||
@@ -278,21 +336,19 @@ bool setBambuSpool(String payload) {
|
|||||||
doc["print"]["nozzle_diameter"] = "0.4";
|
doc["print"]["nozzle_diameter"] = "0.4";
|
||||||
doc["print"]["cali_idx"] = cali_idx.toInt();
|
doc["print"]["cali_idx"] = cali_idx.toInt();
|
||||||
doc["print"]["tray_id"] = trayId < 200 ? trayId : 254;
|
doc["print"]["tray_id"] = trayId < 200 ? trayId : 254;
|
||||||
//doc["print"]["ams_id"] = amsId < 200 ? amsId : 255;
|
|
||||||
|
|
||||||
// Serialize the JSON
|
// Serialize the JSON
|
||||||
String output;
|
String output;
|
||||||
serializeJson(doc, output);
|
serializeJson(doc, output);
|
||||||
|
Serial.println("Sending calibration to printer:");
|
||||||
|
Serial.println(output);
|
||||||
|
|
||||||
if (sendMqttMessage(output)) {
|
if (!sendMqttMessage(output)) {
|
||||||
Serial.println("Extrusion calibration successfully set");
|
Serial.println("Failed to send calibration settings to printer");
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Serial.println("Failed to set extrusion calibration");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Serial.println("Calibration settings sent successfully");
|
||||||
doc.clear();
|
doc.clear();
|
||||||
yield();
|
yield();
|
||||||
}
|
}
|
||||||
@@ -549,36 +605,57 @@ void reconnect() {
|
|||||||
uint8_t retries = 0;
|
uint8_t retries = 0;
|
||||||
while (!client.connected()) {
|
while (!client.connected()) {
|
||||||
Serial.println("Attempting MQTT re/connection...");
|
Serial.println("Attempting MQTT re/connection...");
|
||||||
|
Serial.print("State before connect: ");
|
||||||
|
Serial.println(client.state());
|
||||||
bambu_connected = false;
|
bambu_connected = false;
|
||||||
oledShowTopRow();
|
oledShowTopRow();
|
||||||
|
|
||||||
// Attempt to connect
|
// Generate a random client ID suffix
|
||||||
String clientId = String(bambu_serialnr) + "_" + String(random(0, 100));
|
String clientId = String(bambu_serialnr) + "_" + String(random(0xffff), HEX);
|
||||||
if (client.connect(clientId.c_str(), bambu_username, bambu_accesscode)){
|
Serial.print("Reconnecting with client ID: ");
|
||||||
|
Serial.println(clientId);
|
||||||
|
|
||||||
|
// Attempt to connect with clean session and will message
|
||||||
|
if (client.connect(clientId.c_str(), bambu_username, bambu_accesscode, nullptr, 0, true, nullptr)) {
|
||||||
Serial.println("MQTT re/connected");
|
Serial.println("MQTT re/connected");
|
||||||
|
|
||||||
client.subscribe(report_topic.c_str());
|
// Subscribe with QoS 1
|
||||||
|
if (client.subscribe(report_topic.c_str(), 1)) {
|
||||||
|
Serial.println("Successfully subscribed to topic with QoS 1: " + report_topic);
|
||||||
|
} else {
|
||||||
|
Serial.println("Failed to subscribe to topic: " + report_topic);
|
||||||
|
}
|
||||||
bambu_connected = true;
|
bambu_connected = true;
|
||||||
oledShowTopRow();
|
oledShowTopRow();
|
||||||
}
|
} else {
|
||||||
else
|
int state = client.state();
|
||||||
{
|
|
||||||
Serial.print("failed, rc=");
|
Serial.print("failed, rc=");
|
||||||
Serial.print(client.state());
|
Serial.print(state);
|
||||||
Serial.println(" try again in 5 seconds");
|
Serial.print(" (");
|
||||||
|
// Print detailed error message
|
||||||
|
switch(state) {
|
||||||
|
case -4: Serial.print("MQTT_CONNECTION_TIMEOUT"); break;
|
||||||
|
case -3: Serial.print("MQTT_CONNECTION_LOST"); break;
|
||||||
|
case -2: Serial.print("MQTT_CONNECT_FAILED"); break;
|
||||||
|
case -1: Serial.print("MQTT_DISCONNECTED"); break;
|
||||||
|
case 1: Serial.print("MQTT_CONNECT_BAD_PROTOCOL"); break;
|
||||||
|
case 2: Serial.print("MQTT_CONNECT_BAD_CLIENT_ID"); break;
|
||||||
|
case 3: Serial.print("MQTT_CONNECT_UNAVAILABLE"); break;
|
||||||
|
case 4: Serial.print("MQTT_CONNECT_BAD_CREDENTIALS"); break;
|
||||||
|
case 5: Serial.print("MQTT_CONNECT_UNAUTHORIZED"); break;
|
||||||
|
default: Serial.print("UNKNOWN"); break;
|
||||||
|
}
|
||||||
|
Serial.println(") try again in 5 seconds");
|
||||||
bambu_connected = false;
|
bambu_connected = false;
|
||||||
oledShowTopRow();
|
oledShowTopRow();
|
||||||
|
|
||||||
yield();
|
yield();
|
||||||
vTaskDelay(5000 / portTICK_PERIOD_MS);
|
vTaskDelay(5000 / portTICK_PERIOD_MS);
|
||||||
if (retries > 5)
|
if (retries > 5) {
|
||||||
{
|
|
||||||
Serial.println("Disable Bambu MQTT Task after 5 retries");
|
Serial.println("Disable Bambu MQTT Task after 5 retries");
|
||||||
// vTaskSuspend(BambuMqttTask);
|
|
||||||
vTaskDelete(BambuMqttTask);
|
vTaskDelete(BambuMqttTask);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
retries++;
|
retries++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -586,17 +663,32 @@ void reconnect() {
|
|||||||
|
|
||||||
void mqtt_loop(void * parameter) {
|
void mqtt_loop(void * parameter) {
|
||||||
Serial.println("Bambu MQTT Task gestartet");
|
Serial.println("Bambu MQTT Task gestartet");
|
||||||
|
unsigned long lastCheck = 0;
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
if (pauseBambuMqttTask) {
|
if (pauseBambuMqttTask) {
|
||||||
vTaskDelay(10000);
|
vTaskDelay(10000);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned long now = millis();
|
||||||
|
|
||||||
if (!client.connected()) {
|
if (!client.connected()) {
|
||||||
|
Serial.println("Connection lost, attempting reconnect...");
|
||||||
reconnect();
|
reconnect();
|
||||||
yield();
|
yield();
|
||||||
esp_task_wdt_reset();
|
esp_task_wdt_reset();
|
||||||
vTaskDelay(100);
|
vTaskDelay(100);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Periodically check connection status
|
||||||
|
if (now - lastCheck > 30000) { // Check every 30 seconds
|
||||||
|
Serial.print("MQTT Status Check - Connected: ");
|
||||||
|
Serial.println(client.connected() ? "Yes" : "No");
|
||||||
|
lastCheck = now;
|
||||||
|
}
|
||||||
|
|
||||||
client.loop();
|
client.loop();
|
||||||
yield();
|
yield();
|
||||||
esp_task_wdt_reset();
|
esp_task_wdt_reset();
|
||||||
@@ -621,15 +713,30 @@ bool setupMqtt() {
|
|||||||
sslClient.setInsecure();
|
sslClient.setInsecure();
|
||||||
client.setServer(bambu_ip, 8883);
|
client.setServer(bambu_ip, 8883);
|
||||||
|
|
||||||
|
// Generate a random client ID suffix
|
||||||
|
String clientId = String(bambu_serialnr) + "_" + String(random(0xffff), HEX);
|
||||||
|
|
||||||
|
// MQTT Connection Options
|
||||||
|
client.setKeepAlive(60);
|
||||||
|
client.setSocketTimeout(60); // Increase socket timeout
|
||||||
|
|
||||||
|
Serial.print("Connecting with client ID: ");
|
||||||
|
Serial.println(clientId);
|
||||||
|
|
||||||
// Verbinden mit dem MQTT-Server
|
// Verbinden mit dem MQTT-Server
|
||||||
bool connected = true;
|
bool connected = true;
|
||||||
String clientId = String(bambu_serialnr) + "_" + String(random(0, 100));
|
if (client.connect(clientId.c_str(), bambu_username, bambu_accesscode, nullptr, 0, true, nullptr))
|
||||||
if (client.connect(clientId.c_str(), bambu_username, bambu_accesscode))
|
|
||||||
{
|
{
|
||||||
client.setCallback(mqtt_callback);
|
client.setCallback(mqtt_callback);
|
||||||
client.setBufferSize(5120);
|
client.setBufferSize(16384); // Increased to 16KB to handle larger JSON
|
||||||
client.subscribe(report_topic.c_str());
|
|
||||||
// client.subscribe(request_topic.c_str());
|
// Subscribe with QoS 1
|
||||||
|
if (client.subscribe(report_topic.c_str(), 1)) {
|
||||||
|
Serial.println("Successfully subscribed to topic with QoS 1: " + report_topic);
|
||||||
|
} else {
|
||||||
|
Serial.println("Failed to subscribe to topic: " + report_topic);
|
||||||
|
}
|
||||||
|
|
||||||
Serial.println("MQTT-Client initialisiert");
|
Serial.println("MQTT-Client initialisiert");
|
||||||
|
|
||||||
oledShowMessage("Bambu Connected");
|
oledShowMessage("Bambu Connected");
|
||||||
@@ -637,13 +744,13 @@ bool setupMqtt() {
|
|||||||
oledShowTopRow();
|
oledShowTopRow();
|
||||||
|
|
||||||
xTaskCreatePinnedToCore(
|
xTaskCreatePinnedToCore(
|
||||||
mqtt_loop, /* Function to implement the task */
|
mqtt_loop, /* Function to implement the task */
|
||||||
"BambuMqtt", /* Name of the task */
|
"BambuMqtt", /* Name of the task */
|
||||||
10240, /* Stack size in words */
|
16384, /* Stack size in words */
|
||||||
NULL, /* Task input parameter */
|
NULL, /* Task input parameter */
|
||||||
mqttTaskPrio, /* Priority of the task */
|
mqttTaskPrio, /* Priority of the task */
|
||||||
&BambuMqttTask, /* Task handle. */
|
&BambuMqttTask, /* Task handle. */
|
||||||
mqttTaskCore); /* Core where the task should run */
|
mqttTaskCore); /* Core where the task should run */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -654,8 +761,7 @@ bool setupMqtt() {
|
|||||||
oledShowTopRow();
|
oledShowTopRow();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!connected)
|
if (!connected) return false;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user