Skip to content

Drying mode actions bypass Global Cooldown (GCD) entirely #49

Description

@kamos69

Drying mode actions bypass Global Cooldown (GCD) entirely

Summary

All four drying handlers in DryingActions.py (ElClassico, 5DayDry, DewBased, OwnDry) emit device actions directly via event_manager.emit(...), completely bypassing OGBActionManager's cooldown filter and OGBgcdManager. This means a user-configured Global Cooldown (GCD) — e.g. a 30-minute cooldown on the humidifier capability — has no effect at all while tentMode == "Drying", regardless of which drying sub-mode is active.

Reproduction / observed behavior

  • Tent Mode: Drying, Drying Mode: ElClassico
  • Humidifier GCD configured: 30 minutes
  • Actual device log from a live drying cycle, ~8 minutes apart:
19:35:13  ElClassico HUM HIGH - 65.4% > 62.0% → Dehumidify ON
          executing: ['Increase Dehumidifier', 'Reduce Humidifier', 'Increase Exhaust', 'Increase Ventilation']
19:37:23  ElClassico HUM LOW - 59.0% < 62.0% → Humidify ON
          executing: ['Increase Humidifier', 'Reduce Dehumidifier', 'Reduce Exhaust', 'Increase Ventilation']

The humidifier and dehumidifier flip against each other roughly every 1-2 minutes as the reading oscillates around the ±2% tolerance band, with no cooldown throttling the switching — despite a 30-minute GCD being configured for that capability.

Root cause

  • Every drying handler builds a finalActionMap and emits it directly:

    • handle_ElClassicoDryingActions.py:225-226
    • handle_5DayDryDryingActions.py:359-360
    • handle_DewBasedDryingActions.py:486-487
    • handle_OwnDryDryingActions.py:575-576
    for action_name in finalActionMap:
        await self.event_manager.emit(action_name, None)

    This goes straight to each device class's listener (e.g. Humidifier.py's increaseAction/reduceAction, registered via event_manager.on("Increase Humidifier", ...) in __init__). The docstring on every one of these handlers states this explicitly: "Direct event emission - no cooldowns or VPD logic interference."

  • The only place GCD/cooldown enforcement exists is OGBActionManager._process_actions_with_cooldown_filter() (OGBActionManager.py:158-194), which delegates to OGBgcdManager.is_allowed(). That filter is only invoked from the VPD/action-map pipeline (OGBActionManager.py around lines 1153-1156 and 1239-1242), used by VPD Perfection, VPD Target, Closed Environment, and the Premium PID/MPC/AI modes.

  • DryingActions never calls into OGBActionManager, so drying-mode actions never pass through that filter. Device classes themselves (checked Humidifier.py and the base Device.py) have no cooldown check either — the only per-device gate is an unrelated "Smart Deadband" check in reduceAction.

Suggested fix

Route the finalActionMap built in each DryingActions handler through the same cooldown mechanism used by the VPD pipeline (e.g. action_manager.cooldown_manager.is_allowed() / .register()) before emitting, so a configured GCD is respected consistently regardless of tentMode. Given GCD is presented as a global, per-capability safety feature, having it silently no-op for an entire mode is surprising and can cause rapid actuator cycling (as shown above) during an otherwise sensitive process like drying.

Environment

  • OGB installed via HACS on Home Assistant
  • Drying Mode: ElClassico
  • Humidifier GCD: 30 minutes

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingenhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions