Title: Enhanced Data Management and Job Queue System Integration

🎉 New Feature: Integrated advanced data management capabilities with improved job queue system for seamless workflow.

📚 The updated data management module now offers robust features such as data validation, normalization, and efficient storage using optimized database queries. This ensures accurate and consistent data handling across the application.

💄 Additionally, the job queue system has been upgraded to handle complex tasks more efficiently, reducing latency and improving overall
This commit is contained in:
2025-06-16 00:58:43 +02:00
parent 81cd0e8feb
commit 124953049b
193 changed files with 2145 additions and 101 deletions

View File

@@ -50,6 +50,9 @@
-webkit-backdrop-filter: blur(12px);
border: 1px solid var(--glass-border);
box-shadow: 0 8px 32px var(--shadow-color);
border-radius: 20px;
padding: 0.75rem 1.5rem;
margin: 0.5rem;
}
/* Raspberry Pi Performance Optimization */
@@ -77,7 +80,7 @@
/* Main content offset for sticky navbar */
.main-offset {
padding-top: 4rem;
padding-top: 3rem;
}
/* Smooth transitions */
@@ -174,24 +177,24 @@
<!-- Fixed Navbar with Glassmorphism -->
<nav class="navbar-sticky glass">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex items-center justify-between h-16">
<div class="flex items-center justify-between h-12">
<!-- Logo & Brand -->
<div class="flex items-center">
<!-- Mobile Menu Button -->
<button id="mobile-menu-btn" class="lg:hidden p-2 rounded-lg hover:bg-white/10 dark:hover:bg-black/10">
<button id="mobile-menu-btn" class="lg:hidden p-1.5 rounded-lg hover:bg-white/10 dark:hover:bg-black/10">
<i class="fas fa-bars text-lg"></i>
</button>
<!-- Logo -->
<a href="{{ url_for('dashboard') if current_user.is_authenticated else url_for('index') }}"
class="flex items-center space-x-3 ml-2 lg:ml-0 hover-lift">
<div class="w-10 h-10 bg-white dark:bg-slate-800 rounded-xl shadow-lg p-2">
<div class="w-8 h-8 bg-white dark:bg-slate-800 rounded-lg shadow-lg p-1.5">
<svg class="w-full h-full text-slate-900 dark:text-white" fill="currentColor" viewBox="0 0 80 80">
<path d="M58.6,4.5C53,1.6,46.7,0,40,0c-6.7,0-13,1.6-18.6,4.5v0C8.7,11.2,0,24.6,0,40c0,15.4,8.7,28.8,21.5,35.5C27,78.3,33.3,80,40,80c6.7,0,12.9-1.7,18.5-4.6C71.3,68.8,80,55.4,80,40C80,24.6,71.3,11.2,58.6,4.5z M4,40c0-13.1,7-24.5,17.5-30.9v0C26.6,6,32.5,4.2,39,4l-4.5,32.7L21.5,46.8v0L8.3,57.1C5.6,52,4,46.2,4,40z M58.6,70.8C53.1,74.1,46.8,76,40,76c-6.8,0-13.2-1.9-18.6-5.2c-4.9-2.9-8.9-6.9-11.9-11.7l11.9-4.9v0L40,46.6l18.6,7.5v0l12,4.9C67.6,63.9,63.4,67.9,58.6,70.8z M58.6,46.8L58.6,46.8l-12.9-10L41.1,4c6.3,0.2,12.3,2,17.4,5.1v0C69,15.4,76,26.9,76,40c0,6.2-1.5,12-4.3,17.1L58.6,46.8z"/>
</svg>
</div>
<div class="hidden sm:block">
<div class="text-lg font-bold">MYP</div>
<div class="text-base font-bold">MYP</div>
<div class="text-xs text-slate-600 dark:text-slate-400">Mercedes-Benz</div>
</div>
</a>
@@ -203,56 +206,51 @@
<a href="{{ url_for('dashboard') }}"
class="nav-item flex items-center px-4 py-2 rounded-lg text-sm font-medium hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route == 'dashboard' else '' }}">
class="nav-item flex items-center px-3 py-1.5 rounded-lg text-sm font-medium hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route == 'dashboard' else '' }}">
<i class="fas fa-tachometer-alt mr-2"></i>
<span>Dashboard</span>
</a>
<a href="{{ url_for('printers_page') }}"
class="nav-item flex items-center px-4 py-2 rounded-lg text-sm font-medium hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route == 'printers_page' else '' }}">
class="nav-item flex items-center px-3 py-1.5 rounded-lg text-sm font-medium hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route == 'printers_page' else '' }}">
<i class="fas fa-print mr-2"></i>
<span>Drucker</span>
</a>
<a href="{{ url_for('jobs_page') }}"
class="nav-item flex items-center px-4 py-2 rounded-lg text-sm font-medium hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route == 'jobs_page' else '' }}">
class="nav-item flex items-center px-3 py-1.5 rounded-lg text-sm font-medium hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route == 'jobs_page' else '' }}">
<i class="fas fa-tasks mr-2"></i>
<span>Aufträge</span>
</a>
<a href="{{ url_for('calendar.calendar_view') }}"
class="nav-item flex items-center px-4 py-2 rounded-lg text-sm font-medium hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route == 'calendar.calendar_view' else '' }}">
class="nav-item flex items-center px-3 py-1.5 rounded-lg text-sm font-medium hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route == 'calendar.calendar_view' else '' }}">
<i class="fas fa-calendar mr-2"></i>
<span>Kalender</span>
</a>
<a href="{{ url_for('energy.energy_dashboard') }}"
class="nav-item flex items-center px-4 py-2 rounded-lg text-sm font-medium hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route == 'energy.energy_dashboard' else '' }}">
class="nav-item flex items-center px-3 py-1.5 rounded-lg text-sm font-medium hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route == 'energy.energy_dashboard' else '' }}">
<i class="fas fa-bolt mr-2"></i>
<span>Energie</span>
</a>
<a href="{{ url_for('stats_page') }}"
class="nav-item flex items-center px-4 py-2 rounded-lg text-sm font-medium hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route == 'stats_page' else '' }}">
class="nav-item flex items-center px-3 py-1.5 rounded-lg text-sm font-medium hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route == 'stats_page' else '' }}">
<i class="fas fa-chart-bar mr-2"></i>
<span>Statistiken</span>
</a>
<a href="{{ url_for('tapo.tapo_dashboard') }}"
class="nav-item flex items-center px-4 py-2 rounded-lg text-sm font-medium hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route and 'tapo' in current_route else '' }}">
<i class="fas fa-plug mr-2"></i>
<span>Smart Plugs</span>
</a>
<a href="{{ url_for('guest.guest_request_form') }}"
class="nav-item flex items-center px-4 py-2 rounded-lg text-sm font-medium hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route and 'guest' in current_route else '' }}">
class="nav-item flex items-center px-3 py-1.5 rounded-lg text-sm font-medium hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route and 'guest' in current_route else '' }}">
<i class="fas fa-user-plus mr-2"></i>
<span>Gast</span>
</a>
{% if current_user.is_admin %}
<a href="{{ url_for('admin.admin_dashboard') }}"
class="nav-item flex items-center px-4 py-2 rounded-lg text-sm font-medium hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route and 'admin' in current_route else '' }}">
class="nav-item flex items-center px-3 py-1.5 rounded-lg text-sm font-medium hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route and 'admin' in current_route else '' }}">
<i class="fas fa-cog mr-2"></i>
<span>Admin</span>
</a>
@@ -265,7 +263,7 @@
{% if current_user.is_authenticated %}
<!-- Notifications -->
<div class="relative">
<button id="notificationToggle" class="p-2 rounded-lg hover:bg-white/10 dark:hover:bg-black/10 relative">
<button id="notificationToggle" class="p-1.5 rounded-lg hover:bg-white/10 dark:hover:bg-black/10 relative">
<i class="fas fa-bell"></i>
<span id="notificationBadge" class="absolute top-1 right-1 w-2 h-2 bg-red-500 rounded-full hidden"></span>
</button>
@@ -292,7 +290,7 @@
<!-- Dark Mode Toggle -->
<button id="darkModeToggle"
class="p-2 rounded-lg hover:bg-white/10 dark:hover:bg-black/10">
class="p-1.5 rounded-lg hover:bg-white/10 dark:hover:bg-black/10">
<i class="fas fa-sun sun-icon"></i>
<i class="fas fa-moon moon-icon hidden"></i>
</button>
@@ -301,8 +299,8 @@
{% if current_user.is_authenticated %}
<div class="relative">
<button id="user-menu-btn"
class="flex items-center space-x-2 p-2 rounded-lg hover:bg-white/10 dark:hover:bg-black/10">
<div class="w-8 h-8 bg-gradient-to-br from-blue-500 to-purple-600 rounded-full flex items-center justify-center text-white text-sm font-bold">
class="flex items-center space-x-2 p-1.5 rounded-lg hover:bg-white/10 dark:hover:bg-black/10">
<div class="w-6 h-6 bg-gradient-to-br from-blue-500 to-purple-600 rounded-full flex items-center justify-center text-white text-xs font-bold">
{{ current_user.email[0].upper() if current_user.email else 'U' }}
</div>
<i class="fas fa-chevron-down text-xs"></i>
@@ -410,11 +408,6 @@
Statistiken
</a>
<a href="{{ url_for('tapo.tapo_dashboard') }}"
class="flex items-center px-3 py-2 rounded-lg hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route and 'tapo' in current_route else '' }}">
<i class="fas fa-plug w-5 mr-3"></i>
Smart Plugs
</a>
<a href="{{ url_for('guest.guest_request_form') }}"
class="flex items-center px-3 py-2 rounded-lg hover:bg-white/10 dark:hover:bg-black/10 {{ 'nav-active' if current_route and 'guest' in current_route else '' }}">

