Compare commits
	
		
			20 Commits
		
	
	
		
			v1.4.6
			...
			07a919b6ba
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 07a919b6ba | |||
| 8618b90e33 | |||
| 57723b5354 | |||
| d2be752175 | |||
| 97a050ace8 | |||
| 367e692c74 | |||
| 926a21249b | |||
| 2635c19667 | |||
| 
						 | 
					6cc4efca0a | ||
| 1484a6b0da | |||
| b5f0472af4 | |||
| 95c1bc823c | |||
| 491ba7f526 | |||
| 56d7d8596c | |||
| 1044e91a0a | |||
| e459b53472 | |||
| 024056cb7d | |||
| e040a736b0 | |||
| 72b6b349c6 | |||
| 
						 | 
					fe4d2d7479 | 
							
								
								
									
										37
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										37
									
								
								CHANGELOG.md
									
									
									
									
									
								
							@@ -1,5 +1,42 @@
 | 
				
			|||||||
# Changelog
 | 
					# Changelog
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## [1.4.9] - 2025-03-29
 | 
				
			||||||
 | 
					### Changed
 | 
				
			||||||
 | 
					- update platformio.ini for version v1.4.9
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Fixed
 | 
				
			||||||
 | 
					- enhance HTTP method handling in sendToApi function
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## [1.4.8] - 2025-03-29
 | 
				
			||||||
 | 
					### Changed
 | 
				
			||||||
 | 
					- update platformio.ini for version v1.4.8
 | 
				
			||||||
 | 
					- Merge pull request #30 from janecker/main
 | 
				
			||||||
 | 
					- Merge branch 'testing' into main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Fixed
 | 
				
			||||||
 | 
					- improve HTTP client configuration and clear update documents after API calls
 | 
				
			||||||
 | 
					- Fixes memory leak in HTTPClient by disabling connection reuse
 | 
				
			||||||
 | 
					- update reload logic after removing and saving Bambu credentials for better cache handling
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## [1.4.7] - 2025-03-27
 | 
				
			||||||
 | 
					### Added
 | 
				
			||||||
 | 
					- add forced cache refresh after removing and saving Bambu credentials
 | 
				
			||||||
 | 
					- add functionality to remove Bambu credentials and update API handling
 | 
				
			||||||
 | 
					- add rfid_bambu.html and update bambu connection handling
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Changed
 | 
				
			||||||
 | 
					- update platformio.ini for version v1.4.7
 | 
				
			||||||
 | 
					- Merge branch 'testing'
 | 
				
			||||||
 | 
					- update remove button for Bambu credentials with red background
 | 
				
			||||||
 | 
					- Merge pull request #28 from tugsi/main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Fixed
 | 
				
			||||||
 | 
					- handle Bambu connection state by introducing bambuDisabled flag
 | 
				
			||||||
 | 
					- Fix rfid.js-Failure with X1-Series, if you wanna send a Spool to AMS:  - Uncaught TypeError: Cannot read properties of undefined (reading 'replace')     at handleSpoolIn (rfid.js:493:67)     at HTMLButtonElement.onclick ((Index):1:1) handleSpoolIn	@	rfid.js:493 onclick	@	(Index):1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## [1.4.6] - 2025-03-26
 | 
					## [1.4.6] - 2025-03-26
 | 
				
			||||||
### Changed
 | 
					### Changed
 | 
				
			||||||
- update platformio.ini for version v1.4.6
 | 
					- update platformio.ini for version v1.4.6
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -141,15 +141,6 @@
 | 
				
			|||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <!-- Rechte Spalte -->
 | 
					 | 
				
			||||||
        <div class="column">
 | 
					 | 
				
			||||||
            <div class="feature-box">
 | 
					 | 
				
			||||||
                <h2>Bambu AMS</h2>
 | 
					 | 
				
			||||||
                <div id="amsDataContainer">
 | 
					 | 
				
			||||||
                    <div class="amsData" id="amsData">Wait for AMS-Data...</div>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										12
									
								
								html/rfid.js
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								html/rfid.js
									
									
									
									
									
								
							@@ -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' }));
 | 
				
			||||||
