152 lines
5.1 KiB
PHP
152 lines
5.1 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use Illuminate\Support\Facades\Http;
|
|
use Illuminate\Support\Facades\Log;
|
|
use App\Models\ActivityLog;
|
|
use App\Models\Recommendation;
|
|
use Carbon\Carbon;
|
|
|
|
class FlaskModelService
|
|
{
|
|
protected $apiUrl;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->apiUrl = env('FLASK_API_URL', 'http://127.0.0.1:5000');
|
|
Log::info('Flask API URL: ' . $this->apiUrl);
|
|
}
|
|
|
|
/**
|
|
* TEST KONEKSI KE FLASK API
|
|
*/
|
|
public function testConnection()
|
|
{
|
|
try {
|
|
$response = Http::timeout(5)->get($this->apiUrl . '/health');
|
|
return $response->successful();
|
|
} catch (\Exception $e) {
|
|
Log::error('Test connection failed: ' . $e->getMessage());
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* PREDIKSI HARIAN (HARI 1-7)
|
|
* Method ini dipanggil dari ActivityController
|
|
*/
|
|
public function predictDaily($mood, $durasiBelajar, $durasiTidur)
|
|
{
|
|
try {
|
|
Log::info('Mengirim request ke Flask API (predictDaily):', [
|
|
'mood' => $mood,
|
|
'durasi_belajar' => $durasiBelajar,
|
|
'durasi_tidur' => $durasiTidur
|
|
]);
|
|
|
|
$response = Http::timeout(10)->post($this->apiUrl . '/predict', [
|
|
'mood' => $mood,
|
|
'durasi_belajar' => (int)$durasiBelajar,
|
|
'durasi_tidur' => (float)$durasiTidur
|
|
]);
|
|
|
|
if ($response->successful()) {
|
|
$result = $response->json();
|
|
Log::info('Response dari Flask API (predictDaily):', $result);
|
|
|
|
return [
|
|
'success' => true,
|
|
'category' => $result['prediction'] ?? $result['category'] ?? 'Sedang',
|
|
'confidence' => $result['confidence'] ?? 0.85
|
|
];
|
|
}
|
|
|
|
Log::error('Flask API error (predictDaily): ' . $response->body());
|
|
return [
|
|
'success' => false,
|
|
'message' => 'Gagal memanggil model prediksi'
|
|
];
|
|
|
|
} catch (\Exception $e) {
|
|
Log::error('Exception saat panggil Flask API (predictDaily): ' . $e->getMessage());
|
|
return [
|
|
'success' => false,
|
|
'message' => 'Koneksi ke model server gagal: ' . $e->getMessage()
|
|
];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* PREDIKSI BERDASARKAN POLA SISWA (HARI 8+)
|
|
*/
|
|
public function predictBasedOnPattern($userId)
|
|
{
|
|
try {
|
|
// Ambil data 7 hari terakhir
|
|
$activities = ActivityLog::where('user_id', $userId)
|
|
->orderBy('activity_date', 'desc')
|
|
->take(7)
|
|
->get();
|
|
|
|
if ($activities->count() < 5) {
|
|
return [
|
|
'success' => false,
|
|
'message' => 'Data belum cukup untuk analisis pola (minimal 5 hari)',
|
|
'use_daily' => true
|
|
];
|
|
}
|
|
|
|
// Hitung fitur agregat
|
|
$avgDuration = $activities->avg('duration_minutes');
|
|
$mostFrequentMood = $activities->groupBy('mood')
|
|
->map->count()
|
|
->sortDesc()
|
|
->keys()
|
|
->first();
|
|
$avgSleep = $activities->avg('sleep_hours');
|
|
|
|
Log::info('Mengirim request ke Flask API (predictBasedOnPattern):', [
|
|
'user_id' => $userId,
|
|
'avg_duration' => $avgDuration,
|
|
'most_frequent_mood' => $mostFrequentMood,
|
|
'avg_sleep' => $avgSleep,
|
|
'consistency' => $activities->count()
|
|
]);
|
|
|
|
// Kirim ke Flask API endpoint /predict/pattern
|
|
$response = Http::timeout(10)->post($this->apiUrl . '/predict/pattern', [
|
|
'avg_duration' => (float)$avgDuration,
|
|
'most_frequent_mood' => $mostFrequentMood,
|
|
'avg_sleep' => (float)$avgSleep,
|
|
'trend' => 'stabil',
|
|
'consistency' => $activities->count()
|
|
]);
|
|
|
|
if ($response->successful()) {
|
|
$result = $response->json();
|
|
Log::info('Response dari Flask API (predictBasedOnPattern):', $result);
|
|
|
|
return [
|
|
'success' => true,
|
|
'category' => $result['prediction'] ?? $result['category'] ?? 'Sedang',
|
|
'confidence' => $result['confidence'] ?? 0.85,
|
|
'pattern_analysis' => $result['pattern_analysis'] ?? null
|
|
];
|
|
}
|
|
|
|
Log::error('Flask API error (predictBasedOnPattern): ' . $response->body());
|
|
return [
|
|
'success' => false,
|
|
'message' => 'Gagal memanggil model prediksi pola'
|
|
];
|
|
|
|
} catch (\Exception $e) {
|
|
Log::error('Error dalam pattern analysis: ' . $e->getMessage());
|
|
return [
|
|
'success' => false,
|
|
'message' => $e->getMessage()
|
|
];
|
|
}
|
|
}
|
|
} |