from app.api.errors.iot import MissingIOTDataError from app.models.domain.devices import ACATFUSupplyAirTempSetRequest from app.schemas.season import Season class ACATFUSupplyAirTemperatureController: """ Supply air temperature setting logic version 1 by Wenyan. """ def __init__( self, current_supply_air_temp_set: float, hot_rate: float, cold_rate: float, season: Season, ): self.current_air_temp_set = current_supply_air_temp_set self.hot_rate = hot_rate self.cold_rate = cold_rate self.season = season def get_next_set(self, is_just_booted: bool) -> float: try: cold_hot_ratio = self.cold_rate / self.hot_rate except (ZeroDivisionError, TypeError): cold_hot_ratio = 99 if is_just_booted: if self.season == Season.cooling: next_temperature_set = 20.0 elif self.season == Season.heating: next_temperature_set = 16.0 else: next_temperature_set = self.current_air_temp_set else: if cold_hot_ratio < 0.5: diff = -3 elif cold_hot_ratio < 0.9: diff = -2 elif cold_hot_ratio < 1.1: diff = 0 elif cold_hot_ratio < 1.5: diff = 2 elif cold_hot_ratio >= 1.5: diff = 3 else: # If cold hot ratio is nan. diff = 0 if self.season == Season.cooling or self.season == Season.transition: diff = 0 try: next_temperature_set = self.current_air_temp_set + diff except TypeError: raise MissingIOTDataError next_temperature_set = max(8.0, min(20.0, next_temperature_set)) return next_temperature_set def build_acatfu_supply_air_temperature(params: ACATFUSupplyAirTempSetRequest) -> float: is_just_booted = False if len(params.running_status_list) > 0: if params.running_status_list[-1] == 1.0: for item in params.running_status_list[::-1]: if item == 0.0: is_just_booted = True break controller = ACATFUSupplyAirTemperatureController( params.supply_air_temperature_set, params.hot_ratio, params.cold_ratio, params.season, ) supply_air_temperature_set = controller.get_next_set(is_just_booted) return supply_air_temperature_set