| from flask import Flask, jsonify, render_template |
| import joblib, pandas as pd, numpy as np |
| from datetime import datetime |
| import psycopg2 |
| from psycopg2 import pool |
|
|
| app = Flask(_name_) |
|
|
| |
| bundle = joblib.load('gas_danger_model.pkl') |
| model = bundle['model'] |
| FEATURES = bundle['features'] |
|
|
| |
| PG_POOL = pool.SimpleConnectionPool( |
| 1, 5, |
| user="postgres.czytuqnowdogaowfnfhe", |
| password="235711", |
| host="aws-0-eu-central-1.pooler.supabase.com", |
| port="5432", |
| dbname="postgres" |
| ) |
|
|
| |
| SAFETY_THRESHOLDS = { |
| 'alcohol': 1000, 'NH3': 25, 'CO': 35, 'CO2': 5000, |
| 'Toluene': 100, 'acetone': 750, 'lpg': 1000, 'smoke': 1.0 |
| } |
|
|
| |
| def fetch_latest_reading(): |
| """ |
| Returns a dict with keys exactly matching the ones used elsewhere: |
| CO2, NH3, alcohol, Toluene, acetone, lpg, CO, smoke, timestamp |
| """ |
| sql = """ |
| SELECT co2, |
| nh3, |
| alcohol, |
| toluene, |
| acetone, |
| lpg, |
| co, |
| smoke, |
| "timestamp" |
| FROM gas_data |
| ORDER BY "timestamp" DESC |
| LIMIT 1; |
| """ |
| conn = PG_POOL.getconn() |
| try: |
| with conn.cursor() as cur: |
| cur.execute(sql) |
| row = cur.fetchone() |
| if row is None: |
| return None |
| raw_keys = ['co2','nh3','alcohol','toluene','acetone', |
| 'lpg','co','smoke','timestamp'] |
| raw = dict(zip(raw_keys, row)) |
| |
| return { |
| 'CO2': raw['co2'], |
| 'NH3': raw['nh3'], |
| 'alcohol': raw['alcohol'], |
| 'Toluene': raw['toluene'], |
| 'acetone': raw['acetone'], |
| 'lpg': raw['lpg'], |
| 'CO': raw['co'], |
| 'smoke': raw['smoke'], |
| 'timestamp':raw['timestamp'] |
| } |
| finally: |
| PG_POOL.putconn(conn) |
|
|
| |
| @app.route('/api/predict', methods=['GET']) |
| def predict(): |
| current = fetch_latest_reading() |
| if current is None: |
| return jsonify({'error': 'No rows in gas_data table'}), 404 |
|
|
| ts = current['timestamp'] |
| now = ts if ts else datetime.now() |
|
|
| |
| current.update({ |
| 'Hour': now.hour, |
| 'Weekday': now.weekday(), |
| 'Month': now.month, |
| 'Afternoon': int(12 <= now.hour <= 15) |
| }) |
|
|
| |
| X = pd.DataFrame([[current.get(f, np.nan) for f in FEATURES]], columns=FEATURES) |
| prob = float(model.predict_proba(X)[0, 1]) |
|
|
| |
| alerts = { |
| g: { |
| 'value': current[g], |
| 'threshold': thr, |
| 'status': 'danger' if current[g] > thr else 'safe' |
| } for g, thr in SAFETY_THRESHOLDS.items() |
| } |
|
|
| return jsonify({ |
| 'prediction': prob, |
| 'alerts': alerts, |
| 'overall_status': 'danger' if prob > 0.4 else 'safe', |
| 'timestamp': now.isoformat() |
| }) |
|
|
| @app.route('/') |
| def dashboard(): |
| return render_template('dashboard.html') |
|
|
| if _name_ == '_main_': |
| app.run(debug=True, port=5000) |
|
|