Forráskód Böngészése

add a api named equip/control/atva/v2

chenhaiyang 4 éve
szülő
commit
d62e9b4884
2 módosított fájl, 112 hozzáadás és 56 törlés
  1. 30 8
      app/api/routers/equipment.py
  2. 82 48
      app/controllers/equipment/vav.py

+ 30 - 8
app/api/routers/equipment.py

@@ -2,6 +2,7 @@
 
 from enum import Enum
 
+import numpy as np
 from fastapi import APIRouter, Depends, Query
 from loguru import logger
 from sqlalchemy.orm import Session
@@ -9,7 +10,7 @@ from sqlalchemy.orm import Session
 from app.api.dependencies.db import get_db
 from app.controllers.equipment.fcu.basic import get_fcu_control_result
 from app.controllers.equipment.fcu.q_learning import get_fcu_q_learning_control_result
-from app.controllers.equipment.vav import get_vav_control_result
+from app.controllers.equipment.vav import get_vav_control_v1, get_vav_control_v2
 from app.models.domain.equipment import EquipmentControlResponse, EquipmentControlRequest
 from app.utils.date import get_time_str
 
@@ -26,8 +27,7 @@ router = APIRouter()
 async def get_equipment_command_test(
         project_id: str = Query(..., max_length=50, regex='^Pj', alias='projectId'),
         equip_id: str = Query(..., max_length=50, regex='^Eq', alias='equipId'),
-        equip_type: EquipmentName = Query(..., alias='equipType'),
-        db: Session = Depends(get_db)
+        equip_type: EquipmentName = Query(..., alias='equipType')
 ):
     if equip_type.value == EquipmentName.FCU:
         if project_id in ['Pj1101050030', 'Pj1101080259']:
