mirror of
https://github.com/Sosokker/HomieCare.git
synced 2025-12-18 17:54:04 +01:00
Add prediction endpoint
This commit is contained in:
parent
eb92b5e9de
commit
fe67a6e7c4
@ -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')
|
||||
33
StreamServer/src/query/prediction.py
Normal file
33
StreamServer/src/query/prediction.py
Normal 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()
|
||||
78
StreamServer/src/routers/prediction.py
Normal file
78
StreamServer/src/routers/prediction.py
Normal 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
|
||||
Loading…
Reference in New Issue
Block a user