dynamic dashboard initial
This commit is contained in:
111
apps/ui/templates/dashboard.html
Normal file
111
apps/ui/templates/dashboard.html
Normal file
@@ -0,0 +1,111 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Home Automation Dashboard</title>
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<header>
|
||||
<h1>🏠 Home Automation</h1>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
{% if rooms %}
|
||||
{% for room in rooms %}
|
||||
<section class="room">
|
||||
<h2 class="room-title">{{ room.name }}</h2>
|
||||
|
||||
<div class="devices-grid">
|
||||
{% for device in room.devices %}
|
||||
<div class="device-tile" data-device-id="{{ device.device_id }}">
|
||||
<div class="device-header">
|
||||
<div class="device-icon">{{ device.icon }}</div>
|
||||
<div class="device-info">
|
||||
<h3 class="device-title">{{ device.title }}</h3>
|
||||
<p class="device-id">{{ device.device_id }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="device-state">
|
||||
<span id="state-{{ device.device_id }}" class="state-text">—</span>
|
||||
</div>
|
||||
|
||||
{% if device.type == "light" and device.features.power %}
|
||||
<div class="device-controls">
|
||||
<button class="btn btn-on" onclick="setDeviceState('{{ device.device_id }}', 'on')">
|
||||
AN
|
||||
</button>
|
||||
<button class="btn btn-off" onclick="setDeviceState('{{ device.device_id }}', 'off')">
|
||||
AUS
|
||||
</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</section>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<div class="empty-state">
|
||||
<p>Keine Räume oder Geräte konfiguriert.</p>
|
||||
<p class="hint">Prüfe config/layout.yaml und das API-Gateway.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<p>Home Automation System v0.1.0</p>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Set device state via API
|
||||
async function setDeviceState(deviceId, power) {
|
||||
const stateSpan = document.getElementById(`state-${deviceId}`);
|
||||
|
||||
try {
|
||||
stateSpan.textContent = `⏳ ${power}...`;
|
||||
|
||||
const response = await fetch(`http://localhost:8001/devices/${deviceId}/set`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
type: 'light',
|
||||
payload: {
|
||||
power: power
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
console.log('Device state set:', deviceId, power, result);
|
||||
|
||||
stateSpan.textContent = `✓ ${power}`;
|
||||
|
||||
// Reset to "—" after 2 seconds
|
||||
setTimeout(() => {
|
||||
stateSpan.textContent = '—';
|
||||
}, 2000);
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error setting device state:', error);
|
||||
stateSpan.textContent = `✗ Error`;
|
||||
|
||||
// Reset after 3 seconds
|
||||
setTimeout(() => {
|
||||
stateSpan.textContent = '—';
|
||||
}, 3000);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user