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)