supply_air_temperature_set.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  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__(self, current_supply_air_temp: float, hot_rate: float, cold_rate: float):
  12. self.current_air_temp = current_supply_air_temp
  13. self.hot_rate = hot_rate
  14. self.cold_rate = cold_rate
  15. def get_next_set(self, is_just_booted: bool) -> float:
  16. try:
  17. cold_hot_ratio = self.cold_rate / self.hot_rate
  18. except ZeroDivisionError:
  19. cold_hot_ratio = 99
  20. if is_just_booted:
  21. if cold_hot_ratio < 0.5:
  22. next_temperature_set = 8.0
  23. elif cold_hot_ratio < 0.9:
  24. next_temperature_set = 11.0
  25. elif cold_hot_ratio < 1.1:
  26. next_temperature_set = 14.0
  27. elif cold_hot_ratio < 1.5:
  28. next_temperature_set = 17.0
  29. elif cold_hot_ratio >= 1.5:
  30. next_temperature_set = 20.0
  31. else: # If cold hot ratio is nan.
  32. next_temperature_set = 20.0
  33. else:
  34. if cold_hot_ratio < 0.5:
  35. diff = -3
  36. elif cold_hot_ratio < 0.9:
  37. diff = -2
  38. elif cold_hot_ratio < 1.1:
  39. diff = 0
  40. elif cold_hot_ratio < 1.5:
  41. diff = 2
  42. elif cold_hot_ratio >= 1.5:
  43. diff = 3
  44. else: # If cold hot ratio is nan.
  45. diff = 0
  46. next_temperature_set = self.current_air_temp + diff
  47. next_temperature_set = max(8.0, min(20.0, next_temperature_set))
  48. return next_temperature_set
  49. async def fetch_params(project_id: str, device_id: str) -> Tuple[float, float, float, bool]:
  50. async with AsyncClient() as client:
  51. platform = DataPlatformService(client, project_id)
  52. duoduo = Duoduo(client, project_id)
  53. current_supply_air_temperature = await platform.get_realtime_supply_air_temperature(device_id)
  54. running_status_duration = await platform.get_duration(InfoCode.running_status, device_id, 15 * 60)
  55. hot_rate, cold_rate = await duoduo.query_fill_rate_by_device(device_id)
  56. is_just_booted = False
  57. if running_status_duration[-1]['value'] == 1.0:
  58. for item in running_status_duration[::-1]:
  59. if item['value'] == 0.0:
  60. is_just_booted = True
  61. break
  62. return current_supply_air_temperature, hot_rate, cold_rate, is_just_booted
  63. @logger.catch()
  64. async def get_next_acatfu_supply_air_temperature_set(project_id: str, device_id: str) -> float:
  65. current_supply_air_temperature, hot_rate, cold_rate, is_just_booted = await fetch_params(project_id, device_id)
  66. controller = ACATFUSupplyAirTemperatureController(
  67. current_supply_air_temperature,
  68. hot_rate,
  69. cold_rate
  70. )
  71. next_temperature_set = controller.get_next_set(is_just_booted)
  72. return next_temperature_set
  73. @logger.catch()
  74. def build_acatfu_supply_air_temperature(params: ACATFUSupplyAirTempSetRequest) -> float:
  75. is_just_booted = False
  76. if params.running_status_list[-1] == 1.0:
  77. for item in params.running_status_list[::-1]:
  78. if item == 0.0:
  79. is_just_booted = True
  80. break
  81. controller = ACATFUSupplyAirTemperatureController(
  82. params.supply_air_temperature,
  83. params.hot_ratio,
  84. params.cold_ratio
  85. )
  86. supply_air_temperature_set = controller.get_next_set(is_just_booted)
  87. return supply_air_temperature_set