Compare commits

...

272 Commits

Author SHA1 Message Date
e983ba6e44 docs: update changelog for version 1.2.85
All checks were successful
Release Workflow / route (push) Successful in 7s
Release Workflow / verify-provider (push) Successful in 2s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Successful in 2m48s
2025-02-20 18:37:57 +01:00
37171d6eca docs: update webpages for version v1.2.85 2025-02-20 18:37:57 +01:00
ebb08a7a66 ci: streamline release workflows by removing unnecessary binary uploads and adding SPIFFS formatting 2025-02-20 18:37:51 +01:00
b5330af351 docs: update changelog for version 1.2.84
All checks were successful
Release Workflow / route (push) Successful in 10s
Release Workflow / verify-provider (push) Successful in 4s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Successful in 2m41s
2025-02-20 18:04:06 +01:00
4919d34484 docs: update webpages for version v1.2.84 2025-02-20 18:04:06 +01:00
2da641d604 ci: update installation steps for xxd to include package list update 2025-02-20 18:04:00 +01:00
ce413965c7 docs: update changelog for version 1.2.83
Some checks failed
Release Workflow / route (push) Successful in 7s
Release Workflow / verify-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Failing after 25s
2025-02-20 18:01:22 +01:00
3fafed930e docs: update webpages for version v1.2.83 2025-02-20 18:01:22 +01:00
e1c604ee8d refactor: replace hexdump with xxd for magic byte verification in release workflows 2025-02-20 18:01:16 +01:00
11bbfb7db6 docs: update changelog for version 1.2.82
Some checks failed
Release Workflow / route (push) Successful in 6s
Release Workflow / verify-provider (push) Successful in 2s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Failing after 2m27s
2025-02-20 17:53:00 +01:00
71d8f7ec5a docs: update webpages for version v1.2.82 2025-02-20 17:53:00 +01:00
f4518e4a36 refactor: enhance Gitea and GitHub release workflows to include magic byte handling and improve binary verification 2025-02-20 17:52:18 +01:00
62d9596d08 docs: update changelog for version 1.2.81
All checks were successful
Release Workflow / route (push) Successful in 8s
Release Workflow / verify-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Successful in 2m42s
2025-02-20 17:11:28 +01:00
e27e95d291 docs: update webpages for version v1.2.81 2025-02-20 17:11:28 +01:00
b7651ad50d refactor: update Gitea and GitHub release workflows to use esp32dev_ota for building and uploading firmware and SPIFFS binaries 2025-02-20 17:11:22 +01:00
f1937e2977 docs: update changelog for version 1.2.80
All checks were successful
Release Workflow / route (push) Successful in 7s
Release Workflow / verify-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Successful in 3m37s
2025-02-20 17:05:53 +01:00
ad5ddf713c docs: update webpages for version v1.2.80 2025-02-20 17:05:52 +01:00
ccb494f843 bump version to 1.2.79 in platformio.ini 2025-02-20 17:05:47 +01:00
17307d8f03 refactor: update Gitea and GitHub release workflows to include new firmware and SPIFFS binaries; fix version display in HTML files to v1.2.78 2025-02-20 17:04:56 +01:00
e5240a9572 docs: update changelog for version 1.2.79
All checks were successful
Release Workflow / route (push) Successful in 12s
Release Workflow / verify-provider (push) Successful in 2s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Successful in 2m45s
2025-02-20 16:25:02 +01:00
06ebf105cf docs: update webpages for version v1.2.79 2025-02-20 16:25:02 +01:00
118e099fc5 refactor: simplify Gitea release workflow by using esptool for binary creation 2025-02-20 16:24:57 +01:00
8edd50f786 docs: update changelog for version 1.2.78
Some checks failed
Release Workflow / route (push) Successful in 8s
Release Workflow / verify-provider (push) Successful in 2s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Failing after 2m44s
2025-02-20 16:15:59 +01:00
b85325a747 docs: update webpages for version v1.2.78 2025-02-20 16:15:59 +01:00
e1e0352beb refactor: streamline Gitea release workflow and update version to 1.2.77 2025-02-20 16:15:48 +01:00
8a93cccfce refactor: update Gitea and GitHub release workflows to improve binary preparation and verification
fix: correct version number in HTML files and platformio.ini to v1.2.76
enhance: streamline OTA update handling by removing unnecessary magic byte checks
2025-02-20 16:14:49 +01:00
c374069f36 docs: update changelog for version 1.2.77
All checks were successful
Release Workflow / route (push) Successful in 7s
Release Workflow / verify-provider (push) Successful in 2s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Successful in 2m33s
2025-02-20 15:53:26 +01:00
59cd7c177d refactor: optimize Gitea release workflow by simplifying build steps and improving file handling 2025-02-20 15:53:22 +01:00
45088b5838 docs: update webpages for version v1.2.77 2025-02-20 15:53:07 +01:00
1b9c79b559 docs: update changelog for version 1.2.76
Some checks failed
Release Workflow / route (push) Successful in 7s
Release Workflow / verify-provider (push) Successful in 2s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Failing after 2m48s
2025-02-20 15:42:44 +01:00
37e1e861d3 docs: update webpages for version v1.2.76 2025-02-20 15:42:44 +01:00
cce39319d9 refactor: streamline Gitea release workflow and remove obsolete OTA data initialization script 2025-02-20 15:41:14 +01:00
6391054c23 feat: enhance OTA update process with improved file verification and new OTA data initialization 2025-02-20 15:07:13 +01:00
52cf46d7f8 docs: update changelog for version 1.2.75
All checks were successful
Release Workflow / route (push) Successful in 7s
Release Workflow / verify-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Successful in 2m57s
2025-02-20 14:57:17 +01:00
84b05e48ce docs: update webpages for version v1.2.75 2025-02-20 14:57:16 +01:00
5c41d864c1 refactor: simplify OTA update handling by removing unnecessary variables and improving error reporting 2025-02-20 14:56:31 +01:00
5dc3563da6 docs: update changelog for version 1.2.74
All checks were successful
Release Workflow / route (push) Successful in 7s
Release Workflow / verify-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Successful in 3m17s
2025-02-20 14:46:12 +01:00
9e1b2943d6 docs: update webpages for version v1.2.74 2025-02-20 14:46:12 +01:00
7b89b04621 refactor: enhance OTA update process with improved handling of full image updates and SPIFFS data 2025-02-20 14:45:34 +01:00
e140f8e003 docs: update changelog for version 1.2.73
All checks were successful
Release Workflow / route (push) Successful in 6s
Release Workflow / verify-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Successful in 3m14s
2025-02-20 14:31:44 +01:00
3d0bdde476 docs: update webpages for version v1.2.73 2025-02-20 14:31:44 +01:00
3ac7d6b4f7 refactor: improve OTA update process with enhanced size checks and progress logging 2025-02-20 14:31:10 +01:00
5f52775984 refactor: enhance OTA update process with improved size checks and debugging output 2025-02-20 14:28:11 +01:00
463eaf4b6f docs: update changelog for version 1.2.72
All checks were successful
Release Workflow / route (push) Successful in 13s
Release Workflow / verify-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Successful in 3m16s
2025-02-20 14:17:34 +01:00
4bf6b11d3a docs: update webpages for version v1.2.72 2025-02-20 14:17:34 +01:00
b0c4af7c4e refactor: simplify OTA update process by removing unnecessary buffer and adjusting offsets 2025-02-20 14:16:49 +01:00
249e896ea4 docs: update changelog for version 1.2.71
Some checks failed
Release Workflow / route (push) Successful in 6s
Release Workflow / verify-provider (push) Successful in 2s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Has been cancelled
2025-02-20 14:09:21 +01:00
c74f587fff docs: update webpages for version v1.2.71 2025-02-20 14:09:21 +01:00
7a7ee72585 fix: update version number to v1.2.65 in HTML files and platformio.ini; add script to create full binary 2025-02-20 14:08:17 +01:00
3dd5fbc585 docs: update changelog for version 1.2.70
All checks were successful
Release Workflow / route (push) Successful in 7s
Release Workflow / verify-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Successful in 3m23s
2025-02-20 12:01:08 +01:00
ed9c1487ed docs: update webpages for version v1.2.70 2025-02-20 12:01:08 +01:00
d8756421a1 fix: add logging to stopAllTasks for better debugging 2025-02-20 12:00:45 +01:00
d92c78f9d0 docs: update changelog for version 1.2.69
All checks were successful
Release Workflow / route (push) Successful in 11s
Release Workflow / verify-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Successful in 3m21s
2025-02-20 11:54:38 +01:00
2d19ea745f docs: update webpages for version v1.2.69 2025-02-20 11:54:37 +01:00
13779cc9d7 docs: update changelog for version 1.2.68
Some checks failed
Release Workflow / route (push) Successful in 6s
Release Workflow / verify-provider (push) Successful in 2s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Has been cancelled
2025-02-20 11:53:15 +01:00
b6d5a8a00b docs: update webpages for version v1.2.68 2025-02-20 11:53:15 +01:00
f6319e79f0 fix: update stopAllTasks to suspend RfidReaderTask instead of NfcTask 2025-02-20 11:53:04 +01:00
6f24630a7d feat: add task handles for BambuMqttTask and ScaleTask; rename stopTasks to stopAllTasks 2025-02-20 11:52:36 +01:00
4475d21218 docs: update changelog for version 1.2.67
All checks were successful
Release Workflow / route (push) Successful in 6s
Release Workflow / verify-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Successful in 3m6s
2025-02-20 11:42:41 +01:00
01a926a38d feat: improve OTA upload handling and add SPIFFS update support 2025-02-20 11:42:36 +01:00
6b966c02b3 docs: update webpages for version v1.2.67 2025-02-20 11:42:25 +01:00
1450e1ad2e docs: update changelog for version 1.2.66
All checks were successful
Release Workflow / route (push) Successful in 8s
Release Workflow / verify-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Successful in 3m5s
2025-02-20 11:27:18 +01:00
3102a6c217 docs: update webpages for version v1.2.66 2025-02-20 11:27:18 +01:00
d5b2b2746d feat: enhance OTA upload to support SPIFFS updates 2025-02-20 11:27:11 +01:00
7e776d4816 docs: update changelog for version 1.2.65
All checks were successful
Release Workflow / route (push) Successful in 7s
Release Workflow / verify-provider (push) Successful in 5s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Successful in 3m8s
2025-02-20 11:16:54 +01:00
e84b2973c5 docs: update webpages for version v1.2.65 2025-02-20 11:16:53 +01:00
5793dc1a1f docs: update changelog for version 1.2.64
Some checks failed
Release Workflow / route (push) Successful in 7s
Release Workflow / verify-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Has been cancelled
2025-02-20 11:13:56 +01:00
1732491c48 docs: update webpages for version v1.2.64 2025-02-20 11:13:56 +01:00
0500bb6951 fix: improve error handling in OTA upload process 2025-02-20 11:13:49 +01:00
ef9ef7257a docs: update changelog for version 1.2.63
All checks were successful
Release Workflow / route (push) Successful in 7s
Release Workflow / verify-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Successful in 3m10s
2025-02-20 10:59:17 +01:00
e86fd229dc docs: update webpages for version v1.2.63 2025-02-20 10:59:17 +01:00
b940a166da feat: update version to 1.2.63 2025-02-20 10:59:10 +01:00
c857e16de2 feat: enhance OTA upload handling with magic byte checks for image types
Some checks failed
Release Workflow / route (push) Successful in 7s
Release Workflow / verify-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Failing after 3m4s
2025-02-20 10:53:23 +01:00
8b2a537b72 docs: update changelog for version 1.2.62
All checks were successful
Release Workflow / route (push) Successful in 7s
Release Workflow / verify-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Successful in 3m6s
2025-02-20 10:29:08 +01:00
88ec151c4c docs: update webpages for version 1.2.62 2025-02-20 10:29:08 +01:00
0a203f02eb feat: update version to 1.2.62 2025-02-20 10:29:04 +01:00
04b59f4809 docs: update changelog for version 1.2.61
All checks were successful
Release Workflow / route (push) Successful in 8s
Release Workflow / verify-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Successful in 3m9s
2025-02-20 10:06:15 +01:00
b31861af67 docs: update webpages for version 1.2.61 2025-02-20 10:06:15 +01:00
ce3b423dc1 feat: update version to 1.2.61 and enhance OTA update error handling 2025-02-20 10:06:06 +01:00
05f275142f docs: update changelog for version 1.2.60
All checks were successful
Release Workflow / route (push) Successful in 7s
Release Workflow / verify-provider (push) Successful in 4s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Successful in 3m11s
2025-02-20 01:28:56 +01:00
72af54bd20 docs: update webpages for version 1.2.60 2025-02-20 01:28:56 +01:00
a1e30a3b7f feat: update version to 1.2.60 in platformio configuration 2025-02-20 01:28:45 +01:00
8f8322e629 docs: update changelog for version 1.2.59
All checks were successful
Release Workflow / route (push) Successful in 6s
Release Workflow / verify-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Successful in 3m10s
2025-02-20 01:08:56 +01:00
1e386c49af docs: update webpages for version 1.2.59 2025-02-20 01:08:56 +01:00
3070d75d07 feat: update version to 1.2.59 and enhance OTA upload handling 2025-02-20 01:08:48 +01:00
34ee9badea docs: update changelog for version 1.2.58
All checks were successful
Release Workflow / route (push) Successful in 7s
Release Workflow / verify-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Successful in 3m16s
2025-02-20 00:50:53 +01:00
6594af9540 feat: update version to 1.2.58 in HTML files and platformio configuration 2025-02-20 00:50:48 +01:00
c21bd2d4ec docs: update changelog for version 1.2.57
All checks were successful
Release Workflow / route (push) Successful in 8s
Release Workflow / verify-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Successful in 3m15s
2025-02-20 00:33:35 +01:00
e5f895b560 feat: update version to 1.2.57 in platformio configuration 2025-02-20 00:33:31 +01:00
bb0f50ce1d fix: update spiffs offset and sizes in firmware and partitions configuration 2025-02-20 00:33:16 +01:00
499a08aa75 docs: update changelog for version 1.2.56
Some checks failed
Release Workflow / route (push) Successful in 8s
Release Workflow / verify-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Failing after 2m50s
2025-02-19 22:06:56 +01:00
745d960f62 feat: update version to 1.2.56 and adjust firmware and partition settings 2025-02-19 22:06:47 +01:00
531d0fe9a2 refactor: remove redundant comment from Gitea release workflow 2025-02-19 21:45:26 +01:00
2af23e8084 docs: update changelog for version 1.2.55
All checks were successful
Release Workflow / route (push) Successful in 7s
Release Workflow / verify-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Successful in 3m8s
2025-02-19 21:25:23 +01:00
cd204fdaa8 feat: update version to 1.2.55 and adjust Gitea release workflow to remove 'v' prefix from version 2025-02-19 21:24:38 +01:00
d04ad42b5b docs: update changelog for version 1.2.54
Some checks failed
Release Workflow / route (push) Successful in 10s
Release Workflow / verify-provider (push) Successful in 6s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Failing after 3m38s
2025-02-19 21:03:22 +01:00
8d80a8fb5a feat: update version to 1.2.54 and add check for missing changelog in Gitea release workflow 2025-02-19 21:03:17 +01:00
77032bf9ae docs: update changelog for version 1.2.53
Some checks failed
Release Workflow / route (push) Successful in 7s
Release Workflow / verify-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Failing after 2m56s
2025-02-19 20:54:26 +01:00
3967366ae6 feat: update version to 1.2.53 and enhance Gitea release workflow to handle missing changelog 2025-02-19 20:54:20 +01:00
cd391378c2 docs: update changelog for version 1.2.52
All checks were successful
Release Workflow / route (push) Successful in 7s
Release Workflow / verify-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Successful in 2m59s
2025-02-19 20:36:45 +01:00
3fc3a689cb feat: update version to 1.2.52 and improve Gitea release workflow output handling 2025-02-19 20:35:33 +01:00
bd5b32a3b0 docs: update changelog for version 1.2.51
All checks were successful
Release Workflow / route (push) Successful in 9s
Release Workflow / verify-provider (push) Successful in 4s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Successful in 3m14s
2025-02-19 20:14:54 +01:00
a5c999234c feat: update version to 1.2.51 and add debug output in Gitea release workflow 2025-02-19 20:14:43 +01:00
f64d3e51ce docs: update changelog for version 1.2.50
All checks were successful
Release Workflow / route (push) Successful in 7s
Release Workflow / verify-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Successful in 3m30s
2025-02-19 20:06:08 +01:00
a650b7d860 feat: update version to 1.2.50 and remove obsolete build workflow 2025-02-19 20:05:56 +01:00
14e98072aa docs: update changelog for version 1.2.49
All checks were successful
Release Workflow / route (push) Successful in 7s
Release Workflow / verify-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Successful in 3m0s
2025-02-19 18:24:09 +01:00
0bc4c0565f feat: update version to 1.2.49 and modify changelog reading in Gitea release workflow 2025-02-19 18:24:05 +01:00
4aa8e844ac docs: update changelog for version 1.2.48
All checks were successful
Release Workflow / route (push) Successful in 7s
Release Workflow / verify-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Successful in 3m16s
2025-02-19 18:03:35 +01:00
d7135fddc8 feat: update version to 1.2.48 and modify changelog reading in release workflows 2025-02-19 18:03:31 +01:00
6e3e978839 docs: update changelog for version 1.2.47
All checks were successful
Release Workflow / route (push) Successful in 7s
Release Workflow / verify-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Successful in 3m9s
2025-02-19 17:54:06 +01:00
33b0e79c18 feat: update version to 1.2.47 and modify changelog reading in GitHub release workflow 2025-02-19 17:53:54 +01:00
787d878e83 docs: update changelog for version 1.2.46
All checks were successful
Release Workflow / route (push) Successful in 8s
Release Workflow / verify-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Successful in 3m5s
2025-02-19 15:09:00 +01:00
1e24179b82 feat: update Gitea release workflow to include changelog and increment version to 1.2.46 2025-02-19 15:08:56 +01:00
67027840f4 docs: update changelog for version 1.2.45
All checks were successful
Release Workflow / route (push) Successful in 7s
Release Workflow / verify-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Successful in 3m14s
2025-02-19 14:11:47 +01:00
2755e9c863 feat: update Gitea release workflow to use dynamic upload URL and increment version to 1.2.45 2025-02-19 14:11:44 +01:00
7ae26fb0a9 docs: update changelog for version 1.2.44
Some checks failed
Release Workflow / route (push) Successful in 7s
Release Workflow / verify-provider (push) Successful in 2s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Failing after 3m9s
2025-02-19 12:57:19 +01:00
98bcf98f1e feat: update Gitea release workflow to include additional outputs and increment version to 1.2.44 2025-02-19 12:57:15 +01:00
bc8ac32fee docs: update changelog for version 1.2.43
Some checks failed
Release Workflow / route (push) Successful in 7s
Release Workflow / verify-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Failing after 3m7s
2025-02-19 12:50:18 +01:00
ba74eca21d feat: update Gitea release workflow by removing unnecessary outputs and increment version to 1.2.43 2025-02-19 12:50:16 +01:00
d4e1cf1322 docs: update changelog for version 1.2.42
Some checks failed
Release Workflow / route (push) Successful in 6s
Release Workflow / verify-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Failing after 2m48s
2025-02-19 12:44:09 +01:00
5170784e44 feat: update Gitea release workflow to include additional outputs and increment version to 1.2.42 2025-02-19 12:44:07 +01:00
ac323167d0 docs: update changelog for version 1.2.41
Some checks failed
Release Workflow / route (push) Successful in 8s
Release Workflow / verify-provider (push) Successful in 4s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Failing after 3m4s
2025-02-19 12:20:02 +01:00
003de5bc00 feat: update Gitea release workflow debug output and increment version to 1.2.41 2025-02-19 12:20:00 +01:00
83595cfadf docs: update changelog for version 1.2.40
Some checks failed
Release Workflow / route (push) Successful in 7s
Release Workflow / verify-provider (push) Successful in 2s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Failing after 3m4s
2025-02-19 12:09:15 +01:00
cfe21d63d7 feat: add inputs for Gitea release workflow and increment version to 1.2.40 2025-02-19 12:09:12 +01:00
63e72076ed docs: update changelog for version 1.2.39
Some checks failed
Release Workflow / route (push) Successful in 7s
Release Workflow / verify-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Failing after 3m12s
2025-02-19 12:02:04 +01:00
2a011ee244 feat: update Gitea release workflow to use Python virtual environment and increment version to 1.2.39 2025-02-19 12:02:01 +01:00
84dd2bd40b docs: update changelog for version 1.2.38
Some checks failed
Release Workflow / route (push) Successful in 7s
Release Workflow / verify-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Failing after 18s
2025-02-19 11:58:29 +01:00
1449cacc0e feat: update Gitea release workflow and increment version to 1.2.38 2025-02-19 11:58:26 +01:00
f1c2b2eb87 docs: update changelog for version 1.2.37
Some checks failed
Release Workflow / route (push) Successful in 7s
Release Workflow / verify-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Failing after 10s
2025-02-19 11:46:19 +01:00
0f1a3b1d5b feat: update Gitea release workflow and increment version to 1.2.37 2025-02-19 11:46:17 +01:00
6190cf04db docs: update changelog for version 1.2.36
Some checks failed
Release Workflow / route (push) Successful in 12s
Release Workflow / verify-provider (push) Successful in 4s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Failing after 45s
2025-02-19 11:38:39 +01:00
680aed0e10 feat: update Gitea release workflow and increment version to 1.2.36 2025-02-19 11:38:37 +01:00
fadb122d28 docs: update changelog for version 1.2.35
Some checks failed
Release Workflow / route (push) Successful in 20s
Release Workflow / verify-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Failing after 18s
2025-02-19 11:18:07 +01:00
4347f89c16 feat: update Gitea release workflow and version to 1.2.35 2025-02-19 11:18:05 +01:00
9856757e49 docs: update changelog for version 1.2.34
All checks were successful
Release Workflow / route (push) Successful in 12s
Release Workflow / verify-provider (push) Successful in 4s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Has been skipped
2025-02-19 11:01:57 +01:00
afb7b5f42b feat: update version to 1.2.34 and enhance Gitea and GitHub release workflows 2025-02-19 11:01:54 +01:00
ba8506247b docs: update changelog for version 1.2.33
All checks were successful
Release Workflow / route (push) Successful in 12s
Release Workflow / verify-provider (push) Successful in 8s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Has been skipped
2025-02-19 11:00:03 +01:00
61f3f90d6d feat: update version to 1.2.33 and refactor release workflows for Gitea and GitHub 2025-02-19 11:00:01 +01:00
a143527dd0 docs: update changelog for version 1.2.32
Some checks failed
Release Workflow / route (push) Successful in 7s
Release Workflow / verify-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Failing after 2m24s
2025-02-19 10:58:53 +01:00
f2c9818e61 feat: update version to 1.2.32 and adjust workflow dependencies for GitHub and Gitea releases 2025-02-19 10:58:51 +01:00
9e23af29ff docs: update changelog for version 1.2.31
All checks were successful
Release Workflow / route (push) Successful in 7s
Release Workflow / verify-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Has been skipped
2025-02-19 10:58:06 +01:00
095885442a feat: update version to 1.2.31 2025-02-19 10:58:04 +01:00
359c9b5a6d docs: update changelog for version 1.2.30
All checks were successful
Release Workflow / route (push) Successful in 6s
Release Workflow / verify-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Has been skipped
2025-02-19 10:50:09 +01:00
b16a7a4c17 feat: update version to 1.2.30 and enhance release workflows for Gitea and GitHub with improved artifact handling and changelog integration 2025-02-19 10:50:06 +01:00
b4ea175757 docs: update changelog for version 1.2.29
All checks were successful
Release Workflow / route (push) Successful in 7s
Release Workflow / verify-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Successful in 2m26s
2025-02-19 10:37:44 +01:00
ca4671a7dd feat: update version to 1.2.29 and enhance Gitea release workflow with improved error handling and debugging 2025-02-19 10:37:41 +01:00
7a4b1a934f docs: update changelog for version 1.2.28
All checks were successful
Release Workflow / route (push) Successful in 7s
Release Workflow / verify-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Successful in 2m42s
2025-02-19 10:24:47 +01:00
77d90bbe83 feat: add build and release workflows for Gitea and GitHub, increment version to 1.2.28 2025-02-19 10:24:43 +01:00
c99d802184 docs: update changelog for version 1.2.27
Some checks failed
Release Workflow / route (push) Successful in 7s
Release Workflow / verify-provider (push) Successful in 2s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Failing after 2m49s
2025-02-19 10:12:55 +01:00
ca15d2abe4 feat: enhance CI workflows with provider detection and update version to 1.2.27 2025-02-19 10:12:52 +01:00
bddb48ba9a docs: update changelog for version 1.2.26
Some checks failed
Release Workflow / route (push) Successful in 15s
Release Workflow / gitea-release (push) Has been cancelled
Release Workflow / github-release (push) Has been cancelled
2025-02-19 10:07:45 +01:00
f4b67e52b8 feat: update release workflows for Gitea and GitHub, increment version to 1.2.26 2025-02-19 10:07:41 +01:00
00f6a4b0ae docs: update changelog for version 1.2.25
Some checks failed
Github Release / build (push) Failing after 3m8s
Create Release / build (push) Has been cancelled
2025-02-19 09:43:47 +01:00
ab3937a69d feat: update GitHub release workflows and increment version to 1.2.25 2025-02-19 09:43:44 +01:00
0c4bae48d4 docs: update changelog for version 1.2.24 2025-02-19 09:40:33 +01:00
b4b17cb999 feat: update GitHub release workflow and increment version to 1.2.24 2025-02-19 09:40:30 +01:00
5ff3864d9d docs: update changelog for version 1.2.23
Some checks failed
Release / prepare (push) Has been cancelled
2025-02-19 09:39:43 +01:00
9b8736d35f feat: update Gitea release workflow and increment version to 1.2.23 2025-02-19 09:39:41 +01:00
cf0ba20637 docs: update changelog for version 1.2.22
Some checks failed
Release / prepare (push) Has been cancelled
2025-02-19 09:27:21 +01:00
e06c0b9a76 feat: update Gitea runner configuration and increment version to 1.2.22 2025-02-19 09:27:18 +01:00
4cb370ddff docs: update changelog for version 1.2.21
Some checks failed
Release / prepare (push) Has been cancelled
2025-02-19 01:30:59 +01:00
0b9c1711da feat: update Gitea release condition and increment version to 1.2.21 2025-02-19 01:30:46 +01:00
e2449030c5 docs: update changelog for version 1.2.20
Some checks failed
Release / prepare (push) Has been cancelled
2025-02-19 01:21:23 +01:00
5a91e87afa feat: update release workflows for GitHub and Gitea, increment version to 1.2.20 2025-02-19 01:21:14 +01:00
5e66c3bd45 docs: update changelog for version 1.2.19
Some checks failed
Release / prepare (push) Has been cancelled
Release / github (push) Has been cancelled
Release / gitea (push) Has been cancelled
2025-02-19 01:19:46 +01:00
61c82f796f feat: add Gitea and GitHub release workflows for version 1.2.19 2025-02-19 01:19:42 +01:00
7661e0eb20 docs: update changelog for version 1.2.18
Some checks failed
Release / release (push) Has been cancelled
2025-02-19 01:18:00 +01:00
c06e6de89a feat: remove Gitea and GitHub release workflows and increment version to 1.2.18 2025-02-19 01:17:56 +01:00
262bed84df docs: update changelog for version 1.2.17
Some checks failed
Release / prepare (push) Has been cancelled
Release / github (push) Has been cancelled
Release / gitea (push) Has been cancelled
2025-02-19 01:03:56 +01:00
c710e5d7f8 feat: update Gitea release workflow for version 1.2.17 and improve job structure 2025-02-19 01:03:53 +01:00
5d39f04786 docs: update changelog for version 1.2.16
Some checks failed
Release / github-release (push) Has been cancelled
Release / gitea-release (push) Has been cancelled
Release / get-version-and-changelog (push) Has been cancelled
2025-02-19 00:49:39 +01:00
d955e26b82 feat: update Gitea release workflow and increment version to 1.2.16 2025-02-19 00:49:35 +01:00
c20e7de5c3 docs: update changelog for version 1.2.15
Some checks failed
Release / get-version-and-changelog (push) Successful in 7s
Release / github-release (push) Has been skipped
Release / gitea-release (push) Failing after 2s
2025-02-19 00:46:38 +01:00
55c3b3688a feat: update version to 1.2.15 and clean up Gitea release workflow 2025-02-19 00:46:34 +01:00
fea5932125 docs: update changelog for version 1.2.14
Some checks failed
Release / get-version-and-changelog (push) Successful in 8s
Release / github-release (push) Has been skipped
Release / gitea-release (push) Failing after 3s
2025-02-19 00:43:18 +01:00
04f557939d feat: update version to 1.2.14 and refactor release workflows for improved GitHub and Gitea support 2025-02-19 00:43:15 +01:00
58549a53e4 docs: update changelog for version 1.2.13 2025-02-19 00:32:43 +01:00
64a46e3e7d feat: update version to 1.2.13 and enhance release workflow with Python setup and Gitea support 2025-02-19 00:32:40 +01:00
c2bd0982ab docs: update changelog for version 1.2.12
Some checks failed
Release / prepare (push) Successful in 8s
Release / release (push) Failing after 0s
2025-02-19 00:26:45 +01:00
e0b8da079e feat: update version to 1.2.12 and refactor release workflows for improved provider detection and execution 2025-02-19 00:26:40 +01:00
8c88827a2d docs: update changelog for version 1.2.11
Some checks failed
Release / prepare (push) Successful in 8s
Release / github-release (push) Has been skipped
Release / gitea-release (push) Failing after 3s
2025-02-18 23:50:00 +01:00
6128bc2827 feat: update version to 1.2.11 and enhance GitHub and Gitea release workflows with input validation and improved error handling 2025-02-18 23:49:57 +01:00
6d21a8ec52 docs: update changelog for version 1.2.10 2025-02-18 23:31:16 +01:00
2ee4eca7dd feat: enhance Gitea release workflow with API connection verification and URL validation; update version to 1.2.10 2025-02-18 23:31:00 +01:00
9eb64e06f0 docs: update changelog for version 1.2.9
Some checks failed
Release / release (push) Failing after 2m37s
2025-02-18 23:20:06 +01:00
693ef4e26c feat: update version to 1.2.9 in platformio.ini 2025-02-18 23:20:03 +01:00
11c099eba2 feat: refactor GitHub and Gitea release workflows for improved version handling and firmware uploads 2025-02-18 23:14:52 +01:00
c7c122a505 docs: update changelog for version 1.2.8
Some checks failed
GitHub Release / build (push) Has been cancelled
Release / detect (push) Successful in 7s
Release / gitea-release (push) Failing after 2m22s
Release / github-release (push) Has been skipped
2025-02-18 22:32:11 +01:00
d1bb4b7c83 feat: update version to 1.2.8 in platformio.ini; refactor Gitea and GitHub release workflows 2025-02-18 22:32:07 +01:00
dc5118587c feat: update version to 1.2.7 in platformio.ini; adjust Gitea release workflow 2025-02-18 22:28:31 +01:00
b13f2c4eee docs: update changelog for version 1.2.6
Some checks failed
Gitea Release / build (push) Failing after 0s
GitHub Release / build (push) Failing after 2m41s
Release / detect-and-run (push) Failing after 17s
2025-02-18 22:23:50 +01:00
6d16c35e62 feat: update version to 1.2.6 in platformio.ini 2025-02-18 22:23:45 +01:00
c94ebf5e33 docs: update changelog for version 1.2.5 2025-02-18 22:18:51 +01:00
9203706a20 feat: update version to 1.2.5; enhance Gitea release workflow and streamline release process 2025-02-18 22:18:49 +01:00
c252f48a49 docs: update changelog for version 1.2.4
Some checks failed
GitHub Release / build (push) Has been cancelled
Release / detect-and-run (push) Failing after 0s
Gitea Release / build (push) Failing after 2m48s
2025-02-18 21:56:09 +01:00
228dcacb1e feat: update version to 1.2.4 in HTML files and platformio.ini 2025-02-18 21:56:05 +01:00
9de4ed9ee9 feat: add GitHub and Gitea release workflows; streamline firmware release process 2025-02-18 21:53:23 +01:00
4d8a6fb943 docs: update changelog for version 1.2.3
Some checks failed
Create Release / build (push) Failing after 5m9s
2025-02-18 14:40:02 +01:00
2cab24403e feat: update version to 1.2.3; modify HTML files to reflect new version; enhance firmware update process and UI improvements 2025-02-18 14:18:14 +01:00
8b246e180b docs: update changelog for version 1.2.2
Some checks failed
Create Release / build (push) Has been cancelled
2025-02-18 12:29:07 +01:00
b5c014db86 feat: update version to 1.2.2; change OTA upgrade link in HTML files; enhance OTA upload handling with progress updates and JSON responses 2025-02-18 12:28:47 +01:00
3c783c9844 feat: implement OTA update functionality with web interface; update partition settings and build configuration 2025-02-18 11:42:52 +01:00
175d614d1f feat: remove unused OTA server setup and related includes; update platformio.ini dependencies 2025-02-18 10:05:08 +01:00
678a286af1 feat: adjust weight counter threshold and optimize delay in RFID scanning; include scale header in NFC module 2025-02-17 15:04:21 +01:00
f877f43d90 feat: update version to v1.2.1 and change upgrade link to OTA in HTML files; modify updateSpoolTagId function to return boolean 2025-02-17 14:44:38 +01:00
3cd0798186 docs: update changelog for version 1.2.0
Some checks failed
Create Release / build (push) Has been cancelled
2025-02-17 12:41:44 +01:00
2a67d8f67c feat: implement OTA functionality and update build scripts; change upgrade link to OTA in HTML 2025-02-17 12:41:25 +01:00
240795a2d0 feat: update version to v1.2.0 and modify build scripts in platformio.ini; remove unused includes in scale.cpp and website.cpp 2025-02-17 11:49:39 +01:00
4e384d777e feat: update version to v1.2.0 and add upgrade link in HTML files 2025-02-17 10:46:56 +01:00
03cbf82275 feat: add esp_wifi.h and set maximum transmit power in WiFi initialization 2025-02-16 21:46:06 +01:00
0c1a222636 fix: update version number in header to v1.1.0 2025-02-16 21:45:57 +01:00
8716b4ad73 docs: update changelog for version 1.1.0 2025-02-16 16:26:58 +01:00
6fcfefec8f chore: clean up changelog and update script execution in platformio.ini 2025-02-16 16:26:54 +01:00
b696a79f4b docs: update changelog for version 1.1.0 2025-02-16 16:14:26 +01:00
61ed765d87 fix: correct version number in nav bar 2025-02-16 16:12:07 +01:00
2703689e4e feat: update version to 1.1.0 and modify gzip compression handling for /spoolman route
Some checks failed
Create Release / build (push) Has been cancelled
2025-02-16 13:00:42 +01:00
b24c50722f chore: increment version to 1.0.9 in platformio.ini
Some checks failed
Create Release / build (push) Has been cancelled
2025-02-16 12:54:55 +01:00
3ec23a9f79 feat: implement gzip compression for /spoolman route response 2025-02-16 12:54:24 +01:00
75fe6b55ad chore: increment version to 1.0.8 in platformio.ini
Some checks failed
Create Release / build (push) Has been cancelled
2025-02-16 12:30:19 +01:00
fa2f980312 fix: update partition settings and version in platformio.ini, and enhance release workflow 2025-02-16 12:29:12 +01:00
7964f1cd77 chore: increment version to 1.0.7 in platformio.ini
Some checks failed
Create Release / build (push) Has been cancelled
2025-02-16 12:15:29 +01:00
dd611df9f5 feat: update ESP Async WebServer dependency to use GitHub URL instead of versioned package 2025-02-16 12:14:50 +01:00
0ccc67f4b2 feat: update release workflow trigger and increment version to 1.0.6
Some checks failed
Create Release / build (push) Has been cancelled
2025-02-16 12:11:30 +01:00
a027dfb54e chore: remove unnecessary blank line in release workflow configuration 2025-02-16 12:07:14 +01:00
07741f2a52 feat: enhance release workflow by adding permissions for issues and pull requests, and updating GitHub CLI installation method 2025-02-16 12:05:50 +01:00
3e9b89f69b feat: streamline GitHub Actions release workflow by consolidating permissions and enhancing GitHub CLI installation step 2025-02-16 12:01:41 +01:00
bf67a635f6 feat: add GitHub CLI installation step to release workflow 2025-02-16 11:59:34 +01:00
84cccd5014 feat: update release workflow to include version in asset naming for firmware binaries 2025-02-16 11:58:04 +01:00
e983b0fcfd feat: update release workflow to use new asset naming and streamline release creation process 2025-02-16 11:53:49 +01:00
e01bb9b1f9 feat: enhance GitHub Actions workflow by adding permissions for discussions and packages 2025-02-16 11:50:51 +01:00
17b6051da0 feat: update GitHub Actions workflow for firmware release and add partition configuration 2025-02-16 11:47:20 +01:00
84617ebc53 feat: add German translation of README and link to it from the English version
Some checks failed
Create Release / build (push) Has been cancelled
2025-02-16 11:18:43 +01:00
8ac6ba57a4 docs: update changelog for version 1.0.5 2025-02-16 10:47:26 +01:00
cc17140dc4 feat: update version to 1.0.5 and enhance changelog update process with automatic git push 2025-02-16 10:47:18 +01:00
8741216374 feat: update changelog script to categorize commits and handle new changelog creation 2025-02-16 10:45:12 +01:00
7bdebeab03 feat: improve changelog update script to handle absolute paths and create new changelog if missing 2025-02-16 10:38:12 +01:00
ab33f423c8 chore: remove deprecated release script
Some checks failed
Create Release / build (push) Has been cancelled
2025-02-16 10:34:56 +01:00
15600ceac5 feat: enhance release script to support upstream push and improve error handling 2025-02-16 10:31:00 +01:00
7ccacec68f feat: add GitHub Actions workflow for automated release creation and update CHANGELOG.md structure 2025-02-16 10:26:43 +01:00
2f34a0ca4e feat: update HTML structure and add version display in the navbar 2025-02-16 10:26:36 +01:00
2fb2a2f183 refactor: simplify NFC tag assignment logic and enhance info message styling 2025-02-16 09:29:09 +01:00
269f54b2b3 refactor: clean up mqtt_callback function by removing commented-out code and redundant processing 2025-02-15 15:44:20 +01:00
1c1043ac75 feat: add calibration index handling to tray data and update related API and UI components 2025-02-15 13:30:25 +01:00
d1f22c78f7 feat: implement tray ID handling and add bambu_restart function for MQTT management 2025-02-15 09:05:22 +01:00
3e1490cafc fix: update calibration index check in displayAmsData function 2025-02-15 09:05:11 +01:00
dc82c04a17 feat: enhance reconnect functionality and improve UI feedback for connection status 2025-02-15 09:01:23 +01:00
c6fd5f8ad5 fix: remove unnecessary SPIFFS creation configuration from platformio.ini 2025-02-15 07:17:10 +01:00
a55cce854e refactor: remove combined binary creation script and related configurations 2025-02-15 07:14:12 +01:00
c21be92e98 fix: add calibration index to tray properties and update related logic 2025-02-15 07:14:03 +01:00
d4348944fc fix: update weight and length formatting in statistics display 2025-02-14 19:43:06 +01:00
f1bd896cf1 fix: improve reconnect logic by replacing delay with yield and vTaskDelay 2025-02-14 17:58:12 +01:00
9ace9f0567 fix: enhance Bambu spool handling by adding tray info index and improving logging 2025-02-14 17:40:13 +01:00
0379c4c45f fix: correct label for filament index in tray properties 2025-02-14 16:49:46 +01:00
49f36bb25b fix: update MQTT connection logic to ensure proper task creation and connection handling 2025-02-14 16:46:16 +01:00
a05cde8669 fix: add additional Bambu spool settings and update API response structure 2025-02-14 16:29:46 +01:00
64e5a171b6 fix: update MQTT connection logic to handle failures correctly and not try to connect random 2025-02-14 16:01:56 +01:00
bec403ec1b correct typo 2025-02-14 12:58:12 +01:00
ccc810ab7e fix: update README with German video link and correct About page link in header 2025-02-14 12:50:51 +01:00
61dadc0aa1 fix: comment out combine_binaries target in PlatformIO configuration 2025-02-14 10:50:04 +01:00
a2ee9a98a6 fix: update Bambu spool settings and connection handling logic 2025-02-14 10:35:47 +01:00
ae96c729b1 Corrected Amazon Links in Readme 2025-02-13 21:40:41 +01:00
1d337dd990 add PlatformIO configuration file for ESP32 development with custom build targets 2025-02-13 20:59:07 +01:00
cfa6c12d65 add script to combine firmware and SPIFFS binaries, and remove unused display files 2025-02-13 18:42:34 +01:00
b2aeae5815 add link to image folder and FilaMan website in README for additional resources 2025-02-13 17:39:41 +01:00
5cdbc5f2cc add new image assets for enhanced visual content 2025-02-13 17:37:17 +01:00
7a5415ad80 add FilaMan website link to README for additional resource 2025-02-13 16:57:07 +01:00
36fd271d0c remove unused image files and update scale image for clarity 2025-02-13 16:24:49 +01:00
a39e199c79 update "Buy Me A Coffee" button size in README for better visibility 2025-02-13 16:22:52 +01:00
b7004f5b71 add scale image to README for enhanced visual representation 2025-02-13 16:19:42 +01:00
e5bf05ee43 refactor header and RFID display logic, add spool out functionality, and update image assets 2025-02-13 16:13:46 +01:00
f01a42d850 implement AMS data sending every minute and remove unused CSS file 2025-02-13 13:38:15 +01:00
57 changed files with 2911 additions and 797 deletions

