1010from .const import *
1111from .entry_data import PidConfig , SatConfig
1212from .heating_curve import HeatingCurve
13- from .helpers import float_value , timestamp as _timestamp , clamp_to_range
13+ from .helpers import float_value , clamp_to_range
1414from .temperature .state import TemperatureState
1515from .types import HeatingSystem
1616
1717_LOGGER = logging .getLogger (__name__ )
18- timestamp = _timestamp # keep public name for tests
1918
2019DERIVATIVE_ALPHA1 = 0.8
2120DERIVATIVE_ALPHA2 = 0.6
2221DERIVATIVE_RAW_CAP = 5.0
2322
23+ PID_UPDATE_INTERVAL = 60
24+
2425STORAGE_VERSION = 1
2526STORAGE_KEY_INTEGRAL = "integral"
2627STORAGE_KEY_LAST_ERROR = "last_error"
2728STORAGE_KEY_RAW_DERIVATIVE = "raw_derivative"
2829STORAGE_KEY_LAST_TEMPERATURE = "last_temperature"
29- STORAGE_KEY_LAST_INTEGRAL_UPDATED = "last_integral_updated"
3030STORAGE_KEY_LAST_DERIVATIVE_UPDATED = "last_derivative_updated"
3131
3232
@@ -40,7 +40,6 @@ def __init__(self, heating_system: HeatingSystem, heating_curve: HeatingCurve, c
4040
4141 self ._integral : float = 0.0
4242 self ._last_error : Optional [float ] = None
43- self ._last_integral_updated : Optional [float ] = None
4443
4544 self ._raw_derivative : float = 0.0
4645 self ._last_temperature : Optional [float ] = None
@@ -139,7 +138,6 @@ def reset(self) -> None:
139138 """Reset the PID controller to a clean state."""
140139 self ._integral = 0.0
141140 self ._last_error = None
142- self ._last_integral_updated = None
143141
144142 async def async_added_to_hass (self , hass : HomeAssistant , entity_id : str , device_id : str ) -> None :
145143 """Restore PID controller state from storage when the integration loads."""
@@ -155,7 +153,6 @@ async def async_added_to_hass(self, hass: HomeAssistant, entity_id: str, device_
155153 self ._last_derivative_updated = float_value (data .get (STORAGE_KEY_LAST_DERIVATIVE_UPDATED ))
156154
157155 self ._integral = float (data .get (STORAGE_KEY_INTEGRAL , self ._integral ))
158- self ._last_integral_updated = float_value (data .get (STORAGE_KEY_LAST_INTEGRAL_UPDATED ))
159156 self ._raw_derivative = float (data .get (STORAGE_KEY_RAW_DERIVATIVE , self ._raw_derivative ))
160157
161158 _LOGGER .debug ("Loaded PID state from storage for entity=%s" , self ._entity_id )
@@ -188,35 +185,13 @@ def _update_integral(self, state: TemperatureState) -> None:
188185 """Update the integral value in the PID controller."""
189186 if abs (state .error ) > DEADBAND :
190187 self ._integral = 0.0
191- self ._last_integral_updated = None
192- return
193-
194- if self ._last_integral_updated is None :
195- self ._last_integral_updated = state .last_changed .timestamp ()
196- return
197-
198- delta_time = state .last_changed .timestamp () - self ._last_integral_updated
199-
200- # Ignore non-forward timestamps.
201- if delta_time <= 0 :
202- self ._last_integral_updated = state .last_changed .timestamp ()
203188 return
204189
205- # Skip integration when integral gain is disabled.
206- if self .ki is None :
207- return
208-
209- self ._integral += self .ki * state .error * delta_time
190+ self ._integral += self .ki * state .error * PID_UPDATE_INTERVAL
210191 self ._integral = clamp_to_range (self ._integral , self ._heating_curve .value )
211192
212- # Record the timestamp used for this integration step.
213- self ._last_integral_updated = state .last_changed .timestamp ()
214-
215193 def _update_derivative (self , state : TemperatureState ) -> None :
216194 """Update the derivative term of the PID controller based on temperature slope."""
217- if self .kd is None :
218- return
219-
220195 if self ._last_temperature is None or self ._last_derivative_updated is None :
221196 self ._last_temperature = state .current
222197 self ._last_derivative_updated = state .last_changed .timestamp ()
@@ -228,6 +203,7 @@ def _update_derivative(self, state: TemperatureState) -> None:
228203 return
229204
230205 temperature_delta = state .current - self ._last_temperature
206+
231207 if temperature_delta == 0.0 :
232208 self ._last_temperature = state .current
233209 self ._last_derivative_updated = state .last_changed .timestamp ()
@@ -265,7 +241,6 @@ async def _async_save_state(self) -> None:
265241 STORAGE_KEY_LAST_ERROR : self ._last_error ,
266242 STORAGE_KEY_RAW_DERIVATIVE : self ._raw_derivative ,
267243 STORAGE_KEY_LAST_TEMPERATURE : self ._last_temperature ,
268- STORAGE_KEY_LAST_INTEGRAL_UPDATED : self ._last_integral_updated ,
269244 STORAGE_KEY_LAST_DERIVATIVE_UPDATED : self ._last_derivative_updated ,
270245 }
271246
0 commit comments