basic.py 8.8 KB

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