View File

@ -0,0 +1,119 @@
name: Gitea Release
on:
workflow_call:
inputs:
gitea_ref_name:
required: true
type: string
gitea_server_url:
required: true
type: string
gitea_repository:
required: true
type: string
secrets:
GITEA_TOKEN:
required: true
jobs:
create-release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install PlatformIO
run: |
python -m pip install --upgrade pip
pip install --upgrade platformio esptool
- name: Install xxd
run: |
sudo apt-get update
sudo apt-get install xxd
- name: Build Firmware
run: |
pio run -e esp32dev_ota -t buildfs # Build SPIFFS
pio run -e esp32dev_ota # Build firmware
cp .pio/build/esp32dev_ota/firmware.bin .pio/build/esp32dev_ota/filaman.bin
cp .pio/build/esp32dev_ota/spiffs.bin .pio/build/esp32dev_ota/filaman_spiffs.bin
- name: Prepare binaries
run: |
cd .pio/build/esp32dev_ota
# Create OTA binary (already has correct magic byte)
cp firmware.bin filaman_ota.bin
# Create a magic byte prepended binary for the bootloader
echo -ne '\xE9' > bootloader_with_magic.bin
cat bootloader.bin >> bootloader_with_magic.bin
echo "Creating full binary with magic byte..."
esptool.py --chip esp32 merge_bin \
--fill-flash-size 4MB \
--flash_mode dio \
--flash_freq 40m \
--flash_size 4MB \
-o filaman_full.bin \
0x0000 bootloader_with_magic.bin \
0x8000 partitions.bin \
0x10000 firmware.bin \
0x3D0000 spiffs.bin
# Verify magic bytes
echo "Checking magic bytes:"
echo "Full binary first bytes:"
xxd -l 16 filaman_full.bin
# Verify file sizes
echo "File sizes:"
ls -lh *.bin
- name: Create Release
env:
TOKEN: ${{ secrets.GITEA_TOKEN }}
run: |
TAG="${{ inputs.gitea_ref_name }}"
API_URL="${{ inputs.gitea_server_url }}/api/v1"
REPO="${{ inputs.gitea_repository }}"
# Create release
RESPONSE=$(curl -k -s \
-X POST \
-H "Authorization: token ${TOKEN}" \
-H "Content-Type: application/json" \
-d "{
\"tag_name\":\"${TAG}\",
\"name\":\"Release ${TAG}\",
\"body\":\"${{ steps.changelog.outputs.CHANGES }}\"
}" \
"${API_URL}/repos/${REPO}/releases")
RELEASE_ID=$(echo "$RESPONSE" | grep -o '"id":[0-9]*' | cut -d':' -f2 | head -n1)
if [ -n "$RELEASE_ID" ]; then
echo "Release created with ID: $RELEASE_ID"
# Upload binaries
cd .pio/build/esp32dev_ota
for file in filaman_full.bin; do
echo "Uploading $file..."
curl -k -s \
-X POST \
-H "Authorization: token ${TOKEN}" \
-H "Content-Type: application/octet-stream" \
--data-binary "@$file" \
"${API_URL}/repos/${REPO}/releases/${RELEASE_ID}/assets?name=$file"
done
else
echo "Failed to create release. Response:"
echo "$RESPONSE"
exit 1
fi

