Skip to content

Commit

Permalink
Merge pull request #164 from basbruss/elevation_options
Browse files Browse the repository at this point in the history
Add min/max Elevation controls
  • Loading branch information
basbruss authored May 23, 2024
2 parents 2e78d22 + a3a92be commit 4652571
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 26 deletions.
17 changes: 14 additions & 3 deletions custom_components/adaptive_cover/calculation.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ class AdaptiveGeneralCover(ABC):
blind_spot_right: int
blind_spot_elevation: int
blind_spot_on: bool
min_elevation: int
max_elevation: int
sun_data: SunData = field(init=False)

def __post_init__(self):
Expand Down Expand Up @@ -82,8 +84,6 @@ def is_sun_in_blind_spot(self) -> bool:
return blindspot
return False



@property
def azi_min_abs(self) -> int:
"""Calculate min azimuth."""
Expand All @@ -103,6 +103,17 @@ def gamma(self) -> float:
gamma = (self.win_azi - self.sol_azi + 180) % 360 - 180
return gamma

@property
def valid_elevation(self) -> bool:
"""Check if elevation is within range."""
if self.min_elevation is None and self.max_elevation is None:
return self.sol_elev >= 0
if self.min_elevation is None:
return self.sol_elev <= self.max_elevation
if self.max_elevation is None:
return self.sol_elev >= self.min_elevation
return self.min_elevation <= self.sol_elev <= self.max_elevation

@property
def valid(self) -> bool:
"""Determine if sun is in front of window."""
Expand All @@ -111,7 +122,7 @@ def valid(self) -> bool:
azi_max = min(self.fov_right, 90)

# valid sun positions are those within the blind's azimuth range and above the horizon (FOV)
valid = (self.gamma < azi_min) & (self.gamma > -azi_max) & (self.sol_elev >= 0)
valid = (self.gamma < azi_min) & (self.gamma > -azi_max) & (self.valid_elevation)
return valid

