Browse Source

WIP on dev: d9b2ee3 update python env and fix a AHU switch bug

highing666 3 years ago
parent
commit
0059dd1652

+ 12 - 0
app/api/routers/algorithms.py

@@ -3,6 +3,7 @@ from loguru import logger
 
 
 from app.controllers.algorithms.graph_coloring import get_graph_coloring
 from app.controllers.algorithms.graph_coloring import get_graph_coloring
 from app.models.domain.algorithms import GraphColoringRequest, GraphColoringResponse
 from app.models.domain.algorithms import GraphColoringRequest, GraphColoringResponse
+from app.models.domain.algorithms import AttendeesRecommendationRequest, AttendeesRecommendationResponse
 
 
 router = APIRouter()
 router = APIRouter()
 
 
@@ -17,3 +18,14 @@ async def get_graph_coloring_result(graph: GraphColoringRequest):
     }
     }
 
 
     return solution
     return solution
+
+
+@router.post('/attendees-recommendation', response_model=AttendeesRecommendationResponse)
+async def get_recommended(meeting_info: AttendeesRecommendationRequest):
+    return {
+        'code': 200,
+        'message': 'Test',
+        'data': {
+            'userIdList': []
+        }
+    }

+ 5 - 0
app/api/routers/diagnosis.py

@@ -9,3 +9,8 @@ router = APIRouter()
 @router.post('/space/thermal-comfort', response_model=ThermalComfortDiagnosisResponse)
 @router.post('/space/thermal-comfort', response_model=ThermalComfortDiagnosisResponse)
 async def get_thermal_comfort_diagnosis_result(params: ThermalComfortDiagnosisRequest):
 async def get_thermal_comfort_diagnosis_result(params: ThermalComfortDiagnosisRequest):
     pass
     pass
+
+
+@router.post('/thermal-comfort/fcu', response_model=ThermalComfortDiagnosisResponse)
+async def get_thermal_comfort_fcu_diagnosis():
+    pass

+ 3 - 0
app/api/routers/meetings.py

@@ -0,0 +1,3 @@
+from fastapi import APIRouter
+from loguru import logger
+

+ 146 - 9
app/controllers/diagnosis/thermal_comfort.py

@@ -4,8 +4,10 @@ from typing import Optional
 import numpy as np
 import numpy as np
 from loguru import logger
 from loguru import logger
 
 
+from app.models.domain.diagnosis import ThermalComfortDiagnosisRequest
 from app.schemas.diagnosis import FaultCategory
 from app.schemas.diagnosis import FaultCategory
-from app.schemas.equipment import FCU, VAVBox, VRF
+from app.schemas.equipment import AHU, FCU, VAVBox, VRF
+from app.services.transfer import Season
 
 
 
 
 class DiagnotorBase(ABC):
 class DiagnotorBase(ABC):
@@ -17,7 +19,7 @@ class DiagnotorBase(ABC):
             self,
             self,
             setting_value: float,
             setting_value: float,
             feedback_value: float,
             feedback_value: float,
-            is_categorical: bool = False,
+            is_categorical: bool = True,
             tolerance_pct: float = 0.0
             tolerance_pct: float = 0.0
     ) -> None:
     ) -> None:
         if is_categorical:
         if is_categorical:
@@ -36,9 +38,14 @@ class ThermalComfortDiagnotor(DiagnotorBase):
 
 
 class FCUDiagnotor(DiagnotorBase):
 class FCUDiagnotor(DiagnotorBase):
 
 
-    def __init__(self, fcu: FCU):
+    def __init__(self, fcu: FCU, ahu: AHU, duration: float, target_temp: float, realtime_temp: float, season: Season):
         super(FCUDiagnotor, self).__init__()
         super(FCUDiagnotor, self).__init__()
         self._fcu = fcu
         self._fcu = fcu