View File

@ -0,0 +1,89 @@
name: GitHub Release
on:
workflow_call:
jobs:
create-release:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install PlatformIO
run: |
python -m pip install --upgrade pip
pip install --upgrade platformio esptool
- name: Install xxd
run: |
sudo apt-get update
sudo apt-get install xxd
- name: Build Firmware
run: |
pio run -e esp32dev_ota -t buildfs # Build SPIFFS
pio run -e esp32dev_ota # Build firmware
cp .pio/build/esp32dev_ota/firmware.bin .pio/build/esp32dev_ota/filaman.bin
cp .pio/build/esp32dev_ota/spiffs.bin .pio/build/esp32dev_ota/filaman_spiffs.bin
- name: Prepare binaries
run: |
cd .pio/build/esp32dev_ota
# Create OTA binary (already has correct magic byte)
cp firmware.bin filaman_ota.bin
# Create a magic byte prepended binary for the bootloader
echo -ne '\xE9' > bootloader_with_magic.bin
cat bootloader.bin >> bootloader_with_magic.bin
echo "Creating full binary with magic byte..."
esptool.py --chip esp32 merge_bin \
--fill-flash-size 4MB \
--flash_mode dio \
--flash_freq 40m \
--flash_size 4MB \
-o filaman_full.bin \
0x0000 bootloader_with_magic.bin \
0x8000 partitions.bin \
0x10000 firmware.bin \
0x3D0000 spiffs.bin
# Verify magic bytes
echo "Checking magic bytes:"
echo "Full binary first bytes:"
xxd -l 16 filaman_full.bin
# Verify file sizes
echo "File sizes:"
ls -lh *.bin
- name: Get version from tag
id: get_version
run: |
echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
- name: Read CHANGELOG.md
id: changelog
run: |
VERSION=${{ steps.get_version.outputs.VERSION }}
CHANGELOG=$(awk "/## \\[$VERSION\\]/{p=1;print;next} /## \\[/{p=0} p" CHANGELOG.md)
echo "CHANGES<<EOF" >> $GITHUB_OUTPUT
echo "$CHANGELOG" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Create GitHub Release
env:
GH_TOKEN: ${{ github.token }}
run: |
gh release create "${{ github.ref_name }}" \
--title "Release ${{ steps.get_version.outputs.VERSION }}" \
--notes "${{ steps.changelog.outputs.CHANGES }}" \
.pio/build/esp32dev_ota/filaman_full.bin

70
.github/workflows/release.yml vendored Normal file
View File

@ -0,0 +1,70 @@
name: Release Workflow
on:
push:
tags:
- 'v*'
jobs:
route:
runs-on: ubuntu-latest
outputs:
provider: ${{ steps.provider.outputs.provider }}
gitea_ref_name: ${{ steps.provider.outputs.gitea_ref_name }}
gitea_server_url: ${{ steps.provider.outputs.gitea_server_url }}
gitea_repository: ${{ steps.provider.outputs.gitea_repository }}
steps:
- name: Checkout Repository
uses: actions/checkout@v3
- name: Debug Environment
run: |
echo "CI Environment Details:"
echo "GITHUB_ACTIONS=${GITHUB_ACTIONS:-not set}"
echo "GITEA_ACTIONS=${GITEA_ACTIONS:-not set}"
echo "GITEA_REPOSITORY=${GITEA_REPOSITORY:-not set}"
echo "GITEA_SERVER_URL=${GITEA_SERVER_URL:-not set}"
echo "RUNNER_NAME=${RUNNER_NAME:-not set}"
- name: Determine CI Provider
id: provider
shell: bash
run: |
if [ -n "${GITEA_ACTIONS}" ] || [ -n "${GITEA_REPOSITORY}" ] || [[ "${RUNNER_NAME}" == *"gitea"* ]]; then
echo "provider=gitea" >> "$GITHUB_OUTPUT"
echo "gitea_ref_name=${GITHUB_REF_NAME}" >> "$GITHUB_OUTPUT"
echo "gitea_server_url=${GITHUB_SERVER_URL}" >> "$GITHUB_OUTPUT"
echo "gitea_repository=${GITHUB_REPOSITORY}" >> "$GITHUB_OUTPUT"
elif [ "${GITHUB_ACTIONS}" = "true" ]; then
echo "provider=github" >> "$GITHUB_OUTPUT"
else
echo "provider=unknown" >> "$GITHUB_OUTPUT"
fi
verify-provider:
needs: route
runs-on: ubuntu-latest
steps:
- name: Echo detected provider
run: |
echo "Detected CI Provider: ${{ needs.route.outputs.provider }}"
if [ "${{ needs.route.outputs.provider }}" = "unknown" ]; then
echo "::error::Failed to detect CI provider!"
exit 1
fi
github-release:
needs: [route, verify-provider]
if: needs.route.outputs.provider == 'github'
uses: ./.github/workflows/providers/github-release.yml
gitea-release:
needs: [route, verify-provider]
if: needs.route.outputs.provider == 'gitea'
uses: ./.github/workflows/providers/gitea-release.yml
with:
gitea_ref_name: ${{ needs.route.outputs.gitea_ref_name }}
gitea_server_url: ${{ needs.route.outputs.gitea_server_url }}
gitea_repository: ${{ needs.route.outputs.gitea_repository }}
secrets:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}

558
CHANGELOG.md Normal file
View File

@ -0,0 +1,558 @@
# Changelog
## [1.2.85] - 2025-02-20
### Added
- ci: streamline release workflows by removing unnecessary binary uploads and adding SPIFFS formatting
### Changed
- update webpages for version v1.2.85
## [1.2.84] - 2025-02-20
### Changed
- update webpages for version v1.2.84
- ci: update installation steps for xxd to include package list update
## [1.2.83] - 2025-02-20
### Changed
- update webpages for version v1.2.83
- replace hexdump with xxd for magic byte verification in release workflows
## [1.2.82] - 2025-02-20
### Changed
- update webpages for version v1.2.82
- enhance Gitea and GitHub release workflows to include magic byte handling and improve binary verification
## [1.2.81] - 2025-02-20
### Changed
- update webpages for version v1.2.81
- update Gitea and GitHub release workflows to use esp32dev_ota for building and uploading firmware and SPIFFS binaries
## [1.2.80] - 2025-02-20
### Added
- update Gitea and GitHub release workflows to include new firmware and SPIFFS binaries; fix version display in HTML files to v1.2.78
### Changed
- update webpages for version v1.2.80
- bump version to 1.2.79 in platformio.ini
## [1.2.79] - 2025-02-20
### Changed
- update webpages for version v1.2.79
- simplify Gitea release workflow by using esptool for binary creation
## [1.2.78] - 2025-02-20
### Changed
- update webpages for version v1.2.78
- streamline Gitea release workflow and update version to 1.2.77
### Fixed
- update Gitea and GitHub release workflows to improve binary preparation and verification fix: correct version number in HTML files and platformio.ini to v1.2.76 enhance: streamline OTA update handling by removing unnecessary magic byte checks
## [1.2.77] - 2025-02-20
### Changed
- optimize Gitea release workflow by simplifying build steps and improving file handling
- update webpages for version v1.2.77
## [1.2.76] - 2025-02-20
### Added
- enhance OTA update process with improved file verification and new OTA data initialization
### Changed
- update webpages for version v1.2.76
- streamline Gitea release workflow and remove obsolete OTA data initialization script
## [1.2.75] - 2025-02-20
### Changed
- update webpages for version v1.2.75
- simplify OTA update handling by removing unnecessary variables and improving error reporting
## [1.2.74] - 2025-02-20
### Changed
- update webpages for version v1.2.74
- enhance OTA update process with improved handling of full image updates and SPIFFS data
## [1.2.73] - 2025-02-20
### Changed
- update webpages for version v1.2.73
- improve OTA update process with enhanced size checks and progress logging
### Fixed
- enhance OTA update process with improved size checks and debugging output
## [1.2.72] - 2025-02-20
### Changed
- update webpages for version v1.2.72
- simplify OTA update process by removing unnecessary buffer and adjusting offsets
## [1.2.71] - 2025-02-20
### Added
- update version number to v1.2.65 in HTML files and platformio.ini; add script to create full binary
### Changed
- update webpages for version v1.2.71
## [1.2.70] - 2025-02-20
### Added
- add logging to stopAllTasks for better debugging
### Changed
- update webpages for version v1.2.70
## [1.2.69] - 2025-02-20
### Changed
- update webpages for version v1.2.69
## [1.2.68] - 2025-02-20
### Added
- add task handles for BambuMqttTask and ScaleTask; rename stopTasks to stopAllTasks
### Changed
- update webpages for version v1.2.68
### Fixed
- update stopAllTasks to suspend RfidReaderTask instead of NfcTask
## [1.2.67] - 2025-02-20
### Added
- improve OTA upload handling and add SPIFFS update support
### Changed
- update webpages for version v1.2.67
## [1.2.66] - 2025-02-20
### Added
- enhance OTA upload to support SPIFFS updates
### Changed
- update webpages for version v1.2.66
## [1.2.65] - 2025-02-20
### Changed
- update webpages for version v1.2.65
## [1.2.64] - 2025-02-20
### Changed
- update webpages for version v1.2.64
### Fixed
- improve error handling in OTA upload process
## [1.2.63] - 2025-02-20
### Added
- update version to 1.2.63
### Changed
- update webpages for version v1.2.63
## [1.2.62] - 2025-02-20
### Added
- update version to 1.2.62
### Changed
- update webpages for version 1.2.62
## [1.2.61] - 2025-02-20
### Added
- update version to 1.2.61 and enhance OTA update error handling
### Changed
- update webpages for version 1.2.61
## [1.2.60] - 2025-02-20
### Added
- update version to 1.2.60 in platformio configuration
### Changed
- update webpages for version 1.2.60
## [1.2.59] - 2025-02-20
### Added
- update version to 1.2.59 and enhance OTA upload handling
### Changed
- update webpages for version 1.2.59
## [1.2.58] - 2025-02-20
### Added
- update version to 1.2.58 in HTML files and platformio configuration
## [1.2.57] - 2025-02-20
### Added
- update version to 1.2.57 in platformio configuration
### Fixed
- update spiffs offset and sizes in firmware and partitions configuration
## [1.2.56] - 2025-02-19
### Added
- update version to 1.2.56 and adjust firmware and partition settings
### Changed
- remove redundant comment from Gitea release workflow
## [1.2.55] - 2025-02-19
### Added
- update version to 1.2.55 and adjust Gitea release workflow to remove 'v' prefix from version
## [1.2.54] - 2025-02-19
### Added
- update version to 1.2.54 and add check for missing changelog in Gitea release workflow
## [1.2.53] - 2025-02-19
### Added
- update version to 1.2.53 and enhance Gitea release workflow to handle missing changelog
## [1.2.52] - 2025-02-19
### Added
- update version to 1.2.52 and improve Gitea release workflow output handling
## [1.2.51] - 2025-02-19
### Added
- update version to 1.2.51 and add debug output in Gitea release workflow
## [1.2.50] - 2025-02-19
### Added
- update version to 1.2.50 and remove obsolete build workflow
## [1.2.49] - 2025-02-19
### Added
- update version to 1.2.49 and modify changelog reading in Gitea release workflow
## [1.2.48] - 2025-02-19
### Added
- update version to 1.2.48 and modify changelog reading in release workflows
## [1.2.47] - 2025-02-19
### Added
- update version to 1.2.47 and modify changelog reading in GitHub release workflow
## [1.2.46] - 2025-02-19
### Added
- update Gitea release workflow to include changelog and increment version to 1.2.46
## [1.2.45] - 2025-02-19
### Added
- update Gitea release workflow to use dynamic upload URL and increment version to 1.2.45
## [1.2.44] - 2025-02-19
### Added
- update Gitea release workflow to include additional outputs and increment version to 1.2.44
## [1.2.43] - 2025-02-19
### Added
- update Gitea release workflow by removing unnecessary outputs and increment version to 1.2.43
## [1.2.42] - 2025-02-19
### Added
- update Gitea release workflow to include additional outputs and increment version to 1.2.42
## [1.2.41] - 2025-02-19
### Added
- update Gitea release workflow debug output and increment version to 1.2.41
## [1.2.40] - 2025-02-19
### Added
- add inputs for Gitea release workflow and increment version to 1.2.40
## [1.2.39] - 2025-02-19
### Added
- update Gitea release workflow to use Python virtual environment and increment version to 1.2.39
## [1.2.38] - 2025-02-19
### Added
- update Gitea release workflow and increment version to 1.2.38
## [1.2.37] - 2025-02-19
### Added
- update Gitea release workflow and increment version to 1.2.37
## [1.2.36] - 2025-02-19
### Added
- update Gitea release workflow and increment version to 1.2.36
## [1.2.35] - 2025-02-19
### Added
- update Gitea release workflow and version to 1.2.35
## [1.2.34] - 2025-02-19
### Added
- update version to 1.2.34 and enhance Gitea and GitHub release workflows
## [1.2.33] - 2025-02-19
### Added
- update version to 1.2.33 and refactor release workflows for Gitea and GitHub
## [1.2.32] - 2025-02-19
### Added
- update version to 1.2.32 and adjust workflow dependencies for GitHub and Gitea releases
## [1.2.31] - 2025-02-19
### Added
- update version to 1.2.31
## [1.2.30] - 2025-02-19
### Added
- update version to 1.2.30 and enhance release workflows for Gitea and GitHub with improved artifact handling and changelog integration
## [1.2.29] - 2025-02-19
### Added
- update version to 1.2.29 and enhance Gitea release workflow with improved error handling and debugging
## [1.2.28] - 2025-02-19
### Added
- add build and release workflows for Gitea and GitHub, increment version to 1.2.28
## [1.2.27] - 2025-02-19
### Added
- enhance CI workflows with provider detection and update version to 1.2.27
## [1.2.26] - 2025-02-19
### Added
- update release workflows for Gitea and GitHub, increment version to 1.2.26
## [1.2.25] - 2025-02-19
### Added
- update GitHub release workflows and increment version to 1.2.25
## [1.2.24] - 2025-02-19
### Added
- update GitHub release workflow and increment version to 1.2.24
## [1.2.23] - 2025-02-19
### Added
- update Gitea release workflow and increment version to 1.2.23
## [1.2.22] - 2025-02-19
### Added
- update Gitea runner configuration and increment version to 1.2.22
## [1.2.21] - 2025-02-19
### Added
- update Gitea release condition and increment version to 1.2.21
## [1.2.20] - 2025-02-19
### Added
- update release workflows for GitHub and Gitea, increment version to 1.2.20
## [1.2.19] - 2025-02-19
### Added
- add Gitea and GitHub release workflows for version 1.2.19
## [1.2.18] - 2025-02-19
### Added
- remove Gitea and GitHub release workflows and increment version to 1.2.18
## [1.2.17] - 2025-02-19
### Added
- update Gitea release workflow for version 1.2.17 and improve job structure
## [1.2.16] - 2025-02-19
### Added
- update Gitea release workflow and increment version to 1.2.16
## [1.2.15] - 2025-02-19
### Added
- update version to 1.2.15 and clean up Gitea release workflow
## [1.2.14] - 2025-02-19
### Added
- update version to 1.2.14 and refactor release workflows for improved GitHub and Gitea support
## [1.2.13] - 2025-02-19
### Added
- update version to 1.2.13 and enhance release workflow with Python setup and Gitea support
## [1.2.12] - 2025-02-19
### Added
- update version to 1.2.12 and refactor release workflows for improved provider detection and execution
## [1.2.11] - 2025-02-18
### Added
- update version to 1.2.11 and enhance GitHub and Gitea release workflows with input validation and improved error handling
## [1.2.10] - 2025-02-18
### Added
- enhance Gitea release workflow with API connection verification and URL validation; update version to 1.2.10
## [1.2.9] - 2025-02-18
### Added
- update version to 1.2.9 in platformio.ini
- refactor GitHub and Gitea release workflows for improved version handling and firmware uploads
## [1.2.8] - 2025-02-18
### Added
- update version to 1.2.8 in platformio.ini; refactor Gitea and GitHub release workflows
- update version to 1.2.7 in platformio.ini; adjust Gitea release workflow
## [1.2.6] - 2025-02-18
### Added
- update version to 1.2.6 in platformio.ini
- update version to 1.2.5; enhance Gitea release workflow and streamline release process
### Changed
- update changelog for version 1.2.5
## [1.2.5] - 2025-02-18
### Added
- update version to 1.2.5; enhance Gitea release workflow and streamline release process
## [1.2.4] - 2025-02-18
### Added
- update version to 1.2.4 in HTML files and platformio.ini
- add GitHub and Gitea release workflows; streamline firmware release process
## [1.2.3] - 2025-02-18
### Added
- update version to 1.2.3; modify HTML files to reflect new version; enhance firmware update process and UI improvements
## [1.2.2] - 2025-02-18
### Added
- update version to 1.2.2; change OTA upgrade link in HTML files; enhance OTA upload handling with progress updates and JSON responses
- implement OTA update functionality with web interface; update partition settings and build configuration
- remove unused OTA server setup and related includes; update platformio.ini dependencies
- adjust weight counter threshold and optimize delay in RFID scanning; include scale header in NFC module
- update version to v1.2.1 and change upgrade link to OTA in HTML files; modify updateSpoolTagId function to return boolean
## [1.2.0] - 2025-02-17
### Added
- implement OTA functionality and update build scripts; change upgrade link to OTA in HTML
- update version to v1.2.0 and modify build scripts in platformio.ini; remove unused includes in scale.cpp and website.cpp
- update version to v1.2.0 and add upgrade link in HTML files
- add esp_wifi.h and set maximum transmit power in WiFi initialization
### Changed
- update changelog for version 1.1.0
- clean up changelog and update script execution in platformio.ini
- update changelog for version 1.1.0
### Fixed
- update version number in header to v1.1.0
- correct version number in nav bar
## [1.1.0] - 2025-02-16
### Changed
- clean up changelog and update script execution in platformio.ini
- update changelog for version 1.1.0
### Fixed
- correct version number in nav bar
## [1.0.5] - 2025-02-16
### Added
- update version to 1.0.5 and enhance changelog update process with automatic git push
- update changelog script to categorize commits and handle new changelog creation
- improve changelog update script to handle absolute paths and create new changelog if missing
## [1.0.4] - 2025-02-16
### Added
- improve changelog update script to handle absolute paths and create new changelog if missing
## [1.0.3] - 2025-02-16
### Added
-
### Changed
-
### Fixed
-
## [1.0.2] - 2025-02-16
### Added
- Feature 1
- Feature 2
### Changed
- Change 1
- Change 2
### Fixed
- Fix 1
- Fix 2