@property
Expand Down
71 changes: 66 additions & 5 deletions custom_components/adaptive_cover/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@
CONF_LENGTH_AWNING,
CONF_MANUAL_OVERRIDE_DURATION,
CONF_MANUAL_OVERRIDE_RESET,
CONF_MAX_ELEVATION,
CONF_MAX_POSITION,
CONF_MIN_ELEVATION,
CONF_MODE,
CONF_OUTSIDETEMP_ENTITY,
CONF_PRESENCE_ENTITY,
Expand Down Expand Up @@ -100,6 +102,8 @@
)

),
vol.Optional(CONF_MIN_ELEVATION): vol.All(vol.Coerce(int), vol.Range(min=0, max=90)),
vol.Optional(CONF_MAX_ELEVATION): vol.All(vol.Coerce(int), vol.Range(min=0, max=90)),
vol.Required(CONF_FOV_LEFT, default=90): selector.NumberSelector(
selector.NumberSelectorConfig(
min=1, max=90, step=1, mode="slider", unit_of_measurement="°"
Expand Down Expand Up @@ -314,8 +318,6 @@ def async_get_options_flow(config_entry):
"""Get the options flow for this handler."""
return OptionsFlowHandler(config_entry)



async def async_step_user(self, user_input: dict[str, Any] | None = None):
"""Handle the initial step."""
# errors = {}
Expand All @@ -333,6 +335,13 @@ async def async_step_vertical(self, user_input: dict[str, Any] | None = None):
"""Show basic config for vertical blinds."""
self.type_blind = SensorType.BLIND
if user_input is not None:
if user_input[CONF_MAX_ELEVATION] is not None and user_input[CONF_MIN_ELEVATION] is not None:
if user_input[CONF_MAX_ELEVATION] <= user_input[CONF_MIN_ELEVATION]:
return self.async_show_form(
step_id="vertical",
data_schema=CLIMATE_MODE.extend(VERTICAL_OPTIONS.schema),
errors={CONF_MAX_ELEVATION: "Must be greater than 'Minimal Elevation'"}
)
self.config.update(user_input)
if self.config[CONF_ENABLE_BLIND_SPOT]:
return await self.async_step_blind_spot()
Expand All @@ -346,6 +355,13 @@ async def async_step_horizontal(self, user_input: dict[str, Any] | None = None):
"""Show basic config for horizontal blinds."""
self.type_blind = SensorType.AWNING
if user_input is not None:
if user_input[CONF_MAX_ELEVATION] is not None and user_input[CONF_MIN_ELEVATION] is not None:
if user_input[CONF_MAX_ELEVATION] <= user_input[CONF_MIN_ELEVATION]:
return self.async_show_form(
step_id="horizontal",
data_schema=CLIMATE_MODE.extend(HORIZONTAL_OPTIONS.schema),
errors={CONF_MAX_ELEVATION: "Must be greater than 'Minimal Elevation'"}
)
self.config.update(user_input)
if self.config[CONF_ENABLE_BLIND_SPOT]:
return await self.async_step_blind_spot()
Expand All @@ -359,6 +375,13 @@ async def async_step_tilt(self, user_input: dict[str, Any] | None = None):
"""Show basic config for tilted blinds."""
self.type_blind = SensorType.TILT
if user_input is not None:
if user_input[CONF_MAX_ELEVATION] is not None and user_input[CONF_MIN_ELEVATION] is not None:
if user_input[CONF_MAX_ELEVATION] <= user_input[CONF_MIN_ELEVATION]:
return self.async_show_form(
step_id="tilt",
data_schema=CLIMATE_MODE.extend(TILT_OPTIONS.schema),
errors={CONF_MAX_ELEVATION: "Must be greater than 'Minimal Elevation'"}
)
self.config.update(user_input)
if self.config[CONF_ENABLE_BLIND_SPOT]:
return await self.async_step_blind_spot()
Expand Down Expand Up @@ -462,10 +485,12 @@ async def async_step_update(self, user_input: dict[str, Any] | None = None):
CONF_MANUAL_OVERRIDE_DURATION
),
CONF_MANUAL_OVERRIDE_RESET: self.config.get(CONF_MANUAL_OVERRIDE_RESET),
CONF_BLIND_SPOT_RIGHT: self.config.get(CONF_BLIND_SPOT_RIGHT),
CONF_BLIND_SPOT_LEFT: self.config.get(CONF_BLIND_SPOT_LEFT),
CONF_BLIND_SPOT_ELEVATION: self.config.get(CONF_BLIND_SPOT_ELEVATION),
CONF_BLIND_SPOT_RIGHT: self.config.get(CONF_BLIND_SPOT_RIGHT, None),
CONF_BLIND_SPOT_LEFT: self.config.get(CONF_BLIND_SPOT_LEFT, None),
CONF_BLIND_SPOT_ELEVATION: self.config.get(CONF_BLIND_SPOT_ELEVATION, None),
CONF_ENABLE_BLIND_SPOT: self.config.get(CONF_ENABLE_BLIND_SPOT),
CONF_MIN_ELEVATION: self.config.get(CONF_MIN_ELEVATION, None),
CONF_MAX_ELEVATION: self.config.get(CONF_MAX_ELEVATION, None),
},
)

