Browse Source

modify ATVA missing data logic

highing666 2 years ago
parent
commit
89ac07aaf0
1 changed files with 51 additions and 159 deletions
  1. 51 159
      app/controllers/equipment/vav.py

+ 51 - 159
app/controllers/equipment/vav.py

@@ -1,26 +1,20 @@
 # -*- coding: utf-8 -*-
 
 from operator import attrgetter
-from typing import Dict, List, Optional, Tuple
+from typing import List, Optional, Tuple
 
 import numpy as np
 from fastapi import HTTPException
-from httpx import AsyncClient
 from loguru import logger
-from sqlalchemy.orm import Session
 
+from app.api.errors.iot import MissingIOTDataError
 from app.controllers.equipment.controller import EquipmentController
-from app.crud.space.weight import get_weights_by_vav
-from app.models.domain.devices import (
-    ACATVAInstructionsRequest,
-    ACATVAInstructionsRequestV2,
-)
+from app.models.domain.devices import ACATVAInstructionsRequest, ACATVAInstructionsRequestV2
 from app.schemas.equipment import VAVBox, FCU
 from app.schemas.instructions import ACATVAInstructions
 from app.schemas.sapce_weight import SpaceWeight
 from app.schemas.space import SpaceATVA
-from app.services.platform import DataPlatformService
-from app.services.transfer import Duoduo, SpaceInfoService, Season
+from app.services.transfer import Season
 from app.utils.date import get_time_str
 
 
@@ -65,9 +59,9 @@ class VAVController(EquipmentController):
         return target_result, realtime_result
 
     async def get_supply_air_flow_set(
-        self, temperature_set: float, temperature_realtime: float
+            self, temperature_set: float, temperature_realtime: float
     ) -> float:
-        if np.isnan(temperature_set) or np.isnan(temperature_realtime):
+        if not (temperature_set and temperature_realtime):
             supply_air_flow_set = 0.0
         else:
             temperature_supply = self.equipment.supply_air_temperature
@@ -106,15 +100,24 @@ class VAVController(EquipmentController):
 
 class VAVControllerV2(VAVController):
     def __init__(
-        self,
-        equipment: VAVBox,
-        weights: Optional[List[SpaceWeight]] = None,
-        season: Optional[Season] = None,
+            self,
+            equipment: VAVBox,
+            weights: Optional[List[SpaceWeight]] = None,
+            season: Optional[Season] = None,
     ):
         super(VAVControllerV2, self).__init__(equipment)
         self.weights = weights
         self.season = season
 
+    def get_valid_spaces(self) -> List:
+        valid_spaces = list()
+        for sp in self.equipment.spaces:
+            if sp.realtime_temperature and sp.temperature_target:
+                sp.diff = sp.temperature_target - sp.realtime_temperature
+                valid_spaces.append(sp)
+
+        return valid_spaces
+
     async def build_virtual_temperature(self) -> None:
         valid_spaces = []
         weights = []
@@ -128,7 +131,7 @@ class VAVControllerV2(VAVController):
         if valid_spaces:
             weights = sorted(weights, key=lambda x: x.temporary_weight_update_time)
             if weights[-1].temporary_weight_update_time > get_time_str(
-                60 * 60 * 2, flag="ago"
+                    60 * 60 * 2, flag="ago"
             ):
                 #  If someone has submitted a feedback in past two hours, meet the need.
                 weight_dic = {weight.space_id: 0.0 for weight in weights}
@@ -166,16 +169,17 @@ class VAVControllerV2(VAVController):
 
     async def rectify(self) -> Tuple[float, float]:
         bad_spaces = list()
