slider for thermostats

This commit is contained in:
2025-11-17 08:05:58 +01:00
parent 6152385339
commit a4ae8a2f6c
2 changed files with 125 additions and 25 deletions

View File

@@ -365,32 +365,59 @@
color: #999;
}
.temp-controls {
/* Thermostat Slider Styles */
.thermostat-slider-control {
margin: 1rem 0;
}
.thermostat-slider-label {
display: flex;
gap: 0.5rem;
margin-bottom: 1rem;
justify-content: space-between;
align-items: center;
margin-bottom: 0.5rem;
font-size: 0.875rem;
color: #666;
}
.temp-button {
flex: 1;
padding: 0.75rem;
border: none;
border-radius: 8px;
font-size: 1.125rem;
font-weight: 700;
.thermostat-slider {
width: 100%;
height: 8px;
border-radius: 4px;
background: linear-gradient(to right, #667eea 0%, #764ba2 100%);
outline: none;
-webkit-appearance: none;
appearance: none;
cursor: pointer;
transition: all 0.2s;
background: #667eea;
color: white;
min-height: 44px;
}
.temp-button:hover {
background: #5568d3;
.thermostat-slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 24px;
height: 24px;
border-radius: 50%;
background: white;
border: 3px solid #667eea;
cursor: pointer;
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
}
.temp-button:active {
transform: scale(0.95);
.thermostat-slider::-moz-range-thumb {
width: 24px;
height: 24px;
border-radius: 50%;
background: white;
border: 3px solid #667eea;
cursor: pointer;
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
}
.thermostat-slider-range {
display: flex;
justify-content: space-between;
margin-top: 0.25rem;
font-size: 0.75rem;
color: #999;
}
/* Contact Sensor Styles */
@@ -398,6 +425,7 @@
display: flex;
align-items: center;
gap: 0.75rem;
padding: 1rem;
background: #f8f9fa;
border-radius: 8px;
@@ -965,13 +993,23 @@
</div>
</div>
<div class="temp-controls">
<button class="temp-button" onclick="adjustTarget('{{ device.device_id }}', -1.0)">
-1.0
</button>
<button class="temp-button" onclick="adjustTarget('{{ device.device_id }}', 1.0)">
+1.0
</button>
<div class="thermostat-slider-control">
<label class="thermostat-slider-label">
<span>🎯 Zieltemperatur</span>
</label>
<input type="range"
min="5"
max="30"
step="0.5"
value="21.0"
class="thermostat-slider"
id="slider-{{ device.device_id }}"
oninput="updateThermostatDisplay('{{ device.device_id }}', this.value)"
onchange="setThermostatTarget('{{ device.device_id }}', this.value)">
<div class="thermostat-slider-range">
<span>5°C</span>
<span>30°C</span>
</div>
</div>
{% elif device.type == "contact" or device.type == "contact_sensor" %}
@@ -1327,6 +1365,7 @@
function updateThermostatUI(deviceId, current, target, mode) {
const currentSpan = document.getElementById(`state-${deviceId}-current`);
const targetSpan = document.getElementById(`state-${deviceId}-target`);
const slider = document.getElementById(`slider-${deviceId}`);
if (current !== undefined && currentSpan) {
currentSpan.textContent = current.toFixed(1);
@@ -1336,6 +1375,10 @@
if (targetSpan) {
targetSpan.textContent = target.toFixed(1);
}
// Sync slider with actual state
if (slider) {
slider.value = target;
}
thermostatTargets[deviceId] = target;
}
}
@@ -1733,6 +1776,46 @@
}
}
// Update thermostat display while dragging slider
function updateThermostatDisplay(deviceId, value) {
const targetElement = document.getElementById(`state-${deviceId}-target`);
if (targetElement) {
targetElement.textContent = `${parseFloat(value).toFixed(1)}°C`;
}
}
// Set thermostat target temperature when slider is released
async function setThermostatTarget(deviceId, value) {
try {
const targetTemp = parseFloat(value);
const response = await fetch(api(`/devices/${deviceId}/set`), {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
target_temperature: targetTemp
})
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.detail || 'Request failed');
}
console.log(`Thermostat ${deviceId} target set to ${targetTemp}°C`);
addEvent({
action: 'thermostat_set',
device_id: deviceId,
target_temperature: targetTemp
});
} catch (error) {
console.error('Failed to set thermostat target:', error);
showToast(`Fehler beim Setzen der Zieltemperatur: ${error.message}`, 'error');
}
}
// Execute group action
async function setGroup(groupId, power, buttonElement) {
const allButtons = buttonElement.parentElement.querySelectorAll('button');