thermal_mode.py 3.1 KB

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