1313
1414from .helpers import get_domain , get_safe_state
1515from .sun import SunData
16+ from .config_context_adapter import ConfigContextAdapter
1617
1718
1819@dataclass
1920class AdaptiveGeneralCover (ABC ):
2021 """Collect common data."""
2122
2223 hass : HomeAssistant
24+ logger : ConfigContextAdapter
2325 sol_azi : float
2426 sol_elev : float
2527 sunset_pos : int
@@ -88,6 +90,7 @@ def is_sun_in_blind_spot(self) -> bool:
8890 blindspot = (self .gamma <= left_edge ) & (self .gamma >= right_edge )
8991 if self .blind_spot_elevation is not None :
9092 blindspot = blindspot & (self .sol_elev <= self .blind_spot_elevation )
93+ self .logger .debug ("Is sun in blind spot? %s" , blindspot )
9194 return blindspot
9295 return False
9396
@@ -119,7 +122,9 @@ def valid_elevation(self) -> bool:
119122 return self .sol_elev <= self .max_elevation
120123 if self .max_elevation is None :
121124 return self .sol_elev >= self .min_elevation
122- return self .min_elevation <= self .sol_elev <= self .max_elevation
125+ within_range = self .min_elevation <= self .sol_elev <= self .max_elevation
126+ self .logger .debug ("elevation within range? %s" , within_range )
127+ return within_range
123128
124129 @property
125130 def valid (self ) -> bool :
@@ -132,6 +137,7 @@ def valid(self) -> bool:
132137 valid = (
133138 (self .gamma < azi_min ) & (self .gamma > - azi_max ) & (self .valid_elevation )
134139 )
140+ self .logger .debug ("Sun in front of window (ignoring blindspot)? %s" , valid )
135141 return valid
136142
137143 @property
@@ -143,6 +149,9 @@ def sunset_valid(self) -> bool:
143149 before_sunrise = datetime .utcnow () < (
144150 sunrise + timedelta (minutes = self .sunrise_off )
145151 )
152+ self .logger .debug (
153+ "After sunset plus offset? %s" , (after_sunset or before_sunrise )
154+ )
146155 return after_sunset or before_sunrise
147156
148157 @property
@@ -197,11 +206,20 @@ class NormalCoverState:
197206
198207 def get_state (self ) -> int :
199208 """Return state."""
200- state = np . where (
201- self .cover .direct_sun_valid ,
202- self .cover .calculate_percentage (),
203- self . cover . default ,
209+ self . cover . logger . debug ( "Determining normal position" )
210+ dsv = self .cover .direct_sun_valid
211+ self .cover .logger . debug (
212+ "Sun directly in front of window & before sunset + offset? %s" , dsv
204213 )
214+ if dsv :
215+ state = self .cover .calculate_percentage ()
216+ self .cover .logger .debug (
217+ "Yes sun in window: using calculated percentage (%s)" , state
218+ )
219+ else :
220+ state = self .cover .default
221+ self .cover .logger .debug ("No sun in window: using default value (%s)" , state )
222+
205223 result = np .clip (state , 0 , 100 )
206224 if self .cover .apply_max_position and result > self .cover .max_pos :
207225 return self .cover .max_pos
@@ -215,6 +233,7 @@ class ClimateCoverData:
215233 """Fetch additional data."""
216234
217235 hass : HomeAssistant
236+ logger : ConfigContextAdapter
218237 temp_entity : str
219238 temp_low : float
220239 temp_high : float
@@ -289,8 +308,17 @@ def is_presence(self):
289308 def is_winter (self ) -> bool :
290309 """Check if temperature is below threshold."""
291310 if self .temp_low is not None and self .get_current_temperature is not None :
292- return self .get_current_temperature < self .temp_low
293- return False
311+ is_it = self .get_current_temperature < self .temp_low
312+ else :
313+ is_it = False
314+
315+ self .logger .debug (
316+ "is_winter(): current_temperature < temp_low: %s < %s = %s" ,
317+ self .get_current_temperature ,
318+ self .temp_low ,
319+ is_it ,
320+ )
321+ return is_it
294322
295323 @property
296324 def outside_high (self ) -> bool :
@@ -306,8 +334,18 @@ def outside_high(self) -> bool:
306334 def is_summer (self ) -> bool :
307335 """Check if temperature is over threshold."""
308336 if self .temp_high is not None and self .get_current_temperature is not None :
309- return self .get_current_temperature > self .temp_high and self .outside_high
310- return False
337+ is_it = self .get_current_temperature > self .temp_high and self .outside_high
338+ else :
339+ is_it = False
340+
341+ self .logger .debug (
342+ "is_summer(): current_temp > temp_high and outside_high?: %s > %s and %s = %s" ,
343+ self .get_current_temperature ,
344+ self .temp_high ,
345+ self .outside_high ,
346+ is_it ,
347+ )
348+ return is_it
311349
312350 @property
313351 def is_sunny (self ) -> bool :
@@ -316,9 +354,12 @@ def is_sunny(self) -> bool:
316354 if self .weather_entity is not None :
317355 weather_state = get_safe_state (self .hass , self .weather_entity )
318356 else :
357+ self .logger .debug ("is_sunny(): No weather entity defined" )
319358 return True
320359 if self .weather_condition is not None :
321- return weather_state in self .weather_condition
360+ matches = weather_state in self .weather_condition
361+ self .logger .debug ("is_sunny(): Weather: %s = %s" , weather_state , matches )
362+ return matches
322363
323364 @property
324365 def lux (self ) -> bool :
@@ -349,6 +390,9 @@ class ClimateCoverState(NormalCoverState):
349390
350391 def normal_type_cover (self ) -> int :
351392 """Determine state for horizontal and vertical covers."""
393+
394+ self .cover .logger .debug ("Is presence? %s" , self .climate_data .is_presence )
395+
352396 if self .climate_data .is_presence :
353397 return self .normal_with_presence ()
354398
@@ -357,23 +401,32 @@ def normal_type_cover(self) -> int:
357401 def normal_with_presence (self ) -> int :
358402 """Determine state for horizontal and vertical covers with occupants."""
359403
404+ is_summer = self .climate_data .is_summer
405+
360406 # Check if it's not summer and either lux, irradiance or sunny weather is present
361- if not self . climate_data . is_summer and (
407+ if not is_summer and (
362408 self .climate_data .lux
363409 or self .climate_data .irradiance
364410 or not self .climate_data .is_sunny
365411 ):
366412 # If it's winter and the cover is valid, return 100
367413 if self .climate_data .is_winter and self .cover .valid :
414+ self .cover .logger .debug (
415+ "n_w_p(): Winter and sun is in front of window = use 100"
416+ )
368417 return 100
369418 # Otherwise, return the default cover state
419+ self .cover .logger .debug (
420+ "n_w_p(): it's not summer and sunny weather is not present = use default"
421+ )
370422 return self .cover .default
371423
372424 # If it's summer and there's a transparent blind, return 0
373- if self . climate_data . is_summer and self .climate_data .transparent_blind :
425+ if is_summer and self .climate_data .transparent_blind :
374426 return 0
375427
376428 # If none of the above conditions are met, get the state from the parent class
429+ self .cover .logger .debug ("n_w_p(): None of the climate conditions are met" )
377430 return super ().get_state ()
378431
379432 def normal_without_presence (self ) -> int :
@@ -426,8 +479,18 @@ def get_state(self) -> int:
426479 if self .climate_data .blind_type == "cover_tilt" :
427480 result = self .tilt_state ()
428481 if self .cover .apply_max_position and result > self .cover .max_pos :
482+ self .cover .logger .debug (
483+ "Climate state: Max position applied (%s > %s)" ,
484+ result ,
485+ self .cover .max_pos ,
486+ )
429487 return self .cover .max_pos
430488 if self .cover .apply_min_position and result < self .cover .min_pos :
489+ self .cover .logger .debug (
490+ "Climate state: Min position applied (%s < %s)" ,
491+ result ,
492+ self .cover .min_pos ,
493+ )
431494 return self .cover .min_pos
432495 return result
433496
@@ -453,7 +516,11 @@ def calculate_position(self) -> float:
453516
454517 def calculate_percentage (self ) -> float :
455518 """Convert blind height to percentage or default value."""
456- result = self .calculate_position () / self .h_win * 100
519+ position = self .calculate_position ()
520+ self .logger .debug (
521+ "Converting height to percentage: %s / %s * 100" , position , self .h_win
522+ )
523+ result = position / self .h_win * 100
457524 return round (result )
458525
459526
0 commit comments