feat: added static for main page, added views.py: index, get_condig, websocket_endpoint (functionality for receiving commands from the frontend), added main.py: creating an application, connecting static and connecting a router, added Settings.py: class Settings with model_config and stream_url
This commit is contained in:
89
static/command.js
Normal file
89
static/command.js
Normal file
@@ -0,0 +1,89 @@
|
||||
// Ждём, пока загрузится весь контент DOM
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
// Создаём WebSocket-соединение с сервером
|
||||
const ws = new WebSocket(`ws://${window.location.host}/ws`);
|
||||
|
||||
// Делаем запрос к серверу на эндпоинт "/config"
|
||||
fetch('/config')
|
||||
.then(response => response.json()) // Преобразуем ответ в JSON
|
||||
.then(data => {
|
||||
// Получаем значение stream_url из ответа
|
||||
const streamUrl = data.stream_url;
|
||||
const videoElement = document.getElementById("video-stream");
|
||||
// Устанавливаем URL видеопотока в элемент <video>
|
||||
videoElement.src = streamUrl;
|
||||
});
|
||||
|
||||
// Обработчик события открытия WebSocket-соединения
|
||||
ws.onopen = function() {
|
||||
console.log("WebSocket подключен");
|
||||
};
|
||||
|
||||
// Обработчик события получения сообщения по WebSocket
|
||||
ws.onmessage = function(event) {
|
||||
console.log("Получено:", event.data); // Выводим полученные данные
|
||||
};
|
||||
|
||||
// Обработчик события закрытия WebSocket-соединения
|
||||
ws.onclose = function() {
|
||||
console.log("WebSocket закрыт");
|
||||
};
|
||||
|
||||
// Обработчик ошибок WebSocket
|
||||
ws.onerror = function(error) {
|
||||
console.log("WebSocket ошибка:", error); // Логируем ошибку
|
||||
};
|
||||
|
||||
let commandInterval;
|
||||
|
||||
// Функция для начала отправки команды с заданным интервалом
|
||||
function startSendingCommand(command) {
|
||||
// Отправляем команду сразу
|
||||
sendCommand(command);
|
||||
|
||||
// Запускаем интервал для повторной отправки команды
|
||||
commandInterval = setInterval(() => {
|
||||
sendCommand(command); // Повторяем отправку команды
|
||||
}, 10); // Интервал отправки — каждые 10 мс
|
||||
}
|
||||
|
||||
// Функция для остановки отправки команд
|
||||
function stopSendingCommand() {
|
||||
// Останавливаем интервал
|
||||
clearInterval(commandInterval);
|
||||
}
|
||||
|
||||
// Функция для отправки команды через WebSocket
|
||||
function sendCommand(command) {
|
||||
if (ws.readyState === WebSocket.OPEN) {
|
||||
ws.send(command); // Отправляем команду через WebSocket
|
||||
console.log("Команда:", command); // Логируем отправленную команду
|
||||
} else {
|
||||
console.log("WebSocket не подключён"); // Если WebSocket не открыт
|
||||
}
|
||||
}
|
||||
|
||||
// Назначение обработчиков событий для кнопки "Вперёд"
|
||||
const forwardButton = document.getElementById("forward-button");
|
||||
forwardButton.addEventListener("mousedown", () => startSendingCommand("forward")); // Начало отправки команды
|
||||
forwardButton.addEventListener("mouseup", stopSendingCommand); // Остановка отправки при отпускании кнопки
|
||||
forwardButton.addEventListener("mouseleave", stopSendingCommand); // Остановка отправки, если курсор уходит с кнопки
|
||||
|
||||
// Назначение обработчиков событий для кнопки "Влево"
|
||||
const leftButton = document.getElementById("left-button");
|
||||
leftButton.addEventListener("mousedown", () => startSendingCommand("left"));
|
||||
leftButton.addEventListener("mouseup", stopSendingCommand);
|
||||
leftButton.addEventListener("mouseleave", stopSendingCommand);
|
||||
|
||||
// Назначение обработчиков событий для кнопки "Вправо"
|
||||
const rightButton = document.getElementById("right-button");
|
||||
rightButton.addEventListener("mousedown", () => startSendingCommand("right"));
|
||||
rightButton.addEventListener("mouseup", stopSendingCommand);
|
||||
rightButton.addEventListener("mouseleave", stopSendingCommand);
|
||||
|
||||
// Назначение обработчиков событий для кнопки "Назад"
|
||||
const backwardButton = document.getElementById("backward-button");
|
||||
backwardButton.addEventListener("mousedown", () => startSendingCommand("backward"));
|
||||
backwardButton.addEventListener("mouseup", stopSendingCommand);
|
||||
backwardButton.addEventListener("mouseleave", stopSendingCommand);
|
||||
});
|
||||
57
static/index.html
Normal file
57
static/index.html
Normal file
@@ -0,0 +1,57 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{{ title }}</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons/font/bootstrap-icons.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/static/style.css">
|
||||
<script src="/static/command.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container mt-5">
|
||||
<h1 class="text-center mb-4">Управление роботом {{ name_robot }}</h1>
|
||||
|
||||
<!-- Видеопоток -->
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-7 px-0">
|
||||
<div class="card">
|
||||
<div class="card-body text-center">
|
||||
<img src="" class="img-fluid" id="video-stream" alt="Видеопоток">
|
||||
</div>
|
||||
|
||||
<div class="line"></div>
|
||||
|
||||
<!-- Кнопки -->
|
||||
<div class="col-md-12 d-flex align-items-center px-0">
|
||||
<div class="card-command card d-flex flex-column justify-content-center align-items-center">
|
||||
<!-- Вверх -->
|
||||
<button class="btn btn-warning m-1" id="forward-button">
|
||||
<i class="bi bi-arrow-up"></i>
|
||||
</button>
|
||||
<div class="d-flex">
|
||||
<!-- Влево -->
|
||||
<button class="btn btn-warning m-1" id="left-button">
|
||||
<i class="bi bi-arrow-left"></i>
|
||||
</button>
|
||||
<!-- Вниз -->
|
||||
<button class="btn btn-warning m-1" id="backward-button">
|
||||
<i class="bi bi-arrow-down"></i>
|
||||
</button>
|
||||
<!-- Вправо -->
|
||||
<button class="btn btn-warning m-1" id="right-button">
|
||||
<i class="bi bi-arrow-right"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
34
static/style.css
Normal file
34
static/style.css
Normal file
@@ -0,0 +1,34 @@
|
||||
/* Задает общий фон страницы */
|
||||
body {
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
|
||||
/* Создает тень для карточки, добавляя глубину и визуальную привлекательность */
|
||||
.card {
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* Устанавливает черный цвет фона для элементов с классами card-command и card-body */
|
||||
.card-command, .card-body {
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
/* Устанавливает стили для блока card-command */
|
||||
.card-command {
|
||||
width: 100%; /* Задает ширину в 100% */
|
||||
border-top-left-radius: 0; /* Убирает закругление верхнего левого угла */
|
||||
border-top-right-radius: 0; /* Убирает закругление верхнего правого угла */
|
||||
}
|
||||
|
||||
/* Определяет стили для горизонтальной линии между элементами */
|
||||
.line {
|
||||
background-color: #ffc107; /* Задает желтый цвет линии */
|
||||
height: 6px; /* Высота линии */
|
||||
width: 100%; /* Линия занимает всю ширину блока */
|
||||
}
|
||||
|
||||
/* Определяет максимальную ширину изображения и делает его адаптивным */
|
||||
img {
|
||||
max-width: 100%; /* Ограничивает ширину изображения, чтобы оно не выходило за пределы контейнера */
|
||||
height: auto; /* Автоматически изменяет высоту изображения пропорционально ширине */
|
||||
}
|
||||
Reference in New Issue
Block a user