basic.py 9.8 KB

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