Skip to content

Fix optimistic fan state for consecutive AC setting updates - #118

Open
esolm wants to merge 2 commits into
banter240:mainfrom
esolm:main
Open

Fix optimistic fan state for consecutive AC setting updates#118
esolm wants to merge 2 commits into
banter240:mainfrom
esolm:main

Conversation

@esolm

@esolm esolm commented Aug 2, 2026

Copy link
Copy Markdown

What does this PR do?

Fixes an issue where consecutive AC setting changes (e.g. changing fan speed and then vertical swing) could reuse a stale cached fan state before Home Assistant had received the updated state from Tado.

This PR extends the optimistic state handling to fan_speed and fan_level, making it consistent with the existing optimistic handling for swing settings. As a result, consecutive commands use the latest user-requested values instead of outdated cached values.

Related Issue

Fixes #

Type of Change

  • Bug fix
  • New feature
  • Refactor / cleanup
  • Documentation
  • CI / tooling

Affected Generation(s)

  • V2 - GW Bridge
  • V3 Classic (HomeKit)
  • Tado X (Matter)
  • All / not generation-specific

Testing

Tested on a real air conditioner:

Steps:

  1. Set fan speed to Auto.
  2. Immediately change the vertical swing setting.
  3. Before this fix, the second command reused the previous cached fan speed (e.g. 3) because the state had not yet been refreshed.
  4. After this fix, the optimistic fan state is reused, so the fan remains in Auto while the swing setting changes correctly.

Repeated the test multiple times without reproducing the original issue.

Checklist

  • Pre-commit passes (ruff, mypy, hassfest, HACS)
  • No debug logging left in
  • Tested on real hardware

esolm added 2 commits August 3, 2026 00:00
Add Optimistic for fan_speed and fan_level
Implement fan_level and fan_speed correction
@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@sourcery-ai

sourcery-ai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Reviewer's Guide

Extends optimistic state handling for Tado V3 AC controls so that fan_speed and fan_level use the latest user-requested values between consecutive commands, consistent with swing settings, by threading fan-related optimistic values through the action provider and optimistic manager.

Sequence diagram for optimistic fan state across consecutive AC setting updates

sequenceDiagram
    actor User
    participant ActionProvider
    participant OptimisticManager

    User->>ActionProvider: async_set_ac_setting(zone_id, fan_speed, AUTO)
    ActionProvider->>OptimisticManager: apply_zone_state(zone_id, overlay=True, fan_speed=AUTO)
    OptimisticManager->>OptimisticManager: set_optimistic(zone, zone_id, fan_speed)

    User->>ActionProvider: async_set_ac_setting(zone_id, vertical_swing, HIGH)
    ActionProvider->>OptimisticManager: get_optimistic(zone, zone_id, fan_speed)
    OptimisticManager-->>ActionProvider: AUTO
    ActionProvider->>ActionProvider: _build_ac_fan_settings(..., fan_speed=AUTO)
    ActionProvider->>OptimisticManager: apply_zone_state(zone_id, overlay=True, vertical_swing=HIGH)
Loading

File-Level Changes

Change Details Files
Extend AC fan settings builder to prefer optimistic fan_speed when no direct fan change is requested.
  • Added zone_id parameter to the AC fan settings builder to allow lookup of zone-scoped optimistic fan state.
  • Changed fan_speed selection to fall back to optimistic fan_speed for the zone before using the cached state value.
  • Updated async_set_ac_setting to pass zone_id through to the fan settings builder.
custom_components/tado_hijack/helpers/tadov3/action_provider.py
Propagate optimistic fan_speed and fan_level into the zone optimistic state manager.
  • Extended apply_zone_state signature to accept fan_speed and fan_level arguments.
  • Stored optimistic fan_speed and fan_level for a zone when provided, using the same grace-period handling as existing swing fields.
  • Updated async_set_ac_setting to pass fan_speed and fan_level into apply_zone_state when those keys are being changed.
custom_components/tado_hijack/helpers/tadov3/action_provider.py
custom_components/tado_hijack/helpers/optimistic_manager.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • The nested ternary plus get_optimistic(... ) or getattr(...) inside _build_ac_fan_settings is a bit hard to read; consider splitting it into explicit conditional branches to make the fan speed selection logic clearer.
  • You've added optimistic tracking for fan_level in apply_zone_state, but only fan_speed is consulted in _build_ac_fan_settings; consider wiring fan_level into the command-building path as well so its optimistic state is actually used.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The nested ternary plus `get_optimistic(... ) or getattr(...)` inside `_build_ac_fan_settings` is a bit hard to read; consider splitting it into explicit conditional branches to make the fan speed selection logic clearer.
- You've added optimistic tracking for `fan_level` in `apply_zone_state`, but only `fan_speed` is consulted in `_build_ac_fan_settings`; consider wiring `fan_level` into the command-building path as well so its optimistic state is actually used.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant