basic.py 8.9 KB

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