Compare commits
No commits in common. "main" and "v1.3.97" have entirely different histories.
10
.github/workflows/gitea-release.yml
vendored
10
.github/workflows/gitea-release.yml
vendored
@ -41,16 +41,16 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
VERSION=$(grep '^version = ' platformio.ini | cut -d'"' -f2)
|
VERSION=$(grep '^version = ' platformio.ini | cut -d'"' -f2)
|
||||||
|
|
||||||
# Build firmware and LittleFS
|
# Build firmware and SPIFFS
|
||||||
echo "Building firmware and LittleFS..."
|
echo "Building firmware and SPIFFS..."
|
||||||
pio run -e esp32dev
|
pio run -e esp32dev
|
||||||
pio run -t buildfs
|
pio run -t buildfs
|
||||||
|
|
||||||
# Copy firmware binary
|
# Copy firmware binary
|
||||||
cp .pio/build/esp32dev/firmware.bin .pio/build/esp32dev/upgrade_filaman_firmware_v${VERSION}.bin
|
cp .pio/build/esp32dev/firmware.bin .pio/build/esp32dev/upgrade_filaman_firmware_v${VERSION}.bin
|
||||||
|
|
||||||
# Create LittleFS binary - direct copy without header
|
# Create SPIFFS binary - direct copy without header
|
||||||
cp .pio/build/esp32dev/littlefs.bin .pio/build/esp32dev/upgrade_filaman_website_v${VERSION}.bin
|
cp .pio/build/esp32dev/spiffs.bin .pio/build/esp32dev/upgrade_filaman_website_v${VERSION}.bin
|
||||||
|
|
||||||
# Create full binary
|
# Create full binary
|
||||||
(cd .pio/build/esp32dev &&
|
(cd .pio/build/esp32dev &&
|
||||||
@ -63,7 +63,7 @@ jobs:
|
|||||||
0x1000 bootloader.bin \
|
0x1000 bootloader.bin \
|
||||||
0x8000 partitions.bin \
|
0x8000 partitions.bin \
|
||||||
0x10000 firmware.bin \
|
0x10000 firmware.bin \
|
||||||
0x3D0000 littlefs.bin)
|
0x3D0000 spiffs.bin)
|
||||||
|
|
||||||
# Verify file sizes
|
# Verify file sizes
|
||||||
echo "File sizes:"
|
echo "File sizes:"
|
||||||
|
12
.github/workflows/github-release.yml
vendored
12
.github/workflows/github-release.yml
vendored
@ -39,16 +39,16 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
VERSION=$(grep '^version = ' platformio.ini | cut -d'"' -f2)
|
VERSION=$(grep '^version = ' platformio.ini | cut -d'"' -f2)
|
||||||
|
|
||||||
# Always build firmware and LittleFS
|
# Always build firmware and SPIFFS
|
||||||
echo "Building firmware and LittleFS..."
|
echo "Building firmware and SPIFFS..."
|
||||||
pio run -e esp32dev
|
pio run -e esp32dev
|
||||||
pio run -t buildfs
|
pio run -t buildfs
|
||||||
|
|
||||||
# Copy firmware binary
|
# Copy firmware binary
|
||||||
cp .pio/build/esp32dev/firmware.bin .pio/build/esp32dev/upgrade_filaman_firmware_v${VERSION}.bin
|
cp .pio/build/esp32dev/firmware.bin .pio/build/esp32dev/upgrade_filaman_firmware_v${VERSION}.bin
|
||||||
|
|
||||||
# Create LittleFS binary - direct copy without header
|
# Create SPIFFS binary - direct copy without header
|
||||||
cp .pio/build/esp32dev/littlefs.bin .pio/build/esp32dev/upgrade_filaman_website_v${VERSION}.bin
|
cp .pio/build/esp32dev/spiffs.bin .pio/build/esp32dev/upgrade_filaman_website_v${VERSION}.bin
|
||||||
|
|
||||||
# Create full binary (always)
|
# Create full binary (always)
|
||||||
(cd .pio/build/esp32dev &&
|
(cd .pio/build/esp32dev &&
|
||||||
@ -61,7 +61,7 @@ jobs:
|
|||||||
0x1000 bootloader.bin \
|
0x1000 bootloader.bin \
|
||||||
0x8000 partitions.bin \
|
0x8000 partitions.bin \
|
||||||
0x10000 firmware.bin \
|
0x10000 firmware.bin \
|
||||||
0x3D0000 littlefs.bin)
|
0x3D0000 spiffs.bin)
|
||||||
|
|
||||||
# Verify file sizes
|
# Verify file sizes
|
||||||
echo "File sizes:"
|
echo "File sizes:"
|
||||||
@ -131,7 +131,7 @@ jobs:
|
|||||||
FILES_TO_UPLOAD="$FILES_TO_UPLOAD upgrade_filaman_firmware_v${VERSION}.bin"
|
FILES_TO_UPLOAD="$FILES_TO_UPLOAD upgrade_filaman_firmware_v${VERSION}.bin"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Add LittleFS and full binary only if they exist
|
# Add SPIFFS and full binary only if they exist
|
||||||
if [ -f "upgrade_filaman_website_v${VERSION}.bin" ]; then
|
if [ -f "upgrade_filaman_website_v${VERSION}.bin" ]; then
|
||||||
FILES_TO_UPLOAD="$FILES_TO_UPLOAD upgrade_filaman_website_v${VERSION}.bin"
|
FILES_TO_UPLOAD="$FILES_TO_UPLOAD upgrade_filaman_website_v${VERSION}.bin"
|
||||||
fi
|
fi
|
||||||
|
54
.vscode/settings.json
vendored
Normal file
54
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
{
|
||||||
|
"files.associations": {
|
||||||
|
"algorithm": "cpp",
|
||||||
|
"vector": "cpp",
|
||||||
|
"cmath": "cpp",
|
||||||
|
"array": "cpp",
|
||||||
|
"atomic": "cpp",
|
||||||
|
"*.tcc": "cpp",
|
||||||
|
"bitset": "cpp",
|
||||||
|
"cctype": "cpp",
|
||||||
|
"clocale": "cpp",
|
||||||
|
"cstdarg": "cpp",
|
||||||
|
"cstddef": "cpp",
|
||||||
|
"cstdint": "cpp",
|
||||||
|
"cstdio": "cpp",
|
||||||
|
"cstdlib": "cpp",
|
||||||
|
"cstring": "cpp",
|
||||||
|
"ctime": "cpp",
|
||||||
|
"cwchar": "cpp",
|
||||||
|
"cwctype": "cpp",
|
||||||
|
"deque": "cpp",
|
||||||
|
"unordered_map": "cpp",
|
||||||
|
"unordered_set": "cpp",
|
||||||
|
"exception": "cpp",
|
||||||
|
"functional": "cpp",
|
||||||
|
"iterator": "cpp",
|
||||||
|
"map": "cpp",
|
||||||
|
"memory": "cpp",
|
||||||
|
"memory_resource": "cpp",
|
||||||
|
"numeric": "cpp",
|
||||||
|
"optional": "cpp",
|
||||||
|
"random": "cpp",
|
||||||
|
"regex": "cpp",
|
||||||
|
"string": "cpp",
|
||||||
|
"string_view": "cpp",
|
||||||
|
"system_error": "cpp",
|
||||||
|
"tuple": "cpp",
|
||||||
|
"type_traits": "cpp",
|
||||||
|
"utility": "cpp",
|
||||||
|
"fstream": "cpp",
|
||||||
|
"initializer_list": "cpp",
|
||||||
|
"iomanip": "cpp",
|
||||||
|
"iosfwd": "cpp",
|
||||||
|
"istream": "cpp",
|
||||||
|
"limits": "cpp",
|
||||||
|
"new": "cpp",
|
||||||
|
"ostream": "cpp",
|
||||||
|
"sstream": "cpp",
|
||||||
|
"stdexcept": "cpp",
|
||||||
|
"streambuf": "cpp",
|
||||||
|
"cinttypes": "cpp",
|
||||||
|
"typeinfo": "cpp"
|
||||||
|
}
|
||||||
|
}
|
30
CHANGELOG.md
30
CHANGELOG.md
@ -1,35 +1,5 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## [1.4.0] - 2025-03-01
|
|
||||||
### Added
|
|
||||||
- add support for Spoolman Octoprint Plugin in README files
|
|
||||||
- add OctoPrint integration with configurable fields and update functionality
|
|
||||||
- add version comparison function and check for outdated versions before updates
|
|
||||||
- remove unused version and protocol fields from JSON output; add error message for insufficient memory
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
- update NFC tag references to include NTAG213 and clarify storage capacity
|
|
||||||
- bump version to 1.4.0
|
|
||||||
- remove unused version and protocol fields from NFC data packet
|
|
||||||
- sort vendors alphabetically in the dropdown list
|
|
||||||
- Merge pull request #10 from janecker/nfc-improvements
|
|
||||||
- Improves NFC Tag handling
|
|
||||||
|
|
||||||
|
|
||||||
## [1.3.99] - 2025-02-28
|
|
||||||
### Changed
|
|
||||||
- update platformio.ini for version v1.3.99
|
|
||||||
- update workflows to build firmware with LittleFS instead of SPIFFS
|
|
||||||
|
|
||||||
|
|
||||||
## [1.3.98] - 2025-02-28
|
|
||||||
### Changed
|
|
||||||
- update platformio.ini for version v1.3.98
|
|
||||||
- migrate from SPIFFS to LittleFS for file handling
|
|
||||||
- remove unused VSCode settings file
|
|
||||||
- remove commented-out spoolman and filaman data from api.cpp
|
|
||||||
|
|
||||||
|
|
||||||
## [1.3.97] - 2025-02-28
|
## [1.3.97] - 2025-02-28
|
||||||
### Added
|
### Added
|
||||||
- füge Bestätigungsmeldung für Spool-Einstellung hinzu
|
- füge Bestätigungsmeldung für Spool-Einstellung hinzu
|
||||||
|
@ -9,7 +9,6 @@ Das System integriert sich nahtlos mit der [Spoolman](https://github.com/Donkie/
|
|||||||
Weitere Bilder finden Sie im [img Ordner](/img/)
|
Weitere Bilder finden Sie im [img Ordner](/img/)
|
||||||
oder auf meiner Website: [FilaMan Website](https://www.filaman.app)
|
oder auf meiner Website: [FilaMan Website](https://www.filaman.app)
|
||||||
Deutsches Erklärvideo: [Youtube](https://youtu.be/uNDe2wh9SS8?si=b-jYx4I1w62zaOHU)
|
Deutsches Erklärvideo: [Youtube](https://youtu.be/uNDe2wh9SS8?si=b-jYx4I1w62zaOHU)
|
||||||
Discord Server: [https://discord.gg/vMAx2gf5](https://discord.gg/vMAx2gf5)
|
|
||||||
|
|
||||||
### Es gibt jetzt auch ein Wiki, dort sind nochmal alle Funktionen beschrieben: [Wiki](https://github.com/ManuelW77/Filaman/wiki)
|
### Es gibt jetzt auch ein Wiki, dort sind nochmal alle Funktionen beschrieben: [Wiki](https://github.com/ManuelW77/Filaman/wiki)
|
||||||
|
|
||||||
@ -19,7 +18,7 @@ Discord Server: [https://discord.gg/vMAx2gf5](https://discord.gg/vMAx2gf5)
|
|||||||
- **OLED-Display:** Zeigt aktuelles Gewicht, Verbindungsstatus (WiFi, Bambu Lab, Spoolman).
|
- **OLED-Display:** Zeigt aktuelles Gewicht, Verbindungsstatus (WiFi, Bambu Lab, Spoolman).
|
||||||
- **WLAN-Konnektivität:** WiFiManager für einfache Netzwerkkonfiguration.
|
- **WLAN-Konnektivität:** WiFiManager für einfache Netzwerkkonfiguration.
|
||||||
- **MQTT-Integration:** Verbindet sich mit Bambu Lab Drucker für AMS-Steuerung.
|
- **MQTT-Integration:** Verbindet sich mit Bambu Lab Drucker für AMS-Steuerung.
|
||||||
- **NFC-Tag NTAG213 NTAG215:** Verwendung von NTAG213, besser NTAG215 wegen ausreichendem Speicherplatz auf dem Tag
|
- **NFC-Tag NTAG215:** Verwendung von NTAG215 wegen ausreichendem Speicherplatz auf dem Tag
|
||||||
|
|
||||||
### Weboberflächen-Funktionen
|
### Weboberflächen-Funktionen
|
||||||
- **Echtzeit-Updates:** WebSocket-Verbindung für Live-Daten-Updates.
|
- **Echtzeit-Updates:** WebSocket-Verbindung für Live-Daten-Updates.
|
||||||
@ -36,7 +35,6 @@ Discord Server: [https://discord.gg/vMAx2gf5](https://discord.gg/vMAx2gf5)
|
|||||||
- Filtern und Auswählen von Filamenten.
|
- Filtern und Auswählen von Filamenten.
|
||||||
- Automatische Aktualisierung der Spulengewichte.
|
- Automatische Aktualisierung der Spulengewichte.
|
||||||
- Verfolgung von NFC-Tag-Zuweisungen.
|
- Verfolgung von NFC-Tag-Zuweisungen.
|
||||||
- Unterstützt das Spoolman Octoprint Plugin
|
|
||||||
|
|
||||||
### Wenn Sie meine Arbeit unterstützen möchten, freue ich mich über einen Kaffee
|
### Wenn Sie meine Arbeit unterstützen möchten, freue ich mich über einen Kaffee
|
||||||
<a href="https://www.buymeacoffee.com/manuelw" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" style="height: 30px !important;width: 108px !important;" ></a>
|
<a href="https://www.buymeacoffee.com/manuelw" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" style="height: 30px !important;width: 108px !important;" ></a>
|
||||||
@ -63,7 +61,7 @@ Discord Server: [https://discord.gg/vMAx2gf5](https://discord.gg/vMAx2gf5)
|
|||||||
[Amazon Link](https://amzn.eu/d/0AuBp2c)
|
[Amazon Link](https://amzn.eu/d/0AuBp2c)
|
||||||
- **PN532 NFC NXP RFID-Modul V3:** Für NFC-Tag-Operationen.
|
- **PN532 NFC NXP RFID-Modul V3:** Für NFC-Tag-Operationen.
|
||||||
[Amazon Link](https://amzn.eu/d/jfIuQXb)
|
[Amazon Link](https://amzn.eu/d/jfIuQXb)
|
||||||
- **NFC Tags NTAG213 NTA215:** RFID Tag
|
- **NFC Tags Ntag215:** RFID Tag
|
||||||
[Amazon Link](https://amzn.eu/d/9Z6mXc1)
|
[Amazon Link](https://amzn.eu/d/9Z6mXc1)
|
||||||
|
|
||||||
### Pin-Konfiguration
|
### Pin-Konfiguration
|
||||||
|
@ -6,14 +6,12 @@ FilaMan is a filament management system for 3D printing. It uses ESP32 hardware
|
|||||||
Users can manage filament spools, monitor the status of the Automatic Material System (AMS) and make settings via a web interface.
|
Users can manage filament spools, monitor the status of the Automatic Material System (AMS) and make settings via a web interface.
|
||||||
The system integrates seamlessly with [Bambulab](https://bambulab.com/en-us) 3D printers and [Spoolman](https://github.com/Donkie/Spoolman) filament management as well as the [Openspool](https://github.com/spuder/OpenSpool) NFC-TAG format.
|
The system integrates seamlessly with [Bambulab](https://bambulab.com/en-us) 3D printers and [Spoolman](https://github.com/Donkie/Spoolman) filament management as well as the [Openspool](https://github.com/spuder/OpenSpool) NFC-TAG format.
|
||||||
|
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
More Images can be found in the [img Folder](/img/)
|
More Images can be found in the [img Folder](/img/)
|
||||||
or my website: [FilaMan Website](https://www.filaman.app)
|
or my website:[FilaMan Website](https://www.filaman.app)
|
||||||
german explanatory video: [Youtube](https://youtu.be/uNDe2wh9SS8?si=b-jYx4I1w62zaOHU)
|
german explanatory video: [Youtube](https://youtu.be/uNDe2wh9SS8?si=b-jYx4I1w62zaOHU)
|
||||||
Discord Server: [https://discord.gg/vMAx2gf5](https://discord.gg/vMAx2gf5)
|
|
||||||
|
|
||||||
### Now more detailed informations about the usage: [Wiki](https://github.com/ManuelW77/Filaman/wiki)
|
### Now more detailed informations about the usage: [Wiki](https://github.com/ManuelW77/Filaman/wiki)
|
||||||
|
|
||||||
@ -23,7 +21,7 @@ Discord Server: [https://discord.gg/vMAx2gf5](https://discord.gg/vMAx2gf5)
|
|||||||
- **OLED Display:** Shows current weight, connection status (WiFi, Bambu Lab, Spoolman).
|
- **OLED Display:** Shows current weight, connection status (WiFi, Bambu Lab, Spoolman).
|
||||||
- **WiFi Connectivity:** WiFiManager for easy network configuration.
|
- **WiFi Connectivity:** WiFiManager for easy network configuration.
|
||||||
- **MQTT Integration:** Connects to Bambu Lab printer for AMS control.
|
- **MQTT Integration:** Connects to Bambu Lab printer for AMS control.
|
||||||
- **NFC-Tag NTAG213 NTAG215:** Use NTAG213, better NTAG215 because of enaught space on the Tag
|
- **NFC-Tag NTAG215:** Use NTAG215 because of enaught space on the Tag
|
||||||
|
|
||||||
### Web Interface Features
|
### Web Interface Features
|
||||||
- **Real-time Updates:** WebSocket connection for live data updates.
|
- **Real-time Updates:** WebSocket connection for live data updates.
|
||||||
@ -40,7 +38,6 @@ Discord Server: [https://discord.gg/vMAx2gf5](https://discord.gg/vMAx2gf5)
|
|||||||
- Filter and select filaments.
|
- Filter and select filaments.
|
||||||
- Update spool weights automatically.
|
- Update spool weights automatically.
|
||||||
- Track NFC tag assignments.
|
- Track NFC tag assignments.
|
||||||
- Supports Spoolman Octoprint Plugin
|
|
||||||
|
|
||||||
### If you want to support my work, i would be happy to get a coffe
|
### If you want to support my work, i would be happy to get a coffe
|
||||||
<a href="https://www.buymeacoffee.com/manuelw" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" style="height: 30px !important;width: 108px !important;" ></a>
|
<a href="https://www.buymeacoffee.com/manuelw" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" style="height: 30px !important;width: 108px !important;" ></a>
|
||||||
@ -67,7 +64,7 @@ Discord Server: [https://discord.gg/vMAx2gf5](https://discord.gg/vMAx2gf5)
|
|||||||
[Amazon Link](https://amzn.eu/d/0AuBp2c)
|
[Amazon Link](https://amzn.eu/d/0AuBp2c)
|
||||||
- **PN532 NFC NXP RFID-Modul V3:** For NFC tag operations.
|
- **PN532 NFC NXP RFID-Modul V3:** For NFC tag operations.
|
||||||
[Amazon Link](https://amzn.eu/d/jfIuQXb)
|
[Amazon Link](https://amzn.eu/d/jfIuQXb)
|
||||||
- **NFC Tags NTAG213 NTAG215:** RFID Tag
|
- **NFC Tags Ntag215:** RFID Tag
|
||||||
[Amazon Link](https://amzn.eu/d/9Z6mXc1)
|
[Amazon Link](https://amzn.eu/d/9Z6mXc1)
|
||||||
|
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -640,6 +640,8 @@ function writeNfcTag() {
|
|||||||
|
|
||||||
// Erstelle das NFC-Datenpaket mit korrekten Datentypen
|
// Erstelle das NFC-Datenpaket mit korrekten Datentypen
|
||||||
const nfcData = {
|
const nfcData = {
|
||||||
|
version: "2.0",
|
||||||
|
protocol: "openspool",
|
||||||
color_hex: selectedSpool.filament.color_hex || "FFFFFF",
|
color_hex: selectedSpool.filament.color_hex || "FFFFFF",
|
||||||
type: selectedSpool.filament.material,
|
type: selectedSpool.filament.material,
|
||||||
min_temp: minTemp,
|
min_temp: minTemp,
|
||||||
|
@ -52,18 +52,11 @@
|
|||||||
if (spoolmanUrl && spoolmanUrl.trim() !== "") {
|
if (spoolmanUrl && spoolmanUrl.trim() !== "") {
|
||||||
document.getElementById('spoolmanUrl').value = spoolmanUrl;
|
document.getElementById('spoolmanUrl').value = spoolmanUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize OctoPrint fields visibility
|
|
||||||
toggleOctoFields();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function checkSpoolmanInstance() {
|
function checkSpoolmanInstance() {
|
||||||
const url = document.getElementById('spoolmanUrl').value;
|
const url = document.getElementById('spoolmanUrl').value;
|
||||||
const spoolmanOctoEnabled = document.getElementById('spoolmanOctoEnabled').checked;
|
fetch(`/api/checkSpoolman?url=${encodeURIComponent(url)}`)
|
||||||
const spoolmanOctoUrl = document.getElementById('spoolmanOctoUrl').value;
|
|
||||||
const spoolmanOctoToken = document.getElementById('spoolmanOctoToken').value;
|
|
||||||
|
|
||||||
fetch(`/api/checkSpoolman?url=${encodeURIComponent(url)}&octoEnabled=${spoolmanOctoEnabled}&octoUrl=${spoolmanOctoUrl}&octoToken=${spoolmanOctoToken}`)
|
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
if (data.healthy) {
|
if (data.healthy) {
|
||||||
@ -97,15 +90,6 @@
|
|||||||
document.getElementById('bambuStatusMessage').innerText = 'Error while saving: ' + error.message;
|
document.getElementById('bambuStatusMessage').innerText = 'Error while saving: ' + error.message;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Controls visibility of OctoPrint configuration fields based on checkbox state
|
|
||||||
* Called on page load and when checkbox changes
|
|
||||||
*/
|
|
||||||
function toggleOctoFields() {
|
|
||||||
const octoEnabled = document.getElementById('spoolmanOctoEnabled').checked;
|
|
||||||
document.getElementById('octoFields').style.display = octoEnabled ? 'block' : 'none';
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
<script>
|
<script>
|
||||||
var spoolmanUrl = "{{spoolmanUrl}}";
|
var spoolmanUrl = "{{spoolmanUrl}}";
|
||||||
@ -118,17 +102,6 @@
|
|||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5 class="card-title">Set URL/IP to your Spoolman-Instanz</h5>
|
<h5 class="card-title">Set URL/IP to your Spoolman-Instanz</h5>
|
||||||
<input type="text" id="spoolmanUrl" placeholder="http://ip-or-url-of-your-spoolman-instanz:port">
|
<input type="text" id="spoolmanUrl" placeholder="http://ip-or-url-of-your-spoolman-instanz:port">
|
||||||
<h5 class="card-title">If you want to enable sending Spool to Spoolman Octoprint Plugin:</h5>
|
|
||||||
<p>
|
|
||||||
<input type="checkbox" id="spoolmanOctoEnabled" {{spoolmanOctoEnabled}} onchange="toggleOctoFields()"> Send to Octo-Plugin
|
|
||||||
</p>
|
|
||||||
<div id="octoFields" style="display: none;">
|
|
||||||
<p>
|
|
||||||
<input type="text" id="spoolmanOctoUrl" placeholder="http://ip-or-url-of-your-octoprint-instanz:port" value="{{spoolmanOctoUrl}}">
|
|
||||||
<input type="text" id="spoolmanOctoToken" placeholder="Your Octoprint Token" value="{{spoolmanOctoToken}}">
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button onclick="checkSpoolmanInstance()">Save Spoolman URL</button>
|
<button onclick="checkSpoolmanInstance()">Save Spoolman URL</button>
|
||||||
<p id="statusMessage"></p>
|
<p id="statusMessage"></p>
|
||||||
</div>
|
</div>
|
||||||
@ -154,11 +127,11 @@
|
|||||||
<p>If activated, FilaMan will automatically update the next filled tray with the last scanned and weighed spool.</p>
|
<p>If activated, FilaMan will automatically update the next filled tray with the last scanned and weighed spool.</p>
|
||||||
<div class="input-group" style="display: flex; margin-bottom: 0;">
|
<div class="input-group" style="display: flex; margin-bottom: 0;">
|
||||||
<label for="autoSend" style="width: 250px; margin-right: 5px;">Auto Send to Bambu:</label>
|
<label for="autoSend" style="width: 250px; margin-right: 5px;">Auto Send to Bambu:</label>
|
||||||
<label for="autoSendTime" style="width: 250px; margin-right: 5px;">Wait for Spool in Sec:</label>
|
<label for="autoSendTime" style="width: 250px; margin-right: 5px;">Wait time in Seconds:</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="input-group" style="display: flex;">
|
<div class="input-group" style="display: flex;">
|
||||||
<input type="checkbox" id="autoSend" {{autoSendToBambu}} style="width: 190px; margin-right: 10px;">
|
<input type="checkbox" id="autoSend" {{autoSendToBambu}} style="width: 190px; margin-right: 10px;">
|
||||||
<input type="number" min="60" id="autoSendTime" placeholder="Time to wait" value="{{autoSendTime}}" style="width: 100px;">
|
<input type="text" id="autoSendTime" placeholder="Time to wait for new Spool" value="{{autoSendTime}}" style="width: 100px;">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button style="margin: 0;" onclick="saveBambuCredentials()">Save Bambu Credentials</button>
|
<button style="margin: 0;" onclick="saveBambuCredentials()">Save Bambu Credentials</button>
|
||||||
|
@ -86,7 +86,7 @@ function populateVendorDropdown(data, selectedSmId = null) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Nach der Schleife: Formatierung der Gesamtlänge
|
// Nach der Schleife: Formatierung der Gesamtlänge
|
||||||
console.log("Total Length: ", totalLength);
|
console.log("Total Lenght: ", totalLength);
|
||||||
const formattedLength = totalLength > 1000
|
const formattedLength = totalLength > 1000
|
||||||
? (totalLength / 1000).toFixed(2) + " km"
|
? (totalLength / 1000).toFixed(2) + " km"
|
||||||
: totalLength.toFixed(2) + " m";
|
: totalLength.toFixed(2) + " m";
|
||||||
@ -97,15 +97,13 @@ function populateVendorDropdown(data, selectedSmId = null) {
|
|||||||
? (weightInKg / 1000).toFixed(2) + " t"
|
? (weightInKg / 1000).toFixed(2) + " t"
|
||||||
: weightInKg.toFixed(2) + " kg";
|
: weightInKg.toFixed(2) + " kg";
|
||||||
|
|
||||||
// Dropdown mit gefilterten Herstellern befüllen - alphabetisch sortiert
|
// Dropdown mit gefilterten Herstellern befüllen
|
||||||
Object.entries(filteredVendors)
|
Object.entries(filteredVendors).forEach(([id, name]) => {
|
||||||
.sort(([, nameA], [, nameB]) => nameA.localeCompare(nameB)) // Sort vendors alphabetically by name
|
const option = document.createElement("option");
|
||||||
.forEach(([id, name]) => {
|
option.value = id;
|
||||||
const option = document.createElement("option");
|
option.textContent = name;
|
||||||
option.value = id;
|
vendorSelect.appendChild(option);
|
||||||
option.textContent = name;
|
});
|
||||||
vendorSelect.appendChild(option);
|
|
||||||
});
|
|
||||||
|
|
||||||
document.getElementById("totalSpools").textContent = totalSpools;
|
document.getElementById("totalSpools").textContent = totalSpools;
|
||||||
document.getElementById("spoolsWithoutTag").textContent = spoolsWithoutTag;
|
document.getElementById("spoolsWithoutTag").textContent = spoolsWithoutTag;
|
||||||
|
@ -188,18 +188,14 @@ label {
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="text"], input[type="submit"], input[type="number"] {
|
input[type="text"], input[type="submit"] {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
border: 1px solid #ccc;
|
border: 1px solid #ccc;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="number"] {
|
input[type="text"]:focus {
|
||||||
width: 108px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type="text"]:focus, input[type="number"]:focus {
|
|
||||||
border-color: #007bff;
|
border-color: #007bff;
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
BIN
img/7-enable.png
BIN
img/7-enable.png
Binary file not shown.
Before Width: | Height: | Size: 52 KiB |
@ -9,9 +9,7 @@
|
|||||||
; https://docs.platformio.org/page/projectconf.html
|
; https://docs.platformio.org/page/projectconf.html
|
||||||
|
|
||||||
[common]
|
[common]
|
||||||
version = "1.4.0"
|
version = "1.3.97"
|
||||||
to_old_version = "1.4.0"
|
|
||||||
|
|
||||||
##
|
##
|
||||||
[env:esp32dev]
|
[env:esp32dev]
|
||||||
platform = espressif32
|
platform = espressif32
|
||||||
@ -35,8 +33,7 @@ lib_deps =
|
|||||||
digitaldragon/SSLClient @ ^1.3.2
|
digitaldragon/SSLClient @ ^1.3.2
|
||||||
|
|
||||||
; Enable SPIFFS upload
|
; Enable SPIFFS upload
|
||||||
#board_build.filesystem = spiffs
|
board_build.filesystem = spiffs
|
||||||
board_build.filesystem = littlefs
|
|
||||||
; Update partition settings
|
; Update partition settings
|
||||||
board_build.partitions = partitions.csv
|
board_build.partitions = partitions.csv
|
||||||
board_upload.flash_size = 4MB
|
board_upload.flash_size = 4MB
|
||||||
@ -47,14 +44,13 @@ build_flags =
|
|||||||
-Os
|
-Os
|
||||||
-ffunction-sections
|
-ffunction-sections
|
||||||
-fdata-sections
|
-fdata-sections
|
||||||
#-DNDEBUG
|
-DNDEBUG
|
||||||
-mtext-section-literals
|
-mtext-section-literals
|
||||||
-DVERSION=\"${common.version}\"
|
-DVERSION=\"${common.version}\"
|
||||||
-DTOOLDVERSION=\"${common.to_old_version}\"
|
|
||||||
-DASYNCWEBSERVER_REGEX
|
-DASYNCWEBSERVER_REGEX
|
||||||
#-DCORE_DEBUG_LEVEL=3
|
-DCORE_DEBUG_LEVEL=3
|
||||||
-DCONFIG_ARDUHAL_LOG_COLORS=1
|
-DCONFIG_ARDUHAL_LOG_COLORS=1
|
||||||
#-DOTA_DEBUG=1
|
-DOTA_DEBUG=1
|
||||||
-DCONFIG_OPTIMIZATION_LEVEL_DEBUG=1
|
-DCONFIG_OPTIMIZATION_LEVEL_DEBUG=1
|
||||||
-DBOOT_APP_PARTITION_OTA_0=1
|
-DBOOT_APP_PARTITION_OTA_0=1
|
||||||
-DCONFIG_LWIP_TCP_MSL=60000
|
-DCONFIG_LWIP_TCP_MSL=60000
|
||||||
|
90
src/api.cpp
90
src/api.cpp
@ -5,17 +5,38 @@
|
|||||||
|
|
||||||
bool spoolman_connected = false;
|
bool spoolman_connected = false;
|
||||||
String spoolmanUrl = "";
|
String spoolmanUrl = "";
|
||||||
bool octoEnabled = false;
|
|
||||||
String octoUrl = "";
|
|
||||||
String octoToken = "";
|
|
||||||
|
|
||||||
struct SendToApiParams {
|
struct SendToApiParams {
|
||||||
String httpType;
|
String httpType;
|
||||||
String spoolsUrl;
|
String spoolsUrl;
|
||||||
String updatePayload;
|
String updatePayload;
|
||||||
String octoToken;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Spoolman Data
|
||||||
|
{
|
||||||
|
"version":"1.0",
|
||||||
|
"protocol":"openspool",
|
||||||
|
"color_hex":"AF7933",
|
||||||
|
"type":"ABS",
|
||||||
|
"min_temp":175,
|
||||||
|
"max_temp":275,
|
||||||
|
"brand":"Overture"
|
||||||
|
}
|
||||||
|
|
||||||
|
// FilaMan Data
|
||||||
|
{
|
||||||
|
"version":"1.0",
|
||||||
|
"protocol":"openspool",
|
||||||
|
"color_hex":"AF7933",
|
||||||
|
"type":"ABS",
|
||||||
|
"min_temp":175,
|
||||||
|
"max_temp":275,
|
||||||
|
"brand":"Overture",
|
||||||
|
"sm_id":
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
JsonDocument fetchSingleSpoolInfo(int spoolId) {
|
JsonDocument fetchSingleSpoolInfo(int spoolId) {
|
||||||
HTTPClient http;
|
HTTPClient http;
|
||||||
String spoolsUrl = spoolmanUrl + apiUrl + "/spool/" + spoolId;
|
String spoolsUrl = spoolmanUrl + apiUrl + "/spool/" + spoolId;
|
||||||
@ -91,16 +112,14 @@ void sendToApi(void *parameter) {
|
|||||||
String httpType = params->httpType;
|
String httpType = params->httpType;
|
||||||
String spoolsUrl = params->spoolsUrl;
|
String spoolsUrl = params->spoolsUrl;
|
||||||
String updatePayload = params->updatePayload;
|
String updatePayload = params->updatePayload;
|
||||||
String octoToken = params->octoToken;
|
|
||||||
|
|
||||||
HTTPClient http;
|
HTTPClient http;
|
||||||
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);
|
|
||||||
|
|
||||||
int httpCode = http.PUT(updatePayload);
|
int httpCode = http.PUT(updatePayload);
|
||||||
if (httpType == "PATCH") httpCode = http.PATCH(updatePayload);
|
if (httpType == "PATCH") httpCode = http.PATCH(updatePayload);
|
||||||
if (httpType == "POST") httpCode = http.POST(updatePayload);
|
|
||||||
|
|
||||||
if (httpCode == HTTP_CODE_OK) {
|
if (httpCode == HTTP_CODE_OK) {
|
||||||
Serial.println("Spoolman erfolgreich aktualisiert");
|
Serial.println("Spoolman erfolgreich aktualisiert");
|
||||||
@ -204,43 +223,6 @@ uint8_t updateSpoolWeight(String spoolId, uint16_t weight) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool updateSpoolOcto(int spoolId) {
|
|
||||||
String spoolsUrl = octoUrl + "/plugin/Spoolman/selectSpool";
|
|
||||||
Serial.print("Update Spule in Octoprint mit URL: ");
|
|
||||||
Serial.println(spoolsUrl);
|
|
||||||
|
|
||||||
JsonDocument updateDoc;
|
|
||||||
updateDoc["spool_id"] = spoolId;
|
|
||||||
updateDoc["tool"] = "tool0";
|
|
||||||
|
|
||||||
String updatePayload;
|
|
||||||
serializeJson(updateDoc, updatePayload);
|
|
||||||
Serial.print("Update Payload: ");
|
|
||||||
Serial.println(updatePayload);
|
|
||||||
|
|
||||||
SendToApiParams* params = new SendToApiParams();
|
|
||||||
if (params == nullptr) {
|
|
||||||
Serial.println("Fehler: Kann Speicher für Task-Parameter nicht allokieren.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
params->httpType = "POST";
|
|
||||||
params->spoolsUrl = spoolsUrl;
|
|
||||||
params->updatePayload = updatePayload;
|
|
||||||
params->octoToken = octoToken;
|
|
||||||
|
|
||||||
// Erstelle die Task
|
|
||||||
BaseType_t result = xTaskCreate(
|
|
||||||
sendToApi, // Task-Funktion
|
|
||||||
"SendToApiTask", // Task-Name
|
|
||||||
4096, // Stackgröße in Bytes
|
|
||||||
(void*)params, // Parameter
|
|
||||||
0, // Priorität
|
|
||||||
NULL // Task-Handle (nicht benötigt)
|
|
||||||
);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool updateSpoolBambuData(String payload) {
|
bool updateSpoolBambuData(String payload) {
|
||||||
JsonDocument doc;
|
JsonDocument doc;
|
||||||
DeserializationError error = deserializeJson(doc, payload);
|
DeserializationError error = deserializeJson(doc, payload);
|
||||||
@ -478,24 +460,17 @@ bool checkSpoolmanInstance(const String& url) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool saveSpoolmanUrl(const String& url, bool octoOn, const String& octoWh, const String& octoTk) {
|
bool saveSpoolmanUrl(const String& url) {
|
||||||
if (!checkSpoolmanInstance(url)) return false;
|
if (!checkSpoolmanInstance(url)) return false;
|
||||||
|
|
||||||
JsonDocument doc;
|
JsonDocument doc;
|
||||||
doc["url"] = url;
|
doc["url"] = url;
|
||||||
doc["octoEnabled"] = octoOn;
|
Serial.print("Speichere URL in Datei: ");
|
||||||
doc["octoUrl"] = octoWh;
|
Serial.println(url);
|
||||||
doc["octoToken"] = octoTk;
|
|
||||||
Serial.print("Speichere Spoolman Data in Datei: ");
|
|
||||||
Serial.println(doc.as<String>());
|
|
||||||
if (!saveJsonValue("/spoolman_url.json", doc)) {
|
if (!saveJsonValue("/spoolman_url.json", doc)) {
|
||||||
Serial.println("Fehler beim Speichern der Spoolman-URL.");
|
Serial.println("Fehler beim Speichern der Spoolman-URL.");
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
spoolmanUrl = url;
|
spoolmanUrl = url;
|
||||||
octoEnabled = octoOn;
|
|
||||||
octoUrl = octoWh;
|
|
||||||
octoToken = octoTk;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -503,13 +478,6 @@ bool saveSpoolmanUrl(const String& url, bool octoOn, const String& octoWh, const
|
|||||||
String loadSpoolmanUrl() {
|
String loadSpoolmanUrl() {
|
||||||
JsonDocument doc;
|
JsonDocument doc;
|
||||||
if (loadJsonValue("/spoolman_url.json", doc) && doc["url"].is<String>()) {
|
if (loadJsonValue("/spoolman_url.json", doc) && doc["url"].is<String>()) {
|
||||||
octoEnabled = (doc["octoEnabled"].is<bool>()) ? doc["octoEnabled"].as<bool>() : false;
|
|
||||||
if (octoEnabled && doc["octoToken"].is<String>() && doc["octoUrl"].is<String>())
|
|
||||||
{
|
|
||||||
octoUrl = doc["octoUrl"].as<String>();
|
|
||||||
octoToken = doc["octoToken"].as<String>();
|
|
||||||
}
|
|
||||||
|
|
||||||
return doc["url"].as<String>();
|
return doc["url"].as<String>();
|
||||||
}
|
}
|
||||||
Serial.println("Keine gültige Spoolman-URL gefunden.");
|
Serial.println("Keine gültige Spoolman-URL gefunden.");
|
||||||
|
@ -9,12 +9,9 @@
|
|||||||
|
|
||||||
extern bool spoolman_connected;
|
extern bool spoolman_connected;
|
||||||
extern String spoolmanUrl;
|
extern String spoolmanUrl;
|
||||||
extern bool octoEnabled;
|
|
||||||
extern String octoUrl;
|
|
||||||
extern String octoToken;
|
|
||||||
|
|
||||||
bool checkSpoolmanInstance(const String& url);
|
bool checkSpoolmanInstance(const String& url);
|
||||||
bool saveSpoolmanUrl(const String& url, bool octoOn, const String& octoWh, const String& octoTk);
|
bool saveSpoolmanUrl(const String& url);
|
||||||
String loadSpoolmanUrl(); // Neue Funktion zum Laden der URL
|
String loadSpoolmanUrl(); // Neue Funktion zum Laden der URL
|
||||||
bool checkSpoolmanExtraFields(); // Neue Funktion zum Überprüfen der Extrafelder
|
bool checkSpoolmanExtraFields(); // Neue Funktion zum Überprüfen der Extrafelder
|
||||||
JsonDocument fetchSingleSpoolInfo(int spoolId); // API-Funktion für die Webseite
|
JsonDocument fetchSingleSpoolInfo(int spoolId); // API-Funktion für die Webseite
|
||||||
@ -22,6 +19,5 @@ bool updateSpoolTagId(String uidString, const char* payload); // Neue Funktion z
|
|||||||
uint8_t updateSpoolWeight(String spoolId, uint16_t weight); // Neue Funktion zum Aktualisieren des Gewichts
|
uint8_t updateSpoolWeight(String spoolId, uint16_t weight); // Neue Funktion zum Aktualisieren des Gewichts
|
||||||
bool initSpoolman(); // Neue Funktion zum Initialisieren von Spoolman
|
bool initSpoolman(); // Neue Funktion zum Initialisieren von Spoolman
|
||||||
bool updateSpoolBambuData(String payload); // Neue Funktion zum Aktualisieren der Bambu-Daten
|
bool updateSpoolBambuData(String payload); // Neue Funktion zum Aktualisieren der Bambu-Daten
|
||||||
bool updateSpoolOcto(int spoolId); // Neue Funktion zum Aktualisieren der Octo-Daten
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -341,7 +341,7 @@ void updateAmsWsData(JsonDocument& doc, JsonArray& amsArray, int& ams_count, Jso
|
|||||||
ams_data[i].trays[j].tray_color = trayObj["tray_color"].as<String>();
|
ams_data[i].trays[j].tray_color = trayObj["tray_color"].as<String>();
|
||||||
ams_data[i].trays[j].nozzle_temp_min = trayObj["nozzle_temp_min"].as<int>();
|
ams_data[i].trays[j].nozzle_temp_min = trayObj["nozzle_temp_min"].as<int>();
|
||||||
ams_data[i].trays[j].nozzle_temp_max = trayObj["nozzle_temp_max"].as<int>();
|
ams_data[i].trays[j].nozzle_temp_max = trayObj["nozzle_temp_max"].as<int>();
|
||||||
if (trayObj["tray_type"].as<String>() == "") ams_data[i].trays[j].setting_id = "";
|
//ams_data[i].trays[j].setting_id = trayObj["setting_id"].as<String>();
|
||||||
ams_data[i].trays[j].cali_idx = trayObj["cali_idx"].as<String>();
|
ams_data[i].trays[j].cali_idx = trayObj["cali_idx"].as<String>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -425,8 +425,16 @@ void mqtt_callback(char* topic, byte* payload, unsigned int length) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Wenn bambu auto set spool aktiv und eine spule erkannt und mqtt meldung das neue spule im ams
|
||||||
|
if (autoSendToBambu && autoSetToBambuSpoolId > 0 &&
|
||||||
|
doc["print"]["command"].as<String>() == "push_status" && doc["print"]["ams"]["tray_pre"].as<uint8_t>()
|
||||||
|
&& !doc["print"]["ams"]["ams"].as<JsonArray>())
|
||||||
|
{
|
||||||
|
autoSetSpool(autoSetToBambuSpoolId, doc["print"]["ams"]["tray_pre"].as<uint8_t>());
|
||||||
|
}
|
||||||
|
|
||||||
// Prüfen, ob "print->upgrade_state" und "print.ams.ams" existieren
|
// Prüfen, ob "print->upgrade_state" und "print.ams.ams" existieren
|
||||||
if (doc["print"]["upgrade_state"].is<JsonObject>() || (doc["print"]["command"].is<String>() && doc["print"]["command"] == "push_status"))
|
if (doc["print"]["upgrade_state"].is<JsonObject>())
|
||||||
{
|
{
|
||||||
// Prüfen ob AMS-Daten vorhanden sind
|
// Prüfen ob AMS-Daten vorhanden sind
|
||||||
if (!doc["print"]["ams"].is<JsonObject>() || !doc["print"]["ams"]["ams"].is<JsonArray>())
|
if (!doc["print"]["ams"].is<JsonObject>() || !doc["print"]["ams"]["ams"].is<JsonArray>())
|
||||||
@ -471,12 +479,6 @@ void mqtt_callback(char* topic, byte* payload, unsigned int length) {
|
|||||||
(trayObj["setting_id"].as<String>() != "" && trayObj["setting_id"].as<String>() != ams_data[storedIndex].trays[j].setting_id) ||
|
(trayObj["setting_id"].as<String>() != "" && trayObj["setting_id"].as<String>() != ams_data[storedIndex].trays[j].setting_id) ||
|
||||||
trayObj["cali_idx"].as<String>() != ams_data[storedIndex].trays[j].cali_idx) {
|
trayObj["cali_idx"].as<String>() != ams_data[storedIndex].trays[j].cali_idx) {
|
||||||
hasChanges = true;
|
hasChanges = true;
|
||||||
|
|
||||||
if (autoSendToBambu && autoSetToBambuSpoolId > 0 && hasChanges)
|
|
||||||
{
|
|
||||||
autoSetSpool(autoSetToBambuSpoolId, ams_data[storedIndex].trays[j].id);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -495,11 +497,6 @@ void mqtt_callback(char* topic, byte* payload, unsigned int length) {
|
|||||||
(vtTray["setting_id"].as<String>() != "" && vtTray["setting_id"].as<String>() != ams_data[i].trays[0].setting_id) ||
|
(vtTray["setting_id"].as<String>() != "" && vtTray["setting_id"].as<String>() != ams_data[i].trays[0].setting_id) ||
|
||||||
(vtTray["tray_type"].as<String>() != "" && vtTray["cali_idx"].as<String>() != ams_data[i].trays[0].cali_idx)) {
|
(vtTray["tray_type"].as<String>() != "" && vtTray["cali_idx"].as<String>() != ams_data[i].trays[0].cali_idx)) {
|
||||||
hasChanges = true;
|
hasChanges = true;
|
||||||
|
|
||||||
if (autoSendToBambu && autoSetToBambuSpoolId > 0 && hasChanges)
|
|
||||||
{
|
|
||||||
autoSetSpool(autoSetToBambuSpoolId, 254);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -603,6 +600,7 @@ void mqtt_loop(void * parameter) {
|
|||||||
bool setupMqtt() {
|
bool setupMqtt() {
|
||||||
// Wenn Bambu Daten vorhanden
|
// Wenn Bambu Daten vorhanden
|
||||||
bool success = loadBambuCredentials();
|
bool success = loadBambuCredentials();
|
||||||
|
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
Serial.println("Failed to load Bambu credentials");
|
Serial.println("Failed to load Bambu credentials");
|
||||||
@ -666,7 +664,6 @@ bool setupMqtt() {
|
|||||||
void bambu_restart() {
|
void bambu_restart() {
|
||||||
if (BambuMqttTask) {
|
if (BambuMqttTask) {
|
||||||
vTaskDelete(BambuMqttTask);
|
vTaskDelete(BambuMqttTask);
|
||||||
delay(10);
|
|
||||||
}
|
}
|
||||||
setupMqtt();
|
setupMqtt();
|
||||||
}
|
}
|
@ -1,8 +1,8 @@
|
|||||||
#include "commonFS.h"
|
#include "commonFS.h"
|
||||||
#include <LittleFS.h>
|
#include <SPIFFS.h>
|
||||||
|
|
||||||
bool saveJsonValue(const char* filename, const JsonDocument& doc) {
|
bool saveJsonValue(const char* filename, const JsonDocument& doc) {
|
||||||
File file = LittleFS.open(filename, "w");
|
File file = SPIFFS.open(filename, "w");
|
||||||
if (!file) {
|
if (!file) {
|
||||||
Serial.print("Fehler beim Öffnen der Datei zum Schreiben: ");
|
Serial.print("Fehler beim Öffnen der Datei zum Schreiben: ");
|
||||||
Serial.println(filename);
|
Serial.println(filename);
|
||||||
@ -20,7 +20,7 @@ bool saveJsonValue(const char* filename, const JsonDocument& doc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool loadJsonValue(const char* filename, JsonDocument& doc) {
|
bool loadJsonValue(const char* filename, JsonDocument& doc) {
|
||||||
File file = LittleFS.open(filename, "r");
|
File file = SPIFFS.open(filename, "r");
|
||||||
if (!file) {
|
if (!file) {
|
||||||
Serial.print("Fehler beim Öffnen der Datei zum Lesen: ");
|
Serial.print("Fehler beim Öffnen der Datei zum Lesen: ");
|
||||||
Serial.println(filename);
|
Serial.println(filename);
|
||||||
@ -36,12 +36,12 @@ bool loadJsonValue(const char* filename, JsonDocument& doc) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void initializeFileSystem() {
|
void initializeSPIFFS() {
|
||||||
if (!LittleFS.begin(true)) {
|
if (!SPIFFS.begin(true, "/spiffs", 10, "spiffs")) {
|
||||||
Serial.println("LittleFS Mount Failed");
|
Serial.println("SPIFFS Mount Failed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Serial.printf("LittleFS Total: %u bytes\n", LittleFS.totalBytes());
|
Serial.printf("SPIFFS Total: %u bytes\n", SPIFFS.totalBytes());
|
||||||
Serial.printf("LittleFS Used: %u bytes\n", LittleFS.usedBytes());
|
Serial.printf("SPIFFS Used: %u bytes\n", SPIFFS.usedBytes());
|
||||||
Serial.printf("LittleFS Free: %u bytes\n", LittleFS.totalBytes() - LittleFS.usedBytes());
|
Serial.printf("SPIFFS Free: %u bytes\n", SPIFFS.totalBytes() - SPIFFS.usedBytes());
|
||||||
}
|
}
|
@ -2,11 +2,11 @@
|
|||||||
#define COMMONFS_H
|
#define COMMONFS_H
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
#include <SPIFFS.h>
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
#include <LittleFS.h>
|
|
||||||
|
|
||||||
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 initializeSPIFFS();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
64
src/main.cpp
64
src/main.cpp
@ -24,7 +24,7 @@ void setup() {
|
|||||||
Serial.printf("%08X\n", (uint32_t)chipid); //print Low 4bytes.
|
Serial.printf("%08X\n", (uint32_t)chipid); //print Low 4bytes.
|
||||||
|
|
||||||
// Initialize SPIFFS
|
// Initialize SPIFFS
|
||||||
initializeFileSystem();
|
initializeSPIFFS();
|
||||||
|
|
||||||
// Start Display
|
// Start Display
|
||||||
setupDisplay();
|
setupDisplay();
|
||||||
@ -74,21 +74,6 @@ void setup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Safe interval check that handles millis() overflow
|
|
||||||
* @param currentTime Current millis() value
|
|
||||||
* @param lastTime Last recorded time
|
|
||||||
* @param interval Desired interval in milliseconds
|
|
||||||
* @return True if interval has elapsed
|
|
||||||
*/
|
|
||||||
bool intervalElapsed(unsigned long currentTime, unsigned long &lastTime, unsigned long interval) {
|
|
||||||
if (currentTime - lastTime >= interval || currentTime < lastTime) {
|
|
||||||
lastTime = currentTime;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long lastWeightReadTime = 0;
|
unsigned long lastWeightReadTime = 0;
|
||||||
const unsigned long weightReadInterval = 1000; // 1 second
|
const unsigned long weightReadInterval = 1000; // 1 second
|
||||||
|
|
||||||
@ -96,6 +81,9 @@ unsigned long lastAutoSetBambuAmsTime = 0;
|
|||||||
const unsigned long autoSetBambuAmsInterval = 1000; // 1 second
|
const unsigned long autoSetBambuAmsInterval = 1000; // 1 second
|
||||||
uint8_t autoAmsCounter = 0;
|
uint8_t autoAmsCounter = 0;
|
||||||
|
|
||||||
|
unsigned long lastAmsSendTime = 0;
|
||||||
|
const unsigned long amsSendInterval = 60000; // 1 minute
|
||||||
|
|
||||||
uint8_t weightSend = 0;
|
uint8_t weightSend = 0;
|
||||||
int16_t lastWeight = 0;
|
int16_t lastWeight = 0;
|
||||||
|
|
||||||
@ -107,34 +95,41 @@ void loop() {
|
|||||||
unsigned long currentMillis = millis();
|
unsigned long currentMillis = millis();
|
||||||
|
|
||||||
// Überprüfe regelmäßig die WLAN-Verbindung
|
// Überprüfe regelmäßig die WLAN-Verbindung
|
||||||
if (intervalElapsed(currentMillis, lastWifiCheckTime, wifiCheckInterval)) {
|
if (millis() - lastWifiCheckTime > wifiCheckInterval) {
|
||||||
checkWiFiConnection();
|
checkWiFiConnection();
|
||||||
|
lastWifiCheckTime = millis();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send AMS Data min every Minute
|
||||||
|
if (currentMillis - lastAmsSendTime >= amsSendInterval)
|
||||||
|
{
|
||||||
|
lastAmsSendTime = currentMillis;
|
||||||
|
//sendAmsData(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wenn Bambu auto set Spool aktiv
|
// Wenn Bambu auto set Spool aktiv
|
||||||
if (autoSendToBambu && autoSetToBambuSpoolId > 0) {
|
if (autoSendToBambu && autoSetToBambuSpoolId > 0 && currentMillis - lastAutoSetBambuAmsTime >= autoSetBambuAmsInterval)
|
||||||
if (intervalElapsed(currentMillis, lastAutoSetBambuAmsTime, autoSetBambuAmsInterval))
|
{
|
||||||
|
if (hasReadRfidTag == 0)
|
||||||
{
|
{
|
||||||
if (hasReadRfidTag == 0)
|
lastAutoSetBambuAmsTime = currentMillis;
|
||||||
{
|
oledShowMessage("Auto Set " + String(autoSetBambuAmsCounter - autoAmsCounter) + "s");
|
||||||
lastAutoSetBambuAmsTime = currentMillis;
|
autoAmsCounter++;
|
||||||
oledShowMessage("Auto Set " + String(autoSetBambuAmsCounter - autoAmsCounter) + "s");
|
|
||||||
autoAmsCounter++;
|
|
||||||
|
|
||||||
if (autoAmsCounter >= autoSetBambuAmsCounter)
|
if (autoAmsCounter >= autoSetBambuAmsCounter)
|
||||||
{
|
|
||||||
autoSetToBambuSpoolId = 0;
|
|
||||||
autoAmsCounter = 0;
|
|
||||||
oledShowWeight(weight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
autoSetToBambuSpoolId = 0;
|
||||||
autoAmsCounter = 0;
|
autoAmsCounter = 0;
|
||||||
|
oledShowWeight(weight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
autoAmsCounter = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Wenn Waage nicht Kalibriert
|
// Wenn Waage nicht Kalibriert
|
||||||
if (scaleCalibrated == 3)
|
if (scaleCalibrated == 3)
|
||||||
{
|
{
|
||||||
@ -197,11 +192,6 @@ void loop() {
|
|||||||
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
||||||
weightSend = 1;
|
weightSend = 1;
|
||||||
autoSetToBambuSpoolId = spoolId.toInt();
|
autoSetToBambuSpoolId = spoolId.toInt();
|
||||||
|
|
||||||
if (octoEnabled)
|
|
||||||
{
|
|
||||||
updateSpoolOcto(autoSetToBambuSpoolId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
91
src/nfc.cpp
91
src/nfc.cpp
@ -44,6 +44,8 @@ void payloadToJson(uint8_t *data) {
|
|||||||
DeserializationError error = deserializeJson(doc, jsonString);
|
DeserializationError error = deserializeJson(doc, jsonString);
|
||||||
|
|
||||||
if (!error) {
|
if (!error) {
|
||||||
|
const char* version = doc["version"];
|
||||||
|
const char* protocol = doc["protocol"];
|
||||||
const char* color_hex = doc["color_hex"];
|
const char* color_hex = doc["color_hex"];
|
||||||
const char* type = doc["type"];
|
const char* type = doc["type"];
|
||||||
int min_temp = doc["min_temp"];
|
int min_temp = doc["min_temp"];
|
||||||
@ -53,6 +55,8 @@ void payloadToJson(uint8_t *data) {
|
|||||||
Serial.println();
|
Serial.println();
|
||||||
Serial.println("-----------------");
|
Serial.println("-----------------");
|
||||||
Serial.println("JSON-Parsed Data:");
|
Serial.println("JSON-Parsed Data:");
|
||||||
|
Serial.println(version);
|
||||||
|
Serial.println(protocol);
|
||||||
Serial.println(color_hex);
|
Serial.println(color_hex);
|
||||||
Serial.println(type);
|
Serial.println(type);
|
||||||
Serial.println(min_temp);
|
Serial.println(min_temp);
|
||||||
@ -89,16 +93,8 @@ bool formatNdefTag() {
|
|||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t readTagSize()
|
|
||||||
{
|
|
||||||
uint8_t buffer[4];
|
|
||||||
memset(buffer, 0, 4);
|
|
||||||
nfc.ntag2xx_ReadPage(3, buffer);
|
|
||||||
return buffer[2]*8;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t ntag2xx_WriteNDEF(const char *payload) {
|
uint8_t ntag2xx_WriteNDEF(const char *payload) {
|
||||||
uint16_t tagSize = readTagSize();
|
uint8_t tagSize = 240; // 144 bytes is maximum for NTAG213
|
||||||
Serial.print("Tag Size: ");Serial.println(tagSize);
|
Serial.print("Tag Size: ");Serial.println(tagSize);
|
||||||
|
|
||||||
uint8_t pageBuffer[4] = {0, 0, 0, 0};
|
uint8_t pageBuffer[4] = {0, 0, 0, 0};
|
||||||
@ -140,8 +136,6 @@ uint8_t ntag2xx_WriteNDEF(const char *payload) {
|
|||||||
if (combinedData == NULL)
|
if (combinedData == NULL)
|
||||||
{
|
{
|
||||||
Serial.println("Fehler: Nicht genug Speicher vorhanden.");
|
Serial.println("Fehler: Nicht genug Speicher vorhanden.");
|
||||||
oledShowMessage("Tag too small");
|
|
||||||
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -375,51 +369,46 @@ void scanRfidTask(void * parameter) {
|
|||||||
|
|
||||||
if (uidLength == 7)
|
if (uidLength == 7)
|
||||||
{
|
{
|
||||||
uint16_t tagSize = readTagSize();
|
uint8_t data[256];
|
||||||
if(tagSize > 0)
|
|
||||||
|
// We probably have an NTAG2xx card (though it could be Ultralight as well)
|
||||||
|
Serial.println("Seems to be an NTAG2xx tag (7 byte UID)");
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < 45; i++) {
|
||||||
|
/*
|
||||||
|
if (i < uidLength) {
|
||||||
|
uidString += String(uid[i], HEX);
|
||||||
|
if (i < uidLength - 1) {
|
||||||
|
uidString += ":"; // Optional: Trennzeichen hinzufügen
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
if (!nfc.mifareclassic_ReadDataBlock(i, data + (i - 4) * 4))
|
||||||
|
{
|
||||||
|
break; // Stop if reading fails
|
||||||
|
}
|
||||||
|
// Check for NDEF message end
|
||||||
|
if (data[(i - 4) * 4] == 0xFE)
|
||||||
|
{
|
||||||
|
break; // End of NDEF message
|
||||||
|
}
|
||||||
|
|
||||||
|
yield();
|
||||||
|
esp_task_wdt_reset();
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!decodeNdefAndReturnJson(data))
|
||||||
{
|
{
|
||||||
// Create a buffer depending on the size of the tag
|
oledShowMessage("NFC-Tag unknown");
|
||||||
uint8_t* data = (uint8_t*)malloc(tagSize);
|
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
||||||
memset(data, 0, tagSize);
|
hasReadRfidTag = 2;
|
||||||
|
|
||||||
// We probably have an NTAG2xx card (though it could be Ultralight as well)
|
|
||||||
Serial.println("Seems to be an NTAG2xx tag (7 byte UID)");
|
|
||||||
|
|
||||||
uint8_t numPages = readTagSize()/4;
|
|
||||||
for (uint8_t i = 4; i < 4+numPages; i++) {
|
|
||||||
if (!nfc.ntag2xx_ReadPage(i, data+(i-4) * 4))
|
|
||||||
{
|
|
||||||
break; // Stop if reading fails
|
|
||||||
}
|
|
||||||
// Check for NDEF message end
|
|
||||||
if (data[(i - 4) * 4] == 0xFE)
|
|
||||||
{
|
|
||||||
break; // End of NDEF message
|
|
||||||
}
|
|
||||||
|
|
||||||
yield();
|
|
||||||
esp_task_wdt_reset();
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!decodeNdefAndReturnJson(data))
|
|
||||||
{
|
|
||||||
oledShowMessage("NFC-Tag unknown");
|
|
||||||
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
|
||||||
hasReadRfidTag = 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
hasReadRfidTag = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(data);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
oledShowMessage("NFC-Tag read error");
|
hasReadRfidTag = 1;
|
||||||
hasReadRfidTag = 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
50
src/ota.cpp
50
src/ota.cpp
@ -14,39 +14,11 @@ static size_t updateTotalSize = 0;
|
|||||||
static size_t updateWritten = 0;
|
static size_t updateWritten = 0;
|
||||||
static bool isSpiffsUpdate = false;
|
static bool isSpiffsUpdate = false;
|
||||||
|
|
||||||
/**
|
|
||||||
* Compares two version strings and determines if version1 is less than version2
|
|
||||||
*
|
|
||||||
* @param version1 First version string (format: x.y.z)
|
|
||||||
* @param version2 Second version string (format: x.y.z)
|
|
||||||
* @return true if version1 is less than version2
|
|
||||||
*/
|
|
||||||
bool isVersionLessThan(const String& version1, const String& version2) {
|
|
||||||
int major1 = 0, minor1 = 0, patch1 = 0;
|
|
||||||
int major2 = 0, minor2 = 0, patch2 = 0;
|
|
||||||
|
|
||||||
// Parse version1
|
|
||||||
sscanf(version1.c_str(), "%d.%d.%d", &major1, &minor1, &patch1);
|
|
||||||
|
|
||||||
// Parse version2
|
|
||||||
sscanf(version2.c_str(), "%d.%d.%d", &major2, &minor2, &patch2);
|
|
||||||
|
|
||||||
// Compare major version
|
|
||||||
if (major1 < major2) return true;
|
|
||||||
if (major1 > major2) return false;
|
|
||||||
|
|
||||||
// Major versions equal, compare minor
|
|
||||||
if (minor1 < minor2) return true;
|
|
||||||
if (minor1 > minor2) return false;
|
|
||||||
|
|
||||||
// Minor versions equal, compare patch
|
|
||||||
return patch1 < patch2;
|
|
||||||
}
|
|
||||||
|
|
||||||
void backupJsonConfigs() {
|
void backupJsonConfigs() {
|
||||||
// Bambu Credentials backup
|
// Bambu Credentials backup
|
||||||
if (LittleFS.exists("/bambu_credentials.json")) {
|
if (SPIFFS.exists("/bambu_credentials.json")) {
|
||||||
File file = LittleFS.open("/bambu_credentials.json", "r");
|
File file = SPIFFS.open("/bambu_credentials.json", "r");
|
||||||
if (file) {
|
if (file) {
|
||||||
bambuCredentialsBackup = file.readString();
|
bambuCredentialsBackup = file.readString();
|
||||||
file.close();
|
file.close();
|
||||||
@ -55,8 +27,8 @@ void backupJsonConfigs() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Spoolman URL backup
|
// Spoolman URL backup
|
||||||
if (LittleFS.exists("/spoolman_url.json")) {
|
if (SPIFFS.exists("/spoolman_url.json")) {
|
||||||
File file = LittleFS.open("/spoolman_url.json", "r");
|
File file = SPIFFS.open("/spoolman_url.json", "r");
|
||||||
if (file) {
|
if (file) {
|
||||||
spoolmanUrlBackup = file.readString();
|
spoolmanUrlBackup = file.readString();
|
||||||
file.close();
|
file.close();
|
||||||
@ -68,7 +40,7 @@ void backupJsonConfigs() {
|
|||||||
void restoreJsonConfigs() {
|
void restoreJsonConfigs() {
|
||||||
// Restore Bambu credentials
|
// Restore Bambu credentials
|
||||||
if (bambuCredentialsBackup.length() > 0) {
|
if (bambuCredentialsBackup.length() > 0) {
|
||||||
File file = LittleFS.open("/bambu_credentials.json", "w");
|
File file = SPIFFS.open("/bambu_credentials.json", "w");
|
||||||
if (file) {
|
if (file) {
|
||||||
file.print(bambuCredentialsBackup);
|
file.print(bambuCredentialsBackup);
|
||||||
file.close();
|
file.close();
|
||||||
@ -79,7 +51,7 @@ void restoreJsonConfigs() {
|
|||||||
|
|
||||||
// Restore Spoolman URL
|
// Restore Spoolman URL
|
||||||
if (spoolmanUrlBackup.length() > 0) {
|
if (spoolmanUrlBackup.length() > 0) {
|
||||||
File file = LittleFS.open("/spoolman_url.json", "w");
|
File file = SPIFFS.open("/spoolman_url.json", "w");
|
||||||
if (file) {
|
if (file) {
|
||||||
file.print(spoolmanUrlBackup);
|
file.print(spoolmanUrlBackup);
|
||||||
file.close();
|
file.close();
|
||||||
@ -139,16 +111,6 @@ void handleUpdate(AsyncWebServer &server) {
|
|||||||
updateHandler->setUri("/update");
|
updateHandler->setUri("/update");
|
||||||
updateHandler->setMethod(HTTP_POST);
|
updateHandler->setMethod(HTTP_POST);
|
||||||
|
|
||||||
// Check if current version is less than defined TOOLVERSION before proceeding with update
|
|
||||||
if (isVersionLessThan(VERSION, TOOLDVERSION)) {
|
|
||||||
updateHandler->onRequest([](AsyncWebServerRequest *request) {
|
|
||||||
request->send(400, "application/json",
|
|
||||||
"{\"success\":false,\"message\":\"Your current version is too old. Please perform a full upgrade.\"}");
|
|
||||||
});
|
|
||||||
server.addHandler(updateHandler);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
updateHandler->onUpload([](AsyncWebServerRequest *request, String filename,
|
updateHandler->onUpload([](AsyncWebServerRequest *request, String filename,
|
||||||
size_t index, uint8_t *data, size_t len, bool final) {
|
size_t index, uint8_t *data, size_t len, bool final) {
|
||||||
if (!index) {
|
if (!index) {
|
||||||
|
@ -47,7 +47,7 @@ void scale_loop(void * parameter) {
|
|||||||
weight = round(scale.get_units());
|
weight = round(scale.get_units());
|
||||||
}
|
}
|
||||||
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(100));
|
vTaskDelay(pdMS_TO_TICKS(100)); // Verzögerung, um die CPU nicht zu überlasten
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,7 +90,7 @@ uint8_t start_scale() {
|
|||||||
BaseType_t result = xTaskCreatePinnedToCore(
|
BaseType_t result = xTaskCreatePinnedToCore(
|
||||||
scale_loop, /* Function to implement the task */
|
scale_loop, /* Function to implement the task */
|
||||||
"ScaleLoop", /* Name of the task */
|
"ScaleLoop", /* Name of the task */
|
||||||
2048, /* Stack size in words */
|
10000, /* Stack size in words */
|
||||||
NULL, /* Task input parameter */
|
NULL, /* Task input parameter */
|
||||||
scaleTaskPrio, /* Priority of the task */
|
scaleTaskPrio, /* Priority of the task */
|
||||||
&ScaleTask, /* Task handle. */
|
&ScaleTask, /* Task handle. */
|
||||||
@ -110,7 +110,6 @@ uint8_t calibrate_scale() {
|
|||||||
|
|
||||||
//vTaskSuspend(RfidReaderTask);
|
//vTaskSuspend(RfidReaderTask);
|
||||||
vTaskDelete(RfidReaderTask);
|
vTaskDelete(RfidReaderTask);
|
||||||
vTaskDelete(ScaleTask);
|
|
||||||
pauseBambuMqttTask = true;
|
pauseBambuMqttTask = true;
|
||||||
pauseMainTask = 1;
|
pauseMainTask = 1;
|
||||||
|
|
||||||
@ -178,6 +177,8 @@ uint8_t calibrate_scale() {
|
|||||||
vTaskDelay(pdMS_TO_TICKS(1));
|
vTaskDelay(pdMS_TO_TICKS(1));
|
||||||
esp_task_wdt_reset();
|
esp_task_wdt_reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//ESP.restart();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -211,7 +212,8 @@ uint8_t calibrate_scale() {
|
|||||||
|
|
||||||
oledShowMessage("Scale Ready");
|
oledShowMessage("Scale Ready");
|
||||||
|
|
||||||
Serial.println("restart Scale Task");
|
|
||||||
|
Serial.println("starte Scale Task");
|
||||||
start_scale();
|
start_scale();
|
||||||
|
|
||||||
pauseBambuMqttTask = false;
|
pauseBambuMqttTask = false;
|
||||||
|
@ -113,12 +113,12 @@ void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventTyp
|
|||||||
// Funktion zum Laden und Ersetzen des Headers in einer HTML-Datei
|
// Funktion zum Laden und Ersetzen des Headers in einer HTML-Datei
|
||||||
String loadHtmlWithHeader(const char* filename) {
|
String loadHtmlWithHeader(const char* filename) {
|
||||||
Serial.println("Lade HTML-Datei: " + String(filename));
|
Serial.println("Lade HTML-Datei: " + String(filename));
|
||||||
if (!LittleFS.exists(filename)) {
|
if (!SPIFFS.exists(filename)) {
|
||||||
Serial.println("Fehler: Datei nicht gefunden!");
|
Serial.println("Fehler: Datei nicht gefunden!");
|
||||||
return "Fehler: Datei nicht gefunden!";
|
return "Fehler: Datei nicht gefunden!";
|
||||||
}
|
}
|
||||||
|
|
||||||
File file = LittleFS.open(filename, "r");
|
File file = SPIFFS.open(filename, "r");
|
||||||
String html = file.readString();
|
String html = file.readString();
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
@ -195,7 +195,7 @@ void setupWebserver(AsyncWebServer &server) {
|
|||||||
// Route für about
|
// Route für about
|
||||||
server.on("/about", HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on("/about", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
Serial.println("Anfrage für /about erhalten");
|
Serial.println("Anfrage für /about erhalten");
|
||||||
AsyncWebServerResponse *response = request->beginResponse(LittleFS, "/index.html.gz", "text/html");
|
AsyncWebServerResponse *response = request->beginResponse(SPIFFS, "/index.html.gz", "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);
|
||||||
@ -204,7 +204,7 @@ void setupWebserver(AsyncWebServer &server) {
|
|||||||
// Route für Waage
|
// Route für Waage
|
||||||
server.on("/waage", HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on("/waage", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
Serial.println("Anfrage für /waage erhalten");
|
Serial.println("Anfrage für /waage erhalten");
|
||||||
AsyncWebServerResponse *response = request->beginResponse(LittleFS, "/waage.html.gz", "text/html");
|
AsyncWebServerResponse *response = request->beginResponse(SPIFFS, "/waage.html.gz", "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);
|
||||||
@ -213,7 +213,7 @@ 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");
|
AsyncWebServerResponse *response = request->beginResponse(SPIFFS, "/rfid.html.gz", "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);
|
||||||
@ -229,7 +229,7 @@ void setupWebserver(AsyncWebServer &server) {
|
|||||||
// Route für WiFi
|
// Route für WiFi
|
||||||
server.on("/wifi", HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on("/wifi", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
Serial.println("Anfrage für /wifi erhalten");
|
Serial.println("Anfrage für /wifi erhalten");
|
||||||
AsyncWebServerResponse *response = request->beginResponse(LittleFS, "/wifi.html.gz", "text/html");
|
AsyncWebServerResponse *response = request->beginResponse(SPIFFS, "/wifi.html.gz", "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);
|
||||||
@ -239,10 +239,7 @@ void setupWebserver(AsyncWebServer &server) {
|
|||||||
server.on("/spoolman", HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on("/spoolman", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
Serial.println("Anfrage für /spoolman erhalten");
|
Serial.println("Anfrage für /spoolman erhalten");
|
||||||
String html = loadHtmlWithHeader("/spoolman.html");
|
String html = loadHtmlWithHeader("/spoolman.html");
|
||||||
html.replace("{{spoolmanUrl}}", (spoolmanUrl != "") ? spoolmanUrl : "");
|
html.replace("{{spoolmanUrl}}", spoolmanUrl);
|
||||||
html.replace("{{spoolmanOctoEnabled}}", octoEnabled ? "checked" : "");
|
|
||||||
html.replace("{{spoolmanOctoUrl}}", (octoUrl != "") ? octoUrl : "");
|
|
||||||
html.replace("{{spoolmanOctoToken}}", (octoToken != "") ? octoToken : "");
|
|
||||||
|
|
||||||
JsonDocument doc;
|
JsonDocument doc;
|
||||||
if (loadJsonValue("/bambu_credentials.json", doc) && doc["bambu_ip"].is<String>())
|
if (loadJsonValue("/bambu_credentials.json", doc) && doc["bambu_ip"].is<String>())
|
||||||
@ -280,21 +277,10 @@ void setupWebserver(AsyncWebServer &server) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request->getParam("octoEnabled")->value() == "true" && (!request->hasParam("octoUrl") || !request->hasParam("octoToken"))) {
|
|
||||||
request->send(400, "application/json", "{\"success\": false, \"error\": \"Missing OctoPrint URL or Token parameter\"}");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String url = request->getParam("url")->value();
|
String url = request->getParam("url")->value();
|
||||||
bool octoEnabled = (request->getParam("octoEnabled")->value() == "true") ? true : false;
|
|
||||||
String octoUrl = request->getParam("octoUrl")->value();
|
|
||||||
String octoToken = (request->getParam("octoToken")->value() != "") ? request->getParam("octoToken")->value() : "";
|
|
||||||
|
|
||||||
url.trim();
|
url.trim();
|
||||||
octoUrl.trim();
|
|
||||||
octoToken.trim();
|
|
||||||
|
|
||||||
bool healthy = saveSpoolmanUrl(url, octoEnabled, octoUrl, octoToken);
|
bool healthy = saveSpoolmanUrl(url);
|
||||||
String jsonResponse = "{\"healthy\": " + String(healthy ? "true" : "false") + "}";
|
String jsonResponse = "{\"healthy\": " + String(healthy ? "true" : "false") + "}";
|
||||||
|
|
||||||
request->send(200, "application/json", jsonResponse);
|
request->send(200, "application/json", jsonResponse);
|
||||||
@ -336,7 +322,7 @@ void setupWebserver(AsyncWebServer &server) {
|
|||||||
// Route für das Laden der CSS-Datei
|
// Route für das Laden der CSS-Datei
|
||||||
server.on("/style.css", HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on("/style.css", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
Serial.println("Lade style.css");
|
Serial.println("Lade style.css");
|
||||||
AsyncWebServerResponse *response = request->beginResponse(LittleFS, "/style.css.gz", "text/css");
|
AsyncWebServerResponse *response = request->beginResponse(SPIFFS, "/style.css.gz", "text/css");
|
||||||
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);
|
||||||
@ -345,7 +331,7 @@ void setupWebserver(AsyncWebServer &server) {
|
|||||||
|
|
||||||
// Route für das Logo
|
// Route für das Logo
|
||||||
server.on("/logo.png", HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on("/logo.png", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
AsyncWebServerResponse *response = request->beginResponse(LittleFS, "/logo.png.gz", "image/png");
|
AsyncWebServerResponse *response = request->beginResponse(SPIFFS, "/logo.png.gz", "image/png");
|
||||||
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);
|
||||||
@ -354,7 +340,7 @@ void setupWebserver(AsyncWebServer &server) {
|
|||||||
|
|
||||||
// Route für Favicon
|
// Route für Favicon
|
||||||
server.on("/favicon.ico", HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on("/favicon.ico", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
AsyncWebServerResponse *response = request->beginResponse(LittleFS, "/favicon.ico", "image/x-icon");
|
AsyncWebServerResponse *response = request->beginResponse(SPIFFS, "/favicon.ico", "image/x-icon");
|
||||||
response->addHeader("Cache-Control", CACHE_CONTROL);
|
response->addHeader("Cache-Control", CACHE_CONTROL);
|
||||||
request->send(response);
|
request->send(response);
|
||||||
Serial.println("favicon.ico gesendet");
|
Serial.println("favicon.ico gesendet");
|
||||||
@ -362,7 +348,7 @@ void setupWebserver(AsyncWebServer &server) {
|
|||||||
|
|
||||||
// Route für spool_in.png
|
// Route für spool_in.png
|
||||||
server.on("/spool_in.png", HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on("/spool_in.png", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
AsyncWebServerResponse *response = request->beginResponse(LittleFS, "/spool_in.png.gz", "image/png");
|
AsyncWebServerResponse *response = request->beginResponse(SPIFFS, "/spool_in.png.gz", "image/png");
|
||||||
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);
|
||||||
@ -371,7 +357,7 @@ void setupWebserver(AsyncWebServer &server) {
|
|||||||
|
|
||||||
// Route für set_spoolman.png
|
// Route für set_spoolman.png
|
||||||
server.on("/set_spoolman.png", HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on("/set_spoolman.png", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
AsyncWebServerResponse *response = request->beginResponse(LittleFS, "/set_spoolman.png.gz", "image/png");
|
AsyncWebServerResponse *response = request->beginResponse(SPIFFS, "/set_spoolman.png.gz", "image/png");
|
||||||
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);
|
||||||
@ -381,7 +367,7 @@ void setupWebserver(AsyncWebServer &server) {
|
|||||||
// Route für JavaScript Dateien
|
// Route für JavaScript Dateien
|
||||||
server.on("/spoolman.js", HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on("/spoolman.js", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
Serial.println("Anfrage für /spoolman.js erhalten");
|
Serial.println("Anfrage für /spoolman.js erhalten");
|
||||||
AsyncWebServerResponse *response = request->beginResponse(LittleFS, "/spoolman.js.gz", "text/javascript");
|
AsyncWebServerResponse *response = request->beginResponse(SPIFFS, "/spoolman.js.gz", "text/javascript");
|
||||||
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);
|
||||||
@ -390,7 +376,7 @@ void setupWebserver(AsyncWebServer &server) {
|
|||||||
|
|
||||||
server.on("/rfid.js", HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on("/rfid.js", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
Serial.println("Anfrage für /rfid.js erhalten");
|
Serial.println("Anfrage für /rfid.js erhalten");
|
||||||
AsyncWebServerResponse *response = request->beginResponse(LittleFS,"/rfid.js.gz", "text/javascript");
|
AsyncWebServerResponse *response = request->beginResponse(SPIFFS,"/rfid.js.gz", "text/javascript");
|
||||||
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);
|
||||||
@ -399,7 +385,7 @@ void setupWebserver(AsyncWebServer &server) {
|
|||||||
|
|
||||||
// Vereinfachter Update-Handler
|
// Vereinfachter Update-Handler
|
||||||
server.on("/upgrade", HTTP_GET, [](AsyncWebServerRequest *request) {
|
server.on("/upgrade", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||||
AsyncWebServerResponse *response = request->beginResponse(LittleFS, "/upgrade.html.gz", "text/html");
|
AsyncWebServerResponse *response = request->beginResponse(SPIFFS, "/upgrade.html.gz", "text/html");
|
||||||
response->addHeader("Content-Encoding", "gzip");
|
response->addHeader("Content-Encoding", "gzip");
|
||||||
response->addHeader("Cache-Control", "no-store");
|
response->addHeader("Cache-Control", "no-store");
|
||||||
request->send(response);
|
request->send(response);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user