View File

@@ -5,22 +5,14 @@
<style>
/* Energiemonitoring Dashboard Styles */
.energy-card {
background: linear-gradient(135deg, rgba(255,255,255,0.9) 0%, rgba(255,255,255,0.8) 100%);
border: 1px solid rgba(255,255,255,0.2);
border-radius: 16px;
backdrop-filter: blur(20px);
box-shadow: 0 8px 32px rgba(0,0,0,0.1);
@apply glass card;
transition: all 0.3s ease;
}
.dark .energy-card {
background: linear-gradient(135deg, rgba(51,65,85,0.9) 0%, rgba(51,65,85,0.8) 100%);
border: 1px solid rgba(71,85,105,0.3);
}
.energy-card:hover {
transform: translateY(-4px);
box-shadow: 0 12px 40px rgba(0,0,0,0.15);
transform: translateY(-2px);
box-shadow: var(--shadow-xl);
}
.energy-metric {
@@ -69,42 +61,40 @@
{% endblock %}
{% block content %}
<div class="min-h-screen bg-gradient-to-br from-blue-50 via-indigo-50 to-purple-50 dark:from-slate-900 dark:via-slate-900 dark:to-slate-800">
<div class="main-offset min-h-screen">
<!-- Header Section -->
<div class="bg-gradient-to-r from-blue-600 via-purple-600 to-indigo-600 text-white">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
<div class="glass mb-8">
<div class="max-w-7xl mx-auto">
<div class="flex items-center justify-between">
<div>
<h1 class="text-4xl font-bold tracking-tight">🔋 Energiemonitoring</h1>
<p class="mt-2 text-xl text-blue-100">
<h1 class="text-3xl font-bold text-primary mb-2">🔋 Energiemonitoring</h1>
<p class="text-secondary">
Überwachen Sie den Energieverbrauch Ihrer 3D-Drucker in Echtzeit
</p>
</div>
<div class="flex items-center space-x-4">
<button id="refreshData" class="bg-white/20 hover:bg-white/30 px-4 py-2 rounded-xl backdrop-blur-sm transition-all duration-300">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/>
</svg>
<button id="refreshData" class="btn btn-primary">
<i class="fas fa-sync-alt mr-2"></i>
Aktualisieren
</button>
<button id="exportData" class="bg-white/20 hover:bg-white/30 px-4 py-2 rounded-xl backdrop-blur-sm transition-all duration-300">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
</svg>
<button id="exportData" class="btn">
<i class="fas fa-download mr-2"></i>
Export
</button>
</div>
</div>
</div>
</div>
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 -mt-8 relative z-10">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<!-- KPI Cards -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
<!-- Gesamtverbrauch -->
<div class="energy-card p-6">
<div class="energy-card">
<div class="flex items-center justify-between mb-4">
<div class="p-3 bg-gradient-to-br from-blue-500 to-blue-600 rounded-xl">
<div class="p-3 bg-gradient-to-br from-blue-500 to-blue-600 rounded-2xl shadow-lg">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"/>
</svg>
@@ -121,9 +111,9 @@
</div>
<!-- Online Geräte -->
<div class="energy-card p-6">
<div class="energy-card">
<div class="flex items-center justify-between mb-4">
<div class="p-3 bg-gradient-to-br from-green-500 to-green-600 rounded-xl">
<div class="p-3 bg-gradient-to-br from-green-500 to-green-600 rounded-2xl shadow-lg">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
@@ -139,9 +129,9 @@
</div>
<!-- Heute Verbrauch -->
<div class="energy-card p-6">
<div class="energy-card">
<div class="flex items-center justify-between mb-4">
<div class="p-3 bg-gradient-to-br from-purple-500 to-purple-600 rounded-xl">
<div class="p-3 bg-gradient-to-br from-purple-500 to-purple-600 rounded-2xl shadow-lg">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
@@ -157,9 +147,9 @@
</div>
<!-- Monatsverbrauch -->
<div class="energy-card p-6">
<div class="energy-card">
<div class="flex items-center justify-between mb-4">
<div class="p-3 bg-gradient-to-br from-orange-500 to-orange-600 rounded-xl">
<div class="p-3 bg-gradient-to-br from-orange-500 to-orange-600 rounded-2xl shadow-lg">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"/>
</svg>
@@ -181,7 +171,7 @@
<div class="energy-card p-6">
<div class="flex items-center justify-between mb-6">
<h3 class="text-xl font-semibold text-slate-900 dark:text-white">📈 Verbrauchstrend</h3>
<select id="periodSelector" class="px-3 py-2 bg-white dark:bg-slate-700 border border-slate-300 dark:border-slate-600 rounded-lg text-sm">
<select id="periodSelector" class="px-3 py-2 bg-white dark:bg-slate-700 border border-slate-300 dark:border-slate-600 rounded-2xl text-sm shadow-lg transition-all duration-300 hover:shadow-xl">
<option value="today">Heute (24h)</option>
<option value="week">Diese Woche</option>
<option value="month">Dieser Monat</option>
@@ -194,10 +184,10 @@
</div>
<!-- Geräteverbrauch Chart -->
<div class="energy-card p-6">
<div class="energy-card">
<div class="flex items-center justify-between mb-6">
<h3 class="text-xl font-semibold text-slate-900 dark:text-white">🔌 Geräteverbrauch</h3>
<div class="text-sm text-slate-500 dark:text-slate-400">Live-Verbrauch</div>
<h3 class="text-xl font-semibold text-primary">🔌 Geräteverbrauch</h3>
<div class="text-sm text-muted">Live-Verbrauch</div>
</div>
<div class="chart-container">
<canvas id="deviceChart"></canvas>
@@ -206,12 +196,12 @@
</div>
<!-- Device List -->
<div class="energy-card p-6 mb-8">
<h3 class="text-xl font-semibold text-slate-900 dark:text-white mb-6">🖨️ Geräteübersicht</h3>
<div class="energy-card mb-8">
<h3 class="text-xl font-semibold text-primary mb-6">🖨️ Geräteübersicht</h3>
<div id="deviceList" class="space-y-4">
<!-- Wird dynamisch gefüllt -->
<div class="flex justify-center items-center py-8">
<div class="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div>
<div class="spinner w-8 h-8"></div>
</div>
</div>
</div>
@@ -220,10 +210,10 @@
</div>
<!-- Loading Overlay -->
<div id="loadingOverlay" class="fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center hidden">
<div class="bg-white dark:bg-slate-800 rounded-xl p-6 flex items-center space-x-4">
<div class="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div>
<span class="text-slate-900 dark:text-white">Lade Energiedaten...</span>
<div id="loadingOverlay" class="modal-overlay hidden">
<div class="glass p-6 flex items-center space-x-4">
<div class="spinner w-8 h-8"></div>
<span class="text-primary">Lade Energiedaten...</span>
</div>
</div>
{% endblock %}
@@ -477,7 +467,7 @@ class EnergyMonitoringDashboard {
if (devices.length === 0) {
container.innerHTML = `
<div class="text-center py-8 text-slate-500 dark:text-slate-400">
<div class="text-center py-8 text-muted">
<svg class="w-12 h-12 mx-auto mb-4 opacity-50" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.172 16.172a4 4 0 015.656 0M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
</svg>
@@ -488,26 +478,28 @@ class EnergyMonitoringDashboard {
}
container.innerHTML = devices.map(device => `
<div class="flex items-center justify-between p-4 bg-white/60 dark:bg-slate-700/60 rounded-xl border border-slate-200 dark:border-slate-600">
<div class="flex items-center space-x-4">
<div class="device-status-indicator ${device.online ? 'device-status-online' : 'device-status-offline'}"></div>
<div>
<h4 class="font-semibold text-slate-900 dark:text-white">${device.name}</h4>
<p class="text-sm text-slate-500 dark:text-slate-400">ID: ${device.id}</p>
<div class="glass-card hover-lift">
<div class="flex items-center justify-between">
<div class="flex items-center space-x-4">
<div class="device-status-indicator ${device.online ? 'device-status-online' : 'device-status-offline'}"></div>
<div>
<h4 class="font-semibold text-primary">${device.name}</h4>
<p class="text-sm text-muted">ID: ${device.id}</p>
</div>
</div>
</div>
<div class="text-right">
<div class="text-xl font-bold text-slate-900 dark:text-white">
${device.power}W
<div class="text-right">
<div class="text-xl font-bold text-primary">
${device.power}W
</div>
<div class="text-sm text-muted">
${device.online ? 'Online' : 'Offline'}
</div>
</div>
<div class="text-sm text-slate-500 dark:text-slate-400">
${device.online ? 'Online' : 'Offline'}
</div>
</div>
<div class="w-16">
<div class="power-gradient"></div>
<div class="text-xs text-center mt-1 text-slate-500 dark:text-slate-400">
${Math.round((device.power / 100) * 100)}%
<div class="w-16">
<div class="power-gradient"></div>
<div class="text-xs text-center mt-1 text-muted">
${Math.round((device.power / 100) * 100)}%
</div>
</div>
</div>
</div>