155
README.de.md Normal file
View File

@ -0,0 +1,155 @@
# FilaMan - Filament Management System
FilaMan ist ein Filament-Managementsystem für den 3D-Druck. Es verwendet ESP32-Hardware für Gewichtsmessungen und NFC-Tag-Management.
Benutzer können Filamentspulen verwalten, den Status des Automatic Material System (AMS) von Bablulab Druckern überwachen und Einstellungen über eine Weboberfläche vornehmen.
Das System integriert sich nahtlos mit der [Spoolman](https://github.com/Donkie/Spoolman) Filamentverwaltung, zusätzlich mit [Bambulab](https://bambulab.com/en-us) 3D-Druckern und sowie dem [Openspool](https://github.com/spuder/OpenSpool) NFC-TAG Format.
![Scale](./img/scale_trans.png)
Weitere Bilder finden Sie im [img Ordner](/img/)
oder auf meiner Website: [FilaMan Website](https://www.filaman.app)
Deutsches Erklärvideo: [Youtube](https://youtu.be/uNDe2wh9SS8?si=b-jYx4I1w62zaOHU)
### ESP32 Hardware-Funktionen
- **Gewichtsmessung:** Verwendung einer Wägezelle mit HX711-Verstärker für präzise Gewichtsverfolgung.
- **NFC-Tag Lesen/Schreiben:** PN532-Modul zum Lesen und Schreiben von Filamentdaten auf NFC-Tags.
- **OLED-Display:** Zeigt aktuelles Gewicht, Verbindungsstatus (WiFi, Bambu Lab, Spoolman).
- **WLAN-Konnektivität:** WiFiManager für einfache Netzwerkkonfiguration.
- **MQTT-Integration:** Verbindet sich mit Bambu Lab Drucker für AMS-Steuerung.
- **NFC-Tag NTAG215:** Verwendung von NTAG215 wegen ausreichendem Speicherplatz auf dem Tag
### Weboberflächen-Funktionen
- **Echtzeit-Updates:** WebSocket-Verbindung für Live-Daten-Updates.
- **NFC-Tag-Verwaltung:**
- Filamentdaten auf NFC-Tags schreiben.
- Verwendet das NFC-Tag-Format von [Openspool](https://github.com/spuder/OpenSpool)
- Ermöglicht automatische Spulenerkennung im AMS
- **Bambulab AMS-Integration:**
- Anzeige der aktuellen AMS-Fachbelegung.
- Zuordnung von Filamenten zu AMS-Slots.
- Unterstützung für externe Spulenhalter.
- **Spoolman-Integration:**
- Auflistung verfügbarer Filamentspulen.
- Filtern und Auswählen von Filamenten.
- Automatische Aktualisierung der Spulengewichte.
- Verfolgung von NFC-Tag-Zuweisungen.
### 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>
## Detaillierte Funktionalität
### ESP32-Funktionalität
- **Druckaufträge steuern und überwachen:** Der ESP32 kommuniziert mit dem Bambu Lab Drucker.
- **Drucker-Kommunikation:** Nutzt MQTT für Echtzeit-Kommunikation mit dem Drucker.
- **Benutzerinteraktionen:** Das OLED-Display bietet sofortiges Feedback zum Systemstatus.
### Weboberflächen-Funktionalität
- **Benutzerinteraktionen:** Die Weboberfläche ermöglicht Benutzern die Interaktion mit dem System.
- **UI-Elemente:** Enthält Dropdown-Menüs für Hersteller und Filamente, Buttons zum Beschreiben von NFC-Tags und Echtzeit-Statusanzeigen.
## Hardware-Anforderungen
### Komponenten
- **ESP32 Entwicklungsboard:** Jede ESP32-Variante.
[Amazon Link](https://amzn.eu/d/aXThslf)
- **HX711 Wägezellen-Verstärker:** Für Gewichtsmessung.
[Amazon Link](https://amzn.eu/d/1wZ4v0x)
- **OLED Display:** 128x64 SSD1306.
[Amazon Link](https://amzn.eu/d/dozAYDU)
- **PN532 NFC Modul:** Für NFC-Tag-Operationen.
[Amazon Link](https://amzn.eu/d/8205DDh)
- **NFC-Tag:** NTAG215
[Amazon Link](https://amzn.eu/d/fywy4c4)
### Pin-Konfiguration
| Komponente | ESP32 Pin |
|-------------------|-----------|
| HX711 DOUT | 16 |
| HX711 SCK | 17 |
| OLED SDA | 21 |
| OLED SCL | 22 |
| PN532 IRQ | 32 |
| PN532 RESET | 33 |
| PN532 SCK | 14 |
| PN532 MOSI | 13 |
| PN532 MISO | 12 |
| PN532 CS/SS | 15 |
## Software-Abhängigkeiten
### ESP32-Bibliotheken
- `WiFiManager`: Netzwerkkonfiguration
- `ESPAsyncWebServer`: Webserver-Funktionalität
- `ArduinoJson`: JSON-Verarbeitung
- `PubSubClient`: MQTT-Kommunikation
- `Adafruit_PN532`: NFC-Funktionalität
- `Adafruit_SSD1306`: OLED-Display-Steuerung
- `HX711`: Wägezellen-Kommunikation
## Installation
### Voraussetzungen
- **Software:**
- [PlatformIO](https://platformio.org/) in VS Code
- [Spoolman](https://github.com/Donkie/Spoolman) Instanz
- **Hardware:**
- ESP32 Entwicklungsboard
- HX711 Wägezellen-Verstärker
- Wägezelle (Gewichtssensor)
- OLED Display (128x64 SSD1306)
- PN532 NFC Modul
- Verbindungskabel
### Schritt-für-Schritt Installation
1. **Repository klonen:**
```bash
git clone https://github.com/ManuelW77/Filaman.git
cd FilaMan
```
2. **Abhängigkeiten installieren:**
```bash
pio lib install
```
3. **ESP32 flashen:**
```bash
pio run --target upload
```
4. **Ersteinrichtung:**
- Mit dem "FilaMan" WLAN-Zugangspunkt verbinden.
- WLAN-Einstellungen über das Konfigurationsportal vornehmen.
- Weboberfläche unter `http://filaman.local` oder der IP-Adresse aufrufen.
## Dokumentation
### Relevante Links
- [PlatformIO Dokumentation](https://docs.platformio.org/)
- [Spoolman Dokumentation](https://github.com/Donkie/Spoolman)
- [Bambu Lab Drucker Dokumentation](https://www.bambulab.com/)
### Tutorials und Beispiele
- [PlatformIO erste Schritte](https://docs.platformio.org/en/latest/tutorials/espressif32/arduino_debugging_unit_testing.html)
- [ESP32 Webserver Tutorial](https://randomnerdtutorials.com/esp32-web-server-arduino-ide/)
## Lizenz
Dieses Projekt ist unter der MIT-Lizenz lizenziert. Siehe [LICENSE](LICENSE) Datei für Details.
## Materialien
### Nützliche Ressourcen
- [ESP32 Offizielle Dokumentation](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/)
- [Arduino Bibliotheken](https://www.arduino.cc/en/Reference/Libraries)
- [NFC Tag Informationen](https://learn.adafruit.com/adafruit-pn532-rfid-nfc/overview)
### Community und Support
- [PlatformIO Community](https://community.platformio.org/)
- [Arduino Forum](https://forum.arduino.cc/)
- [ESP32 Forum](https://www.esp32.com/)
## Verfügbarkeit
Der Code kann getestet und die Anwendung kann vom [GitHub Repository](https://github.com/ManuelW77/Filaman) heruntergeladen werden.
### 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>

View File

@ -1,9 +1,18 @@
# FilaMan - Filament Management System
[Deutsche Version](README.de.md)
FilaMan is a filament management system for 3D printing. It uses ESP32 hardware for weight measurement and NFC tag management.
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.
![Scale](./img/scale_trans.png)
More Images can be found in the [img Folder](/img/)
or my website:[FilaMan Website](https://www.filaman.app)
german explanatory video: [Youtube](https://youtu.be/uNDe2wh9SS8?si=b-jYx4I1w62zaOHU)
### ESP32 Hardware Features
- **Weight Measurement:** Using a load cell with HX711 amplifier for precise weight tracking.
- **NFC Tag Reading/Writing:** PN532 module for reading and writing filament data to NFC tags.
@ -29,7 +38,7 @@ The system integrates seamlessly with [Bambulab](https://bambulab.com/en-us) 3D
- Track NFC tag assignments.
### 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: 60px !important;width: 217px !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>
## Detailed Functionality
@ -46,14 +55,15 @@ The system integrates seamlessly with [Bambulab](https://bambulab.com/en-us) 3D
### Components
- **ESP32 Development Board:** Any ESP32 variant.
[https://amzn.eu/d/aXThslf](url)
[Amazon Link](https://amzn.eu/d/aXThslf)
- **HX711 Load Cell Amplifier:** For weight measurement.
[https://amzn.eu/d/1wZ4v0x](url)
[Amazon Link](https://amzn.eu/d/1wZ4v0x)
- **OLED Display:** 128x64 SSD1306.
[https://amzn.eu/d/dozAYDU](url)
[Amazon Link](https://amzn.eu/d/dozAYDU)
- **PN532 NFC Module:** For NFC tag operations.
[https://amzn.eu/d/8205DDh](url)
- **NFC-Tag:** [https://amzn.eu/d/fywy4c4](url)
[Amazon Link](https://amzn.eu/d/8205DDh)
- **NFC-Tag:** NTAG215
[Amazon Link](https://amzn.eu/d/fywy4c4)
### Pin Configuration
@ -114,6 +124,24 @@ The system integrates seamlessly with [Bambulab](https://bambulab.com/en-us) 3D
- Configure WiFi settings through the captive portal.
- Access the web interface at `http://filaman.local` or the IP address.
## GitHub Actions Configuration
### Required Secrets for Gitea Releases
When using Gitea as your repository host, you need to configure the following secrets in your repository:
- `GITEA_API_URL`: The base URL of your Gitea instance, including protocol (e.g., `https://git.example.com`)
- `GITEA_TOKEN`: Your Gitea access token with permissions to create releases
- `GITEA_REPOSITORY`: The repository name in format `owner/repo` (e.g., `username/filaman`)
Example values:
```
GITEA_API_URL=https://git.example.com
GITEA_TOKEN=abcdef1234567890
GITEA_REPOSITORY=username/filaman
```
Make sure to set these secrets in your repository settings under Settings > Secrets and Variables > Actions.
## Documentation
@ -147,4 +175,4 @@ This project is licensed under the MIT License. See the [LICENSE](LICENSE) file
The code can be tested and the application can be downloaded from the [GitHub repository](https://github.com/ManuelW77/Filaman).
### 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: 60px !important;width: 217px !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>

View File

View File

View File

@ -6,14 +6,13 @@
<title>FilaMan - Filament Management Tool</title>
<link rel="icon" type="image/png" href="/favicon.ico">
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="style2.css">
</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</h1>
<h1>FilaMan<span class="version">v1.2.85</span></h1>
<h4>Filament Management Tool</h4>
</div>
</div>
@ -21,7 +20,8 @@
<a href="/">Start</a>
<a href="/waage">Scale</a>
<a href="/spoolman">Spoolman/Bambu</a>
<a href="/">About</a>
<a href="/about">About</a>
<a href="/upgrade">Upgrade</a>
</nav>
<div class="status-container">
<div class="status-item">
@ -33,3 +33,4 @@
<div class="ram-status" id="ramStatus"></div>
</div>
</div>

View File

@ -1,4 +1,40 @@
{{header}}
<!-- 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">
</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">v1.2.85</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="container">
<h1>FilaMan</h1>

View File

@ -1,4 +1,41 @@
{{header}}
<!-- 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">
</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">v1.2.85</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>
@ -35,11 +72,11 @@
</li>
<li>
<span class="stat-label">Weight:</span>
<span class="stat-value"><span id="totalWeight"></span> kg</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> m</span>
<span class="stat-value"><span id="totalLength"></span></span>
</li>
</ul>
</div>

View File

@ -112,9 +112,39 @@ function initWebSocket() {
if (bambuDot) {
bambuDot.className = 'status-dot ' + (data.bambu_connected ? 'online' : 'offline');
// Add click handler only when offline
if (!data.bambu_connected) {
bambuDot.style.cursor = 'pointer';
bambuDot.onclick = function() {
if (socket && socket.readyState === WebSocket.OPEN) {
socket.send(JSON.stringify({
type: 'reconnect',
payload: 'bambu'
}));
}
};
} else {
bambuDot.style.cursor = 'default';
bambuDot.onclick = null;
}
}
if (spoolmanDot) {
spoolmanDot.className = 'status-dot ' + (data.spoolman_connected ? 'online' : 'offline');
// Add click handler only when offline
if (!data.spoolman_connected) {
spoolmanDot.style.cursor = 'pointer';
spoolmanDot.onclick = function() {
if (socket && socket.readyState === WebSocket.OPEN) {
socket.send(JSON.stringify({
type: 'reconnect',
payload: 'spoolman'
}));
}
};
} else {
spoolmanDot.style.cursor = 'default';
spoolmanDot.onclick = null;
}
}
if (ramStatus) {
ramStatus.textContent = `${data.freeHeap}k`;
@ -209,16 +239,6 @@ function updateNfcInfo() {
`${spool.id} | ${spool.filament.name} (${spool.filament.material})` === selectedText
);
if (selectedSpool && selectedSpool.extra.nfc_id) {
nfcInfo.textContent = "NFC Tag assigned";
nfcInfo.classList.add("nfc-success");
nfcInfo.classList.remove("nfc-error");
} else {
nfcInfo.textContent = "No NFC-Tag assigned";
nfcInfo.classList.add("nfc-error");
nfcInfo.classList.remove("nfc-success");
}
if (selectedSpool) {
writeButton.classList.remove("hidden");
} else {
@ -236,7 +256,7 @@ function displayAmsData(amsData) {
const trayHTML = ams.tray.map(tray => {
// Prüfe ob überhaupt Daten vorhanden sind
const relevantFields = ['tray_type', 'tray_sub_brands', 'tray_info_idx', 'setting_id'];
const relevantFields = ['tray_type', 'tray_sub_brands', 'tray_info_idx', 'setting_id', 'cali_idx'];
const hasAnyContent = relevantFields.some(field =>
tray[field] !== null &&
tray[field] !== undefined &&
@ -244,23 +264,38 @@ function displayAmsData(amsData) {
tray[field] !== 'null'
);
if (!hasAnyContent) {
return `
<div class="tray">
<p class="tray-head">Tray ${tray.id}</p>
<p>Empty</p>
</div>
<hr>`;
}
// Bestimme den Anzeigenamen für das Tray
const trayDisplayName = (ams.ams_id === 255) ? 'External' : `Tray ${tray.id}`;
// Nur für nicht-leere Trays den Button-HTML erstellen
const buttonHtml = `
<button class="spool-button" onclick="handleSpoolIn(${ams.ams_id}, ${tray.id})"
style="position: absolute; top: -35px; left: -15px;
style="position: absolute; top: -30px; left: -15px;
background: none; border: none; padding: 0;
cursor: pointer; display: none;">
<img src="spool_in.png" alt="Spool In" style="width: 48px; height: 48px;">
</button>`;
// Nur für nicht-leere Trays den Button-HTML erstellen
const outButtonHtml = `
<button class="spool-button" onclick="handleSpoolOut()"
style="position: absolute; top: -35px; right: -15px;
background: none; border: none; padding: 0;
cursor: pointer; display: block;">
<img src="spool_in.png" alt="Spool In" style="width: 48px; height: 48px; transform: rotate(180deg) scaleX(-1);">
</button>`;
if (!hasAnyContent) {
return `
<div class="tray">
<p class="tray-head">${trayDisplayName}</p>
<p>
${(ams.ams_id === 255 && tray.tray_type === '') ? buttonHtml : ''}
Empty
</p>
</div>
<hr>`;
}
// Generiere den Type mit Color-Box zusammen
const typeWithColor = tray.tray_type ?
@ -277,8 +312,9 @@ function displayAmsData(amsData) {
// Array mit restlichen Tray-Eigenschaften
const trayProperties = [
{ key: 'tray_sub_brands', label: 'Sub Brands' },
{ key: 'tray_info_idx', label: 'Filament Index' },
{ key: 'setting_id', label: 'Setting ID' }
{ key: 'tray_info_idx', label: 'Filament IDX' },
{ key: 'setting_id', label: 'Setting ID' },
{ key: 'cali_idx', label: 'Calibration IDX' }
];
// Nur gültige Felder anzeigen
@ -289,7 +325,13 @@ function displayAmsData(amsData) {
tray[prop.key] !== '' &&
tray[prop.key] !== 'null'
)
.map(prop => `<p>${prop.label}: ${tray[prop.key]}</p>`)
.map(prop => {
// Spezielle Behandlung für setting_id
if (prop.key === 'cali_idx' && tray[prop.key] === '-1') {
return `<p>${prop.label}: not calibrated</p>`;
}
return `<p>${prop.label}: ${tray[prop.key]}</p>`;
})
.join('');
// Temperaturen nur anzeigen, wenn beide nicht 0 sind
@ -297,9 +339,6 @@ function displayAmsData(amsData) {
? `<p>Nozzle Temp: ${tray.nozzle_temp_min}°C - ${tray.nozzle_temp_max}°C</p>`
: '';
// Bestimme den Anzeigenamen für das Tray
const trayDisplayName = (ams.ams_id === 255) ? 'External' : `Tray ${tray.id}`;
return `
<div class="tray" ${tray.tray_color ? `style="border-left: 4px solid #${tray.tray_color};"` : 'style="border-left: 4px solid #007bff;"'}>
<div style="position: relative;">
@ -308,7 +347,9 @@ function displayAmsData(amsData) {
${typeWithColor}
${trayDetails}
${tempHTML}
${(ams.ams_id === 255 && tray.tray_type !== '') ? outButtonHtml : ''}
</div>
</div>`;
}).join('');
@ -332,6 +373,30 @@ function updateSpoolButtons(show) {
});
}
function handleSpoolOut() {
// Erstelle Payload
const payload = {
type: 'setBambuSpool',
payload: {
amsId: 255,
trayId: 254,
color: "FFFFFF",
nozzle_temp_min: 0,
nozzle_temp_max: 0,
type: "",
brand: ""
}
};
try {
socket.send(JSON.stringify(payload));
showNotification(`External Spool removed. Pls wait`, true);
} catch (error) {
console.error("Fehler beim Senden der WebSocket Nachricht:", error);
showNotification("Error while sending!", false);
}
}
// Neue Funktion zum Behandeln des Spool-In-Klicks
function handleSpoolIn(amsId, trayId) {
// Prüfe WebSocket Verbindung zuerst
@ -361,7 +426,7 @@ function handleSpoolIn(amsId, trayId) {
// Temperaturwerte extrahieren
let minTemp = "175";
let maxTemp = "275";
if (Array.isArray(selectedSpool.filament.nozzle_temperature) &&
selectedSpool.filament.nozzle_temperature.length >= 2) {
minTemp = selectedSpool.filament.nozzle_temperature[0];
@ -378,19 +443,30 @@ function handleSpoolIn(amsId, trayId) {
nozzle_temp_min: parseInt(minTemp),
nozzle_temp_max: parseInt(maxTemp),
type: selectedSpool.filament.material,
brand: selectedSpool.filament.vendor.name
brand: selectedSpool.filament.vendor.name,
tray_info_idx: selectedSpool.filament.extra.bambu_idx.replace(/['"]+/g, '').trim(),
cali_idx: "-1" // Default-Wert setzen
}
};
// Debug logging
console.log("Sende WebSocket Nachricht:", payload);
// Prüfe, ob der Key cali_idx vorhanden ist und setze ihn
if (selectedSpool.filament.extra.bambu_cali_id) {
payload.payload.cali_idx = selectedSpool.filament.extra.bambu_cali_id.replace(/['"]+/g, '').trim();
}
// Prüfe, ob der Key bambu_setting_id vorhanden ist
if (selectedSpool.filament.extra.bambu_setting_id) {
payload.payload.bambu_setting_id = selectedSpool.filament.extra.bambu_setting_id.replace(/['"]+/g, '').trim();
}
console.log("Spool-In Payload:", payload);
try {
socket.send(JSON.stringify(payload));
showNotification(`Spool set in AMS ${amsId} Tray ${trayId}. Pls wait`, true);
} catch (error) {
console.error("Fehler beim Senden der WebSocket Nachricht:", error);
showNotification("Fehler beim Senden der Daten", false);
showNotification("Error while sending", false);
}
}
@ -440,7 +516,7 @@ function updateNfcData(data) {
}
} else {
nfcDataDiv.innerHTML = '<div style="margin-top: 10px;"></div>';
nfcDataDiv.innerHTML = '<div class="info-message-inner" style="margin-top: 10px;"></div>';
}
nfcStatusContainer.appendChild(nfcDataDiv);
return;
@ -566,4 +642,4 @@ function showNotification(message, isSuccess) {
notification.remove();
}, 300);
}, 3000);
}
}

View File

@ -1,4 +1,41 @@
{{header}}
<!-- 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">
</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">v1.2.85</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 -->
<script>
window.onload = function() {
if (spoolmanUrl && spoolmanUrl.trim() !== "") {

View File

@ -61,9 +61,6 @@ function populateVendorDropdown(data, selectedSmId = null) {
totalLength += spool.remaining_length;
}
console.log("Länge gesamt: " + spool.remaining_length);
console.log("Gewicht gesamt" + spool.remaining_weight);
const vendor = spool.filament.vendor;
const hasValidNfcId = spool.extra &&
@ -88,6 +85,18 @@ function populateVendorDropdown(data, selectedSmId = null) {
}
});
// Nach der Schleife: Formatierung der Gesamtlänge
console.log("Total Lenght: ", totalLength);
const formattedLength = totalLength > 1000
? (totalLength / 1000).toFixed(2) + " km"
: totalLength.toFixed(2) + " m";
// Formatierung des Gesamtgewichts (von g zu kg zu t)
const weightInKg = totalWeight / 1000; // erst in kg umrechnen
const formattedWeight = weightInKg > 1000
? (weightInKg / 1000).toFixed(2) + " t"
: weightInKg.toFixed(2) + " kg";
// Dropdown mit gefilterten Herstellern befüllen
Object.entries(filteredVendors).forEach(([id, name]) => {
const option = document.createElement("option");
@ -102,8 +111,8 @@ function populateVendorDropdown(data, selectedSmId = null) {
document.getElementById("totalVendors").textContent = Object.keys(allVendors).length;
// Neue Statistiken hinzufügen
document.getElementById("totalWeight").textContent = (totalWeight / 1000).toFixed(2);
document.getElementById("totalLength").textContent = (totalLength / 1000).toFixed(2);
document.getElementById("totalWeight").textContent = formattedWeight;
document.getElementById("totalLength").textContent = formattedLength;
// Material-Statistiken zum DOM hinzufügen
const materialsList = document.getElementById("materialsList");
@ -112,7 +121,7 @@ function populateVendorDropdown(data, selectedSmId = null) {
.sort(([,a], [,b]) => b - a) // Sortiere nach Anzahl absteigend
.forEach(([material, count]) => {
const li = document.createElement("li");
li.textContent = `${material}: ${count} ${count === 1 ? 'Spule' : 'Spulen'}`;
li.textContent = `${material}: ${count} ${count === 1 ? 'Spool' : 'Spools'}`;
materialsList.appendChild(li);
});

View File

@ -133,6 +133,15 @@ body {
background-color: #dc2626;
}
.status-dot.offline {
cursor: pointer;
}
.status-dot.offline:hover {
opacity: 0.8;
transform: scale(1.1);
}
.ram-status {
color: var(--inner-text-color);
font-size: 0.9em;
@ -471,11 +480,15 @@ a:hover {
.info-message {
padding: 10px;
background-color: #fff3f3;
background-color: var(--header-bg);
border-radius: 4px;
border-left: 4px solid #39d82e;
}
.info-message-inner {
background-color: var(--header-bg) !important;
}
.nfc-header {
display: grid;
grid-template-columns: 40px 1fr 40px;
@ -489,3 +502,594 @@ a:hover {
text-align: center;
color: var(--accent-color);
}
.nfc-header .status-circle {
grid-column: 3;
justify-self: end;
}
.content-header {
display: flex;
justify-content: center;
align-items: center;
position: relative;
}
.connection-status {
display: flex;
align-items: center;
gap: 10px;
background-color: #fff3f3;
border: 1px solid #dc3545;
border-radius: 4px;
padding: 10px 15px;
margin: 15px auto;
color: #dc3545;
position: fixed;
top: 20px;
left: 50%;
transform: translateX(-50%);
z-index: 1000;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
max-width: 90%;
opacity: 0;
transition: opacity 0.3s ease;
}
.connection-status.visible {
opacity: 1;
}
.spinner {
flex-shrink: 0;
width: 16px;
height: 16px;
border: 2px solid rgba(220, 53, 69, 0.2);
border-top-color: #dc3545;
border-radius: 50%;
}
.connection-status.visible .spinner {
animation: spin 0.8s linear infinite;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
.connection-status.hidden {
display: none;
}
.nfc-actions {
display: flex;
gap: 10px;
justify-content: center; /* Zentriert das div */
}
.btn {
padding: 8px 16px;
border-radius: 4px;
border: none;
cursor: pointer;
font-weight: bold;
}
.btn-primary {
background-color: #007bff;
color: white;
}
.btn-primary:hover {
background-color: #0056b3;
}
.btn-danger {
background-color: #dc3545;
color: white;
}
.btn-danger:hover {
background-color: #c82333;
}
/* Filament Select Styling */
#filamentSelect {
width: 100%;
padding: 12px 15px;
font-size: 16px;
border: 2px solid #e0e0e0;
border-radius: 8px;
background-color: #fff;
cursor: pointer;
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23007bff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e");
background-repeat: no-repeat;
background-position: right 15px center;
background-size: 15px;
transition: all 0.3s ease;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}
#filamentSelect:hover {
border-color: #007bff;
box-shadow: 0 3px 6px rgba(0, 123, 255, 0.1);
}
#filamentSelect:focus {
border-color: #007bff;
outline: none;
box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.25);
}
#filamentSelect option {
padding: 8px 15px;
font-size: 16px;
background-color: #fff;
color: #000; /* Standard Textfarbe für alles außer dem Farbblock */
}
#filamentSelect option::first-letter {
font-size: 16px;
margin-right: 5px;
}
#filamentSelect option::before {
content: '';
display: inline-block;
width: 12px;
margin-right: 8px;
}
/* Color Box im Select */
.color-box {
display: inline-block;
width: 12px;
height: 12px;
border: 1px solid #333;
border-radius: 2px;
margin-right: 5px;
vertical-align: middle;
}
#filamentSelect option span {
display: inline-block;
pointer-events: none;
}
#filamentSelect option span:first-child {
margin-right: 5px;
font-size: 16px;
}
/* Filament Select Option Styling */
#filamentSelect option span.color-circle {
display: inline-block;
width: 12px;
height: 12px;
border-radius: 50%;
margin-right: 8px;
border: 1px solid #333;
vertical-align: middle;
}
/* Custom Dropdown */
.custom-dropdown {
position: relative;
width: 100%;
font-family: inherit;
cursor: default; /* Container selbst soll normalen Cursor haben */
color: black;
}
.dropdown-button {
padding: 12px 15px;
border: 2px solid #e0e0e0;
border-radius: 8px;
background-color: #fff;
cursor: pointer;
display: flex;
align-items: center;
gap: 8px;
transition: all 0.3s ease;
}
.dropdown-button:hover {
border-color: #007bff;
}
.selected-color {
width: 16px;
height: 16px;
border-radius: 50%;
border: 1px solid #333;
flex-shrink: 0;
}
.dropdown-arrow {
margin-left: auto;
color: #007bff;
font-size: 12px;
}
.dropdown-content {
display: none;
position: absolute;
top: 100%;
left: 0;
right: 0;
background-color: #fff;
border: 1px solid #e0e0e0;
border-radius: 8px;
margin-top: 4px;
max-height: 300px;
overflow-y: auto;
z-index: 1000;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.dropdown-content.show {
display: block;
}
.dropdown-option {
padding: 10px 15px;
cursor: pointer;
display: flex;
align-items: center;
gap: 8px;
}
.dropdown-option:hover {
background-color: #f8f9fa;
}
.option-color {
width: 16px;
height: 16px;
border-radius: 50%;
border: 1px solid #333;
flex-shrink: 0;
}
.notification {
position: fixed;
top: 20px;
right: 20px;
padding: 15px 25px;
border-radius: 4px;
color: white;
z-index: 1000;
animation: slideIn 0.3s ease-out;
}
.notification.success {
background-color: #28a745;
}
.notification.error {
background-color: #dc3545;
}
.notification.fade-out {
opacity: 0;
transition: opacity 0.3s ease-out;
}
@keyframes slideIn {
from {
transform: translateX(100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
/* Neue Styles für die Statistiken */
.statistics-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
gap: 1rem;
margin-top: 15px;
}
.statistics-column {
background: var(--inner-box-bg);
border: 1px solid rgba(99, 187, 103, 0.2);
border-radius: 0.5rem;
}
.statistics-column h3 {
color: var(--inner-text-color);
border-bottom: 1px solid rgba(99, 187, 103, 0.2);
font-size: 1.1rem;
}
.statistics-list {
list-style: none;
padding: 0;
margin: 0;
}
.statistics-list li {
display: flex;
justify-content: space-between;
padding: 0.5rem;
border-bottom: 1px solid rgba(99, 187, 103, 0.1);
}
.statistics-list li:last-child {
border-bottom: none;
}
.stat-label {
color: var(--inner-text-color);
}
.stat-value {
color: var(--stat-value-color);
font-weight: 500;
}
/* Responsive Design Anpassung */
@media (max-width: 768px) {
.statistics-grid {
grid-template-columns: 1fr;
}
}
.statistics-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
padding-bottom: 0;
border-bottom: 1px solid #e9ecef;
}
.refresh-button {
display: flex;
align-items: center;
padding: 8px 16px;
background-color: #007bff;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
transition: background-color 0.2s;
}
.refresh-button:hover {
background-color: #0056b3;
}
.refresh-button:active {
background-color: #004494;
}
.spools-info {
display: flex;
justify-content: flex-start;
gap: 20px;
margin-bottom: 15px;
}
.spool-stat {
display: flex;
align-items: center;
gap: 8px;
background: var(--inner-box-bg);
border: 1px solid rgba(99, 187, 103, 0.2);
border-radius: 0.5rem;
}
.spool-stat .stat-label {
color: var(--inner-text-color);
}
.spool-stat .stat-value {
color: var(--stat-value-color);
font-weight: 500;
}
/* Buttons und klickbare Elemente */
button,
input[type="submit"],
.dropdown-button,
.dropdown-option,
.refresh-button,
.btn,
.styled-select,
select,
a {
cursor: pointer !important;
}
/* Disabled Zustände */
button:disabled,
input[type="submit"]:disabled,
.btn:disabled,
.styled-select:disabled {
cursor: not-allowed !important;
opacity: 0.7;
}
/* Schreib-Button */
#writeNfcButton {
background-color: #007bff;
color: white;
transition: background-color 0.3s, color 0.3s;
width: 160px;
}
#writeNfcButton.writing {
background-color: #ffc107;
color: black;
width: 160px;
}
#writeNfcButton.success {
background-color: #28a745;
color: white;
width: 160px;
}
#writeNfcButton.error {
background-color: #dc3545;
color: white;
width: 160px;
}
@keyframes dots {
0% { content: ""; }
33% { content: "."; }
66% { content: ".."; }
100% { content: "..."; }
}
#writeNfcButton.writing::after {
content: "...";
animation: dots 1s steps(3, end) infinite;
}
/* Bambu Settings Erweiterung */
.bambu-settings {
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
max-width: 400px;
margin: 20px auto;
}
.bambu-settings .input-group {
margin-bottom: 15px;
text-align: left;
}
.bambu-settings .input-group label {
display: block;
margin-bottom: 5px;
}
.bambu-settings .input-group input {
width: 95%;
}
#bambuStatusMessage {
margin-top: 15px;
display: flex;
align-items: center;
gap: 10px;
justify-content: center;
}
.amsData {
border-color: black !important;
border-width: 1px !important;
}
.tray {
position: relative;
}
.tray-head {
color: var(--stat-value-color) !important;
text-align: center !important;
font-weight: bold !important;
}
.spool-button:hover {
opacity: 0.8;
}
.version {
font-size: 0.4em;
color: #000;
vertical-align: middle;
margin-left: 0.5rem;
}
.progress-container {
width: 100%;
margin: 20px 0;
display: none;
background: #f0f0f0;
border-radius: 4px;
overflow: hidden;
}
.progress-bar {
width: 0%;
height: 24px;
background-color: #4CAF50;
text-align: center;
line-height: 24px;
color: white;
transition: width 0.3s ease-in-out;
font-weight: bold;
}
.status {
margin: 10px 0;
padding: 15px;
border-radius: 4px;
display: none;
}
.error {
background-color: #ffebee;
color: #c62828;
border: 1px solid #ef9a9a;
}
.success {
background-color: #e8f5e9;
color: #2e7d32;
border: 1px solid #a5d6a7;
}
.update-form {
background: var(--primary-color);
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
margin: 0 auto;
width: 400px;
text-align: center;
}
.update-form input[type="file"] {
margin-bottom: 15px;
width: 80%;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
background: white;
}
.update-form input[type="submit"] {
background-color: #4CAF50;
color: white;
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
transition: background-color 0.3s;
}
.update-form input[type="submit"]:hover {
background-color: #45a049;
}
.update-form input[type="submit"]:disabled {
background-color: #cccccc;
cursor: not-allowed;
}
.warning {
background-color: var(--primary-color);
border: 1px solid #ffe0b2;
color: white;
padding: 15px;
margin: 20px auto;
border-radius: 4px;
max-width: 600px;
text-align: center;
}

View File

@ -1,505 +0,0 @@
.nfc-header .status-circle {
grid-column: 3;
justify-self: end;
}
.content-header {
display: flex;
justify-content: center;
align-items: center;
position: relative;
}
.connection-status {
display: flex;
align-items: center;
gap: 10px;
background-color: #fff3f3;
border: 1px solid #dc3545;
border-radius: 4px;
padding: 10px 15px;
margin: 15px auto;
color: #dc3545;
position: fixed;
top: 20px;
left: 50%;
transform: translateX(-50%);
z-index: 1000;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
max-width: 90%;
opacity: 0;
transition: opacity 0.3s ease;
}
.connection-status.visible {
opacity: 1;
}
.spinner {
flex-shrink: 0;
width: 16px;
height: 16px;
border: 2px solid rgba(220, 53, 69, 0.2);
border-top-color: #dc3545;
border-radius: 50%;
}
.connection-status.visible .spinner {
animation: spin 0.8s linear infinite;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
.connection-status.hidden {
display: none;
}
.nfc-actions {
display: flex;
gap: 10px;
justify-content: center; /* Zentriert das div */
}
.btn {
padding: 8px 16px;
border-radius: 4px;
border: none;
cursor: pointer;
font-weight: bold;
}
.btn-primary {
background-color: #007bff;
color: white;
}
.btn-primary:hover {
background-color: #0056b3;
}
.btn-danger {
background-color: #dc3545;
color: white;
}
.btn-danger:hover {
background-color: #c82333;
}
/* Filament Select Styling */
#filamentSelect {
width: 100%;
padding: 12px 15px;
font-size: 16px;
border: 2px solid #e0e0e0;
border-radius: 8px;
background-color: #fff;
cursor: pointer;
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23007bff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e");
background-repeat: no-repeat;
background-position: right 15px center;
background-size: 15px;
transition: all 0.3s ease;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}
#filamentSelect:hover {
border-color: #007bff;
box-shadow: 0 3px 6px rgba(0, 123, 255, 0.1);
}
#filamentSelect:focus {
border-color: #007bff;
outline: none;
box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.25);
}
#filamentSelect option {
padding: 8px 15px;
font-size: 16px;
background-color: #fff;
color: #000; /* Standard Textfarbe für alles außer dem Farbblock */
}
#filamentSelect option::first-letter {
font-size: 16px;
margin-right: 5px;
}
#filamentSelect option::before {
content: '';
display: inline-block;
width: 12px;
margin-right: 8px;
}
/* Color Box im Select */
.color-box {
display: inline-block;
width: 12px;
height: 12px;
border: 1px solid #333;
border-radius: 2px;
margin-right: 5px;
vertical-align: middle;
}
#filamentSelect option span {
display: inline-block;
pointer-events: none;
}
#filamentSelect option span:first-child {
margin-right: 5px;
font-size: 16px;
}
/* Filament Select Option Styling */
#filamentSelect option span.color-circle {
display: inline-block;
width: 12px;
height: 12px;
border-radius: 50%;
margin-right: 8px;
border: 1px solid #333;
vertical-align: middle;
}
/* Custom Dropdown */
.custom-dropdown {
position: relative;
width: 100%;
font-family: inherit;
cursor: default; /* Container selbst soll normalen Cursor haben */
color: black;
}
.dropdown-button {
padding: 12px 15px;
border: 2px solid #e0e0e0;
border-radius: 8px;
background-color: #fff;
cursor: pointer;
display: flex;
align-items: center;
gap: 8px;
transition: all 0.3s ease;
}
.dropdown-button:hover {
border-color: #007bff;
}
.selected-color {
width: 16px;
height: 16px;
border-radius: 50%;
border: 1px solid #333;
flex-shrink: 0;
}
.dropdown-arrow {
margin-left: auto;
color: #007bff;
font-size: 12px;
}
.dropdown-content {
display: none;
position: absolute;
top: 100%;
left: 0;
right: 0;
background-color: #fff;
border: 1px solid #e0e0e0;
border-radius: 8px;
margin-top: 4px;
max-height: 300px;
overflow-y: auto;
z-index: 1000;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.dropdown-content.show {
display: block;
}
.dropdown-option {
padding: 10px 15px;
cursor: pointer;
display: flex;
align-items: center;
gap: 8px;
}
.dropdown-option:hover {
background-color: #f8f9fa;
}
.option-color {
width: 16px;
height: 16px;
border-radius: 50%;
border: 1px solid #333;
flex-shrink: 0;
}
.notification {
position: fixed;
top: 20px;
right: 20px;
padding: 15px 25px;
border-radius: 4px;
color: white;
z-index: 1000;
animation: slideIn 0.3s ease-out;
}
.notification.success {
background-color: #28a745;
}
.notification.error {
background-color: #dc3545;
}
.notification.fade-out {
opacity: 0;
transition: opacity 0.3s ease-out;
}
@keyframes slideIn {
from {
transform: translateX(100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
/* Neue Styles für die Statistiken */
.statistics-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
gap: 1rem;
margin-top: 15px;
}
.statistics-column {
background: var(--inner-box-bg);
border: 1px solid rgba(99, 187, 103, 0.2);
border-radius: 0.5rem;
}
.statistics-column h3 {
color: var(--inner-text-color);
border-bottom: 1px solid rgba(99, 187, 103, 0.2);
font-size: 1.1rem;
}
.statistics-list {
list-style: none;
padding: 0;
margin: 0;
}
.statistics-list li {
display: flex;
justify-content: space-between;
padding: 0.5rem;
border-bottom: 1px solid rgba(99, 187, 103, 0.1);
}
.statistics-list li:last-child {
border-bottom: none;
}
.stat-label {
color: var(--inner-text-color);
}
.stat-value {
color: var(--stat-value-color);
font-weight: 500;
}
/* Responsive Design Anpassung */
@media (max-width: 768px) {
.statistics-grid {
grid-template-columns: 1fr;
}
}
.statistics-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
padding-bottom: 0;
border-bottom: 1px solid #e9ecef;
}
.refresh-button {
display: flex;
align-items: center;
padding: 8px 16px;
background-color: #007bff;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
transition: background-color 0.2s;
}
.refresh-button:hover {
background-color: #0056b3;
}
.refresh-button:active {
background-color: #004494;
}
.spools-info {
display: flex;
justify-content: flex-start;
gap: 20px;
margin-bottom: 15px;
}
.spool-stat {
display: flex;
align-items: center;
gap: 8px;
background: var(--inner-box-bg);
border: 1px solid rgba(99, 187, 103, 0.2);
border-radius: 0.5rem;
}
.spool-stat .stat-label {
color: var(--inner-text-color);
}
.spool-stat .stat-value {
color: var(--stat-value-color);
font-weight: 500;
}
/* Buttons und klickbare Elemente */
button,
input[type="submit"],
.dropdown-button,
.dropdown-option,
.refresh-button,
.btn,
.styled-select,
select,
a {
cursor: pointer !important;
}
/* Disabled Zustände */
button:disabled,
input[type="submit"]:disabled,
.btn:disabled,
.styled-select:disabled {
cursor: not-allowed !important;
opacity: 0.7;
}
/* Schreib-Button */
#writeNfcButton {
background-color: #007bff;
color: white;
transition: background-color 0.3s, color 0.3s;
width: 160px;
}
#writeNfcButton.writing {
background-color: #ffc107;
color: black;
width: 160px;
}
#writeNfcButton.success {
background-color: #28a745;
color: white;
width: 160px;
}
#writeNfcButton.error {
background-color: #dc3545;
color: white;
width: 160px;
}
@keyframes dots {
0% { content: ""; }
33% { content: "."; }
66% { content: ".."; }
100% { content: "..."; }
}
#writeNfcButton.writing::after {
content: "...";
animation: dots 1s steps(3, end) infinite;
}
/* Bambu Settings Erweiterung */
.bambu-settings {
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
max-width: 400px;
margin: 20px auto;
}
.bambu-settings .input-group {
margin-bottom: 15px;
text-align: left;
}
.bambu-settings .input-group label {
display: block;
margin-bottom: 5px;
}
.bambu-settings .input-group input {
width: 95%;
}
#bambuStatusMessage {
margin-top: 15px;
display: flex;
align-items: center;
gap: 10px;
justify-content: center;
}
.amsData {
border-color: black !important;
border-width: 1px !important;
}
.tray {
position: relative;
}
.tray-head {
color: var(--stat-value-color) !important;
text-align: center !important;
font-weight: bold !important;
}
.spool-button:hover {
opacity: 0.8;
}

154
html/upgrade.html Normal file
View File

@ -0,0 +1,154 @@
<!-- 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">
</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">v1.2.85</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="content">
<h1>Firmware Upgrade</h1>
<div class="warning">
<strong>Warning:</strong> Please do not turn off or restart the device during the update.
The device will restart automatically after the update.
</div>
<div class="update-form">
<form id="updateForm" enctype='multipart/form-data'>
<input type='file' name='update' accept='.bin' required>
<input type='submit' value='Start Firmware Update'>
</form>
</div>
<div class="progress-container">
<div class="progress-bar">0%</div>
</div>
<div class="status"></div>
</div>
<script>
// Hide status indicators during update
const statusContainer = document.querySelector('.status-container');
if (statusContainer) {
statusContainer.style.display = 'none';
}
document.getElementById('updateForm').addEventListener('submit', async (e) => {
e.preventDefault();
const form = e.target;
const file = form.update.files[0];
if (!file) {
alert('Please select a firmware file.');
return;
}
const formData = new FormData();
formData.append('update', file);
const progress = document.querySelector('.progress-bar');
const progressContainer = document.querySelector('.progress-container');
const status = document.querySelector('.status');
progressContainer.style.display = 'block';
status.style.display = 'none';
status.className = 'status';
form.querySelector('input[type=submit]').disabled = true;
const xhr = new XMLHttpRequest();
xhr.open('POST', '/update', true);
xhr.upload.onprogress = (e) => {
if (e.lengthComputable) {
const percentComplete = (e.loaded / e.total) * 100;
progress.style.width = percentComplete + '%';
progress.textContent = Math.round(percentComplete) + '%';
}
};
xhr.onload = function() {
try {
let response = this.responseText;
try {
const jsonResponse = JSON.parse(response);
response = jsonResponse.message;
if (jsonResponse.restart) {
status.textContent = response + " Redirecting in 20 seconds...";
let countdown = 20;
const timer = setInterval(() => {
countdown--;
if (countdown <= 0) {
clearInterval(timer);
window.location.href = '/';
} else {
status.textContent = response + ` Redirecting in ${countdown} seconds...`;
}
}, 1000);
}
} catch (e) {
if (!isNaN(response)) {
const percent = parseInt(response);
progress.style.width = percent + '%';
progress.textContent = percent + '%';
return;
}
}
status.textContent = response;
status.classList.add(xhr.status === 200 ? 'success' : 'error');
status.style.display = 'block';
if (xhr.status !== 200) {
form.querySelector('input[type=submit]').disabled = false;
}
} catch (error) {
status.textContent = 'Error: ' + error.message;
status.classList.add('error');
status.style.display = 'block';
form.querySelector('input[type=submit]').disabled = false;
}
};
xhr.onerror = function() {
status.textContent = 'Update failed: Network error';
status.classList.add('error');
status.style.display = 'block';
form.querySelector('input[type=submit]').disabled = false;
};
xhr.send(formData);
});
</script>
</body>
</html>

View File

@ -1,4 +1,41 @@
{{header}}
<!-- 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">
</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">v1.2.85</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="content">
<h1>Scale Configuration Page</h1>

View File

@ -1,4 +1,41 @@
{{header}}
<!-- 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">
</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">v1.2.85</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="content">
<h1>WiFi Configuration Page</h1>
<form action="/setToken" method="post">

BIN
img/display_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 571 KiB

BIN
img/display_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 470 KiB

BIN
img/display_3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 535 KiB

BIN
img/display_4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 534 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 255 KiB

BIN
img/scale_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 735 KiB

BIN
img/scale_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 835 KiB

BIN
img/scale_3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 814 KiB

BIN
img/scale_4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 648 KiB

BIN
img/scale_side.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 594 KiB

BIN
img/scale_trans.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 665 KiB

BIN
img/web_1.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 488 KiB

BIN
img/web_ams.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 KiB

BIN
img/web_nfc.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

BIN
img/web_spoolm_to_ams.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 KiB

BIN
img/web_spoolman.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

BIN
img/web_statistics.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

6
partitions.csv Normal file
View File

@ -0,0 +1,6 @@
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x1E0000,
app1, app, ota_1, 0x1F0000, 0x1E0000,
spiffs, data, spiffs, 0x3D0000, 0x30000,
1 # Name Type SubType Offset Size Flags
2 nvs data nvs 0x9000 0x5000
3 otadata data ota 0xe000 0x2000
4 app0 app ota_0 0x10000 0x1E0000
5 app1 app ota_1 0x1F0000 0x1E0000
6 spiffs data spiffs 0x3D0000 0x30000

150
platformio.ini Normal file
View File

@ -0,0 +1,150 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[common]
version = "1.2.85"
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200
lib_deps =
tzapu/WiFiManager @ ^2.0.17
https://github.com/me-no-dev/ESPAsyncWebServer.git#master
me-no-dev/AsyncTCP @ ^1.1.1
bogde/HX711 @ ^0.7.5
adafruit/Adafruit SSD1306 @ ^2.5.13
adafruit/Adafruit GFX Library @ ^1.11.11
adafruit/Adafruit PN532 @ ^1.3.3
bblanchon/ArduinoJson @ ^7.3.0
knolleary/PubSubClient @ ^2.8
digitaldragon/SSLClient @ ^1.3.2
; Enable SPIFFS upload
board_build.filesystem = spiffs
; Update partition settings
board_build.partitions = partitions.csv
board_upload.flash_size = 4MB
board_build.flash_mode = dio
board_upload.flash_freq = "40m"
build_flags =
-Os
-ffunction-sections
-fdata-sections
-DNDEBUG
-mtext-section-literals
'-D VERSION="${common.version}"'
-DASYNCWEBSERVER_REGEX
-DCORE_DEBUG_LEVEL=1
-DCONFIG_ARDUHAL_LOG_COLORS=1
-DOTA_DEBUG=1
-DARDUINO_RUNNING_CORE=1
-DARDUINO_EVENT_RUNNING_CORE=1
-DCONFIG_OPTIMIZATION_LEVEL_DEBUG=1
-DCONFIG_ESP32_PANIC_PRINT_REBOOT
-DCONFIG_ARDUINO_OTA_READSIZE=1024
-DCONFIG_ASYNC_TCP_RUNNING_CORE=1
-DCONFIG_ASYNC_TCP_USE_WDT=0
-DCONFIG_LWIP_TCP_MSS=1460
-DOTA_PARTITION_SUBTYPE=0x10
-DPARTITION_TABLE_OFFSET=0x8000
-DPARTITION_TABLE_SIZE=0x1000
-DCONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE=1
-DCONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP=1
-DCONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON=1
-DCONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0x1000
-DCONFIG_PARTITION_TABLE_OFFSET=0x8000
-DCONFIG_PARTITION_TABLE_MD5=y
-DBOOT_APP_PARTITION_OTA_0=1
extra_scripts =
scripts/extra_script.py
pre:scripts/pre_build.py ; wird zuerst ausgeführt
pre:scripts/pre_spiffs.py ; wird als zweites ausgeführt
pre:scripts/combine_html.py ; wird als drittes ausgeführt
scripts/gzip_files.py
; Remove or comment out the targets line
;targets = buildfs, build
; Add a custom target to build both
[env:esp32dev_ota]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200
lib_deps =
tzapu/WiFiManager @ ^2.0.17
https://github.com/me-no-dev/ESPAsyncWebServer.git#master
me-no-dev/AsyncTCP @ ^1.1.1
bogde/HX711 @ ^0.7.5
adafruit/Adafruit SSD1306 @ ^2.5.13
adafruit/Adafruit GFX Library @ ^1.11.11
adafruit/Adafruit PN532 @ ^1.3.3
bblanchon/ArduinoJson @ ^7.3.0
knolleary/PubSubClient @ ^2.8
digitaldragon/SSLClient @ ^1.3.2
; Enable SPIFFS upload
board_build.filesystem = spiffs
; Update partition settings
board_build.partitions = partitions.csv
board_upload.flash_size = 4MB
board_build.flash_mode = dio
board_upload.flash_freq = "40m"
build_flags =
-Os
-ffunction-sections
-fdata-sections
-DNDEBUG
-mtext-section-literals
'-D VERSION="${common.version}"'
-DASYNCWEBSERVER_REGEX
-DCORE_DEBUG_LEVEL=1
-DCONFIG_ARDUHAL_LOG_COLORS=1
-DOTA_DEBUG=1
-DARDUINO_RUNNING_CORE=1
-DARDUINO_EVENT_RUNNING_CORE=1
-DCONFIG_OPTIMIZATION_LEVEL_DEBUG=1
-DCONFIG_ESP32_PANIC_PRINT_REBOOT
-DCONFIG_ARDUINO_OTA_READSIZE=1024
-DCONFIG_ASYNC_TCP_RUNNING_CORE=1
-DCONFIG_ASYNC_TCP_USE_WDT=0
-DCONFIG_LWIP_TCP_MSS=1460
-DOTA_PARTITION_SUBTYPE=0x10
-DPARTITION_TABLE_OFFSET=0x8000
-DPARTITION_TABLE_SIZE=0x1000
-DCONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE=1
-DCONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP=1
-DCONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON=1
-DCONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0x1000
-DCONFIG_PARTITION_TABLE_OFFSET=0x8000
-DCONFIG_PARTITION_TABLE_MD5=y
-DBOOT_APP_PARTITION_OTA_0=1
extra_scripts =
scripts/extra_script.py
pre:scripts/pre_build.py ; wird zuerst ausgeführt
pre:scripts/pre_spiffs.py ; wird als zweites ausgeführt
pre:scripts/combine_html.py ; wird als drittes ausgeführt
scripts/gzip_files.py
; Remove or comment out the targets line
;targets = buildfs, build
; Add a custom target to build both
[platformio]
default_envs = esp32dev, esp32dev_ota

34
scripts/combine_html.py Normal file
View File

@ -0,0 +1,34 @@
Import("env")
import os
import re
def combine_html_files(source, target, env):
print("COMBINE HTML FILES")
html_dir = "./html"
header_file = os.path.join(html_dir, "header.html")
# Read header content
with open(header_file, 'r') as f:
header_content = f.read()
# Process all HTML files except header.html
for filename in os.listdir(html_dir):
if filename.endswith('.html') and filename != 'header.html':
file_path = os.path.join(html_dir, filename)
# Read content
with open(file_path, 'r') as f:
content = f.read()
# Replace content between head comments with header content
pattern = r'(<!-- head -->).*?(<!-- head -->)'
new_content = re.sub(pattern, r'\1' + header_content + r'\2', content, flags=re.DOTALL)
# Write back combined content
with open(file_path, 'w') as f:
f.write(new_content)
print(f"Combined header with {filename}")
# Register the script to run before building SPIFFS
env.AddPreAction("buildfs", combine_html_files)

View File

@ -13,8 +13,11 @@ def copy_file(input_file, output_file):
shutil.copy2(input_file, output_file)
def should_compress(file):
# Skip compression for spoolman.html
if file == 'spoolman.html':
return False
# Komprimiere nur bestimmte Dateitypen
return file.endswith(('.js', '.png', '.css'))
return file.endswith(('.js', '.png', '.css', '.html'))
def main(source_dir, target_dir):
for root, dirs, files in os.walk(source_dir):

25
scripts/pre_build.py Normal file
View File

@ -0,0 +1,25 @@
Import("env")
import os
def replace_version(source, target, env):
# Get version from common section
version = env.GetProjectConfig().get("common", "version").strip('"')
header_file = "./html/header.html"
with open(header_file, 'r') as file:
content = file.read()
# Replace version in header.html using string manipulation instead of regex
search = '<h1>FilaMan<span class="version">v'
end = '</span>'
start_pos = content.find(search)
if start_pos != -1:
start_pos += len(search)
end_pos = content.find(end, start_pos)
if end_pos != -1:
content = content[:start_pos] + version + content[end_pos:]
with open(header_file, 'w') as file:
file.write(content)
env.AddPreAction("buildfs", replace_version)

21
scripts/pre_spiffs.py Normal file
View File

@ -0,0 +1,21 @@
Import("env")
# Wiederverwendung der replace_version Funktion
exec(open("./scripts/pre_build.py").read())
# Bind to SPIFFS build
env.AddPreAction("buildfs", replace_version)
import os
import shutil
from SCons.Script import DefaultEnvironment
env = DefaultEnvironment()
# Format SPIFFS partition before uploading new files
spiffs_dir = os.path.join(env.subst("$BUILD_DIR"), "spiffs")
if os.path.exists(spiffs_dir):
shutil.rmtree(spiffs_dir)
os.makedirs(spiffs_dir)
print("SPIFFS partition formatted.")

128
scripts/update_changelog.py Normal file
View File

@ -0,0 +1,128 @@
import os
import re
import subprocess
from datetime import datetime
def get_version():
script_dir = os.path.dirname(os.path.abspath(__file__))
project_dir = os.path.dirname(script_dir)
platformio_path = os.path.join(project_dir, 'platformio.ini')
with open(platformio_path, 'r') as f:
content = f.read()
version_match = re.search(r'version\s*=\s*"([^"]+)"', content)
return version_match.group(1) if version_match else None
def get_last_tag():
try:
result = subprocess.run(['git', 'describe', '--tags', '--abbrev=0'],
capture_output=True, text=True)
return result.stdout.strip()
except subprocess.CalledProcessError:
return None
def categorize_commit(commit_msg):
"""Categorize commit messages based on conventional commits"""
lower_msg = commit_msg.lower()
if any(x in lower_msg for x in ['feat', 'add', 'new']):
return 'Added'
elif any(x in lower_msg for x in ['fix', 'bug']):
return 'Fixed'
else:
return 'Changed'
def get_changes_from_git():
"""Get changes from git commits since last tag"""
changes = {
'Added': [],
'Changed': [],
'Fixed': []
}
last_tag = get_last_tag()
# Get commits since last tag
git_log_command = ['git', 'log', '--pretty=format:%s']
if last_tag:
git_log_command.append(f'{last_tag}..HEAD')
try:
result = subprocess.run(git_log_command, capture_output=True, text=True)
commits = result.stdout.strip().split('\n')
# Filter out empty commits and categorize
for commit in commits:
if commit:
category = categorize_commit(commit)
# Clean up commit message
clean_msg = re.sub(r'^(feat|fix|chore|docs|style|refactor|perf|test)(\(.*\))?:', '', commit).strip()
changes[category].append(clean_msg)
except subprocess.CalledProcessError:
print("Error: Failed to get git commits")
return None
return changes
def push_changes(version):
"""Push changes to upstream"""
try:
# Stage the CHANGELOG.md
subprocess.run(['git', 'add', 'CHANGELOG.md'], check=True)
# Commit the changelog
commit_msg = f"docs: update changelog for version {version}"
subprocess.run(['git', 'commit', '-m', commit_msg], check=True)
# Push to origin (local)
subprocess.run(['git', 'push', 'origin'], check=True)
print("Successfully pushed to origin")
except subprocess.CalledProcessError as e:
print(f"Error during git operations: {e}")
return False
return True
def update_changelog():
print("Starting changelog update...") # Add this line
version = get_version()
print(f"Current version: {version}") # Add this line
today = datetime.now().strftime('%Y-%m-%d')
script_dir = os.path.dirname(os.path.abspath(__file__))
project_dir = os.path.dirname(script_dir)
changelog_path = os.path.join(project_dir, 'CHANGELOG.md')
# Get changes from git
changes = get_changes_from_git()
if not changes:
print("No changes found or error occurred")
return
# Create changelog entry
changelog_entry = f"## [{version}] - {today}\n"
for section, entries in changes.items():
if entries: # Only add sections that have entries
changelog_entry += f"### {section}\n"
for entry in entries:
changelog_entry += f"- {entry}\n"
changelog_entry += "\n"
if not os.path.exists(changelog_path):
with open(changelog_path, 'w') as f:
f.write(f"# Changelog\n\n{changelog_entry}")
push_changes(version)
else:
with open(changelog_path, 'r') as f:
content = f.read()
if f"[{version}]" not in content:
updated_content = content.replace("# Changelog\n", f"# Changelog\n\n{changelog_entry}")
with open(changelog_path, 'w') as f:
f.write(updated_content)
push_changes(version)
else:
print(f"Version {version} already exists in changelog")
if __name__ == "__main__":
update_changelog()

View File

@ -175,20 +175,20 @@ void sendToApi(void *parameter) {
vTaskDelete(NULL);
}
uint8_t updateSpoolTagId(String uidString, const char* payload) {
bool updateSpoolTagId(String uidString, const char* payload) {
JsonDocument doc;
DeserializationError error = deserializeJson(doc, payload);
if (error) {
Serial.print("Fehler beim JSON-Parsing: ");
Serial.println(error.c_str());
return 0;
return false;
}
// Überprüfe, ob die erforderlichen Felder vorhanden sind
if (!doc.containsKey("sm_id") || doc["sm_id"] == "") {
Serial.println("Keine Spoolman-ID gefunden.");
return 0;
return false;
}
String spoolsUrl = spoolmanUrl + apiUrl + "/spool/" + doc["sm_id"].as<String>();
@ -207,7 +207,7 @@ uint8_t updateSpoolTagId(String uidString, const char* payload) {
SendToApiParams* params = new SendToApiParams();
if (params == nullptr) {
Serial.println("Fehler: Kann Speicher für Task-Parameter nicht allokieren.");
return 0;
return false;
}
params->httpType = "PATCH";
params->spoolsUrl = spoolsUrl;
@ -223,7 +223,7 @@ uint8_t updateSpoolTagId(String uidString, const char* payload) {
NULL // Task-Handle (nicht benötigt)
);
return 1;
return true;
}
uint8_t updateSpoolWeight(String spoolId, uint16_t weight) {
@ -279,7 +279,11 @@ bool checkSpoolmanExtraFields() {
"price_meter",
"price_gramm",
"bambu_setting_id",
"bambu_idx"
"bambu_cali_id",
"bambu_idx",
"bambu_k",
"bambu_flow_ratio",
"bambu_max_volspeed"
};
String spoolExtraFields[] = {
@ -309,9 +313,27 @@ bool checkSpoolmanExtraFields() {
"\"field_type\": \"text\","
"\"key\": \"bambu_setting_id\"}",
"{\"name\": \"Bambu IDX\","
"{\"name\": \"Bambu Cali ID\","
"\"field_type\": \"text\","
"\"key\": \"bambu_idx\"}"
"\"key\": \"bambu_cali_id\"}",
"{\"name\": \"Bambu Filament IDX\","
"\"field_type\": \"text\","
"\"key\": \"bambu_idx\"}",
"{\"name\": \"Bambu k\","
"\"field_type\": \"float\","
"\"key\": \"bambu_k\"}",
"{\"name\": \"Bambu Flow Ratio\","
"\"field_type\": \"float\","
"\"key\": \"bambu_flow_ratio\"}",
"{\"name\": \"Bambu Max Vol. Speed\","
"\"unit\": \"mm3/s\","
"\"field_type\": \"integer\","
"\"default_value\": \"12\","
"\"key\": \"bambu_max_volspeed\"}"
};
Serial.println("Überprüfe Extrafelder...");
@ -374,8 +396,10 @@ bool checkSpoolmanExtraFields() {
Serial.println("Fehler beim Senden der Anfrage: " + String(http.errorToString(httpCode)));
return false;
}
http.end();
//http.end();
}
yield();
vTaskDelay(100 / portTICK_PERIOD_MS);
}
}
}

View File

@ -17,7 +17,7 @@ bool checkSpoolmanExtraFields(); // Neue Funktion zum Überprüfen der Extrafeld
JsonDocument fetchSpoolsForWebsite(); // API-Funktion für die Webseite
JsonDocument fetchAllSpoolsInfo();
void sendAmsData(AsyncWebSocketClient *client); // Neue Funktion zum Senden von AMS-Daten
uint8_t updateSpoolTagId(String uidString, const char* payload); // Neue Funktion zum Aktualisieren eines Spools
bool updateSpoolTagId(String uidString, const char* payload); // Neue Funktion zum Aktualisieren eines Spools
uint8_t updateSpoolWeight(String spoolId, uint16_t weight); // Neue Funktion zum Aktualisieren des Gewichts
bool initSpoolman(); // Neue Funktion zum Initialisieren von Spoolman

View File

@ -137,43 +137,8 @@ bool sendMqttMessage(String payload) {
}
bool setBambuSpool(String payload) {
/* payload
//// set Spool
{
"print": {
"sequence_id": 0,
"command": "ams_filament_setting",
"ams_id": 0, // AMS ID 0-3 oder externe Spule 255
"tray_id": 0, // Tray ID 0-3 oder externe Spule 254
"tray_color": "000000FF",
"nozzle_temp_min": 170,
"nozzle_temp_max": 200,
"tray_type": "PETG",
"setting_id": "",
"tray_info_idx": "GFG99"
}
}
//// Remove Spool
{
"print":{
"ams_id":255,
"command":"ams_filament_setting",
"nozzle_temp_max": 0,
"nozzle_temp_min": 0,
"sequence_id": 0,
"setting_id": "",
"tray_color": "FFFFFFFF",
"tray_id": 254,
"tray_info_idx": "",
"tray_type": "",
}
}
*/
Serial.println("Setting spool");
Serial.println("Spool settings in");
Serial.println(payload);
// Parse the JSON
JsonDocument doc;
@ -192,25 +157,29 @@ bool setBambuSpool(String payload) {
int maxTemp = doc["nozzle_temp_max"];
String type = doc["type"].as<String>();
String brand = doc["brand"].as<String>();
String tray_info_idx = findFilamentIdx(brand, type);
String tray_info_idx = (doc["tray_info_idx"].as<String>() != "-1") ? doc["tray_info_idx"].as<String>() : "";
if (tray_info_idx == "") tray_info_idx = (brand != "" && type != "") ? findFilamentIdx(brand, type) : "";
String setting_id = doc["bambu_setting_id"].as<String>();
String cali_idx = doc["cali_idx"].as<String>();
doc.clear();
doc["print"]["sequence_id"] = 0;
doc["print"]["command"] = "ams_filament_setting";
doc["print"]["ams_id"] = amsId < 200 ? amsId-1 : 255;
doc["print"]["tray_id"] = trayId < 200 ? trayId-1 : 254;
doc["print"]["ams_id"] = amsId < 200 ? amsId : 255;
doc["print"]["tray_id"] = trayId < 200 ? trayId : 254;
doc["print"]["tray_color"] = color.length() == 8 ? color : color+"FF";
doc["print"]["nozzle_temp_min"] = minTemp;
doc["print"]["nozzle_temp_max"] = maxTemp;
doc["print"]["tray_type"] = type;
doc["print"]["setting_id"] = "";
doc["print"]["cali_idx"] = (cali_idx != "") ? cali_idx : "";
doc["print"]["tray_info_idx"] = tray_info_idx;
doc["print"]["setting_id"] = setting_id;
// Serialize the JSON
String output;
serializeJson(doc, output);
if (sendMqttMessage(output)) {
Serial.println("Spool successfully set");
}
@ -220,6 +189,67 @@ bool setBambuSpool(String payload) {
return false;
}
doc.clear();
yield();
if (cali_idx != "") {
yield();
doc["print"]["sequence_id"] = 0;
doc["print"]["command"] = "extrusion_cali_sel";
doc["print"]["filament_id"] = tray_info_idx;
doc["print"]["nozzle_diameter"] = "0.4";
doc["print"]["cali_idx"] = cali_idx.toInt();
doc["print"]["tray_id"] = trayId < 200 ? trayId : 254;
doc["print"]["ams_id"] = amsId < 200 ? amsId : 255;
// Serialize the JSON
String output;
serializeJson(doc, output);
if (sendMqttMessage(output)) {
Serial.println("Extrusion calibration successfully set");
}
else
{
Serial.println("Failed to set extrusion calibration");
return false;
}
doc.clear();
yield();
}
/*
if (setting_id != "") {
yield();
doc["print"]["sequence_id"] = 0;
doc["print"]["command"] = "ams_filament_setting";
doc["print"]["nozzle_temp_min"] = minTemp;
doc["print"]["nozzle_temp_max"] = maxTemp;
doc["print"]["setting_id"] = setting_id;
doc["print"]["tray_color"] = color.length() == 8 ? color : color+"FF";
doc["print"]["ams_id"] = amsId < 200 ? amsId : 255;
doc["print"]["tray_id"] = trayId < 200 ? trayId : 254;
doc["print"]["tray_info_idx"] = tray_info_idx;
doc["print"]["tray_type"] = type;
// Serialize the JSON
String output;
serializeJson(doc, output);
if (sendMqttMessage(output)) {
Serial.println("Filament Setting successfully set");
}
else
{
Serial.println("Failed to set Filament setting");
return false;
}
doc.clear();
yield();
}
*/
return true;
}
@ -276,7 +306,8 @@ void mqtt_callback(char* topic, byte* payload, unsigned int length) {
JsonObject trayObj = trayArray[j];
if (trayObj["tray_info_idx"].as<String>() != ams_data[storedIndex].trays[j].tray_info_idx ||
trayObj["tray_type"].as<String>() != ams_data[storedIndex].trays[j].tray_type ||
trayObj["tray_color"].as<String>() != ams_data[storedIndex].trays[j].tray_color) {
trayObj["tray_color"].as<String>() != ams_data[storedIndex].trays[j].tray_color ||
trayObj["cali_idx"].as<String>() != ams_data[storedIndex].trays[j].cali_idx) {
hasChanges = true;
break;
}
@ -293,7 +324,8 @@ void mqtt_callback(char* topic, byte* payload, unsigned int length) {
foundExternal = true;
if (vtTray["tray_info_idx"].as<String>() != ams_data[i].trays[0].tray_info_idx ||
vtTray["tray_type"].as<String>() != ams_data[i].trays[0].tray_type ||
vtTray["tray_color"].as<String>() != ams_data[i].trays[0].tray_color) {
vtTray["tray_color"].as<String>() != ams_data[i].trays[0].tray_color ||
vtTray["cali_idx"].as<String>() != ams_data[i].trays[0].cali_idx) {
hasChanges = true;
}
break;
@ -307,7 +339,6 @@ void mqtt_callback(char* topic, byte* payload, unsigned int length) {
// Fortfahren mit der bestehenden Verarbeitung, da Änderungen gefunden wurden
ams_count = amsArray.size();
// Restlicher bestehender Code...
for (int i = 0; i < ams_count && i < 16; i++) {
JsonObject amsObj = amsArray[i];
JsonArray trayArray = amsObj["tray"].as<JsonArray>();
@ -324,25 +355,7 @@ void mqtt_callback(char* topic, byte* payload, unsigned int length) {
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].setting_id = trayObj["setting_id"].as<String>();
}
}
//Serial.println("----------------");
//Serial.println();
// Sende die aktualisierten AMS-Daten an alle WebSocket-Clients
sendAmsData(nullptr);
// Verarbeite erst die normalen AMS-Daten
for (int i = 0; i < amsArray.size() && i < 16; i++) {
JsonObject amsObj = amsArray[i];
JsonArray trayArray = amsObj["tray"].as<JsonArray>();
ams_data[i].ams_id = amsObj["id"].as<uint8_t>();
for (int j = 0; j < trayArray.size() && j < 4; j++) {
JsonObject trayObj = trayArray[j];
ams_data[i].trays[j].id = trayObj["id"].as<uint8_t>();
ams_data[i].trays[j].tray_info_idx = trayObj["tray_info_idx"].as<String>();
// ... weitere Tray-Daten ...
ams_data[i].trays[j].cali_idx = trayObj["cali_idx"].as<String>();
}
}
@ -362,11 +375,12 @@ void mqtt_callback(char* topic, byte* payload, unsigned int length) {
ams_data[extIdx].trays[0].nozzle_temp_min = vtTray["nozzle_temp_min"].as<int>();
ams_data[extIdx].trays[0].nozzle_temp_max = vtTray["nozzle_temp_max"].as<int>();
ams_data[extIdx].trays[0].setting_id = vtTray["setting_id"].as<String>();
ams_data[extIdx].trays[0].cali_idx = vtTray["cali_idx"].as<String>();
ams_count++; // Erhöhe ams_count für die externe Spule
}
// Sende die aktualisierten AMS-Daten
sendAmsData(nullptr);
//sendAmsData(nullptr);
// Erstelle JSON für WebSocket-Clients
JsonDocument wsDoc;
@ -389,18 +403,68 @@ void mqtt_callback(char* topic, byte* payload, unsigned int length) {
trayObj["nozzle_temp_min"] = ams_data[i].trays[j].nozzle_temp_min;
trayObj["nozzle_temp_max"] = ams_data[i].trays[j].nozzle_temp_max;
trayObj["setting_id"] = ams_data[i].trays[j].setting_id;
trayObj["cali_idx"] = ams_data[i].trays[j].cali_idx;
}
}
serializeJson(wsArray, amsJsonData);
sendAmsData(nullptr);
}
// Neue Bedingung für ams_filament_setting
else if (doc["print"]["command"] == "ams_filament_setting") {
int amsId = doc["print"]["ams_id"].as<int>();
int trayId = doc["print"]["tray_id"].as<int>();
String settingId = doc["print"]["setting_id"].as<String>();
// Finde das entsprechende AMS und Tray
for (int i = 0; i < ams_count; i++) {
if (ams_data[i].ams_id == amsId) {
// Update setting_id im entsprechenden Tray
ams_data[i].trays[trayId].setting_id = settingId;
// Erstelle neues JSON für WebSocket-Clients
JsonDocument wsDoc;
JsonArray wsArray = wsDoc.to<JsonArray>();
for (int j = 0; j < ams_count; j++) {
JsonObject amsObj = wsArray.createNestedObject();
amsObj["ams_id"] = ams_data[j].ams_id;
JsonArray trays = amsObj.createNestedArray("tray");
int maxTrays = (ams_data[j].ams_id == 255) ? 1 : 4;
for (int k = 0; k < maxTrays; k++) {
JsonObject trayObj = trays.createNestedObject();
trayObj["id"] = ams_data[j].trays[k].id;
trayObj["tray_info_idx"] = ams_data[j].trays[k].tray_info_idx;
trayObj["tray_type"] = ams_data[j].trays[k].tray_type;
trayObj["tray_sub_brands"] = ams_data[j].trays[k].tray_sub_brands;
trayObj["tray_color"] = ams_data[j].trays[k].tray_color;
trayObj["nozzle_temp_min"] = ams_data[j].trays[k].nozzle_temp_min;
trayObj["nozzle_temp_max"] = ams_data[j].trays[k].nozzle_temp_max;
trayObj["setting_id"] = ams_data[j].trays[k].setting_id;
trayObj["cali_idx"] = ams_data[j].trays[k].cali_idx;
}
}
// Aktualisiere das globale amsJsonData
amsJsonData = "";
serializeJson(wsArray, amsJsonData);
// Sende an WebSocket Clients
sendAmsData(nullptr);
break;
}
}
}
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
bambu_connected = false;
oledShowTopRow();
// Attempt to connect
if (client.connect(bambu_serialnr, bambu_username, bambu_accesscode)) {
@ -416,7 +480,8 @@ void reconnect() {
bambu_connected = false;
oledShowTopRow();
// Wait 5 seconds before retrying
delay(5000);
yield();
vTaskDelay(5000 / portTICK_PERIOD_MS);
}
}
}
@ -434,6 +499,8 @@ void mqtt_loop(void * parameter) {
vTaskDelay(100);
}
client.loop();
yield();
vTaskDelay(100);
}
}
@ -466,28 +533,28 @@ bool setupMqtt() {
//client.subscribe(request_topic.c_str());
Serial.println("MQTT-Client initialisiert");
oledShowTopRow();
oledShowMessage("Bambu Connected");
bambu_connected = true;
oledShowTopRow();
xTaskCreatePinnedToCore(
mqtt_loop, /* Function to implement the task */
"BambuMqtt", /* Name of the task */
10000, /* Stack size in words */
NULL, /* Task input parameter */
mqttTaskPrio, /* Priority of the task */
&BambuMqttTask, /* Task handle. */
mqttTaskCore); /* Core where the task should run */
}
else
{
Serial.println("Fehler: Konnte sich nicht beim MQTT-Server anmelden");
oledShowMessage("Bambu Connection Failed");
oledShowTopRow();
vTaskDelay(2000 / portTICK_PERIOD_MS);
connected = false;
oledShowTopRow();
}
xTaskCreatePinnedToCore(
mqtt_loop, /* Function to implement the task */
"BambuMqtt", /* Name of the task */
10000, /* Stack size in words */
NULL, /* Task input parameter */
mqttTaskPrio, /* Priority of the task */
&BambuMqttTask, /* Task handle. */
mqttTaskCore); /* Core where the task should run */
if (!connected) return false;
}
else
@ -499,4 +566,11 @@ bool setupMqtt() {
return false;
}
return true;
}
void bambu_restart() {
if (BambuMqttTask) {
vTaskDelete(BambuMqttTask);
}
setupMqtt();
}

View File

@ -13,6 +13,7 @@ struct TrayData {
int nozzle_temp_min;
int nozzle_temp_max;
String setting_id;
String cali_idx;
};
#define MAX_AMS 17 // 16 normale AMS + 1 externe Spule
@ -33,5 +34,7 @@ bool saveBambuCredentials(const String& bambu_ip, const String& bambu_serialnr,
bool setupMqtt();
void mqtt_loop(void * parameter);
bool setBambuSpool(String payload);
void bambu_restart();
extern TaskHandle_t BambuMqttTask;
#endif

View File

@ -1,10 +1,10 @@
#include <Arduino.h>
#include <WiFi.h>
#include <DNSServer.h>
#include <WiFiManager.h>
#include <ESPmDNS.h>
#include <Wire.h>
#include <WiFi.h>
#include "wlan.h"
#include "config.h"
#include "website.h"
#include "api.h"
@ -15,12 +15,6 @@
#include "esp_task_wdt.h"
#include "commonFS.h"
// ***** WIFI initialisieren
WiFiManager wm;
bool wm_nonblocking = false;
void initWiFi();
// ################### Functions
// ##### SETUP #####
void setup() {
Serial.begin(115200);
@ -74,6 +68,10 @@ void setup() {
unsigned long lastWeightReadTime = 0;
const unsigned long weightReadInterval = 1000; // 1 second
unsigned long lastAmsSendTime = 0;
const unsigned long amsSendInterval = 60000; // 1 minute
uint8_t weightSend = 0;
int16_t lastWeight = 0;
uint8_t wifiErrorCounter = 0;
@ -92,8 +90,11 @@ void loop() {
unsigned long currentMillis = millis();
// Falls WifiManager im nicht blockenden Modus ist
//if(wm_nonblocking) wm.process();
// Send AMS Data min every Minute
if (currentMillis - lastAmsSendTime >= amsSendInterval) {
lastAmsSendTime = currentMillis;
sendAmsData(nullptr);
}
// Ausgabe der Waage auf Display
if (pauseMainTask == 0 && weight != lastWeight && hasReadRfidTag == 0)
@ -127,6 +128,7 @@ void loop() {
weightSend = 0;
}
}
// reset weight counter after writing tag
if (currentMillis - lastWeightReadTime >= weightReadInterval && hasReadRfidTag > 1)
{
@ -136,7 +138,7 @@ void loop() {
lastWeight = weight;
// Wenn ein Tag mit SM id erkannte wurde und der Waage Counter anspricht an SM Senden
if (spoolId != "" && weigthCouterToApi > 5 && weightSend == 0 && hasReadRfidTag == 1) {
if (spoolId != "" && weigthCouterToApi > 3 && weightSend == 0 && hasReadRfidTag == 1) {
oledShowIcon("loading");
if (updateSpoolWeight(spoolId, weight))
{
@ -154,38 +156,3 @@ void loop() {
yield();
esp_task_wdt_reset();
}
// ##### Funktionen für Konfiguration #####
void initWiFi() {
WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP
if(wm_nonblocking) wm.setConfigPortalBlocking(false);
wm.setConfigPortalTimeout(320); // Portal nach 5min schließen
oledShowTopRow();
oledShowMessage("WiFi Setup");
bool res;
// res = wm.autoConnect(); // auto generated AP name from chipid
res = wm.autoConnect("FilaMan"); // anonymous ap
// res = wm.autoConnect("spoolman","password"); // password protected ap
if(!res) {
Serial.println("Failed to connect or hit timeout");
// ESP.restart();
oledShowTopRow();
oledShowMessage("WiFi not connected Check Portal");
}
else {
wifiOn = true;
//if you get here you have connected to the WiFi
Serial.println("connected...yeey :)");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
oledShowTopRow();
display.display();
}
}
// ##### Funktionen für Konfiguration Ende #####

View File

@ -6,6 +6,7 @@
#include "website.h"
#include "api.h"
#include "esp_task_wdt.h"
#include "scale.h"
//Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS);
Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);
@ -93,14 +94,6 @@ bool formatNdefTag() {
}
uint8_t ntag2xx_WriteNDEF(const char *payload) {
/*
if (!formatNdefTag()) {
Serial.println("Fehler beim Formatieren des NDEF-Tags.");
hasReadRfidTag = 2;
return 0;
}
*/
uint8_t tagSize = 240; // 144 bytes is maximum for NTAG213
Serial.print("Tag Size: ");Serial.println(tagSize);
@ -137,9 +130,6 @@ uint8_t ntag2xx_WriteNDEF(const char *payload) {
return 0;
}
//Serial.println();
//Serial.print("Header Size: ");Serial.println(sizeof(pageHeader));
// Kombiniere Header und Payload
int totalSize = sizeof(pageHeader) + len;
uint8_t* combinedData = (uint8_t*) malloc(totalSize);
@ -149,37 +139,10 @@ uint8_t ntag2xx_WriteNDEF(const char *payload) {
return 0;
}
// Überprüfe die Kombination von Header und Payload
/*
Serial.print("Header: ");
for (int i = 0; i < sizeof(pageHeader); i++) {
Serial.print(pageHeader[i], HEX);
Serial.print(" ");
}
Serial.println();
Serial.print("Payload: ");
for (int i = 0; i < len; i++) {
Serial.print(payload[i], HEX);
Serial.print(" ");
}
Serial.println();
*/
// Kombiniere Header und Payload
memcpy(combinedData, pageHeader, sizeof(pageHeader));
memcpy(&combinedData[sizeof(pageHeader)], payload, len);
// Überprüfe die Kombination von Header und Payload
/*
Serial.print("Kombinierte Daten: ");
for (int i = 0; i < totalSize; i++) {
Serial.print(combinedData[i], HEX);
Serial.print(" ");
}
Serial.println();
*/
// Schreibe die Seiten
uint8_t a = 0;
uint8_t i = 0;
@ -188,21 +151,9 @@ uint8_t ntag2xx_WriteNDEF(const char *payload) {
int bytesToWrite = (totalSize < 4) ? totalSize : 4;
memcpy(pageBuffer, combinedData + a, bytesToWrite);
// Überprüfe die Schreibung der Seiten
/*
Serial.print("Seite ");
Serial.print(i);
Serial.print(": ");
for (int j = 0; j < bytesToWrite; j++) {
Serial.print(pageBuffer[j], HEX);
Serial.print(" ");
}
Serial.println();
*/
uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID
uint8_t uidLength;
nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength, 500);
//Serial.print("Schreibe Seite: ");Serial.println(i);
//uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID
//uint8_t uidLength;
//nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength, 100);
if (!(nfc.ntag2xx_WritePage(4+i, pageBuffer)))
{
@ -210,8 +161,6 @@ uint8_t ntag2xx_WriteNDEF(const char *payload) {
free(combinedData);
return 0;
}
//Serial.print("Seite geschrieben: ");Serial.println(i);
yield();
//esp_task_wdt_reset();
@ -285,11 +234,15 @@ void writeJsonToTag(void *parameter) {
// Gib die erstellte NDEF-Message aus
Serial.println("Erstelle NDEF-Message...");
Serial.println(payload);
hasReadRfidTag = 3;
vTaskSuspend(RfidReaderTask);
vTaskDelay(500 / portTICK_PERIOD_MS);
//pauseBambuMqttTask = true;
// aktualisieren der Website wenn sich der Status ändert
sendNfcData(nullptr);
oledShowMessage("Waiting for NFC-Tag");
// Wait 10sec for tag
uint8_t success = 0;
@ -326,13 +279,23 @@ void writeJsonToTag(void *parameter) {
Serial.println("NDEF-Message erfolgreich auf den Tag geschrieben");
//oledShowMessage("NFC-Tag written");
oledShowIcon("success");
vTaskDelay(2000 / portTICK_PERIOD_MS);
vTaskDelay(1000 / portTICK_PERIOD_MS);
hasReadRfidTag = 5;
// aktualisieren der Website wenn sich der Status ändert
sendNfcData(nullptr);
vTaskResume(RfidReaderTask);
pauseBambuMqttTask = false;
updateSpoolTagId(uidString, payload);
if (updateSpoolTagId(uidString, payload)) {
uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID
uint8_t uidLength;
oledShowIcon("success");
while (nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength, 500)) {
yield();
}
}
vTaskResume(RfidReaderTask);
vTaskDelay(500 / portTICK_PERIOD_MS);
}
else
{
@ -361,16 +324,19 @@ void writeJsonToTag(void *parameter) {
void startWriteJsonToTag(const char* payload) {
char* payloadCopy = strdup(payload);
// Erstelle die Task
xTaskCreate(
writeJsonToTag, // Task-Funktion
"WriteJsonToTagTask", // Task-Name
4096, // Stackgröße in Bytes
(void*)payloadCopy, // Parameter
rfidWriteTaskPrio, // Priorität
NULL // Task-Handle (nicht benötigt)
);
// Task nicht mehrfach starten
if (hasReadRfidTag != 3) {
// Erstelle die Task
xTaskCreate(
writeJsonToTag, // Task-Funktion
"WriteJsonToTagTask", // Task-Name
4096, // Stackgröße in Bytes
(void*)payloadCopy, // Parameter
rfidWriteTaskPrio, // Priorität
NULL // Task-Handle (nicht benötigt)
);
}
}
void scanRfidTask(void * parameter) {
@ -397,7 +363,7 @@ void scanRfidTask(void * parameter) {
hasReadRfidTag = 6;
oledShowIcon("transfer");
vTaskDelay(1000 / portTICK_PERIOD_MS);
vTaskDelay(500 / portTICK_PERIOD_MS);
if (uidLength == 7)
{

77
src/ota.cpp Normal file
View File

@ -0,0 +1,77 @@
#include <Arduino.h>
#include "ota.h"
#include <Update.h>
#include <SPIFFS.h>
#include "commonFS.h"
#include "bambu.h"
#include "scale.h"
#include "nfc.h"
static bool tasksAreStopped = false;
void stopAllTasks() {
Serial.println("Stopping RFID Reader");
if (RfidReaderTask) vTaskSuspend(RfidReaderTask);
Serial.println("Stopping Bambu");
if (BambuMqttTask) vTaskSuspend(BambuMqttTask);
Serial.println("Stopping Scale");
if (ScaleTask) vTaskSuspend(ScaleTask);
vTaskDelay(100 / portTICK_PERIOD_MS);
Serial.println("All tasks stopped");
}
void handleOTAUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final) {
if (!index) {
bool isFullImage = filename.endsWith("full.bin");
Serial.printf("Update Start: %s (type: %s)\n", filename.c_str(), isFullImage ? "full" : "OTA");
if (request->contentLength() == 0) {
request->send(400, "application/json", "{\"status\":\"error\",\"message\":\"Invalid file size\"}");
return;
}
if (!tasksAreStopped && (RfidReaderTask || BambuMqttTask || ScaleTask)) {
stopAllTasks();
tasksAreStopped = true;
}
bool success;
if (isFullImage) {
// Full image update ohne Magic Byte Check, aber mit U_FLASH
success = Update.begin(UPDATE_SIZE_UNKNOWN, U_FLASH);
} else {
// Normales OTA update mit Magic Byte Check
if (data[0] != 0xE9) {
Serial.printf("Wrong magic byte: 0x%02X (expected 0xE9)\n", data[0]);
request->send(400, "application/json", "{\"status\":\"error\",\"message\":\"Invalid firmware format\"}");
return;
}
success = Update.begin(request->contentLength());
}
if (!success) {
Update.printError(Serial);
request->send(400, "application/json", "{\"status\":\"error\",\"message\":\"Update start failed\"}");
return;
}
}
if (Update.write(data, len) != len) {
Update.printError(Serial);
request->send(400, "application/json", "{\"status\":\"error\",\"message\":\"Write failed\"}");
return;
}
if (final) {
if (!Update.end(true)) {
Update.printError(Serial);
request->send(400, "application/json", "{\"status\":\"error\",\"message\":\"Update failed\"}");
return;
}
Serial.println("Update successful, restarting...");
request->send(200, "application/json", "{\"status\":\"success\",\"message\":\"Update successful! Device will restart...\",\"restart\":true}");
delay(500);
ESP.restart();
}
}

14
src/ota.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef OTA_H
#define OTA_H
#include <ESPAsyncWebServer.h>
// Update size unknown constant, falls nicht bereits definiert
#ifndef UPDATE_SIZE_UNKNOWN
#define UPDATE_SIZE_UNKNOWN 0xFFFFFFFF
#endif
void stopAllTasks();
void handleOTAUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final);
#endif

View File

@ -5,7 +5,6 @@
#include "HX711.h"
#include <EEPROM.h>
#include "display.h"
#include "nfc.h"
#include "esp_task_wdt.h"
HX711 scale;

View File

@ -15,4 +15,6 @@ extern uint8_t weigthCouterToApi;
extern uint8_t scale_tare_counter;
extern uint8_t pauseMainTask;
extern TaskHandle_t ScaleTask;
#endif

View File

@ -3,11 +3,11 @@
#include "api.h"
#include <ArduinoJson.h>
#include <ESPAsyncWebServer.h>
//#include <AsyncWebSocket.h>
#include "bambu.h"
#include "nfc.h"
#include "scale.h"
#include "esp_task_wdt.h"
#include "ota.h"
// Cache-Control Header definieren
#define CACHE_CONTROL "max-age=31536000" // Cache für 1 Jahr
@ -69,6 +69,16 @@ void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventTyp
}
}
else if (doc["type"] == "reconnect") {
if (doc["payload"] == "bambu") {
bambu_restart();
}
if (doc["payload"] == "spoolman") {
initSpoolman();
}
}
else if (doc["type"] == "setBambuSpool") {
Serial.println(doc["payload"].as<String>());
setBambuSpool(doc["payload"]);
@ -82,24 +92,16 @@ void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventTyp
// Funktion zum Laden und Ersetzen des Headers in einer HTML-Datei
String loadHtmlWithHeader(const char* filename) {
if (!SPIFFS.exists(filename) || !SPIFFS.exists("/header.html")) {
Serial.println("Lade HTML-Datei: " + String(filename));
if (!SPIFFS.exists(filename)) {
Serial.println("Fehler: Datei nicht gefunden!");
return "Fehler: Datei nicht gefunden!";
}
// Lade den Header
File headerFile = SPIFFS.open("/header.html", "r");
String header = headerFile.readString();
headerFile.close();
// Lade die Hauptdatei
File file = SPIFFS.open(filename, "r");
String html = file.readString();
file.close();
// Ersetze den Platzhalter mit dem Header
html.replace("{{header}}", header);
return html;
}
@ -159,25 +161,31 @@ void setupWebserver(AsyncWebServer &server) {
Serial.print("Geladene Spoolman-URL: ");
Serial.println(spoolmanUrl);
// Route für die Startseite
// Route für about
server.on("/about", HTTP_GET, [](AsyncWebServerRequest *request){
Serial.println("Anfrage für / erhalten");
String html = loadHtmlWithHeader("/index.html");
request->send(200, "text/html", html);
Serial.println("Anfrage für /about erhalten");
AsyncWebServerResponse *response = request->beginResponse(SPIFFS, "/index.html.gz", "text/html");
response->addHeader("Content-Encoding", "gzip");
response->addHeader("Cache-Control", CACHE_CONTROL);
request->send(response);
});
// Route für Waage
server.on("/waage", HTTP_GET, [](AsyncWebServerRequest *request){
Serial.println("Anfrage für /waage erhalten");
String html = loadHtmlWithHeader("/waage.html");
request->send(200, "text/html", html);
AsyncWebServerResponse *response = request->beginResponse(SPIFFS, "/waage.html.gz", "text/html");
response->addHeader("Content-Encoding", "gzip");
response->addHeader("Cache-Control", CACHE_CONTROL);
request->send(response);
});
// Route für RFID
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
Serial.println("Anfrage für /rfid erhalten");
String html = loadHtmlWithHeader("/rfid.html");
request->send(200, "text/html", html);
AsyncWebServerResponse *response = request->beginResponse(SPIFFS, "/rfid.html.gz", "text/html");
response->addHeader("Content-Encoding", "gzip");
response->addHeader("Cache-Control", CACHE_CONTROL);
request->send(response);
Serial.println("RFID-Seite gesendet");
});
@ -201,8 +209,10 @@ void setupWebserver(AsyncWebServer &server) {
// Route für WiFi
server.on("/wifi", HTTP_GET, [](AsyncWebServerRequest *request){
Serial.println("Anfrage für /wifi erhalten");
String html = loadHtmlWithHeader("/wifi.html");
request->send(200, "text/html", html);
AsyncWebServerResponse *response = request->beginResponse(SPIFFS, "/wifi.html.gz", "text/html");
response->addHeader("Content-Encoding", "gzip");
response->addHeader("Cache-Control", CACHE_CONTROL);
request->send(response);
});
// Route für Spoolman Setting
@ -283,15 +293,6 @@ void setupWebserver(AsyncWebServer &server) {
Serial.println("style.css gesendet");
});
server.on("/style2.css", HTTP_GET, [](AsyncWebServerRequest *request){
Serial.println("Lade style2.css");
AsyncWebServerResponse *response = request->beginResponse(SPIFFS, "/style2.css.gz", "text/css");
response->addHeader("Content-Encoding", "gzip");
response->addHeader("Cache-Control", CACHE_CONTROL);
request->send(response);
Serial.println("style2.css gesendet");
});
// Route für das Logo
server.on("/logo.png", HTTP_GET, [](AsyncWebServerRequest *request){
AsyncWebServerResponse *response = request->beginResponse(SPIFFS, "/logo.png.gz", "image/png");
@ -336,7 +337,32 @@ void setupWebserver(AsyncWebServer &server) {
request->send(response);
Serial.println("RFID.js gesendet");
});
// Route for Firmware Update
server.on("/upgrade", HTTP_GET, [](AsyncWebServerRequest *request) {
// During OTA, reduce memory usage
ws.enable(false); // Temporarily disable WebSocket
ws.cleanupClients();
Serial.println("Request for /upgrade received");
AsyncWebServerResponse *response = request->beginResponse(SPIFFS, "/upgrade.html.gz", "text/html");
response->addHeader("Content-Encoding", "gzip");
response->addHeader("Cache-Control", CACHE_CONTROL);
request->send(response);
});
server.on("/update", HTTP_POST,
[](AsyncWebServerRequest *request) {
// The response will be sent from handleOTAUpload when the upload is complete
},
[](AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final) {
// Free memory before handling update
ws.enable(false);
ws.cleanupClients();
handleOTAUpload(request, filename, index, data, len, final);
}
);
// Fehlerbehandlung für nicht gefundene Seiten
server.onNotFound([](AsyncWebServerRequest *request){
Serial.print("404 - Nicht gefunden: ");

45
src/wlan.cpp Normal file
View File

@ -0,0 +1,45 @@
#include <Arduino.h>
#include "wlan.h"
#include <WiFi.h>
#include <esp_wifi.h>
#include <WiFiManager.h>
#include "display.h"
#include "config.h"
WiFiManager wm;
bool wm_nonblocking = false;
void initWiFi() {
WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP
//esp_wifi_set_max_tx_power(72); // Setze maximale Sendeleistung auf 20dBm
if(wm_nonblocking) wm.setConfigPortalBlocking(false);
wm.setConfigPortalTimeout(320); // Portal nach 5min schließen
oledShowTopRow();
oledShowMessage("WiFi Setup");
bool res;
// res = wm.autoConnect(); // auto generated AP name from chipid
res = wm.autoConnect("FilaMan"); // anonymous ap
// res = wm.autoConnect("spoolman","password"); // password protected ap
if(!res) {
Serial.println("Failed to connect or hit timeout");
// ESP.restart();
oledShowTopRow();
oledShowMessage("WiFi not connected Check Portal");
}
else {
wifiOn = true;
//if you get here you have connected to the WiFi
Serial.println("connected...yeey :)");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
oledShowTopRow();
display.display();
}
}

8
src/wlan.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef WLAN_H
#define WLAN_H
#include <Arduino.h>
void initWiFi();
#endif