Expand Down Expand Up @@ -529,6 +554,18 @@ async def async_step_vertical(self, user_input: dict[str, Any] | None = None):
if self.options[CONF_CLIMATE_MODE]:
schema = VERTICAL_OPTIONS
if user_input is not None:
keys = [
CONF_MIN_ELEVATION,
CONF_MAX_ELEVATION,
]
self.optional_entities(keys, user_input)
if user_input[CONF_MAX_ELEVATION] is not None and user_input[CONF_MIN_ELEVATION] is not None:
if user_input[CONF_MAX_ELEVATION] <= user_input[CONF_MIN_ELEVATION]:
return self.async_show_form(
step_id="vertical",
data_schema=CLIMATE_MODE.extend(VERTICAL_OPTIONS.schema),
errors={CONF_MAX_ELEVATION: "Must be greater than 'Minimal Elevation'"}
)
self.options.update(user_input)
if self.options[CONF_CLIMATE_MODE]:
return await self.async_step_climate()
Expand All @@ -547,6 +584,18 @@ async def async_step_horizontal(self, user_input: dict[str, Any] | None = None):
if self.options[CONF_CLIMATE_MODE]:
schema = HORIZONTAL_OPTIONS
if user_input is not None:
keys = [
CONF_MIN_ELEVATION,
CONF_MAX_ELEVATION,
]
self.optional_entities(keys, user_input)
if user_input[CONF_MAX_ELEVATION] is not None and user_input[CONF_MIN_ELEVATION] is not None:
if user_input[CONF_MAX_ELEVATION] <= user_input[CONF_MIN_ELEVATION]:
return self.async_show_form(
step_id="horizontal",
data_schema=CLIMATE_MODE.extend(HORIZONTAL_OPTIONS.schema),
errors={CONF_MAX_ELEVATION: "Must be greater than 'Minimal Elevation'"}
)
self.options.update(user_input)
if self.options[CONF_CLIMATE_MODE]:
return await self.async_step_climate()
Expand All @@ -565,6 +614,18 @@ async def async_step_tilt(self, user_input: dict[str, Any] | None = None):
if self.options[CONF_CLIMATE_MODE]:
schema = TILT_OPTIONS
if user_input is not None:
keys = [
CONF_MIN_ELEVATION,
CONF_MAX_ELEVATION,
]
self.optional_entities(keys, user_input)
if user_input[CONF_MAX_ELEVATION] is not None and user_input[CONF_MIN_ELEVATION] is not None:
if user_input[CONF_MAX_ELEVATION] <= user_input[CONF_MIN_ELEVATION]:
return self.async_show_form(
step_id="tilt",
data_schema=CLIMATE_MODE.extend(TILT_OPTIONS.schema),
errors={CONF_MAX_ELEVATION: "Must be greater than 'Minimal Elevation'"}
)
self.options.update(user_input)
if self.options[CONF_CLIMATE_MODE]:
return await self.async_step_climate()
Expand Down
2 changes: 2 additions & 0 deletions custom_components/adaptive_cover/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
CONF_BLIND_SPOT_RIGHT = "blind_spot_right"
CONF_BLIND_SPOT_LEFT = "blind_spot_left"
CONF_BLIND_SPOT_ELEVATION = "blind_spot_elevation"
CONF_MIN_ELEVATION = "min_elevation"
CONF_MAX_ELEVATION = "max_elevation"


CONF_DELTA_POSITION = "delta_position"
Expand Down
4 changes: 4 additions & 0 deletions custom_components/adaptive_cover/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@
CONF_LENGTH_AWNING,
CONF_MANUAL_OVERRIDE_DURATION,
CONF_MANUAL_OVERRIDE_RESET,
CONF_MAX_ELEVATION,
CONF_MAX_POSITION,
CONF_MIN_ELEVATION,
CONF_OUTSIDETEMP_ENTITY,
CONF_PRESENCE_ENTITY,
CONF_START_ENTITY,
Expand Down Expand Up @@ -418,6 +420,8 @@ def common_data(self):
self.config_entry.options.get(CONF_BLIND_SPOT_RIGHT),
self.config_entry.options.get(CONF_BLIND_SPOT_ELEVATION),
self.config_entry.options.get(CONF_ENABLE_BLIND_SPOT, False),
self.config_entry.options.get(CONF_MIN_ELEVATION, None),
self.config_entry.options.get(CONF_MAX_ELEVATION, None),
]

