basic.py 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. # -*- coding: utf-8 -*-
  2. from typing import Dict
  3. import numpy as np
  4. from httpx import AsyncClient
  5. from loguru import logger
  6. from app.controllers.equipment.controller import EquipmentController
  7. from app.schemas.equipment import AirValveSpeed, FCU
  8. from app.schemas.space import Space
  9. from app.services.platform import DataPlatformService, InfoCode
  10. from app.services.transfer import SpaceInfoService, Duoduo, Season
  11. from app.utils.math import round_half_up
  12. class FCUController(EquipmentController):
  13. def __init__(self, equipment: FCU, season: Season):
  14. super(FCUController, self).__init__()
  15. self._equipment = equipment
  16. self.season = season
  17. async def get_temperature_target(self) -> float:
  18. target = self._equipment.space.temperature_target
  19. if not np.isnan(target):
  20. setting_target = target
  21. else:
  22. setting_target = 25.0
  23. self._equipment.setting_temperature = setting_target
  24. return setting_target
  25. async def get_mode(self) -> int:
  26. temperature_target = self._equipment.space.temperature_target
  27. if self.season == Season.heating:
  28. if temperature_target >= self._equipment.space.realtime_temperature:
  29. mode = 2
  30. else:
  31. mode = 1
  32. elif self.season == Season.cooling:
  33. mode = 1
  34. else:
  35. mode = 0
  36. self._equipment.work_mode = mode
  37. return mode
  38. async def get_air_valve_speed(self):
  39. temperature_target = self._equipment.space.temperature_target
  40. if temperature_target > 0:
  41. if self.season == Season.heating:
  42. diff = abs(self._equipment.space.realtime_temperature - temperature_target)
  43. if diff >= 1.5:
  44. self._equipment.air_valve_speed = AirValveSpeed.high
  45. elif diff >= 1.0:
  46. self._equipment.air_valve_speed = AirValveSpeed.medium
  47. elif diff >= 0.5:
  48. self._equipment.air_valve_speed = AirValveSpeed.low
  49. else:
  50. self._equipment.air_valve_speed = AirValveSpeed.off
  51. else:
  52. diff = self._equipment.space.realtime_temperature - temperature_target
  53. if diff >= 1.0:
  54. self._equipment.air_valve_speed = AirValveSpeed.high
  55. elif diff >= 0.5:
  56. self._equipment.air_valve_speed = AirValveSpeed.medium
  57. elif diff >= 0.0:
  58. self._equipment.air_valve_speed = AirValveSpeed.low
  59. else:
  60. self._equipment.air_valve_speed = AirValveSpeed.off
  61. else:
  62. self._equipment.air_valve_speed = AirValveSpeed.off
  63. async def get_running_status(self):
  64. if self._equipment.air_valve_speed == AirValveSpeed.off:
  65. self._equipment.running_status = False
  66. else:
  67. self._equipment.running_status = True
  68. async def run(self):
  69. # await self.get_temperature_target()
  70. await self.get_air_valve_speed()
  71. await self.get_running_status()
  72. await self.get_mode()
  73. def get_results(self):
  74. return self._equipment
  75. class FCUControllerV2(EquipmentController):
  76. """Writen by Wenyan"""
  77. def __init__(self, equipment: FCU, season: Season):
  78. super(FCUControllerV2, self).__init__()
  79. self.equipment = equipment
  80. self.season = season
  81. def get_mode(self) -> int:
  82. if not np.isnan(self.equipment.water_in_temperature):
  83. if self.equipment.water_in_temperature > self.equipment.space.temperature_target:
  84. mode = 2
  85. else:
  86. mode = 1
  87. elif not np.isnan(self.equipment.supply_air_temperature):
  88. if self.equipment.supply_air_temperature > self.equipment.space.temperature_target:
  89. mode = 2
  90. else:
  91. mode = 1
  92. else:
  93. if self.season == Season.heating:
  94. mode = 2
  95. elif self.season == Season.cooling:
  96. mode = 1
  97. else:
  98. mode = 0
  99. self.equipment.work_mode = mode
  100. return mode
  101. def build_air_valve_speed(self):
  102. target = self.equipment.space.temperature_target
  103. if target > 0:
  104. if self.equipment.space.realtime_temperature > 0:
  105. mode = self.get_mode()
  106. if mode == 2:
  107. diff = target - self.equipment.space.realtime_temperature
  108. elif mode == 1:
  109. diff = self.equipment.space.realtime_temperature - target
  110. else:
  111. diff = 0
  112. if diff < 0:
  113. speed = AirValveSpeed.off
  114. elif diff < 0.5:
  115. speed = AirValveSpeed.low
  116. elif diff < 1.5:
  117. speed = AirValveSpeed.medium
  118. else:
  119. speed = AirValveSpeed.high
  120. self.equipment.air_valve_speed = speed
  121. else:
  122. self.equipment.air_valve_speed = AirValveSpeed.medium
  123. else:
  124. self.equipment.air_valve_speed = AirValveSpeed.off
  125. def build_running_status(self):
  126. if self.equipment.air_valve_speed == AirValveSpeed.off:
  127. self.equipment.running_status = False
  128. else:
  129. self.equipment.running_status = True
  130. def build_temperature_set(self):
  131. if np.isnan(self.equipment.space.temperature_target):
  132. self.equipment.setting_temperature = 0.0
  133. else:
  134. self.equipment.setting_temperature = self.equipment.space.temperature_target
  135. async def run(self):
  136. self.build_air_valve_speed()
  137. self.build_running_status()
  138. self.get_mode()
  139. self.build_temperature_set()
  140. def get_results(self):
  141. return self.equipment
  142. @logger.catch()
  143. async def get_fcu_control_result(project_id: str, equipment_id: str) -> Dict:
  144. async with AsyncClient() as client:
  145. duo_duo = Duoduo(client, project_id)
  146. platform = DataPlatformService(client, project_id)
  147. spaces = await duo_duo.get_space_by_equipment(equipment_id)
  148. if project_id == 'Pj1101150003':
  149. supply_air_temperature = await platform.get_realtime_data(InfoCode.supply_temperature, equipment_id)
  150. water_in_temperature = await platform.get_realtime_data(InfoCode.water_in_temperature, equipment_id)
  151. else:
  152. supply_air_temperature = np.NAN
  153. water_in_temperature = np.NAN
  154. for sp in spaces:
  155. transfer = SpaceInfoService(client, project_id, sp.get('id'))
  156. current_target = await transfer.get_current_temperature_target()
  157. realtime_temperature = await platform.get_realtime_temperature(sp.get('id'))
  158. season = await duo_duo.get_season()
  159. temp_space_params = {
  160. 'id': sp.get('id'),
  161. 'temperature_target': current_target,
  162. 'realtime_temperature': realtime_temperature
  163. }
  164. space = Space(**temp_space_params)
  165. break
  166. fcu_temp_params = {
  167. 'id': equipment_id,
  168. 'space': space,
  169. 'supply_air_temperature': supply_air_temperature,
  170. 'water_in_temperature': water_in_temperature
  171. }
  172. fcu = FCU(**fcu_temp_params)
  173. if project_id == 'Pj1101050030':
  174. fcu_controller = FCUController(fcu, season)
  175. else:
  176. fcu_controller = FCUControllerV2(fcu, season)
  177. await fcu_controller.run()
  178. regulated_fcu = fcu_controller.get_results()
  179. output = {
  180. 'onOff': 1 if regulated_fcu.running_status else 0,
  181. 'mode': regulated_fcu.work_mode,
  182. 'speed': regulated_fcu.air_valve_speed.value,
  183. 'temperature': float(round_half_up(regulated_fcu.setting_temperature, 1)),
  184. 'water': 1 if regulated_fcu.running_status else 0
  185. }
  186. return output