96 lines
3.4 KiB
Python
96 lines
3.4 KiB
Python
from flask import Flask, request, jsonify
|
|
import numpy as np
|
|
import tensorflow as tf
|
|
from tensorflow.keras.models import load_model
|
|
from flask_cors import CORS
|
|
import joblib
|
|
import logging
|
|
import requests
|
|
import datetime
|
|
|
|
app = Flask(__name__)
|
|
CORS(app)
|
|
|
|
# Setup logging
|
|
logging.basicConfig(level=logging.INFO)
|
|
|
|
# Load model dan scaler
|
|
try:
|
|
model = load_model('lstm_model3.h5')
|
|
scaler = joblib.load('scaler.pkl')
|
|
logging.info("✅ Model dan scaler berhasil dimuat.")
|
|
except Exception as e:
|
|
logging.error(f"❌ Gagal memuat model atau scaler: {e}")
|
|
model = None
|
|
scaler = None
|
|
|
|
SAMPLE_TRAINED = 30
|
|
LARAVEL_URL = "http://192.168.1.11:8000/api/predict" # Sesuaikan dengan endpoint Laravel dan ip laptop
|
|
|
|
@app.route('/predict', methods=['POST'])
|
|
def predict():
|
|
try:
|
|
data = request.get_json()
|
|
if not data or "sensor_data" not in data:
|
|
return jsonify({"error": "Data tidak valid"}), 400
|
|
|
|
sensor_data = data["sensor_data"]
|
|
if len(sensor_data) != SAMPLE_TRAINED:
|
|
return jsonify({"error": f"Jumlah data harus {SAMPLE_TRAINED}"}), 400
|
|
|
|
# for sensor in data['sensor_data']:
|
|
# print(sensor)
|
|
|
|
# Pastikan semua data numerik
|
|
try:
|
|
input_data = np.array([[float(d["suhu"]), float(d["kelembaban"])] for d in sensor_data])
|
|
timestamps = [datetime.datetime.strptime(d["datetime"], "%Y-%m-%d %H:%M:%S") for d in sensor_data]
|
|
except (ValueError, KeyError) as e:
|
|
logging.error(f"❌ Error dalam konversi data: {e}")
|
|
return jsonify({"error": "Format data tidak valid"}), 400
|
|
|
|
if model is None or scaler is None:
|
|
return jsonify({"error": "Model atau scaler tidak tersedia"}), 500
|
|
|
|
# Normalisasi data
|
|
input_scaled = scaler.transform(input_data)
|
|
input_scaled = np.reshape(input_scaled, (1, SAMPLE_TRAINED, 2))
|
|
|
|
# Prediksi
|
|
prediction_scaled = model.predict(input_scaled)
|
|
prediction = scaler.inverse_transform(prediction_scaled)
|
|
|
|
# Ambil waktu prediksi (5 menit setelah data terakhir)
|
|
last_datetime = max(timestamps)
|
|
prediction_datetime = last_datetime + datetime.timedelta(minutes=5)
|
|
|
|
# Format hasil prediksi
|
|
hasil_prediksi = {
|
|
"predicted_suhu": round(float(prediction[0][0]), 2),
|
|
"predicted_kelembaban": round(float(prediction[0][1]), 2),
|
|
"prediction_datetime": prediction_datetime.strftime("%Y-%m-%d %H:%M:%S")
|
|
}
|
|
|
|
logging.info(f"✅ Hasil prediksi: {hasil_prediksi}")
|
|
|
|
# Kirim ke Laravel
|
|
try:
|
|
response = requests.post(LARAVEL_URL, json=hasil_prediksi, timeout=30)
|
|
if response.status_code == 201:
|
|
logging.info("✅ Hasil prediksi berhasil dikirim ke Laravel")
|
|
else:
|
|
logging.error(f"❌ Gagal mengirim ke Laravel: {response.text}")
|
|
except requests.RequestException as e:
|
|
logging.error(f"❌ Error mengirim ke Laravel: {e}")
|
|
return jsonify({"error": "Gagal mengirim ke Laravel"}), 500
|
|
|
|
return jsonify({"message": "Data berhasil dikirim ke Laravel"}), 200 # Hanya mengirim status ke client
|
|
|
|
except Exception as e:
|
|
logging.error(f"❌ Terjadi error: {e}")
|
|
return jsonify({"error": "Terjadi kesalahan pada server"}), 500
|
|
|
|
|
|
if __name__ == '__main__':
|
|
app.run(host="0.0.0.0", port=5000, debug=True)
|