@property
Expand Down
24 changes: 18 additions & 6 deletions custom_components/adaptive_cover/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@
"sunset_offset": "Sunset Offset",
"sunrise_offset": "Sunrise Offset",
"climate_mode": "Climate Mode",
"blind_spot": "Setup Blindspot"
"blind_spot": "Setup Blindspot",
"min_elevation": "Minimum Elevation of the sun",
"max_elevation": "Maximum Elevation of the sun"
},
"data_description": {
"set_azimuth": "Adjust Azimuth",
Expand Down Expand Up @@ -110,7 +112,9 @@
"sunset_offset": "Sunset Offset",
"sunrise_offset": "Sunrise Offset",
"climate_mode": "Climate Mode",
"blind_spot": "Setup Blindspot"
"blind_spot": "Setup Blindspot",
"min_elevation": "Minimum Elevation of the sun",
"max_elevation": "Maximum Elevation of the sun"
},
"data_description": {
"set_azimuth": "Specify the Azimuth",
Expand Down Expand Up @@ -148,7 +152,9 @@
"sunrise_offset": "Sunrise Offset",
"climate_mode": "Climate Mode",
"tilt_mode": "Type of movement",
"blind_spot": "Setup Blindspot"
"blind_spot": "Setup Blindspot",
"min_elevation": "Minimum Elevation of the sun",
"max_elevation": "Maximum Elevation of the sun"
},
"data_description": {
"set_azimuth": "Specify the Azimuth",
Expand Down Expand Up @@ -232,7 +238,9 @@
"sunset_offset": "Sunset Offset",
"sunrise_offset": "Sunrise Offset",
"climate_mode": "Climate Mode",
"blind_spot": "Setup Blindspot"
"blind_spot": "Setup Blindspot",
"min_elevation": "Minimum Elevation of the sun",
"max_elevation": "Maximum Elevation of the sun"
},
"data_description": {
"set_azimuth": "Adjust Azimuth",
Expand Down Expand Up @@ -295,7 +303,9 @@
"sunset_offset": "Sunset Offset",
"sunrise_offset": "Sunrise Offset",
"climate_mode": "Climate Mode",
"blind_spot": "Setup Blindspot"
"blind_spot": "Setup Blindspot",
"min_elevation": "Minimum Elevation of the sun",
"max_elevation": "Maximum Elevation of the sun"
},
"data_description": {
"set_azimuth": "Specify the Azimuth",
Expand Down Expand Up @@ -333,7 +343,9 @@
"sunrise_offset": "Sunrise Offset",
"climate_mode": "Climate Mode",
"tilt_mode": "Type of movement",
"blind_spot": "Setup Blindspot"
"blind_spot": "Setup Blindspot",
"min_elevation": "Minimum Elevation of the sun",
"max_elevation": "Maximum Elevation of the sun"
},
"data_description": {
"set_azimuth": "Specify the Azimuth",
Expand Down
24 changes: 18 additions & 6 deletions custom_components/adaptive_cover/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@
"sunset_offset": "Sunset Offset",
"sunrise_offset": "Sunrise Offset",
"climate_mode": "Climate Mode",
"blind_spot": "Setup Blindspot"
"blind_spot": "Setup Blindspot",
"min_elevation": "Minimum Elevation of the sun",
"max_elevation": "Maximum Elevation of the sun"
},
"data_description": {
"set_azimuth": "Adjust Azimuth",
Expand Down Expand Up @@ -110,7 +112,9 @@
"sunset_offset": "Sunset Offset",
"sunrise_offset": "Sunrise Offset",
"climate_mode": "Climate Mode",
"blind_spot": "Setup Blindspot"
"blind_spot": "Setup Blindspot",
"min_elevation": "Minimum Elevation of the sun",
"max_elevation": "Maximum Elevation of the sun"
},
"data_description": {
"set_azimuth": "Specify the Azimuth",
Expand Down Expand Up @@ -148,7 +152,9 @@
"sunrise_offset": "Sunrise Offset",
"climate_mode": "Climate Mode",
"tilt_mode": "Type of movement",
"blind_spot": "Setup Blindspot"
"blind_spot": "Setup Blindspot",
"min_elevation": "Minimum Elevation of the sun",
"max_elevation": "Maximum Elevation of the sun"
},
"data_description": {
"set_azimuth": "Specify the Azimuth",
Expand Down Expand Up @@ -233,7 +239,9 @@
"sunset_offset": "Sunset Offset",
"sunrise_offset": "Sunrise Offset",
"climate_mode": "Climate Mode",
"blind_spot": "Setup Blindspot"
"blind_spot": "Setup Blindspot",
"min_elevation": "Minimum Elevation of the sun",
"max_elevation": "Maximum Elevation of the sun"
},
"data_description": {
"set_azimuth": "Adjust Azimuth",
Expand Down Expand Up @@ -296,7 +304,9 @@
"sunset_offset": "Sunset Offset",
"sunrise_offset": "Sunrise Offset",
"climate_mode": "Climate Mode",
"blind_spot": "Setup Blindspot"
"blind_spot": "Setup Blindspot",
"min_elevation": "Minimum Elevation of the sun",
"max_elevation": "Maximum Elevation of the sun"
},
"data_description": {
"set_azimuth": "Specify the Azimuth",
Expand Down Expand Up @@ -334,7 +344,9 @@
"sunrise_offset": "Sunrise Offset",
"climate_mode": "Climate Mode",
"tilt_mode": "Type of movement",
"blind_spot": "Setup Blindspot"
"blind_spot": "Setup Blindspot",
"min_elevation": "Minimum Elevation of the sun",
"max_elevation": "Maximum Elevation of the sun"
},
"data_description": {
"set_azimuth": "Specify the Azimuth",
Expand Down
Loading

0 comments on commit 4652571

Please sign in to comment.