false, 'message' => 'device_id parameter is required.', ]); exit; } $minutes = max(1, min(1440, $minutes)); $limit = $limit > 0 ? min($limit, 5000) : 1500; try { $connection = controls_db_connect(); } catch (Throwable $exception) { echo json_encode([ 'success' => false, 'message' => 'Database connection failed: ' . $exception->getMessage(), ]); exit; } $startTime = (new DateTimeImmutable('now', new DateTimeZone('UTC'))) ->modify(sprintf('-%d minutes', $minutes)); $startBound = $startTime->format('Y-m-d H:i:s'); try { $statement = $connection->prepare( 'SELECT checked_at, latency_ms, status ' . 'FROM monitoring_latency_log ' . 'WHERE device_id = ? AND checked_at >= ? ' . 'ORDER BY checked_at ASC ' . 'LIMIT ?' ); $statement->bind_param('isi', $deviceId, $startBound, $limit); $statement->execute(); $result = $statement->get_result(); $series = []; while ($row = $result->fetch_assoc()) { $series[] = [ 'x' => gmdate('c', strtotime($row['checked_at'])), 'y' => $row['latency_ms'] !== null ? (float) $row['latency_ms'] : null, 'status' => $row['status'], ]; } $statement->close(); $connection->close(); echo json_encode([ 'success' => true, 'data' => $series, ]); } catch (Throwable $exception) { if (isset($statement) && $statement instanceof mysqli_stmt) { $statement->close(); } $connection->close(); echo json_encode([ 'success' => false, 'message' => 'Query failed: ' . $exception->getMessage(), ]); }