Skip to content

Fix DM spiral by preventing offset raises during anti-windup#15

Merged
enoch85 merged 8 commits intomainfrom
fix/dm-spiral-anti-windup-jan2026
Jan 25, 2026
Merged

Fix DM spiral by preventing offset raises during anti-windup#15
enoch85 merged 8 commits intomainfrom
fix/dm-spiral-anti-windup-jan2026

Conversation

@enoch85
Copy link
Copy Markdown
Owner

@enoch85 enoch85 commented Jan 22, 2026

Problem: When DM is dropping while offset is positive, raising offset makes DM drop FASTER (S1 target increases but BT25 actual can't catch up). This caused a death spiral from -747 to -1549 triggering aux heating.

Changes:

  • Anti-windup now PREVENTS offset raises (returns early, not caps after)
  • Active offset REDUCTION when dm_rate < -100/h (1°C per 100/h worse)
  • 30-minute cooldown after anti-windup to let pump stabilize
  • Z1 threshold lowered from 10% to 2% for earlier intervention

Based on debug.log analysis showing spirals from -53/h (mild) to -456/h (severe).

Problem: When DM is dropping while offset is positive, raising offset
makes DM drop FASTER (S1 target increases but BT25 actual can't catch up).
This caused a death spiral from -747 to -1549 triggering aux heating.

Changes:
- Anti-windup now PREVENTS offset raises (returns early, not caps after)
- Active offset REDUCTION when dm_rate < -100/h (1°C per 100/h worse)
- 30-minute cooldown after anti-windup to let pump stabilize
- Z1 threshold lowered from 10% to 2% for earlier intervention

Based on debug.log analysis showing spirals from -53/h (mild) to -456/h (severe).
Only trigger anti-windup if offset was raised within the last 90 minutes.
This distinguishes self-induced spirals from environmental DM drops.

- Add ANTI_WINDUP_CAUSATION_WINDOW_MINUTES constant (90 min)
- Track offset raises with _last_offset_raise_time/_last_offset_value
- Add _track_offset_change() and _raised_offset_recently() methods
- Skip anti-windup if offset has been stable >90 min (likely cold snap)
- Add 8 unit tests for causation window feature
The base_nibe_state fixture was missing current_offset, causing
TypeError when anti-windup tracking tried to compare MagicMock objects.
- Raise anti-windup layer weight from 0.5 to 0.7 to give it more
  influence in the blended decision (was being outvoted by other layers)
- Show dynamic remaining cooldown time instead of static "30min"
@enoch85 enoch85 merged commit d205dff into main Jan 25, 2026
1 check passed
@enoch85 enoch85 deleted the fix/dm-spiral-anti-windup-jan2026 branch January 25, 2026 17:30
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