basic.py 8.7 KB

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