Spaces:
Sleeping
Sleeping
File size: 4,976 Bytes
6dd0fd8 f385856 6dd0fd8 7e0f7d5 6dd0fd8 7e0f7d5 fbb2cd4 6dd0fd8 7e0f7d5 6dd0fd8 7e0f7d5 6dd0fd8 7f2fba1 6dd0fd8 b7e3734 c3a0e0c 6dd0fd8 7e0f7d5 fbb2cd4 7f2fba1 fbb2cd4 f385856 fbb2cd4 7e0f7d5 fbb2cd4 7e0f7d5 fbb2cd4 7dfc955 84656de 7dfc955 7e0f7d5 fbb2cd4 f385856 fbb2cd4 7e0f7d5 fbb2cd4 7e0f7d5 6dd0fd8 7e0f7d5 b7e3734 7e0f7d5 334dd19 c3a0e0c 7e0f7d5 6dd0fd8 7e0f7d5 c3a0e0c 6dd0fd8 7e0f7d5 6dd0fd8 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 | from fastapi import FastAPI
from pydantic import BaseModel
import numpy as np
import pandas as pd
import joblib
from supabase import create_client
import os
from dotenv import load_dotenv
from datetime import datetime
# ---------------- LOAD ENV ----------------
load_dotenv()
SUPABASE_URL = os.getenv("SUPABASE_URL")
SUPABASE_KEY = os.getenv("SUPABASE_KEY")
supabase = create_client(SUPABASE_URL, SUPABASE_KEY)
# ---------------- LOAD MODEL ----------------
model = joblib.load("xgb_model.pkl")
scaler = joblib.load("xgb_scaler.pkl")
le = joblib.load("label_encoder.pkl")
# ---------------- FASTAPI ----------------
app = FastAPI(title="Energy Monitor API")
# ---------------- INPUT SCHEMA ----------------
class Features(BaseModel):
mean: float
max: float
min: float
std: float
range: float
peak_count: int
slope: float
power: float
relay: bool
# ---------------- FEATURE ENGINEERING ----------------
def transform_features(data: Features):
mean = data.mean
mx = data.max
mn = data.min
std = data.std
rng = data.range
peak = data.peak_count
slope = data.slope
energy = data.power * (40 * 0.04) / 3600
ratio = mx / (mn + 1)
cv = std / (mean + 1)
peak_ratio = peak / 40
delta_mean = std * 0.8
power_density = mean / (rng + 1)
return [
mean, mx, mn, std, rng,
peak, slope,
energy, ratio,
cv, peak_ratio,
delta_mean, power_density
]
# ---------------- ROOT ----------------
@app.get("/")
def root():
return {"message": "Energy API running ๐"}
# ---------------- HEALTH ----------------
@app.get("/health")
def health():
return {"status": "ok"}
# ---------------- PREDICT ----------------
@app.post("/predict")
def predict(data: Features):
if not data.relay:
# No power โ skip prediction
appliance = "Overloaded"
confidence = 1.0
energy = 0.0 # no energy usage
# store in DB
supabase.table("energy_logs").insert({
"timestamp": datetime.utcnow().isoformat(),
"appliance": appliance,
"confidence": confidence,
"mean": data.mean,
"max": data.max,
"min": data.min,
"std": data.std,
"range": data.range,
"peak_count": data.peak_count,
"slope": data.slope,
"energy": energy,
"power": 0.0,
"relay": data.relay
}).execute()
return {
"appliance": appliance,
"confidence": confidence,
"relay": data.relay
}
features = transform_features(data)
columns = [
"mean","max","min","std","range",
"peak_count","slope",
"energy","ratio",
"cv","peak_ratio",
"delta_mean","power_density"
]
df = pd.DataFrame([features], columns=columns)
X = scaler.transform(df)
probs = model.predict_proba(X)[0]
pred_index = np.argmax(probs)
appliance = le.inverse_transform([pred_index])[0]
confidence = float(np.max(probs))
# ๐ฅ Optional threshold (lower to reduce Unknown)
if confidence < 0.3:
appliance = "Unknown"
# ---------------- ENERGY CALC ----------------
time_seconds = 40 * 0.04 # 40 samples ร 40ms = 1.6 sec
energy = (data.power * time_seconds) / 3600.0
# ---------------- STORE IN SUPABASE ----------------
supabase.table("energy_logs").insert({
"timestamp": datetime.utcnow().isoformat(),
"appliance": appliance,
"confidence": confidence,
"mean": data.mean,
"max": data.max,
"min": data.min,
"std": data.std,
"range": data.range,
"peak_count": data.peak_count,
"slope": data.slope,
"energy": energy,
"power": data.power,
"relay": data.relay,
}).execute()
return {
"appliance": appliance,
"confidence": round(confidence, 3),
"relay": data.relay
}
# ---------------- GET LATEST ----------------
@app.get("/latest")
def latest():
res = supabase.table("energy_logs") \
.select("*") \
.order("timestamp", desc=True) \
.limit(1) \
.execute()
return res.data[0] if res.data else {}
# ---------------- GET HISTORY ----------------
@app.get("/history")
def history():
res = supabase.table("energy_logs") \
.select("*") \
.order("timestamp", desc=True) \
.limit(50) \
.execute()
return res.data
# ---------------- MONTHLY ENERGY ----------------
@app.get("/monthly-energy")
def monthly_energy():
res = supabase.table("energy_logs") \
.select("energy") \
.execute()
total = sum([r["energy"] for r in res.data])
return {
"total_energy": total
}
# ---------------- SERVER ----------------
if __name__ == "__main__":
import uvicorn
uvicorn.run("app:app", host="0.0.0.0", port=7860) |