supply_air_temperature_set.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. from typing import Tuple
  2. from httpx import AsyncClient
  3. from loguru import logger
  4. from app.models.domain.devices import ACATFUSupplyAirTempSetRequest
  5. from app.services.platform import DataPlatformService, InfoCode
  6. from app.services.transfer import Duoduo
  7. class ACATFUSupplyAirTemperatureController:
  8. """
  9. Supply air temperature setting logic version 1 by Wenyan.
  10. """
  11. def __init__(
  12. self, current_supply_air_temp: float, hot_rate: float, cold_rate: float
  13. ):
  14. self.current_air_temp = current_supply_air_temp
  15. self.hot_rate = hot_rate
  16. self.cold_rate = cold_rate
  17. def get_next_set(self, is_just_booted: bool) -> float:
  18. try:
  19. cold_hot_ratio = self.cold_rate / self.hot_rate
  20. except ZeroDivisionError:
  21. cold_hot_ratio = 99
  22. if is_just_booted:
  23. if cold_hot_ratio < 0.5:
  24. next_temperature_set = 8.0
  25. elif cold_hot_ratio < 0.9:
  26. next_temperature_set = 11.0
  27. elif cold_hot_ratio < 1.1:
  28. next_temperature_set = 14.0
  29. elif cold_hot_ratio < 1.5:
  30. next_temperature_set = 17.0
  31. elif cold_hot_ratio >= 1.5:
  32. next_temperature_set = 20.0
  33. else: # If cold hot ratio is nan.
  34. next_temperature_set = 20.0
  35. else:
  36. if cold_hot_ratio < 0.5:
  37. diff = -3
  38. elif cold_hot_ratio < 0.9:
  39. diff = -2
  40. elif cold_hot_ratio < 1.1:
  41. diff = 0
  42. elif cold_hot_ratio < 1.5:
  43. diff = 2
  44. elif cold_hot_ratio >= 1.5:
  45. diff = 3
  46. else: # If cold hot ratio is nan.
  47. diff = 0
  48. next_temperature_set = self.current_air_temp + diff
  49. next_temperature_set = max(8.0, min(20.0, next_temperature_set))
  50. return next_temperature_set
  51. async def fetch_params(
  52. project_id: str, device_id: str
  53. ) -> Tuple[float, float, float, bool]:
  54. async with AsyncClient() as client:
  55. platform = DataPlatformService(client, project_id)
  56. duoduo = Duoduo(client, project_id)
  57. current_supply_air_temperature = (
  58. await platform.get_realtime_supply_air_temperature(device_id)
  59. )
  60. running_status_duration = await platform.get_duration(
  61. InfoCode.running_status, device_id, 15 * 60
  62. )
  63. hot_rate, cold_rate = await duoduo.query_fill_rate_by_device(device_id)
  64. is_just_booted = False
  65. if running_status_duration[-1]["value"] == 1.0:
  66. for item in running_status_duration[::-1]:
  67. if item["value"] == 0.0:
  68. is_just_booted = True
  69. break
  70. return current_supply_air_temperature, hot_rate, cold_rate, is_just_booted
  71. @logger.catch()
  72. async def get_next_acatfu_supply_air_temperature_set(
  73. project_id: str, device_id: str
  74. ) -> float:
  75. (
  76. current_supply_air_temperature,
  77. hot_rate,
  78. cold_rate,
  79. is_just_booted,
  80. ) = await fetch_params(project_id, device_id)
  81. controller = ACATFUSupplyAirTemperatureController(
  82. current_supply_air_temperature, hot_rate, cold_rate
  83. )
  84. next_temperature_set = controller.get_next_set(is_just_booted)
  85. return next_temperature_set
  86. @logger.catch()
  87. def build_acatfu_supply_air_temperature(params: ACATFUSupplyAirTempSetRequest) -> float:
  88. is_just_booted = False
  89. if params.running_status_list[-1] == 1.0:
  90. for item in params.running_status_list[::-1]:
  91. if item == 0.0:
  92. is_just_booted = True
  93. break
  94. controller = ACATFUSupplyAirTemperatureController(
  95. params.supply_air_temperature, params.hot_ratio, params.cold_ratio
  96. )
  97. supply_air_temperature_set = controller.get_next_set(is_just_booted)
  98. return supply_air_temperature_set