Add prediction endpoint

This commit is contained in:
sosokker 2024-05-11 02:05:42 +07:00
parent eb92b5e9de
commit fe67a6e7c4
3 changed files with 115 additions and 1 deletions

View File

@ -28,4 +28,7 @@ CONFIG_FILE = config('CONFIG_FILE')
YOLO_WEIGHT_FILE = config('YOLO_WEIGHT_FILE')
SPPE_WEIGHT_FILE = config('SPPE_WEIGHT_FILE')
TSSTG_WEIGHT_FILE = config('TSSTG_WEIGHT_FILE')
LINE_NOTIFY_TOKEN = config('LINE_NOTIFY_TOKEN')
LINE_NOTIFY_TOKEN = config('LINE_NOTIFY_TOKEN')
WEATHER_API_KEY = config('WEATHER_API_KEY')
LAT = config('LAT')
LON = config('LON')

View File

@ -0,0 +1,33 @@
from datetime import datetime, timedelta
from sqlalchemy import func
from sqlalchemy.orm import Session
from models import PredictionData
def get_temp_prediction_data(session: Session):
"""Get indoor temperature prediction for the next five days"""
current_time = datetime.now()
limit_day = current_time + timedelta(days=5)
return session.query(
PredictionData.timestamp, PredictionData.indoor_temp
).filter(
PredictionData.timestamp >= current_time,
PredictionData.timestamp < limit_day
).order_by(PredictionData.timestamp.desc()).all()
def get_feature_prediction_data(session: Session):
"""Get all features used to predict indoor temperature for the next five days"""
current_time = datetime.now()
limit_day = current_time + timedelta(days=5)
return session.query(
PredictionData.timestamp, PredictionData.outdoor_temp, PredictionData.outdoor_feels_like,
PredictionData.outdoor_pressure, PredictionData.outdoor_humidity
).filter(
PredictionData.timestamp >= current_time,
PredictionData.timestamp < limit_day
).order_by(PredictionData.timestamp.desc()).all()

View File

@ -0,0 +1,78 @@
import httpx
from datetime import datetime
from sqlalchemy import func
from sqlalchemy.orm import Session
from fastapi import APIRouter, Depends, HTTPException, status
from analytic.health.indoor_model import XgboostIndoorModel
from config import WEATHER_API_KEY, LAT, LON
from database import SessionLocal
from scheme import IndoorTemperature
from models import PredictionData
from query.prediction import get_temp_prediction_data, get_feature_prediction_data
router = APIRouter()
#Dependency
def get_db():
db = SessionLocal()
try :
yield db
finally:
db.close()
# Load prediction data -> FOUND -> Return
# NOT FOUND
# Try load data from database -> Load future data from database -> predict -> RETURN
# -> Not found -> Load data from api -> Predict/Save to database -> RETURN
def _fetch_data_from_api() -> dict:
# api.openweathermap.org/data/2.5/forecast?lat={lat}&lon={lon}&appid={API key}
url = f"https://api.openweathermap.org/data/2.5/forecast?lat={LAT}&lon={LON}&units=metric&appid={WEATHER_API_KEY}"
response = httpx.get(url)
return response.json()
@router.get("/indoor/predict/", response_model=list[IndoorTemperature])
async def get_tomorrow_indoor_temp(db: Session = Depends(get_db)):
result = get_temp_prediction_data(db)
if not result:
features = get_feature_prediction_data(db)
xgboost = XgboostIndoorModel()
if not features:
datas = _fetch_data_from_api()
# Save to database
if datas:
results = []
for data in datas['list']:
ts = datetime.fromtimestamp(data['dt'])
data = data['main']
features = [data['temp'], data['feels_like'], data['pressure'], data['humidity']]
result = xgboost.predict(features)
results.append(IndoorTemperature(indoor_temp=result, timestamp=ts))
new_data_entry = PredictionData(
timestamp=ts,
indoor_temp=result,
outdoor_temp=data['temp'],
outdoor_feels_like=data['feels_like'],
outdoor_pressure=data['pressure'],
outdoor_humidity=data['humidity']
)
db.add(new_data_entry)
db.commit()
result = results
else:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Failed to fetch data from API"
)
else:
for i in features:
indoor = xgboost.predict([i.outdoor_temp, i.outdoor_feels_like, i.outdoor_pressure, i.outdoor_humidity])
result.append(IndoorTemperature(timestamp=i.timestamp, indoor_temp=indoor))
return result