Ver código fonte

update supply air temperature logic of ATAH

highing666 3 anos atrás
pai
commit
41f692bdfd

+ 19 - 6
app/controllers/equipment/ahu/supply_air_temperature_set.py

@@ -1,6 +1,7 @@
 from typing import List
 
 import arrow
+import numpy as np
 from httpx import AsyncClient
 from loguru import logger
 
@@ -48,20 +49,20 @@ class ACATAHSupplyAirTemperatureController:
             elif cold_ratio <= 0.7:
                 new = self.current + 1.0
             elif cold_ratio <= 1.0:
-                new = self.return_air
+                new = self.return_air + 1.0
             else:
                 new = self.current
         elif self.thermal_mode == ThermalMode.heating:
             if cold_ratio < 0.3:
                 new = self.return_air
             elif cold_ratio < 0.45:
-                new = self.current - 1
+                new = self.current - 1.0
             elif cold_ratio <= 0.55:
                 new = self.current
             elif cold_ratio <= 0.7:
                 new = self.current + 0.5
             elif cold_ratio <= 1.0:
-                new = self.current + 1
+                new = self.current + 1.0
             else:
                 new = self.current
         else:
@@ -72,11 +73,23 @@ class ACATAHSupplyAirTemperatureController:
     def get_cold_ratio(self):
         cold, total = 0, 0
         for box in self.vav_boxes_list:
-            temp = count_vav_box_weight(box.virtual_realtime_temperature, box.virtual_target_temperature)
+            temp = 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,
+                self.season
+            )
             cold += temp if temp < 0 else 0
             total += abs(temp)
 
-        return abs(cold / total)
+        try:
+            cold_ratio = abs(cold / total)
+        except ZeroDivisionError:
+            cold_ratio = np.NAN
+
+        return cold_ratio
 
     def build(self) -> float:
         if not self.is_off_to_on:
@@ -159,7 +172,7 @@ async def get_planned(project_id: str, device_id: str) -> float:
                 if item['value'] == 0.0:
                     is_off_to_on = True
                     break
-        logger.debug(f'{device_id} was off to on: {is_off_to_on}')
+        # logger.debug(f'{device_id} was off to on: {is_off_to_on}')
 
         is_thermal_mode_switched = False
         if len(set([item['value'] for item in hot_water_valve_opening_set_duration])) > 1:

+ 53 - 21
app/controllers/equipment/ahu/thermal_mode.py

@@ -5,25 +5,42 @@ from loguru import logger
 
 from app.models.domain.devices import ThermalMode
 from app.schemas.equipment import VAVBox
-from app.services.platform import DataPlatformService
-from app.services.transfer import Duoduo
-
-
-def count_vav_box_weight(realtime: float, target: float) -> float:
-    diff = abs(realtime - target)
-    if diff > 3:
-        weight = 4
-    elif diff > 2:
-        weight = 3
-    elif diff > 1:
-        weight = 2
-    elif diff > 0:
-        weight = 1
+from app.services.platform import DataPlatformService, InfoCode
+from app.services.transfer import Duoduo, Season
+
+
+def count_vav_box_weight(
+        realtime: float,
+        target: float,
+        upper_limit_flow: float,
+        lower_limit_flow: float,
+        current_flow_set: float,
+        season: Season
+) -> float:
+    diff = realtime - target
+    flag = False
+    if current_flow_set < lower_limit_flow * 1.1:
+        if season == Season.cooling:
+            if diff < 0:
+                flag = True
+        if season == Season.heating:
+            if diff > 0:
+                flag = True
+    elif current_flow_set > upper_limit_flow * 0.9:
+        if season == Season.cooling:
+            if diff > 0:
+                flag = True
+        if season == Season.heating:
+            if diff < 0:
+                flag = True
+
+    if flag:
+        weight = round(diff, 0)
+        weight = max(-4.0, min(4.0, weight))
     else:
         weight = 0
 
-    sign = 1 if realtime - target > 0 else -1
-    return weight * sign
+    return weight
 
 
 class ACATAHThermalModeController:
@@ -32,14 +49,22 @@ class ACATAHThermalModeController:
     Writen by WuXu
     """
 
-    def __init__(self, vav_boxes_list: List[VAVBox]):
+    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:
-            weight += count_vav_box_weight(box.virtual_realtime_temperature, box.virtual_target_temperature)
+            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,
+                self.season
+            )
 
         if weight > 0:
             mode = 'cooling'
@@ -56,6 +81,7 @@ async def fetch_status_params(project_id: str, device_id: str) -> Dict:
         platform = DataPlatformService(client, project_id)
         duoduo = Duoduo(client, project_id)
 
+        season = duoduo.get_season()
         relations = await platform.query_relations(from_id=device_id, graph_id='GtControlEquipNetwork001')
         vav_id_list = [item.get('to_id') for item in relations]
         vav_boxes_list = []
@@ -65,20 +91,26 @@ async def fetch_status_params(project_id: str, device_id: str) -> Dict:
                 'VirtualRealtimeTemperature'
             )
             virtual_temperature_target = await duoduo.query_device_virtual_data(vav_id, 'TargetTemperatureSet')
+            lower_limit_flow, upper_limit_flow = await platform.get_air_flow_limit(vav_id)
+            current_flow_set = await platform.get_realtime_data(InfoCode.supply_air_flow_set, vav_id)
             vav_params = {
                 'id': vav_id,
                 'virtual_realtime_temperature': virtual_realtime_temperature,
-                'virtual_target_temperature': virtual_temperature_target
+                'virtual_target_temperature': virtual_temperature_target,
+                'supply_air_flow_lower_limit': lower_limit_flow,
+                'supply_air_flow_upper_limit': upper_limit_flow,
+                'supply_air_flow_set': current_flow_set
             }
             vav = VAVBox(**vav_params)
             vav_boxes_list.append(vav)
 
-        return {'vav_boxes_list': vav_boxes_list}
+        return {'vav_boxes_list': vav_boxes_list, 'season': season}
 
 
+@logger.catch()
 async def get_thermal_mode(project_id: str, device_id: str) -> ThermalMode:
     prams = await fetch_status_params(project_id, device_id)
-    controller = ACATAHThermalModeController(prams.get('vav_boxes_list'))
+    controller = ACATAHThermalModeController(prams.get('vav_boxes_list'), prams.get('season'))
     mode = controller.build()
 
     return ThermalMode(mode)

+ 1 - 0
app/services/platform.py

@@ -21,6 +21,7 @@ class InfoCode(str, Enum):
     pm2d5 = 'PM2d5'
     humidity = 'RH'
     supply_air_flow = 'SupplyAirFlow'
+    supply_air_flow_set = 'SupplyAirFlowSet'
     supply_air_temperature = 'SupplyAirTemp'
     supply_air_temperature_set = 'SupplyAirTempSet'
     fan_speed = 'FanGear'