diff --git a/apps/rules/rule_interface.py b/apps/rules/rule_interface.py index 47c4482..f47aa74 100644 --- a/apps/rules/rule_interface.py +++ b/apps/rules/rule_interface.py @@ -246,6 +246,23 @@ class RedisState: await self._execute_with_retry(_expire, key, ttl_secs) + async def delete(self, key: str) -> None: + """ + Delete a key from Redis. + + Args: + key: Redis key to delete + + Example: + >>> state = RedisState("redis://localhost:6379/0") + >>> await state.set("rules:r1:temp", "22.5") + >>> await state.delete("rules:r1:temp") + """ + async def _delete(client, k): + await client.delete(k) + + await self._execute_with_retry(_delete, key) + async def close(self) -> None: """ Close Redis connection and cleanup resources. diff --git a/apps/ui/templates/dashboard.html b/apps/ui/templates/dashboard.html index 6c9280a..b6cbfc9 100644 --- a/apps/ui/templates/dashboard.html +++ b/apps/ui/templates/dashboard.html @@ -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 @@ -