+        self._ahu = ahu
+        self._duration = duration
+        self._target_temp = target_temp
+        self._realtime_temp = realtime_temp
+        self._season = season
 
 
     def low_in_heating(self) -> None:
     def low_in_heating(self) -> None:
         if self._fcu.air_valve_speed == 'off':
         if self._fcu.air_valve_speed == 'off':
@@ -51,10 +58,15 @@ class FCUDiagnotor(DiagnotorBase):
                 self.controller_check(self._fcu.air_valve_speed_set, self._fcu.air_valve_speed)
                 self.controller_check(self._fcu.air_valve_speed_set, self._fcu.air_valve_speed)
                 if not self._result.controller_err:
                 if not self._result.controller_err:
                     if self._fcu.air_valve_speed_set == 'high':
                     if self._fcu.air_valve_speed_set == 'high':
-                        pass
+                        if self._duration > 120:
+                            if self._fcu.supply_air_temperature < self._target_temp + 1:
+                                self._result.insufficient_heating = True
+                            else:
+                                self._result.undefined_err = True
+                        else:
+                            self._result.no_problems_found = True
                     else:
                     else:
                         self._result.control_logic_err = True
                         self._result.control_logic_err = True
-
             else:
             else:
                 if self._fcu.speed_limit == self._fcu.air_valve_speed:
                 if self._fcu.speed_limit == self._fcu.air_valve_speed:
                     self._result.over_constrained = True
                     self._result.over_constrained = True
@@ -62,20 +74,132 @@ class FCUDiagnotor(DiagnotorBase):
                     self._result.obj_info_err = True
                     self._result.obj_info_err = True
 
 
     def low_in_cooling(self) -> None:
     def low_in_cooling(self) -> None:
-        pass
+        if self._fcu.recommended_speed == 'off':
+            if self._fcu.air_valve_speed == self._fcu.recommended_speed:
+                self.controller_check(self._fcu.air_valve_speed_set, self._fcu.air_valve_speed)
+                if not self._result.controller_err:
+                    if self._duration > 120:
+                        self._result.undefined_err = True
+                    else:
+                        self._result.no_problems_found = True
+            else:
+                self._result.obj_info_err = True
+        else:
+            self._result.control_logic_err = True
 
 
     def high_in_heating(self) -> None:
     def high_in_heating(self) -> None:
-        pass
+        self.low_in_cooling()
 
 
     def high_in_cooling(self) -> None:
     def high_in_cooling(self) -> None:
-        pass
+        self.low_in_heating()
+        if self._result.insufficient_heating:
+            self._result.insufficient_heating = False
+            self._result.insufficient_cooling = True
+
+    def run(self) -> None:
+        if self._season == Season.heating or self._fcu.supply_air_temperature > self._target_temp:
+            if self._realtime_temp < self._target_temp - 1:
+                self.low_in_heating()
+            elif self._realtime_temp > self._target_temp + 1:
+                self.high_in_heating()
+        elif self._season == Season.cooling or self._fcu.supply_air_temperature < self._target_temp:
+            if self._realtime_temp < self._target_temp - 1:
+                self.low_in_cooling()
+            elif self._realtime_temp > self._target_temp + 1:
+                self.high_in_cooling()
 
 
 
 
 class VAVDiagnotor(DiagnotorBase):
 class VAVDiagnotor(DiagnotorBase):
 
 
-    def __init__(self, vav: VAVBox):
+    def __init__(self, vav: VAVBox, ahu: AHU, known_err: FaultCategory, duration: float, season: Season):
         super(VAVDiagnotor, self).__init__()
         super(VAVDiagnotor, self).__init__()
         self._vav = vav
         self._vav = vav
