Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
178 changes: 178 additions & 0 deletions SCENARIO_MODES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
# Szenario-Modi für ComfoClime Climate Entity

## Übersicht

Die ComfoClime Integration unterstützt jetzt Szenario-Modi als Preset-Optionen in der Climate Entity. Diese Modi ermöglichen zeitlich begrenzte Betriebsmodi für spezielle Situationen.

## Verfügbare Szenario-Modi

| Szenario | Preset Name | Wert | Standard-Dauer | Beschreibung |
| ----------- | ----------- | ---- | -------------------- | ---------------------------------------- |
| 🍳 Kochen | `cooking` | 4 | 30 Minuten | Hohe Lüftung für Kochaktivitäten |
| 🎉 Party | `party` | 5 | 30 Minuten | Hohe Lüftung für Gäste |
| 🏖️ Urlaub | `away` | 7 | 24 Stunden (1440min) | Reduzierter Betrieb während Abwesenheit |
| ⚡ Boost | `boost` | 8 | 30 Minuten | Maximale Leistung |

## Verwendung

### Via Home Assistant UI

1. Öffne die Climate Entity (z.B. `climate.comfoclime`)
2. Wähle einen Szenario-Modus aus dem Preset-Dropdown
3. Der Modus wird mit der Standard-Dauer aktiviert

### Via Service Call

#### Methode 1: Standard Climate Service (Standard-Dauer)

```yaml
service: climate.set_preset_mode
target:
entity_id: climate.comfoclime
data:
preset_mode: cooking
```

#### Methode 2: Custom Service (mit benutzerdefinierter Dauer)

```yaml
service: comfoclime.set_scenario_mode
data:
entity_id: climate.comfoclime
scenario: cooking
duration: 60 # Dauer in Minuten, z.B. 60 für 1 Stunde
```



## Restzeit-Anzeige

Die verbleibende Zeit des aktiven Szenarios wird als Attribut der Climate Entity angezeigt:

```yaml
# Attribute der Climate Entity:
scenario_time_left: 1798 # in Sekunden
scenario_time_left_formatted: "29m 58s" # lesbares Format
```

### Template Sensor für Restzeit

```yaml
template:
- sensor:
- name: "ComfoClime Szenario Restzeit"
state: >
{{ state_attr('climate.comfoclime', 'scenario_time_left_formatted') | default('Kein aktives Szenario') }}
icon: mdi:timer-outline
```

## Dashboard-Integration

### Beispiel Lovelace Card

```yaml
type: entities
title: ComfoClime Steuerung
entities:
- entity: climate.comfoclime
type: climate
- type: attribute
entity: climate.comfoclime
attribute: scenario_time_left_formatted
name: Szenario Restzeit
icon: mdi:timer-outline
```

### Button Card für schnellen Zugriff

```yaml
type: horizontal-stack
cards:
- type: button
name: Kochen
icon: mdi:pot-steam
tap_action:
action: call-service
service: climate.set_preset_mode
service_data:
entity_id: climate.comfoclime
preset_mode: cooking
- type: button
name: Party
icon: mdi:party-popper
tap_action:
action: call-service
service: climate.set_preset_mode
service_data:
entity_id: climate.comfoclime
preset_mode: party
- type: button
name: Urlaub
icon: mdi:beach
tap_action:
action: call-service
service: climate.set_preset_mode
service_data:
entity_id: climate.comfoclime
preset_mode: away
- type: button
name: Boost
icon: mdi:rocket-launch
tap_action:
action: call-service
service: climate.set_preset_mode
service_data:
entity_id: climate.comfoclime
preset_mode: boost
```

## API Details

### Dashboard API Parameter

Beim Aktivieren eines Szenarios werden folgende Parameter an die Dashboard API gesendet:

```python
{
"scenario": 4, # Szenario-Wert (4, 5, 7, oder 8)
"scenarioTimeLeft": 1800, # Dauer (API-Parameter in Sekunden; wird im Code aus Minuten * 60 berechnet, Benutzer geben die Dauer in Minuten an)
"timestamp": "YYYY-MM-DDTHH:MM:SSZ"
}
```

### Standard-Dauern (in Code definiert)

```python
SCENARIO_DEFAULT_DURATIONS = {
4: 30, # Kochen: 30 Minuten
5: 30, # Party: 30 Minuten
7: 1440, # Urlaub: 24 Stunden
8: 30, # Boost: 30 Minuten
}
```