@@ -83,7 +83,7 @@ function initWebSocket() {
 | 
				
			|||||||
            isConnected = false;
 | 
					            isConnected = false;
 | 
				
			||||||
            updateConnectionStatus();
 | 
					            updateConnectionStatus();
 | 
				
			||||||
            if (heartbeatTimer) clearInterval(heartbeatTimer);
 | 
					            if (heartbeatTimer) clearInterval(heartbeatTimer);
 | 
				
			||||||
            
 | 
					
 | 
				
			||||||
            // Bei Fehler Verbindung schließen und neu aufbauen
 | 
					            // Bei Fehler Verbindung schließen und neu aufbauen
 | 
				
			||||||
            if (socket) {
 | 
					            if (socket) {
 | 
				
			||||||
                socket.close();
 | 
					                socket.close();
 | 
				
			||||||
@@ -109,7 +109,7 @@ function initWebSocket() {
 | 
				
			|||||||
                const bambuDot = document.getElementById('bambuDot');
 | 
					                const bambuDot = document.getElementById('bambuDot');
 | 
				
			||||||
                const spoolmanDot = document.getElementById('spoolmanDot');
 | 
					                const spoolmanDot = document.getElementById('spoolmanDot');
 | 
				
			||||||
                const ramStatus = document.getElementById('ramStatus');
 | 
					                const ramStatus = document.getElementById('ramStatus');
 | 
				
			||||||
                
 | 
					
 | 
				
			||||||
                if (bambuDot) {
 | 
					                if (bambuDot) {
 | 
				
			||||||
                    bambuDot.className = 'status-dot ' + (data.bambu_connected ? 'online' : 'offline');
 | 
					                    bambuDot.className = 'status-dot ' + (data.bambu_connected ? 'online' : 'offline');
 | 
				
			||||||
                    // Add click handler only when offline
 | 
					                    // Add click handler only when offline
 | 
				
			||||||
@@ -208,7 +208,7 @@ 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;
 | 
				
			||||||
@@ -686,4 +686,4 @@ function showNotification(message, isSuccess) {
 | 
				
			|||||||
            notification.remove();
 | 
					            notification.remove();
 | 
				
			||||||
        }, 300);
 | 
					        }, 300);
 | 
				
			||||||
    }, 3000);
 | 
					    }, 3000);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										160
									
								
								html/rfid_bambu.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										160
									
								
								html/rfid_bambu.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,160 @@
 | 
				
			|||||||
 | 
					<!-- head --><!DOCTYPE html>
 | 
				
			||||||
 | 
					<html lang="en">
 | 
				
			||||||
 | 
					<head>
 | 
				
			||||||
 | 
					    <meta charset="UTF-8">
 | 
				
			||||||
 | 
					    <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | 
				
			||||||
 | 
					    <title>FilaMan - Filament Management Tool</title>
 | 
				
			||||||
 | 
					    <link rel="icon" type="image/png" href="/favicon.ico">
 | 
				
			||||||
 | 
					    <link rel="stylesheet" href="style.css">
 | 
				
			||||||
 | 
					    <script>
 | 
				
			||||||
 | 
					        fetch('/api/version')
 | 
				
			||||||
 | 
					            .then(response => response.json())
 | 
				
			||||||
 | 
					            .then(data => {
 | 
				
			||||||
 | 
					                const versionSpan = document.querySelector('.version');
 | 
				
			||||||
 | 
					                if (versionSpan) {
 | 
				
			||||||
 | 
					                    versionSpan.textContent = 'v' + data.version;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					            .catch(error => console.error('Error fetching version:', error));
 | 
				
			||||||
 | 
					    </script>
 | 
				
			||||||
 | 
					</head>
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					    <div class="navbar">
 | 
				
			||||||
 | 
					        <div style="display: flex; align-items: center; gap: 2rem;">
 | 
				
			||||||
 | 
					            <img src="/logo.png" alt="FilaMan Logo" class="logo">
 | 
				
			||||||
 | 
					            <div class="logo-text">
 | 
				
			||||||
 | 
					                <h1>FilaMan<span class="version"></span></h1>
 | 
				
			||||||
 | 
					                <h4>Filament Management Tool</h4>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <nav style="display: flex; gap: 1rem;">
 | 
				
			||||||
 | 
					            <a href="/">Start</a>
 | 
				
			||||||
 | 
					            <a href="/waage">Scale</a>
 | 
				
			||||||
 | 
					            <a href="/spoolman">Spoolman/Bambu</a>
 | 
				
			||||||
 | 
					            <a href="/about">About</a>
 | 
				
			||||||
 | 
					            <a href="/upgrade">Upgrade</a>
 | 
				
			||||||
 | 
					        </nav>
 | 
				
			||||||
 | 
					        <div class="status-container">
 | 
				
			||||||
 | 
					            <div class="status-item">
 | 
				
			||||||
 | 
					                <span class="status-dot" id="bambuDot"></span>B
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div class="status-item">
 | 
				
			||||||
 | 
					                <span class="status-dot" id="spoolmanDot"></span>S
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div class="ram-status" id="ramStatus"></div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<!-- head -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="connection-status hidden">
 | 
				
			||||||
 | 
					    <div class="spinner"></div>
 | 
				
			||||||
 | 
					    <span>Connection lost. Trying to reconnect...</span>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					<div class="content">
 | 
				
			||||||
 | 
					    <div class="three-column-layout">
 | 
				
			||||||
 | 
					        <!-- Linke Spalte -->
 | 
				
			||||||
 | 
					        <div class="column">
 | 
				
			||||||
 | 
					            <div class="feature-box">
 | 
				
			||||||
 | 
					                <div class="statistics-header">
 | 
				
			||||||
 | 
					                    <h2>Statistics</h2>
 | 
				
			||||||
 | 
					                    <button id="refreshSpoolman" class="refresh-button">
 | 
				
			||||||
 | 
					                        <span>Refresh Spoolman</span>
 | 
				
			||||||
 | 
					                    </button>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					                <div class="statistics-column">
 | 
				
			||||||
 | 
					                    <h3>Spools</h3>
 | 
				
			||||||
 | 
					                        <div class="spool-stat" style="display: flex; justify-content: center; align-items: center;">
 | 
				
			||||||
 | 
					                            <span class="stat-label">total:</span>
 | 
				
			||||||
 | 
					                            <span class="stat-value" id="totalSpools"></span>
 | 
				
			||||||
 | 
					                            <div style="width: auto;"></div>
 | 
				
			||||||
 | 
					                            <span class="stat-label">without Tag:</span>
 | 
				
			||||||
 | 
					                            <span class="stat-value" id="spoolsWithoutTag"></span>
 | 
				
			||||||
 | 
					                        </div>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <div class="statistics-grid">
 | 
				
			||||||
 | 
					                    <div class="statistics-column">
 | 
				
			||||||
 | 
					                        <h3>Overview</h3>
 | 
				
			||||||
 | 
					                        <ul class="statistics-list">
 | 
				
			||||||
 | 
					                            <li>
 | 
				
			||||||
 | 
					                                <span class="stat-label">Manufacturer:</span>
 | 
				
			||||||
 | 
					                                <span class="stat-value" id="totalVendors"></span>
 | 
				
			||||||
 | 
					                            </li>
 | 
				
			||||||
 | 
					                            <li>
 | 
				
			||||||
 | 
					                                <span class="stat-label">Weight:</span>
 | 
				
			||||||
 | 
					                                <span class="stat-value"><span id="totalWeight"></span></span>
 | 
				
			||||||
 | 
					                            </li>
 | 
				
			||||||
 | 
					                            <li>
 | 
				
			||||||
 | 
					                                <span class="stat-label">Length:</span>
 | 
				
			||||||
 | 
					                                <span class="stat-value"><span id="totalLength"></span></span>
 | 
				
			||||||
 | 
					                            </li>
 | 
				
			||||||
 | 
					                        </ul>
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                    <div class="statistics-column">
 | 
				
			||||||
 | 
					                        <h3>Materials</h3>
 | 
				
			||||||
 | 
					                        <ul class="statistics-list" id="materialsList">
 | 
				
			||||||
 | 
					                            <!-- Wird dynamisch befüllt -->
 | 
				
			||||||
 | 
					                        </ul>
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div class="feature-box">
 | 
				
			||||||
 | 
					                <div class="nfc-header">
 | 
				
			||||||
 | 
					                    <h2>NFC-Tag</h2>
 | 
				
			||||||
 | 
					                    <span id="nfcStatusIndicator" class="status-circle"></span>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					                <div class="nfc-status-display"></div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <!-- Mittlere Spalte -->
 | 
				
			||||||
 | 
					        <div class="column">
 | 
				
			||||||
 | 
					            <div class="feature-box">
 | 
				
			||||||
 | 
					                <h2>Spoolman Spools</h2>
 | 
				
			||||||
 | 
					                <label for="vendorSelect">Manufacturer:</label>
 | 
				
			||||||
 | 
					                <div style="display: flex; justify-content: space-between; align-items: center;">
 | 
				
			||||||
 | 
					                    <select id="vendorSelect" class="styled-select">
 | 
				
			||||||
 | 
					                        <option value="">Please choose...</option>
 | 
				
			||||||
 | 
					                    </select>
 | 
				
			||||||
 | 
					                    <label style="margin-left: 10px;">
 | 
				
			||||||
 | 
					                        <input type="checkbox" id="onlyWithoutSmId" checked onchange="updateFilamentDropdown()">
 | 
				
			||||||
 | 
					                        Only Spools without SM ID
 | 
				
			||||||
 | 
					                    </label>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <div id="filamentSection" class="feature-box hidden">
 | 
				
			||||||
 | 
					                <label>Spool / Filament:</label>
 | 
				
			||||||
 | 
					                <div class="custom-dropdown">
 | 
				
			||||||
 | 
					                    <div class="dropdown-button" onclick="toggleFilamentDropdown()">
 | 
				
			||||||
 | 
					                        <div class="selected-color" id="selected-color"></div>
 | 
				
			||||||
 | 
					                        <span id="selected-filament">Please choose...</span>
 | 
				
			||||||
 | 
					                        <span class="dropdown-arrow">▼</span>
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                    <div class="dropdown-content" id="filament-dropdown-content">
 | 
				
			||||||
 | 
					                        <!-- Optionen werden dynamisch hinzugefügt -->
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					                <p id="nfcInfo" class="nfc-status"></p>
 | 
				
			||||||
 | 
					                <button id="writeNfcButton" class="btn btn-primary hidden" onclick="writeNfcTag()">Write Tag</button>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <!-- Rechte Spalte -->
 | 
				
			||||||
 | 
					        <div class="column">
 | 
				
			||||||
 | 
					            <div class="feature-box">
 | 
				
			||||||
 | 
					                <h2>Bambu AMS</h2>
 | 
				
			||||||
 | 
					                <div id="amsDataContainer">
 | 
				
			||||||
 | 
					                    <div class="amsData" id="amsData">Wait for AMS-Data...</div>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script src="spoolman.js"></script>
 | 
				
			||||||
 | 
					<script src="rfid.js"></script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
@@ -57,6 +57,31 @@
 | 
				
			|||||||
            toggleOctoFields();
 | 
					            toggleOctoFields();
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        function removeBambuCredentials() {
 | 
				
			||||||
 | 
					            fetch('/api/bambu?remove=true')
 | 
				
			||||||
 | 
					                .then(response => response.json())
 | 
				
			||||||
 | 
					                .then(data => {
 | 
				
			||||||
 | 
					                    if (data.success) {
 | 
				
			||||||
 | 
					                        document.getElementById('bambuIp').value = '';
 | 
				
			||||||
 | 
					                        document.getElementById('bambuSerial').value = '';
 | 
				
			||||||
 | 
					                        document.getElementById('bambuCode').value = '';
 | 
				
			||||||
 | 
					                        document.getElementById('autoSend').checked = false;
 | 
				
			||||||
 | 
					                        document.getElementById('autoSendTime').value = '';
 | 
				
			||||||
 | 
					                        document.getElementById('bambuStatusMessage').innerText = 'Bambu Credentials removed!';
 | 
				
			||||||
 | 
					                        // Reload with forced cache refresh after short delay
 | 
				
			||||||
 | 
					                        setTimeout(() => {
 | 
				
			||||||
 | 
					                            window.location.reload(true);
 | 
				
			||||||
 | 
					                            window.location.href = '/';
 | 
				
			||||||
 | 
					                        }, 1500);
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        document.getElementById('bambuStatusMessage').innerText = 'Error while removing Bambu Credentials.';
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                })
 | 
				
			||||||
 | 
					                .catch(error => {
 | 
				
			||||||
 | 
					                    document.getElementById('bambuStatusMessage').innerText = 'Error while removing: ' + error.message;
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        function checkSpoolmanInstance() {
 | 
					        function checkSpoolmanInstance() {
 | 
				
			||||||
            const url = document.getElementById('spoolmanUrl').value;
 | 
					            const url = document.getElementById('spoolmanUrl').value;
 | 
				
			||||||
            const spoolmanOctoEnabled = document.getElementById('spoolmanOctoEnabled').checked;
 | 
					            const spoolmanOctoEnabled = document.getElementById('spoolmanOctoEnabled').checked;
 | 
				
			||||||
@@ -89,6 +114,11 @@
 | 
				
			|||||||
                .then(data => {
 | 
					                .then(data => {
 | 
				
			||||||
                    if (data.healthy) {
 | 
					                    if (data.healthy) {
 | 
				
			||||||
                        document.getElementById('bambuStatusMessage').innerText = 'Bambu Credentials saved!';
 | 
					                        document.getElementById('bambuStatusMessage').innerText = 'Bambu Credentials saved!';
 | 
				
			||||||
 | 
					                        // Reload with forced cache refresh after short delay
 | 
				
			||||||
 | 
					                        setTimeout(() => {
 | 
				
			||||||
 | 
					                            window.location.reload(true);
 | 
				
			||||||
 | 
					                            window.location.href = '/';
 | 
				
			||||||
 | 
					                        }, 1500);
 | 
				
			||||||
                    } else {
 | 
					                    } else {
 | 
				
			||||||
                        document.getElementById('bambuStatusMessage').innerText = 'Error while saving Bambu Credentials.';
 | 
					                        document.getElementById('bambuStatusMessage').innerText = 'Error while saving Bambu Credentials.';
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
@@ -162,6 +192,7 @@
 | 
				
			|||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    <button style="margin: 0;" onclick="saveBambuCredentials()">Save Bambu Credentials</button>
 | 
					                    <button style="margin: 0;" onclick="saveBambuCredentials()">Save Bambu Credentials</button>
 | 
				
			||||||
 | 
					                    <button style="margin: 0; background-color: red;" onclick="removeBambuCredentials()">Remove Credentials</button>
 | 
				
			||||||
                    <p id="bambuStatusMessage"></p>
 | 
					                    <p id="bambuStatusMessage"></p>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,7 +9,7 @@
 | 
				
			|||||||
; https://docs.platformio.org/page/projectconf.html
 | 
					; https://docs.platformio.org/page/projectconf.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[common]
 | 
					[common]
 | 
				
			||||||
version = "1.4.6"
 | 
					version = "1.4.9"
 | 
				
			||||||
to_old_version = "1.4.0"
 | 
					to_old_version = "1.4.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
##
 | 
					##
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										14
									
								
								src/api.cpp
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								src/api.cpp
									
									
									
									
									
								
							@@ -94,13 +94,16 @@ void sendToApi(void *parameter) {
 | 
				
			|||||||
    String octoToken = params->octoToken;    
 | 
					    String octoToken = params->octoToken;    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    HTTPClient http;
 | 
					    HTTPClient http;
 | 
				
			||||||
 | 
					    http.setReuse(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    http.begin(spoolsUrl);
 | 
					    http.begin(spoolsUrl);
 | 
				
			||||||
    http.addHeader("Content-Type", "application/json");
 | 
					    http.addHeader("Content-Type", "application/json");
 | 
				
			||||||
    if (octoEnabled && octoToken != "") http.addHeader("X-Api-Key", octoToken);
 | 
					    if (octoEnabled && octoToken != "") http.addHeader("X-Api-Key", octoToken);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int httpCode = http.PUT(updatePayload);
 | 
					    int httpCode;
 | 
				
			||||||
    if (httpType == "PATCH") httpCode = http.PATCH(updatePayload);
 | 
					    if (httpType == "PATCH") httpCode = http.PATCH(updatePayload);
 | 
				
			||||||
    if (httpType == "POST") httpCode = http.POST(updatePayload);
 | 
					    else if (httpType == "POST") httpCode = http.POST(updatePayload);
 | 
				
			||||||
 | 
					    else httpCode = http.PUT(updatePayload);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (httpCode == HTTP_CODE_OK) {
 | 
					    if (httpCode == HTTP_CODE_OK) {
 | 
				
			||||||
        Serial.println("Spoolman erfolgreich aktualisiert");
 | 
					        Serial.println("Spoolman erfolgreich aktualisiert");
 | 
				
			||||||
@@ -111,6 +114,7 @@ void sendToApi(void *parameter) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    http.end();
 | 
					    http.end();
 | 
				
			||||||
 | 
					    vTaskDelay(50 / portTICK_PERIOD_MS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Speicher freigeben
 | 
					    // Speicher freigeben
 | 
				
			||||||
    delete params;
 | 
					    delete params;
 | 
				
			||||||
@@ -165,6 +169,8 @@ bool updateSpoolTagId(String uidString, const char* payload) {
 | 
				
			|||||||
        NULL                      // Task-Handle (nicht benötigt)
 | 
					        NULL                      // Task-Handle (nicht benötigt)
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    updateDoc.clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -201,6 +207,8 @@ uint8_t updateSpoolWeight(String spoolId, uint16_t weight) {
 | 
				
			|||||||
        NULL                      // Task-Handle (nicht benötigt)
 | 
					        NULL                      // Task-Handle (nicht benötigt)
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    updateDoc.clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return 1;
 | 
					    return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -238,6 +246,8 @@ bool updateSpoolOcto(int spoolId) {
 | 
				
			|||||||
        NULL                      // Task-Handle (nicht benötigt)
 | 
					        NULL                      // Task-Handle (nicht benötigt)
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    updateDoc.clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,6 +27,7 @@ const char* bambu_serialnr = nullptr;
 | 
				
			|||||||
String g_bambu_ip = "";
 | 
					String g_bambu_ip = "";
 | 
				
			||||||
String g_bambu_accesscode = "";
 | 
					String g_bambu_accesscode = "";
 | 
				
			||||||
String g_bambu_serialnr = "";
 | 
					String g_bambu_serialnr = "";
 | 
				
			||||||
 | 
					bool bambuDisabled = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool bambu_connected = false;
 | 
					bool bambu_connected = false;
 | 
				
			||||||
bool autoSendToBambu = false;
 | 
					bool autoSendToBambu = false;
 | 
				
			||||||
@@ -37,6 +38,32 @@ int ams_count = 0;
 | 
				
			|||||||
String amsJsonData;  // Speichert das fertige JSON für WebSocket-Clients
 | 
					String amsJsonData;  // Speichert das fertige JSON für WebSocket-Clients
 | 
				
			||||||
AMSData ams_data[MAX_AMS];  // Definition des Arrays;
 | 
					AMSData ams_data[MAX_AMS];  // Definition des Arrays;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool removeBambuCredentials() {
 | 
				
			||||||
 | 
					    if (BambuMqttTask) {
 | 
				
			||||||
 | 
					        vTaskDelete(BambuMqttTask);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (!removeJsonValue("/bambu_credentials.json")) {
 | 
				
			||||||
 | 
					        Serial.println("Fehler beim Löschen der Bambu-Credentials.");
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    // Löschen der globalen Variablen
 | 
				
			||||||
 | 
					    g_bambu_ip = "";
 | 
				
			||||||
 | 
					    g_bambu_accesscode = "";
 | 
				
			||||||
 | 
					    g_bambu_serialnr = "";
 | 
				
			||||||
 | 
					    bambu_ip = nullptr;
 | 
				
			||||||
 | 
					    bambu_accesscode = nullptr;
 | 
				
			||||||
 | 
					    bambu_serialnr = nullptr;
 | 
				
			||||||
 | 
					    autoSendToBambu = false;
 | 
				
			||||||
 | 
					    autoSetToBambuSpoolId = 0;
 | 
				
			||||||
 | 
					    ams_count = 0;
 | 
				
			||||||
 | 
					    amsJsonData = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bambuDisabled = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool saveBambuCredentials(const String& ip, const String& serialnr, const String& accesscode, bool autoSend, const String& autoSendTime) {
 | 
					bool saveBambuCredentials(const String& ip, const String& serialnr, const String& accesscode, bool autoSend, const String& autoSendTime) {
 | 
				
			||||||
    if (BambuMqttTask) {
 | 
					    if (BambuMqttTask) {
 | 
				
			||||||
        vTaskDelete(BambuMqttTask);
 | 
					        vTaskDelete(BambuMqttTask);
 | 
				
			||||||
@@ -606,14 +633,13 @@ bool setupMqtt() {
 | 
				
			|||||||
    bool success = loadBambuCredentials();
 | 
					    bool success = loadBambuCredentials();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!success) {
 | 
					    if (!success) {
 | 
				
			||||||
        Serial.println("Failed to load Bambu credentials");
 | 
					        bambuDisabled = true;
 | 
				
			||||||
        oledShowMessage("Bambu Credentials Missing");
 | 
					 | 
				
			||||||
        vTaskDelay(2000 / portTICK_PERIOD_MS);
 | 
					 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (success && bambu_ip != "" && bambu_accesscode != "" && bambu_serialnr != "") 
 | 
					    if (success && bambu_ip != "" && bambu_accesscode != "" && bambu_serialnr != "") 
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        bambuDisabled = false;
 | 
				
			||||||
        sslClient.setCACert(root_ca);
 | 
					        sslClient.setCACert(root_ca);
 | 
				
			||||||
        sslClient.setInsecure();
 | 
					        sslClient.setInsecure();
 | 
				
			||||||
        client.setServer(bambu_ip, 8883);
 | 
					        client.setServer(bambu_ip, 8883);
 | 
				
			||||||
@@ -654,10 +680,7 @@ bool setupMqtt() {
 | 
				
			|||||||
    } 
 | 
					    } 
 | 
				
			||||||
    else 
 | 
					    else 
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        Serial.println("Fehler: Keine MQTT-Daten vorhanden");
 | 
					        bambuDisabled = true;
 | 
				
			||||||
        oledShowMessage("Bambu Credentials Missing");
 | 
					 | 
				
			||||||
        oledShowTopRow();
 | 
					 | 
				
			||||||
        vTaskDelay(2000 / portTICK_PERIOD_MS);
 | 
					 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,7 +30,9 @@ extern int ams_count;
 | 
				
			|||||||
extern AMSData ams_data[MAX_AMS];
 | 
					extern AMSData ams_data[MAX_AMS];
 | 
				
			||||||
extern bool autoSendToBambu;
 | 
					extern bool autoSendToBambu;
 | 
				
			||||||
extern int autoSetToBambuSpoolId;
 | 
					extern int autoSetToBambuSpoolId;
 | 
				
			||||||
 | 
					extern bool bambuDisabled;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool removeBambuCredentials();
 | 
				
			||||||
bool loadBambuCredentials();
 | 
					bool loadBambuCredentials();
 | 
				
			||||||
bool saveBambuCredentials(const String& bambu_ip, const String& bambu_serialnr, const String& bambu_accesscode, const bool autoSend, const String& autoSendTime);
 | 
					bool saveBambuCredentials(const String& bambu_ip, const String& bambu_serialnr, const String& bambu_accesscode, const bool autoSend, const String& autoSendTime);
 | 
				
			||||||
bool setupMqtt();
 | 
					bool setupMqtt();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,20 @@
 | 
				
			|||||||
#include "commonFS.h"
 | 
					#include "commonFS.h"
 | 
				
			||||||
#include <LittleFS.h>
 | 
					#include <LittleFS.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool removeJsonValue(const char* filename) {
 | 
				
			||||||
 | 
					    File file = LittleFS.open(filename, "r");
 | 
				
			||||||
 | 
					    if (!file) {
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    file.close();
 | 
				
			||||||
 | 
					    if (!LittleFS.remove(filename)) {
 | 
				
			||||||
 | 
					        Serial.print("Fehler beim Löschen der Datei: ");
 | 
				
			||||||
 | 
					        Serial.println(filename);
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool saveJsonValue(const char* filename, const JsonDocument& doc) {
 | 
					bool saveJsonValue(const char* filename, const JsonDocument& doc) {
 | 
				
			||||||
    File file = LittleFS.open(filename, "w");
 | 
					    File file = LittleFS.open(filename, "w");
 | 
				
			||||||
    if (!file) {
 | 
					    if (!file) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,7 @@
 | 
				
			|||||||
#include <ArduinoJson.h>
 | 
					#include <ArduinoJson.h>
 | 
				
			||||||
#include <LittleFS.h>
 | 
					#include <LittleFS.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool removeJsonValue(const char* filename);
 | 
				
			||||||
bool saveJsonValue(const char* filename, const JsonDocument& doc);
 | 
					bool saveJsonValue(const char* filename, const JsonDocument& doc);
 | 
				
			||||||
bool loadJsonValue(const char* filename, JsonDocument& doc);
 | 
					bool loadJsonValue(const char* filename, JsonDocument& doc);
 | 
				
			||||||
void initializeFileSystem();
 | 
					void initializeFileSystem();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -100,7 +100,7 @@ void loop() {
 | 
				
			|||||||
  // Wenn Bambu auto set Spool aktiv
 | 
					  // Wenn Bambu auto set Spool aktiv
 | 
				
			||||||
  if (autoSendToBambu && autoSetToBambuSpoolId > 0) 
 | 
					  if (autoSendToBambu && autoSetToBambuSpoolId > 0) 
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    if (!bambu_connected) 
 | 
					    if (!bambuDisabled && !bambu_connected) 
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      bambu_restart();
 | 
					      bambu_restart();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,7 +29,7 @@ void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventTyp
 | 
				
			|||||||
    if (type == WS_EVT_CONNECT) {
 | 
					    if (type == WS_EVT_CONNECT) {
 | 
				
			||||||
        Serial.println("Neuer Client verbunden!");
 | 
					        Serial.println("Neuer Client verbunden!");
 | 
				
			||||||
        // Sende die AMS-Daten an den neuen Client
 | 
					        // Sende die AMS-Daten an den neuen Client
 | 
				
			||||||
        sendAmsData(client);
 | 
					        if (!bambuDisabled) sendAmsData(client);
 | 
				
			||||||
        sendNfcData(client);
 | 
					        sendNfcData(client);
 | 
				
			||||||
        foundNfcTag(client, 0);
 | 
					        foundNfcTag(client, 0);
 | 
				
			||||||
        sendWriteResult(client, 3);
 | 
					        sendWriteResult(client, 3);
 | 
				
			||||||
@@ -213,7 +213,10 @@ void setupWebserver(AsyncWebServer &server) {
 | 
				
			|||||||
    // Route für RFID
 | 
					    // Route für RFID
 | 
				
			||||||
    server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
 | 
					    server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
 | 
				
			||||||
        Serial.println("Anfrage für /rfid erhalten");
 | 
					        Serial.println("Anfrage für /rfid erhalten");
 | 
				
			||||||
        AsyncWebServerResponse *response = request->beginResponse(LittleFS, "/rfid.html.gz", "text/html");
 | 
					        
 | 
				
			||||||
 | 
					        String page = (bambuDisabled) ? "/rfid.html.gz" : "/rfid_bambu.html.gz";
 | 
				
			||||||
 | 
					        AsyncWebServerResponse *response = request->beginResponse(LittleFS, page, "text/html");
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
        response->addHeader("Content-Encoding", "gzip");
 | 
					        response->addHeader("Content-Encoding", "gzip");
 | 
				
			||||||
        response->addHeader("Cache-Control", CACHE_CONTROL);
 | 
					        response->addHeader("Cache-Control", CACHE_CONTROL);
 | 
				
			||||||
        request->send(response);
 | 
					        request->send(response);
 | 
				
			||||||
@@ -310,6 +313,15 @@ void setupWebserver(AsyncWebServer &server) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // Route für das Überprüfen der Bambu-Instanz
 | 
					    // Route für das Überprüfen der Bambu-Instanz
 | 
				
			||||||
    server.on("/api/bambu", HTTP_GET, [](AsyncWebServerRequest *request){
 | 
					    server.on("/api/bambu", HTTP_GET, [](AsyncWebServerRequest *request){
 | 
				
			||||||
 | 
					        if (request->hasParam("remove")) {
 | 
				
			||||||
 | 
					            if (removeBambuCredentials()) {
 | 
				
			||||||
 | 
					                request->send(200, "application/json", "{\"success\": true}");
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                request->send(500, "application/json", "{\"success\": false, \"error\": \"Fehler beim Löschen der Bambu-Credentials\"}");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!request->hasParam("bambu_ip") || !request->hasParam("bambu_serialnr") || !request->hasParam("bambu_accesscode")) {
 | 
					        if (!request->hasParam("bambu_ip") || !request->hasParam("bambu_serialnr") || !request->hasParam("bambu_accesscode")) {
 | 
				
			||||||
            request->send(400, "application/json", "{\"success\": false, \"error\": \"Missing parameter\"}");
 | 
					            request->send(400, "application/json", "{\"success\": false, \"error\": \"Missing parameter\"}");
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user