+        self._ahu = ahu
+        self._known_err = known_err
+        self._duration = duration
+        self._season = season
+
+    def low_in_heating(self) -> None:
+        self.controller_check(
+            self._vav.supply_air_flow_set,
+            self._vav.supply_air_flow,
+            is_categorical=False,
+            tolerance_pct=0.1
+        )
+        if self._vav.recommended_supply_air_flow >= self._vav.supply_air_flow_upper_limit:
+            if self._vav.recommended_supply_air_flow == self._vav.supply_air_flow_set:
+                if not self._result.controller_err:
+                    if self._duration > 120.0:
+                        if self._vav.supply_air_temperature < self._vav.virtual_target_temperature + 1 \
+                                or self._ahu.supply_air_temperature < self._vav.virtual_target_temperature + 2:
+                            self._result.insufficient_heating = True
+                        else:
+                            if self._vav.supply_air_flow_upper_limit < 1200.0:
+                                self._result.unreasonable_vav_flow_limit = True
+                            else:
+                                if not self._known_err.sensor_err:
+                                    self._result.undefined_err = True
+                    else:
+                        self._result.no_problems_found = True
+            else:
+                self._result.obj_info_err = True
+        else:
+            if self._vav.recommended_supply_air_flow != self._vav.supply_air_flow_set:
+                self._result.obj_info_err = True
+
+    def low_in_cooling(self) -> None:
+        if self._vav.recommended_supply_air_flow == self._vav.supply_air_flow_set:
+            self.controller_check(
+                self._vav.supply_air_flow_set,
+                self._vav.supply_air_flow,
+                is_categorical=False,
+                tolerance_pct=0.1
+            )
+            if self._vav.supply_air_flow_set <= self._vav.supply_air_flow_lower_limit:
+                if not self._result.controller_err:
+                    if self._duration >= 120.0:
+                        if self._vav.supply_air_flow_lower_limit > 400:
+                            self._result.unreasonable_vav_flow_limit = True
+                        else:
+                            if not self._known_err.sensor_err:
+                                if self._vav.supply_air_temperature < 18 or self._ahu.supply_air_temperature < 18:
+                                    self._result.excessive_cooling = True
+                                else:
+                                    self._result.obj_info_err = True
+                    else:
+                        self._result.no_problems_found = True
+            else:
+                self._result.no_problems_found = True
+        else:
+            self._result.obj_info_err = True
+
+    def high_in_heating(self) -> None:
+        self.low_in_cooling()
+        if self._result.excessive_cooling:
+            self._result.excessive_cooling = False
+            self._result.excessive_heating = True
+
+    def high_in_cooling(self) -> None:
+        self.low_in_heating()
+        if self._vav.recommended_supply_air_flow >= self._vav.supply_air_flow_upper_limit:
+            if self._vav.recommended_supply_air_flow == self._vav.supply_air_flow_set:
+                if not self._result.controller_err:
+                    if self._duration > 120.0:
+                        if self._vav.supply_air_temperature > self._vav.virtual_target_temperature + 1 \
+                                or self._ahu.supply_air_temperature > self._vav.virtual_target_temperature + 2:
+                            self._result.insufficient_cooling = True
+
+    def run(self) -> None:
+        if self._season == Season.heating or self._vav.supply_air_temperature > self._vav.virtual_target_temperature:
+            if self._vav.virtual_realtime_temperature < self._vav.virtual_target_temperature - 1:
+                self.low_in_heating()
+            elif self._vav.virtual_realtime_temperature > self._vav.virtual_target_temperature + 1:
+                self.high_in_heating()
+        elif self._season == Season.cooling or self._vav.supply_air_temperature < self._vav.virtual_target_temperature:
+            if self._vav.virtual_realtime_temperature < self._vav.virtual_target_temperature - 1:
+                self.low_in_cooling()
+            elif self._vav.virtual_realtime_temperature > self._vav.virtual_target_temperature + 1:
+                self.high_in_cooling()
 
 
 
 
 class VRFDiagnotor(DiagnotorBase):
 class VRFDiagnotor(DiagnotorBase):