## Hinweise

- ⏱️ Die Restzeit wird automatisch vom Gerät heruntergezählt
- 🔄 Ein aktives Szenario kann jederzeit durch ein anderes Preset überschrieben werden
- 🛑 Um ein Szenario vorzeitig zu beenden, wähle ein anderes Preset (z.B. "Komfort")
- 📊 Die Restzeit wird über die Dashboard API abgerufen und alle 30 Sekunden aktualisiert

## Troubleshooting

### Szenario wird nicht aktiviert

1. Prüfe die Logs: `Settings -> System -> Logs -> Custom Component: comfoclime`
2. Stelle sicher, dass die Climate Entity verfügbar ist
3. Überprüfe die Netzwerkverbindung zum ComfoClime-Gerät

### Restzeit wird nicht angezeigt

Die Restzeit wird als Attribut der Climate Entity bereitgestellt. Stelle sicher, dass:

- Die Dashboard-Daten erfolgreich abgerufen werden
- Der Coordinator läuft (Update-Intervall: 30 Sekunden)

### Benutzerdefinierte Dauer funktioniert nicht

Verwende den `comfoclime.set_scenario_mode` Service statt `climate.set_preset_mode` für benutzerdefinierte Dauern.
81 changes: 81 additions & 0 deletions custom_components/comfoclime/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,89 @@ async def handle_reset_system_service(call: ServiceCall):
_LOGGER.error(f"Fehler beim Neustart des Geräts: {e}")
raise HomeAssistantError(f"Fehler beim Neustart des Geräts: {e}")

async def handle_set_scenario_mode_service(call: ServiceCall):
"""Handle set_scenario_mode service call.

This service activates special operating modes (scenarios) on the ComfoClime
climate entity with optional custom duration.

Supported scenarios:
- cooking: High ventilation for cooking (default: 30 min)
- party: High ventilation for parties (default: 30 min)
- away: Reduced mode for vacation (default: 24 hours)
- scenario_boost: Maximum power boost (default: 30 min)
"""
entity_id = call.data["entity_id"]
scenario = call.data["scenario"]
duration = call.data.get("duration")
start_delay = call.data.get("start_delay")

# Validate scenario parameter
from .climate import SCENARIO_REVERSE_MAPPING

valid_scenarios = list(SCENARIO_REVERSE_MAPPING.keys())
if scenario not in valid_scenarios:
raise HomeAssistantError(
f"Invalid scenario '{scenario}'. Must be one of: {', '.join(valid_scenarios)}"
)

# Validate duration if provided
if duration is not None:
if not isinstance(duration, (int, float)) or duration <= 0:
raise HomeAssistantError(
f"Duration must be a positive number, got: {duration}"
)

# Validate start_delay format if provided
if start_delay is not None:
if not isinstance(start_delay, str):
raise HomeAssistantError(
f"start_delay must be a datetime string (e.g. 'YYYY-MM-DD HH:MM:SS'), got: {type(start_delay).__name__}"
)

_LOGGER.debug(
f"Service call: set_scenario_mode for {entity_id}, "
f"scenario={scenario}, duration={duration}, start_delay={start_delay}"
)

# Get climate entity from component
# Access the entity via the state machine's entities
component = hass.data.get("entity_components", {}).get("climate")
if component:
climate_entity = component.get_entity(entity_id)

if climate_entity and hasattr(climate_entity, "async_set_scenario_mode"):
try:
await climate_entity.async_set_scenario_mode(
scenario_mode=scenario,
duration=duration,
start_delay=start_delay,
)
except Exception as e:
_LOGGER.exception(
f"Error setting scenario mode '{scenario}' on {entity_id}"
)
raise HomeAssistantError(
f"Failed to set scenario mode '{scenario}'"
) from e
else:
_LOGGER.info(
f"Scenario mode '{scenario}' activated for {entity_id} "
f"with duration {duration} and start_delay {start_delay}"
)
return

# Entity not found or doesn't support scenarios
raise HomeAssistantError(
f"Climate entity '{entity_id}' not found or does not support scenario modes. "
f"Make sure the entity exists and belongs to the ComfoClime integration."
)

hass.services.async_register(DOMAIN, "set_property", handle_set_property_service)
hass.services.async_register(DOMAIN, "reset_system", handle_reset_system_service)
hass.services.async_register(
DOMAIN, "set_scenario_mode", handle_set_scenario_mode_service
)
return True


Expand Down
Loading