thermal_mode.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. from typing import List
  2. from app.api.errors.iot import MissingIOTDataError
  3. from app.models.domain.devices import ACATAHThermalModeSetRequest
  4. from app.schemas.equipment import VAVBox
  5. from app.services.transfer import Season
  6. def count_vav_box_weight(
  7. realtime: float,
  8. target: float,
  9. upper_limit_flow: float,
  10. lower_limit_flow: float,
  11. current_flow_set: float,
  12. valve_opening: float,
  13. supply_air_temp: float,
  14. ) -> float:
  15. diff = realtime - target
  16. flag = False
  17. if current_flow_set < lower_limit_flow * 1.1 or valve_opening < 10.0:
  18. if supply_air_temp < realtime:
  19. if diff < 0:
  20. flag = True
  21. if supply_air_temp > realtime:
  22. if diff > 0:
  23. flag = True
  24. elif current_flow_set > upper_limit_flow * 0.9 or valve_opening > 90.0:
  25. if supply_air_temp > realtime:
  26. if diff > 0:
  27. flag = True
  28. if supply_air_temp < realtime:
  29. if diff < 0:
  30. flag = True
  31. if flag:
  32. if abs(diff) < 1:
  33. weight = 0.0
  34. else:
  35. weight = diff
  36. weight = max(-4.0, min(4.0, weight))
  37. else:
  38. weight = 0
  39. return weight
  40. class ACATAHThermalModeController:
  41. """
  42. Decide whether to use cooling or heating mode according to space condition
  43. controlled by VAV Box.
  44. Writen by WuXu
  45. """
  46. def __init__(self, vav_boxes_list: List[VAVBox], season: Season):
  47. super(ACATAHThermalModeController, self).__init__()
  48. self.vav_boxes_list = vav_boxes_list
  49. self.season = season
  50. def build(self) -> str:
  51. weight = 0.0
  52. for box in self.vav_boxes_list:
  53. try:
  54. weight += count_vav_box_weight(
  55. box.virtual_realtime_temperature,
  56. box.virtual_target_temperature,
  57. box.supply_air_flow_upper_limit,
  58. box.supply_air_flow_lower_limit,
  59. box.supply_air_flow_set,
  60. box.valve_opening,
  61. box.supply_air_temperature
  62. )
  63. except TypeError:
  64. raise MissingIOTDataError
  65. if weight > 0:
  66. mode = "cooling"
  67. elif weight < 0:
  68. mode = "heating"
  69. else:
  70. mode = "hold"
  71. return mode
  72. def build_acatah_thermal_mode_set(params: ACATAHThermalModeSetRequest) -> str:
  73. vav_list = list()
  74. for raw_vav in params.vav_list:
  75. if raw_vav.virtual_realtime_temperature and raw_vav.virtual_temperature_target:
  76. vav = VAVBox(
  77. virtual_realtime_temperature=raw_vav.virtual_realtime_temperature,
  78. virtual_target_temperature=raw_vav.virtual_temperature_target,
  79. supply_air_flow_lower_limit=raw_vav.supply_air_flow_lower_limit,
  80. supply_air_flow_upper_limit=raw_vav.supply_air_flow_upper_limit,
  81. supply_air_flow_set=raw_vav.supply_air_flow_set,
  82. valve_opening=raw_vav.valve_opening,
  83. )
  84. vav_list.append(vav)
  85. controller = ACATAHThermalModeController(vav_list, Season(params.season))
  86. mode = controller.build()
  87. return mode