@@ -83,3 +207,16 @@ class VRFDiagnotor(DiagnotorBase):
     def __init__(self, vrf: VRF):
     def __init__(self, vrf: VRF):
         super(VRFDiagnotor, self).__init__()
         super(VRFDiagnotor, self).__init__()
         self._vrf = vrf
         self._vrf = vrf
+
+
+def get_diagnosis_result(params: ThermalComfortDiagnosisRequest) -> FaultCategory:
+    if params.fcu_list:
+        for fcu in params.fcu_list:
+            fcu_diagnotor = FCUDiagnotor(
+                fcu,
+                params.ahu,
+                params.duration_minutes,
+                params.target_temp,
+                params.realtime_temp,
+                params.season
+            )

+ 21 - 1
app/models/domain/algorithms.py

@@ -1,7 +1,9 @@
-from typing import Dict, List
+from typing import Dict, List, Optional
 
 
 from pydantic import BaseModel
 from pydantic import BaseModel
 
 
+from app.models.domain.base import ResponseBase
+
 
 
 class GraphColoringResponse(BaseModel):
 class GraphColoringResponse(BaseModel):
     is_solvable: bool
     is_solvable: bool
@@ -10,3 +12,21 @@ class GraphColoringResponse(BaseModel):
 
 
 class GraphColoringRequest(BaseModel):
 class GraphColoringRequest(BaseModel):
     graph: Dict[str, List]
     graph: Dict[str, List]
+
+
+class AttendeesRecommendationRequest(BaseModel):
+    initiatorId: str
+    meetingRoomId: Optional[str]
+    meetingRoomLocation: Optional[str]
+    topic: Optional[str]
+    seatCount: Optional[int]
+    startTime: Optional[str]
+    endTime: Optional[str]
+
+
+class AttendeesRecommendationResult(BaseModel):
+    userIdList: List
+
+
+class AttendeesRecommendationResponse(ResponseBase):
+    data: AttendeesRecommendationResult

+ 6 - 0
app/models/domain/base.py

@@ -0,0 +1,6 @@
+from pydantic import BaseModel
+
+
+class ResponseBase(BaseModel):
+    code: int
+    message: str

+ 7 - 5
app/models/domain/diagnosis.py

@@ -3,17 +3,19 @@ from typing import List, Optional
 from pydantic import BaseModel
 from pydantic import BaseModel
 
 
 from app.schemas.equipment import AHU, FCU, VAVBox
 from app.schemas.equipment import AHU, FCU, VAVBox
+from app.schemas.diagnosis import FaultCategory
 from app.services.transfer import Season
 from app.services.transfer import Season
 
 
 
 
 class ThermalComfortDiagnosisRequest(BaseModel):
 class ThermalComfortDiagnosisRequest(BaseModel):
-    realtimeTemp: float
-    targetTemp: float
+    realtime_temp: float
+    target_temp: float
     season: Season
     season: Season
     duration_minutes: float
     duration_minutes: float
-    fcu: Optional[List[FCU]]
-    vav: Optional[List[VAVBox]]
-    ahu: Optional[AHU]
+    fcu_list: Optional[List[FCU]] = None
+    vav_list: Optional[List[VAVBox]] = None
+    ahu: Optional[AHU] = None
+    known_err: Optional[FaultCategory] = None
 
 
 
 
 class ThermalComfortDiagnosisResponse(BaseModel):
 class ThermalComfortDiagnosisResponse(BaseModel):

+ 44 - 0
app/models/meetings/meeting_info.py

