from app.api.errors.iot import MissingIOTDataError from app.models.domain.devices import ACATAHThermalModeSetRequest from app.schemas.equipment import VAVBox from app.services.transfer import Season def count_vav_box_weight( realtime: float, target: float, upper_limit_flow: float, lower_limit_flow: float, current_flow_set: float, valve_opening: float, supply_air_temp: float, ) -> float: diff = realtime - target flag = False if current_flow_set < lower_limit_flow * 1.1 or valve_opening < 10.0: if supply_air_temp < realtime: if diff < 0: flag = True if supply_air_temp > realtime: if diff > 0: flag = True elif current_flow_set > upper_limit_flow * 0.9 or valve_opening > 90.0: if supply_air_temp > realtime: if diff > 0: flag = True if supply_air_temp < realtime: if diff < 0: flag = True if flag: if abs(diff) < 1: weight = 0.0 else: weight = diff weight = max(-4.0, min(4.0, weight)) else: weight = 0 return weight class ACATAHThermalModeController: """ Decide whether to use cooling or heating mode according to space condition controlled by VAV Box. Writen by WuXu """ def __init__(self, vav_boxes_list: list[VAVBox], season: Season): super(ACATAHThermalModeController, self).__init__() self.vav_boxes_list = vav_boxes_list self.season = season def build(self) -> str: weight = 0.0 for box in self.vav_boxes_list: try: weight += count_vav_box_weight( box.virtual_realtime_temperature, box.virtual_target_temperature, box.supply_air_flow_upper_limit, box.supply_air_flow_lower_limit, box.supply_air_flow_set, box.valve_opening, box.supply_air_temperature ) except TypeError: raise MissingIOTDataError if weight > 0: mode = "cooling" elif weight < 0: mode = "heating" else: mode = "hold" return mode def build_acatah_thermal_mode_set(params: ACATAHThermalModeSetRequest) -> str: vav_list = list() for raw_vav in params.vav_list: if raw_vav.virtual_realtime_temperature and raw_vav.virtual_temperature_target: vav = VAVBox( virtual_realtime_temperature=raw_vav.virtual_realtime_temperature, virtual_target_temperature=raw_vav.virtual_temperature_target, supply_air_flow_lower_limit=raw_vav.supply_air_flow_lower_limit, supply_air_flow_upper_limit=raw_vav.supply_air_flow_upper_limit, supply_air_flow_set=raw_vav.supply_air_flow_set, valve_opening=raw_vav.valve_opening, ) vav_list.append(vav) controller = ACATAHThermalModeController(vav_list, Season(params.season)) mode = controller.build() return mode