getConnection(); if (isset($_GET['kirim']) && isset($_GET['id'])) { function kirimWA($pesan) { $token = "XjC9oSr4jECWG93JQRWf"; $data = [ "target" => "120363407747513164@g.us", "message" => $pesan, ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.fonnte.com/send", CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_POSTFIELDS => http_build_query($data), CURLOPT_HTTPHEADER => [ "Authorization: $token" ], ]); curl_exec($curl); curl_close($curl); } $id = $_GET['id']; // 🔥 ambil ODP $stmt = $conn->prepare(" SELECT i.id, i.name, i.latitude, i.longitude FROM ftth_items i WHERE i.id = ? "); $stmt->execute([$id]); $odp = $stmt->fetch(PDO::FETCH_ASSOC); if (!$odp) { echo json_encode(['success' => false]); exit; } // 🔥 ambil client $stmtClient = $conn->prepare(" SELECT fi.id, fi.name, fi.serial_number FROM cable_routes cr JOIN ftth_items fi ON (cr.to_item_id = fi.id OR cr.from_item_id = fi.id) WHERE (cr.from_item_id = :id OR cr.to_item_id = :id) AND fi.id != :id "); $stmtClient->bindParam(':id', $id); $stmtClient->execute(); $clients = $stmtClient->fetchAll(PDO::FETCH_ASSOC); $rxValues = []; $clientBad = []; foreach ($clients as $c) { if (empty($c['serial_number'])) continue; $query = json_encode(["_id" => $c['serial_number']]); $url = "http://rmtstb.megadataisp.net:7557/devices/?query=" . urlencode($query); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 5); $res = curl_exec($ch); curl_close($ch); if (!$res) continue; $json = json_decode($res, true); if ( isset($json[0]['VirtualParameters']['RXPower']['_value']) && is_numeric($json[0]['VirtualParameters']['RXPower']['_value']) ) { $rx = floatval($json[0]['VirtualParameters']['RXPower']['_value']); $rxValues[] = $rx; if ($rx < -23) { $clientBad[] = $c['name'] . " (" . $rx . " dBm)"; } } } // 🔥 HITUNG $total = count($rxValues); $bad = count($clientBad); $good = $total - $bad; $avg = $total > 0 ? round(array_sum($rxValues) / $total, 2) : '-'; $min = $total > 0 ? min($rxValues) : '-'; // 🔥 STATUS $status = "BAIK"; if ($total == 0) { $status = "NO DATA"; } elseif ($min < -27) { $status = "KRITIS"; } elseif ($avg < -25 || $bad > ($total * 0.5)) { $status = "BURUK"; } elseif ($avg < -23 || $bad > ($total * 0.3)) { $status = "WARNING"; } // 🔥 FORMAT WA $maps = "https://www.google.com/maps?q={$odp['latitude']},{$odp['longitude']}"; $pesan = "🚨 *LAPORAN ODP*\n\n"; $pesan .= "📍 *ODP:* {$odp['name']}\n"; $pesan .= "📊 *Status:* {$status}\n\n"; $pesan .= "👥 *Total Client:* {$total}\n"; $pesan .= "🟢 Client Baik: {$good}\n"; $pesan .= "🔴 Client Buruk: {$bad}\n\n"; $pesan .= "📶 *AVG RX:* {$avg} dBm\n"; $pesan .= "📉 *MIN RX:* {$min} dBm\n\n"; if (!empty($clientBad)) { $pesan .= "⚠ *Client Bermasalah:*\n"; $pesan .= implode("\n", array_slice($clientBad, 0, 10)); $pesan .= "\n\n"; } $pesan .= "📌 Lokasi:\n$maps\n\n"; $pesan .= "🔎 Silakan cek detail di dashboard."; kirimWA($pesan); echo json_encode(['success' => true]); exit; } // ✅ Ambil semua ODP $stmt = $conn->query(" SELECT i.id, i.name, i.latitude, i.longitude FROM ftth_items i LEFT JOIN item_types it ON i.item_type_id = it.id WHERE LOWER(it.name) = 'odp' AND i.user_id = 22 "); $odps = $stmt->fetchAll(PDO::FETCH_ASSOC); $result = []; foreach ($odps as $odp) { // ✅ ambil client $stmtClient = $conn->prepare(" SELECT fi.id, fi.name, fi.serial_number FROM cable_routes cr JOIN ftth_items fi ON (cr.to_item_id = fi.id OR cr.from_item_id = fi.id) WHERE (cr.from_item_id = :id OR cr.to_item_id = :id) AND fi.id != :id "); $stmtClient->bindParam(':id', $odp['id']); $stmtClient->execute(); $clients = $stmtClient->fetchAll(PDO::FETCH_ASSOC); $rxValues = []; $rxList = []; $rxBadList = []; $clientBad = []; foreach ($clients as $c) { if (empty($c['serial_number'])) continue; $query = json_encode(["_id" => $c['serial_number']]); $url = "http://rmtstb.megadataisp.net:7557/devices/?query=" . urlencode($query); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 5); $res = curl_exec($ch); curl_close($ch); if (!$res) continue; $json = json_decode($res, true); if ( isset($json[0]['VirtualParameters']['RXPower']['_value']) && is_numeric($json[0]['VirtualParameters']['RXPower']['_value']) ) { $rx = floatval($json[0]['VirtualParameters']['RXPower']['_value']); $rxValues[] = $rx; $rxList[] = $rx; if ($rx < -23) { $rxBadList[] = $rx; $clientBad[] = $c['name'] . " (" . $rx . " dBm)"; } } } // 🔴 Tidak ada data if (count($rxValues) == 0) { $result[] = [ 'id' => $odp['id'], 'nama' => $odp['name'], 'lat' => $odp['latitude'], 'lng' => $odp['longitude'], 'total' => 0, 'avg_rx' => null, 'bad_count' => 0, 'min_rx' => null, 'status' => 'NO DATA', 'status_color' => 'secondary', 'analisa' => 'Tidak ada data pelanggan / ONU offline semua' ]; continue; } $total = count($rxValues); $avg = array_sum($rxValues) / $total; $min = min($rxValues); $bad = count($rxBadList); // 🔥 DETEKSI SELISIH $selisih = abs($avg - $min); // 🔥 STATUS $status = "BAIK"; $color = "success"; if ($selisih > 1.5) { $status = "WARNING"; $color = "warning"; } if ($avg < -23 || $bad > ($total * 0.3)) { $status = "WARNING"; $color = "warning"; } if ($avg < -25 || $bad > ($total * 0.5)) { $status = "BURUK"; $color = "danger"; } if ($min < -27) { $status = "KRITIS"; $color = "dark"; } // 🔥 ANALISA + TAMBAHAN INFORMASI CLIENT if ($min < ($avg - 1.5)) { $analisa = "Ada client lebih jelek dari yang lain → kemungkinan IKR/dropcore bermasalah"; } elseif ($status === "KRITIS") { $analisa = "Banyak RX < -27 dBm → kemungkinan feeder/ODP bermasalah"; } elseif ($status === "BURUK") { $analisa = "Lebih dari 50% client jelek → indikasi splitter ODP / konektor kotor"; } elseif ($status === "WARNING") { $analisa = "Sebagian client jelek → kemungkinan jalur ke rumah"; } else { $analisa = "Semua pelanggan normal"; } // 🔥 TAMBAHKAN DETAIL RX & CLIENT BURUK KE ANALISA $analisa .= " | RX: " . implode(", ", $rxList); if (!empty($clientBad)) { $analisa .= " | Client bermasalah: " . implode(", ", $clientBad); } $result[] = [ 'id' => $odp['id'], 'nama' => $odp['name'], 'lat' => $odp['latitude'], 'lng' => $odp['longitude'], 'total' => $total, 'avg_rx' => round($avg, 2), 'bad_count' => $bad, 'min_rx' => $min, 'status' => $status, 'status_color' => $color, 'analisa' => $analisa ]; } echo json_encode([ 'success' => true, 'data' => $result ]);