-        for sp in self.equipment.spaces:
+        valid_spaces = self.get_valid_spaces()
+        for sp in valid_spaces:
             if self.season == Season.heating:
                 if sp.realtime_temperature > max(
-                    26.0, sp.temperature_target
+                        26.0, sp.temperature_target
                 ) or sp.realtime_temperature < min(20.0, sp.temperature_target):
                     if sp.temperature_target > 0.0:
                         bad_spaces.append(sp)
             elif self.season == Season.cooling:
                 if sp.realtime_temperature > max(
-                    27.0, sp.temperature_target
+                        27.0, sp.temperature_target
                 ) or sp.realtime_temperature < min(22.0, sp.temperature_target):
                     if sp.temperature_target > 0.0:
                         bad_spaces.append(sp)
@@ -215,10 +219,13 @@ class VAVControllerV2(VAVController):
         )
 
     async def run(self) -> None:
-        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
+        try:
+            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
+        except TypeError:
+            raise MissingIOTDataError
 
 
 class VAVControllerV3(VAVControllerV2):
@@ -226,26 +233,14 @@ class VAVControllerV3(VAVControllerV2):
         super(VAVControllerV3, self).__init__(vav_params)
         self.season = season
 
-    def get_valid_spaces(self) -> List:
-        valid_spaces = list()
-        for sp in self.equipment.spaces:
-            if sp.realtime_temperature > 0.0 and sp.temperature_target > 0.0:
-                valid_spaces.append(sp)
-
-        return valid_spaces
-
     async def build_virtual_temperature(self) -> None:
         valid_spaces = self.get_valid_spaces()
 
         if not valid_spaces:
-            virtual_realtime, virtual_target = np.NAN, np.NAN
+            virtual_realtime, virtual_target = None, None
         else:
-            sorted_spaces = sorted(
-                valid_spaces, key=lambda x: x.vav_temporary_update_time
-            )
-            if sorted_spaces[-1].vav_temporary_update_time > get_time_str(
-                60 * 60 * 2, flag="ago"
-            ):
+            sorted_spaces = sorted(valid_spaces, key=lambda x: x.vav_temporary_update_time)
+            if sorted_spaces[-1].vav_temporary_update_time > get_time_str(60 * 60 * 2, flag="ago"):
                 virtual_realtime = sorted_spaces[-1].realtime_temperature
                 virtual_target = sorted_spaces[-1].temperature_target
             else:
@@ -276,129 +271,36 @@ class VAVControllerV4(VAVControllerV3):
         super().__init__(vav_params, season)
         self.return_air_temp = return_air_temp
 
-    def get_next_temp_set(
-        self, virtual_realtime_temp: float, virtual_target_temp: float
-    ) -> float:
-        if np.isnan(virtual_realtime_temp) or np.isnan(virtual_target_temp):
+    def get_next_temp_set(self, virtual_realtime_temp: float, virtual_target_temp: float) -> float:
+        if not (virtual_realtime_temp and virtual_target_temp):
             next_temp_set = np.NAN
         else:
-            next_temp_set = (
-                virtual_target_temp + self.return_air_temp - virtual_realtime_temp
-            )
+            next_temp_set = virtual_target_temp + self.return_air_temp - virtual_realtime_temp
 
         self.equipment.setting_temperature = next_temp_set
 
         return next_temp_set
 
     async def run(self) -> None:
-        await self.build_virtual_temperature()
-        temperature_set, temperature_realtime = await self.rectify()
-        self.get_next_temp_set(temperature_realtime, temperature_set)
-        self.equipment.running_status = True
-
-
-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)
-
-        season = await duo_duo.get_season()
-        served_spaces = await duo_duo.get_space_by_equipment(equipment_id)
-        space_objects = []
-        realtime_supply_air_temperature_list = []
-        for sp in served_spaces:
-            sp_id = sp.get("id")
-            transfer = SpaceInfoService(client, project_id, sp_id)
-            current_target = await transfer.get_current_temperature_target()
-            realtime_temperature = await platform.get_realtime_temperature(sp_id)
-
-            related_equipment = await transfer.get_equipment()
-            equipment_objects = []
-            for eq in related_equipment:
-                if eq.get("category") == "ACATFC":
-                    speed = await platform.get_fan_speed(eq.get("id"))
-                    temp_fcu_params = {"id": eq.get("id"), "air_valve_speed": speed}
-                    fcu = FCU(**temp_fcu_params)
-                    equipment_objects.append(fcu)
-                elif eq.get("category") == "ACATAH":
-                    realtime_supply_air_temperature_list.append(
-                        await platform.get_realtime_supply_air_temperature(eq.get("id"))
-                    )
-            temp_space_params = {
-                "id": sp_id,
-                "realtime_temperature": realtime_temperature,
-                "equipment": equipment_objects,
-                "temperature_target": current_target,
-                "diff": current_target - realtime_temperature,
-            }
-            space = SpaceATVA(**temp_space_params)
-            space_objects.append(space)
-
-        realtime_supply_air_temperature = np.array(
-            realtime_supply_air_temperature_list
-        ).mean()
-        realtime_supply_air_flow = await platform.get_realtime_supply_air_flow(
-            equipment_id
-        )
-        lower_limit, upper_limit = await platform.get_air_flow_limit(equipment_id)
-
-        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,
-        }
-
-        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
-
+        try:
+            await self.build_virtual_temperature()
+            temperature_set, temperature_realtime = await self.rectify()
+            self.get_next_temp_set(temperature_realtime, temperature_set)
+            self.equipment.running_status = True
+        except TypeError:
+            raise MissingIOTDataError
 
-@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 = VAVControllerV2(
-        vav, [SpaceWeight.from_orm(weight) for weight in weights], vav_params["season"]
-    )
-    await vav_controller.run()
-    regulated_vav = vav_controller.get_results()
-
-    return regulated_vav
-
-
-@logger.catch()
-async def build_acatva_instructions(
-    params: ACATVAInstructionsRequest,
-) -> ACATVAInstructions:
+async def build_acatva_instructions(params: ACATVAInstructionsRequest) -> ACATVAInstructions:
     space_params = []
     for sp in params.spaces:
         temp_sp = SpaceATVA(**sp.dict())
-        temp_sp.diff = temp_sp.temperature_target - temp_sp.realtime_temperature
         space_params.append(temp_sp)
 
-    if params.supply_air_temperature == -1:
-        if params.acatah_supply_air_temperature == -1:
-            supply_air_temperature = np.NAN
-        else:
-            supply_air_temperature = params.acatah_supply_air_temperature
-    else:
+    if params.supply_air_temperature:
         supply_air_temperature = params.supply_air_temperature
+    else:
+        supply_air_temperature = params.acatah_supply_air_temperature
 
     vav_params = VAVBox(
         spaces=space_params,
@@ -421,30 +323,20 @@ async def build_acatva_instructions(
     return instructions
 
 
-@logger.catch()
-async def build_acatva_instructions_for_jm(
-    params: ACATVAInstructionsRequestV2,
-) -> dict:
+async def build_acatva_instructions_for_jm(params: ACATVAInstructionsRequestV2) -> dict:
     # Control logic for Jiaming.
 
     space_params = []
     for sp in params.spaces:
         temp_sp = SpaceATVA(**sp.dict())
-        if temp_sp.temperature_target:
-            temp_sp.diff = temp_sp.temperature_target - temp_sp.realtime_temperature
-        else:
-            temp_sp.diff = 0.0
         space_params.append(temp_sp)
 
     vav_params = VAVBox(spaces=space_params)
-    return_air_temp = (
-        np.NAN if params.return_air_temperature == -1.0 else params.return_air_temperature
-    )
 
     controller = VAVControllerV4(
         vav_params=vav_params,
         season=Season(params.season),
-        return_air_temp=return_air_temp,
+        return_air_temp=params.return_air_temperature,
     )
     await controller.run()
     regulated_vav = controller.get_results()
@@ -455,7 +347,7 @@ async def build_acatva_instructions_for_jm(
             next_temp_set = -1.0
     else:
         next_temp_set = -1.0
-    
+
     instructions = {
         'temperature_target_set': next_temp_set,
         'virtual_target_temperature': regulated_vav.virtual_target_temperature,