@@ -0,0 +1,44 @@
+from sqlalchemy import Column, Integer, String, ForeignKey, TIMESTAMP
+from sqlalchemy.orm import relationship
+
+
+from app.db.session import Base
+
+
+class MeetingInfo(Base):
+    __tablename__ = 'meetings_info'
+
+    id = Column(String, primary_key=True, index=True)
+    initiator_id = Column(String, ForeignKey('tenantslink_users.id'))
+    room_id = Column(String, ForeignKey('meeting_rooms_info.id'))
+    start_time = Column(TIMESTAMP)
+    end_time = Column(TIMESTAMP)
+    topic = Column(String)
+    status = Column()
+
+    initiator = relationship('TenantslinkUser', back_populates='meetings_info')
+    room = relationship('MeetingRoom', back_populates='meetings_info')
+
+
+class MeetingRoom(Base):
+    __tablename__ = 'meeting_rooms_info'
+
+    id = Column(String, primary_key=True, index=True)
+    name = Column(String)
+    location = Column(String)
+    category = Column(String)
+    seat_count = Column(Integer)
+
+
+class MeetingAttendee(Base):
+    __tablename__ = 'meeting_attendees'
+
+    meeting_id = Column(String, index=True)
+    user_id = Column(String, index=True)
+
+
+class TenantslinkUser(Base):
+    __tablename__ = 'tenantslink_users'
+
+    id = Column(String, primary_key=True, index=True)
+    name = Column(String)

+ 2 - 1
app/schemas/diagnosis.py

@@ -14,6 +14,7 @@ class FaultCategory(BaseModel):
     excessive_cooling: Optional[bool] = False
     excessive_cooling: Optional[bool] = False
     controller_err: Optional[bool] = False
     controller_err: Optional[bool] = False
     sensor_err: Optional[bool] = False
     sensor_err: Optional[bool] = False
-    unreasonable_space_weight: Optional[bool] = False
     unreasonable_vav_flow_limit: Optional[bool] = False
     unreasonable_vav_flow_limit: Optional[bool] = False
     obj_info_err: Optional[bool] = False
     obj_info_err: Optional[bool] = False
+    undefined_err: Optional[bool] = True
+    hardware_err: Optional[bool] = False

+ 12 - 9
app/schemas/equipment.py

@@ -3,6 +3,7 @@
 from enum import Enum
 from enum import Enum
 from typing import List, Optional
 from typing import List, Optional
 
 
+import numpy as np
 from pydantic import BaseModel
 from pydantic import BaseModel
 
 
 from app.schemas.space import Space
 from app.schemas.space import Space
@@ -39,20 +40,22 @@ class FCU(BaseEquipment):
 
 
 class VAVBox(BaseEquipment):
 class VAVBox(BaseEquipment):
     spaces: Optional[List[Space]]
     spaces: Optional[List[Space]]
-    supply_air_temperature: Optional[float]
-    supply_air_flow: Optional[float]
-    supply_air_flow_set: Optional[float]
-    supply_air_flow_lower_limit: Optional[float]
-    supply_air_flow_upper_limit: Optional[float]
-    valve_opening: Optional[float]
+    supply_air_temperature: Optional[float] = np.NAN
+    supply_air_flow: Optional[float] = np.NAN
+    supply_air_flow_set: Optional[float] = np.NAN
+    supply_air_flow_lower_limit: Optional[float] = np.NAN
+    supply_air_flow_upper_limit: Optional[float] = np.NAN
+    recommended_supply_air_flow: Optional[float] = np.NAN
+    valve_opening: Optional[float] = np.NAN
     setting_temperature: Optional[float] = 0.0
     setting_temperature: Optional[float] = 0.0
-    virtual_realtime_temperature: Optional[float]
-    virtual_target_temperature: Optional[float]
+    virtual_realtime_temperature: Optional[float] = np.NAN
+    virtual_target_temperature: Optional[float] = np.NAN
 
 
 
 
 class AHU(BaseEquipment):
 class AHU(BaseEquipment):
     fan_freq_set: Optional[float]
     fan_freq_set: Optional[float]
-    supply_air_temperature_set: Optional[float]
+    supply_air_temperature: Optional[float] = np.NAN
+    supply_air_temperature_set: Optional[float] = np.NAN
 
 
 
 
 class VentilationFan(BaseEquipment):
 class VentilationFan(BaseEquipment):