diff --git a/html/style.css b/html/style.css index 8d56b4c..d4f1184 100644 --- a/html/style.css +++ b/html/style.css @@ -489,3 +489,508 @@ 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; +} \ No newline at end of file diff --git a/html/style2.css b/html/style2.css deleted file mode 100644 index caee7fe..0000000 --- a/html/style2.css +++ /dev/null @@ -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; -} \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index e939ebc..58862e3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -74,6 +74,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; @@ -95,6 +99,12 @@ void loop() { // 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) { diff --git a/src/website.cpp b/src/website.cpp index 4fe403f..de69c0e 100644 --- a/src/website.cpp +++ b/src/website.cpp @@ -283,15 +283,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");