@@ -35,7 +35,7 @@ async def get_equipment_command_test(
         else:
             output = await get_fcu_q_learning_control_result(project_id, equip_id)
     elif equip_type.value == EquipmentName.VAV:
-        vav = await get_vav_control_result(db, project_id, equip_id)
+        vav = await get_vav_control_v1(project_id, equip_id)
         output = {
             'SupplyAirFlowSet': vav.supply_air_flow_set,
             'VirtualRealtimeTemperature': vav.virtual_realtime_temperature,
@@ -54,7 +54,7 @@ async def get_equipment_command_test(
 
 
 @router.post('/control', response_model=EquipmentControlResponse)
-async def get_equipment_command(equipment_control_info: EquipmentControlRequest, db: Session = Depends(get_db)):
+async def get_equipment_command(equipment_control_info: EquipmentControlRequest):
     if equipment_control_info.equipType == EquipmentName.FCU:
         if equipment_control_info.projectId in ['Pj1101050030', 'Pj1101080259']:
             output = await get_fcu_control_result(equipment_control_info.projectId, equipment_control_info.equipId)
@@ -64,11 +64,13 @@ async def get_equipment_command(equipment_control_info: EquipmentControlRequest,
                 equipment_control_info.equipId
             )
     elif equipment_control_info.equipType == EquipmentName.VAV:
-        vav = await get_vav_control_result(db, equipment_control_info.projectId, equipment_control_info.equipId)
+        vav = await get_vav_control_v1(equipment_control_info.projectId, equipment_control_info.equipId)
         output = {
             'SupplyAirFlowSet': vav.supply_air_flow_set,
-            'VirtualRealtimeTemperature': vav.virtual_realtime_temperature,
-            'TargetTemperatureSet': vav.virtual_target_temperature
+            'VirtualRealtimeTemperature': vav.virtual_realtime_temperature if not np.isnan(
+                vav.virtual_realtime_temperature) else None,
+            'TargetTemperatureSet': vav.virtual_target_temperature if not np.isnan(
+                vav.virtual_target_temperature) else None
         }
     else:
         output = {}
@@ -81,3 +83,23 @@ async def get_equipment_command(equipment_control_info: EquipmentControlRequest,
     }
     logger.info(response)
     return response
+
+
+@router.post('/control/atva/v2', response_model=EquipmentControlResponse)
+async def get_fcu_command(equipment_control_info: EquipmentControlRequest, db: Session = Depends(get_db)):
+    vav = await get_vav_control_v2(db, equipment_control_info.projectId, equipment_control_info.equipId)
+    output = {
+        'SupplyAirFlowSet': vav.supply_air_flow_set,
+        'VirtualRealtimeTemperature': vav.virtual_realtime_temperature if not np.isnan(
+            vav.virtual_realtime_temperature) else None,
+        'TargetTemperatureSet': vav.virtual_target_temperature if not np.isnan(vav.virtual_target_temperature) else None
+    }
+
+    response = {
+        'projectId': equipment_control_info.projectId,
+        'equipId': equipment_control_info.equipId,
+        'time': get_time_str(),
+        'output': output
+    }
+    logger.info(response)
+    return response

+ 82 - 48
app/controllers/equipment/vav.py

@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 
-from typing import List, Tuple
+from typing import Dict, List, Tuple
 
 import numpy as np
 from fastapi import HTTPException
@@ -20,15 +20,13 @@ from app.utils.date import get_time_str
 
 class VAVController(EquipmentController):
 
-    def __init__(self, equipment: VAVBox, weights: List[SpaceWeight], season: Season):
+    def __init__(self, equipment: VAVBox):
         super(VAVController, self).__init__()
-        self._equipment = equipment
-        self.weights = weights
-        self.season = season
+        self.equipment = equipment
 
     async def get_strategy(self):
         strategy = 'Plan A'
-        for space in self._equipment.spaces:
+        for space in self.equipment.spaces:
             for eq in space.equipment:
                 if isinstance(eq, FCU):
                     strategy = 'Plan B'
@@ -36,11 +34,11 @@ class VAVController(EquipmentController):
 
         return strategy
 
-    async def build_virtual_temperature_v1(self) -> Tuple[float, float]:
+    async def build_virtual_temperature(self) -> Tuple[float, float]:
         target_list, realtime_list = [], []
         buffer_list = []
         strategy = await self.get_strategy()
-        for space in self._equipment.spaces:
+        for space in self.equipment.spaces:
             if not np.isnan(space.temperature_target):
                 target_list.append(space.temperature_target)
                 realtime_list.append(space.realtime_temperature)
@@ -58,16 +56,50 @@ class VAVController(EquipmentController):
         if total_target and total_realtime:
             target_result = np.array(total_target).sum() / len(target_list)
             realtime_result = np.array(total_realtime).sum() / len(realtime_list)
-            self._equipment.setting_temperature = target_result
+            self.equipment.setting_temperature = target_result
         else:
             target_result, realtime_result = np.NAN, np.NAN
 
         return target_result, realtime_result
 
-    async def build_virtual_temperature_v2(self):
+    async def get_supply_air_flow_set(self, temperature_set: float, temperature_realtime: float) -> float:
+        if np.isnan(temperature_set) or np.isnan(temperature_realtime):
+            supply_air_flow_set = 0.0
+        else:
+            temperature_supply = self.equipment.supply_air_temperature
+            if np.isnan(temperature_supply):
+                temperature_supply = 19.0
+            supply_air_flow_set = self.equipment.supply_air_flow * ((temperature_supply - temperature_realtime)
+                                                                    / (temperature_supply - temperature_set))
+        supply_air_flow_set = max(self.equipment.supply_air_flow_lower_limit, supply_air_flow_set)
+        supply_air_flow_set = min(self.equipment.supply_air_flow_upper_limit, supply_air_flow_set)
+        self.equipment.supply_air_flow_set = supply_air_flow_set
+        self.equipment.virtual_target_temperature = temperature_set
+        self.equipment.virtual_realtime_temperature = temperature_realtime
+
+        return supply_air_flow_set
+
+    async def run(self):
+        temperature_set, temperature_realtime = await self.build_virtual_temperature()
+        await self.get_supply_air_flow_set(temperature_set, temperature_realtime)
+        self.equipment.running_status = True
+
+    def get_results(self):
+        return self.equipment
+
+
+class VAVControllerV2(VAVController):
+
+    def __init__(self, equipment: VAVBox, weights: List[SpaceWeight], season: Season):
+        super(VAVControllerV2, self).__init__(equipment)
+        # self.equipment = equipment
+        self.weights = weights
+        self.season = season
+
+    async def build_virtual_temperature(self):
         valid_spaces = []
         weights = []
-        for sp in self._equipment.spaces:
+        for sp in self.equipment.spaces:
             if sp.realtime_temperature > 0.0 and sp.temperature_target > 0.0:
                 valid_spaces.append(sp)
                 for weight in self.weights:
@@ -95,58 +127,41 @@ class VAVController(EquipmentController):
                     virtual_target += sp.temperature_target * weight_dic.get(sp.id)
                     virtual_realtime += sp.realtime_temperature * weight_dic.get(sp.id)
             except KeyError:
-                logger.error(f'{self._equipment.id} has wrong vav-space relation')
+                logger.error(f'{self.equipment.id} has wrong vav-space relation')
                 raise HTTPException(status_code=404, detail='This VAV box has wrong eq-sp relation')
 
-            self._equipment.virtual_target_temperature = virtual_target
-            self._equipment.virtual_realtime_temperature = virtual_realtime
+            self.equipment.virtual_target_temperature = virtual_target
+            self.equipment.virtual_realtime_temperature = virtual_realtime
         else:
-            self._equipment.virtual_target_temperature = np.NAN
-            self._equipment.virtual_realtime_temperature = np.NAN
+            self.equipment.virtual_target_temperature = np.NAN
+            self.equipment.virtual_realtime_temperature = np.NAN
 
     async def rectify(self) -> Tuple[float, float]:
-        for sp in self._equipment.spaces:
+        for sp in self.equipment.spaces:
             if sp.realtime_temperature < min(23.0, sp.temperature_target):
                 if self.season == Season.heating:
-                    self._equipment.virtual_target_temperature = min(23.0, sp.temperature_target) + 0.5
-                    self._equipment.virtual_realtime_temperature = sp.realtime_temperature
+                    self.equipment.virtual_target_temperature = min(23.0, sp.temperature_target) + 0.5
+                    self.equipment.virtual_realtime_temperature = sp.realtime_temperature
                     break
             elif sp.realtime_temperature > max(27.0, sp.temperature_target):
                 if self.season == Season.cooling:
-                    self._equipment.virtual_target_temperature = max(27.0, sp.temperature_target)
-                    self._equipment.virtual_realtime_temperature = sp.realtime_temperature
+                    self.equipment.virtual_target_temperature = max(27.0, sp.temperature_target)
+                    self.equipment.virtual_realtime_temperature = sp.realtime_temperature
                     break
 
-        return self._equipment.virtual_target_temperature, self._equipment.virtual_realtime_temperature
-
-    async def get_supply_air_flow_set(self) -> float:
-        # await self.build_virtual_temperature_v2()
-        # temperature_set, temperature_realtime = await self.rectify()
-        temperature_set, temperature_realtime = await self.build_virtual_temperature_v1()
-        if np.isnan(temperature_set) or np.isnan(temperature_realtime):
-            supply_air_flow_set = 0.0
-        else:
-            temperature_supply = self._equipment.supply_air_temperature
-            if np.isnan(temperature_supply):
-                temperature_supply = 19.0
-            supply_air_flow_set = self._equipment.supply_air_flow * ((temperature_supply - temperature_realtime)
-                                                                     / (temperature_supply - temperature_set))
-        supply_air_flow_set = max(self._equipment.supply_air_flow_lower_limit, supply_air_flow_set)
-        supply_air_flow_set = min(self._equipment.supply_air_flow_upper_limit, supply_air_flow_set)
-        self._equipment.supply_air_flow_set = supply_air_flow_set
-
-        return supply_air_flow_set
+        return self.equipment.virtual_target_temperature, self.equipment.virtual_realtime_temperature
 
     async def run(self):
-        await self.get_supply_air_flow_set()
-        self._equipment.running_status = True
+        await self.build_virtual_temperature()
+        temperature_set, temperature_realtime = await self.rectify()
+        await self.get_supply_air_flow_set(temperature_set, temperature_realtime)
+        self.equipment.running_status = True
 
     def get_results(self):
-        return self._equipment
+        return self.equipment
 
 
-@logger.catch()
-async def get_vav_control_result(db: Session, project_id: str, equipment_id: str) -> VAVBox:
+async def fetch_vav_control_params(project_id: str, equipment_id: str) -> Dict:
     async with AsyncClient() as client:
         duo_duo = Duoduo(client, project_id)
         platform = DataPlatformService(client, project_id)
@@ -188,19 +203,38 @@ async def get_vav_control_result(db: Session, project_id: str, equipment_id: str
             space = Space(**temp_space_params)
             space_objects.append(space)
 
-        temp_vav_params = {
+        vav_params = {
             'id': equipment_id,
             'spaces': space_objects,
             'supply_air_temperature': realtime_supply_air_temperature,
             'supply_air_flow': realtime_supply_air_flow,
             'supply_air_flow_lower_limit': lower_limit,
             'supply_air_flow_upper_limit': upper_limit,
+            'season': season
         }
-        vav = VAVBox(**temp_vav_params)
 
+        return vav_params
+
+
+@logger.catch()
+async def get_vav_control_v1(project: str, equipment_id: str) -> VAVBox:
+    vav_params = await fetch_vav_control_params(project, equipment_id)
+    vav = VAVBox(**vav_params)
+
+    vav_controller = VAVController(vav)
+    await vav_controller.run()
+    regulated_vav = vav_controller.get_results()
+
+    return regulated_vav
+
+
+@logger.catch()
+async def get_vav_control_v2(db: Session, project_id: str, equipment_id: str) -> VAVBox:
+    vav_params = await fetch_vav_control_params(project_id, equipment_id)
+    vav = VAVBox(**vav_params)
     weights = get_weights_by_vav(db, equipment_id)
 
-    vav_controller = VAVController(vav, [SpaceWeight.from_orm(weight) for weight in weights], season)
+    vav_controller = VAVControllerV2(vav, [SpaceWeight.from_orm(weight) for weight in weights], vav_params['season'])
     await vav_controller.run()
     regulated_vav = vav_controller.get_results()