early_start.py 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. from typing import Tuple
  2. from httpx import AsyncClient
  3. from joblib import load
  4. from loguru import logger
  5. from sqlalchemy.orm import Session
  6. from app.core.config import settings
  7. from app.crud.model_path.early_start import model_path_early_start_dtr
  8. from app.models.domain.devices import ACATFCEarlyStartPredictionRequest
  9. from app.services.platform import DataPlatformService
  10. from app.services.transfer import SpaceInfoService
  11. from app.services.weather import WeatherService
  12. class EarlyStartTimeDTRBuilder:
  13. """
  14. Build early start time by decision tree regression.
  15. """
  16. def __init__(self, model_path: str):
  17. self.model_path = f'{settings.ML_MODELS_DIR}{model_path}'
  18. async def get_prediction(self, indoor_temp: float, outdoor_temp: float) -> float:
  19. try:
  20. model = load(self.model_path)
  21. except (FileNotFoundError, IsADirectoryError) as e:
  22. logger.debug(e)
  23. return 0
  24. try:
  25. pre = model.predict([[indoor_temp, outdoor_temp]])
  26. pre_time = pre[0]
  27. except (ValueError, IndexError) as e:
  28. logger.debug(e)
  29. pre_time = 0
  30. return pre_time
  31. async def fetch_params(project_id: str, space_id: str, db: Session) -> Tuple[float, float, str]:
  32. async with AsyncClient() as client:
  33. platform = DataPlatformService(client, project_id)
  34. space_service = SpaceInfoService(client, project_id, space_id)
  35. weather_service = WeatherService(client)
  36. indoor_temp = await platform.get_realtime_temperature(space_id)
  37. weather_info = await weather_service.get_realtime_weather(project_id)
  38. outdoor_temp = weather_info.get('temperature')
  39. device_list = await space_service.get_equipment()
  40. device_id = ''
  41. for device in device_list:
  42. if device.get('category') == 'ACATFC':
  43. device_id = device.get('id')
  44. break
  45. if device_id:
  46. model_path = model_path_early_start_dtr.get_path_by_device(db, device_id)
  47. model_path = model_path.model_path
  48. else:
  49. model_path = ''
  50. return indoor_temp, outdoor_temp, model_path
  51. @logger.catch()
  52. async def get_recommended_early_start_time(db: Session, project_id: str, space_id: str) -> float:
  53. indoor_temp, outdoor_temp, model_path = await fetch_params(project_id, space_id, db)
  54. builder = EarlyStartTimeDTRBuilder(model_path)
  55. hour = await builder.get_prediction(indoor_temp, outdoor_temp)
  56. logger.debug(f'{space_id}: indoor-{indoor_temp}, outdoor-{outdoor_temp}, prediction-{hour * 60}')
  57. return hour * 60
  58. @logger.catch()
  59. async def build_acatfc_early_start_prediction(params: ACATFCEarlyStartPredictionRequest, db: Session) -> float:
  60. model_path = model_path_early_start_dtr.get_path_by_device(db, params.device_id)
  61. builder = EarlyStartTimeDTRBuilder(model_path.model_path)
  62. hour = await builder.get_prediction(params.space_realtime_temperature, params.outdoor_realtime_temperature)
  63. return hour * 60