diff --git a/package-lock.json b/package-lock.json
index 0dd0412..8f60141 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,12 +9,14 @@
"version": "1.0.0",
"license": "ISC",
"dependencies": {
+ "axios": "^1.5.0",
"dotenv": "^16.3.1",
"express": "^4.18.2",
"fs": "^0.0.1-security",
"handlebars": "^4.7.7",
"http": "^0.0.1-security",
"mapbox-gl": "^2.15.0",
+ "moment": "^2.29.4",
"multer": "^1.4.5-lts.1",
"path": "^0.12.7",
"pg": "^8.11.1",
@@ -108,6 +110,21 @@
"safer-buffer": "~2.1.0"
}
},
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
+ },
+ "node_modules/axios": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.5.0.tgz",
+ "integrity": "sha512-D4DdjDo5CY50Qms0qGQTTw6Q44jl7zRwY7bthds06pUGfChBCTcQs+N743eFWGEd6pRTMd6A+I87aWyFV5wiZQ==",
+ "dependencies": {
+ "follow-redirects": "^1.15.0",
+ "form-data": "^4.0.0",
+ "proxy-from-env": "^1.1.0"
+ }
+ },
"node_modules/bcrypt-pbkdf": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
@@ -169,6 +186,17 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
"node_modules/concat-stream": {
"version": "1.6.2",
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
@@ -247,6 +275,14 @@
"ms": "2.0.0"
}
},
+ "node_modules/delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
"node_modules/depd": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
@@ -401,6 +437,38 @@
"node": ">= 0.8"
}
},
+ "node_modules/follow-redirects": {
+ "version": "1.15.2",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
+ "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/form-data": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
+ "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/forwarded": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
@@ -692,6 +760,14 @@
"mkdirp": "bin/cmd.js"
}
},
+ "node_modules/moment": {
+ "version": "2.29.4",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
+ "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==",
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
@@ -957,6 +1033,11 @@
"node": ">= 0.10"
}
},
+ "node_modules/proxy-from-env": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
+ },
"node_modules/qs": {
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
@@ -1378,6 +1459,21 @@
"safer-buffer": "~2.1.0"
}
},
+ "asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
+ },
+ "axios": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.5.0.tgz",
+ "integrity": "sha512-D4DdjDo5CY50Qms0qGQTTw6Q44jl7zRwY7bthds06pUGfChBCTcQs+N743eFWGEd6pRTMd6A+I87aWyFV5wiZQ==",
+ "requires": {
+ "follow-redirects": "^1.15.0",
+ "form-data": "^4.0.0",
+ "proxy-from-env": "^1.1.0"
+ }
+ },
"bcrypt-pbkdf": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
@@ -1424,6 +1520,14 @@
"get-intrinsic": "^1.0.2"
}
},
+ "combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "requires": {
+ "delayed-stream": "~1.0.0"
+ }
+ },
"concat-stream": {
"version": "1.6.2",
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
@@ -1486,6 +1590,11 @@
"ms": "2.0.0"
}
},
+ "delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
+ },
"depd": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
@@ -1610,6 +1719,21 @@
"unpipe": "~1.0.0"
}
},
+ "follow-redirects": {
+ "version": "1.15.2",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
+ "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA=="
+ },
+ "form-data": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
+ "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+ "requires": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "mime-types": "^2.1.12"
+ }
+ },
"forwarded": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
@@ -1816,6 +1940,11 @@
"minimist": "^1.2.6"
}
},
+ "moment": {
+ "version": "2.29.4",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
+ "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w=="
+ },
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
@@ -2021,6 +2150,11 @@
"ipaddr.js": "1.9.1"
}
},
+ "proxy-from-env": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
+ },
"qs": {
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
diff --git a/package.json b/package.json
index 6fa4ad8..0f2b0b3 100644
--- a/package.json
+++ b/package.json
@@ -10,12 +10,14 @@
"author": "",
"license": "ISC",
"dependencies": {
+ "axios": "^1.5.0",
"dotenv": "^16.3.1",
"express": "^4.18.2",
"fs": "^0.0.1-security",
"handlebars": "^4.7.7",
"http": "^0.0.1-security",
"mapbox-gl": "^2.15.0",
+ "moment": "^2.29.4",
"multer": "^1.4.5-lts.1",
"path": "^0.12.7",
"pg": "^8.11.1",
diff --git a/server.js b/server.js
index 595b19c..5096148 100644
--- a/server.js
+++ b/server.js
@@ -8,6 +8,9 @@ require("dotenv").config();
const multer = require("multer");
const http = require("http");
const Client = require('ssh2').Client;
+const axios = require('axios');
+const moment = require('moment');
+
const storage = multer.diskStorage({
@@ -1647,6 +1650,71 @@ async function videoExport(req, res) {
}
}
+app.get('/getData', async (req, res) => {
+ const selectedSerial = req.query.serial;
+ const selectedDate = req.query.selectedDate;
+ const selectedTime = req.query.selectedTime;
+ const selectedChannel = req.query.selectedChannel;
+
+ try {
+ const successResponse = await axios.get(`http://krbl.ru:8080/http/filelist/request?serial=${selectedSerial}&querytime=${selectedDate}&channel=${selectedChannel}`);
+ if (successResponse.data.SUCCESS) {
+ const dataResponse = await axios.get(`http://krbl.ru:8080/http/filelist/get?serial=${selectedSerial}&querytime=${selectedDate}&channel=${selectedChannel}`);
+ if (successResponse.data.SUCCESS) {
+ const dataId = dataResponse.data.DATAID;
+ const dateRanges = dataResponse.data.DATA;
+ let dataFound = false;
+ let selectedDataId = null;
+ const selectedDateTime = moment(selectedDate + selectedTime, 'YYYYMMDDHHmmss').valueOf();
+
+ if (dateRanges.length === 1) {
+ // Если в массиве DATA только одно значение
+ const [startRange, endRange] = dateRanges[0].split('-');
+ const startDateTime = moment(startRange, 'YYYYMMDDHHmmss').valueOf();
+ const endDateTime = moment(endRange, 'YYYYMMDDHHmmss').valueOf();
+
+ if (!isNaN(selectedDateTime) && !isNaN(startDateTime) && !isNaN(endDateTime)) {
+ if (selectedDateTime >= startDateTime && selectedDateTime <= endDateTime) {
+ dataFound = true;
+ selectedDataId = dataId[0];
+ }
+ } else {
+ console.error("Неверный формат данных для сравнения.");
+ }
+ } else {
+ // Если в массиве DATA больше одного значения
+ for (let i = 0; i < dateRanges.length; i++) {
+ const [startRange, endRange] = dateRanges[i].split('-');
+ const startDateTime = moment(startRange, 'YYYYMMDDHHmmss').valueOf();
+ const endDateTime = moment(endRange, 'YYYYMMDDHHmmss').valueOf();
+
+ if (!isNaN(selectedDateTime) && !isNaN(startDateTime) && !isNaN(endDateTime)) {
+ if (selectedDateTime >= startDateTime && selectedDateTime <= endDateTime) {
+ dataFound = true;
+ selectedDataId = dataId[i];
+ break;
+ }
+ } else {
+ console.error("Неверный формат данных для сравнения.");
+ }
+ }
+ }
+
+
+ if (dataFound) {
+ // Здесь можно отправить запрос скоростей и отрисовать график
+ res.json({ success: true, dataId: selectedDataId });
+ } else {
+ res.json({ success: false, message: 'Данных для выбранного периода нет' });
+ }
+ }} else {
+ res.json({ success: false, message: 'Ошибка при получении данных' });
+ }
+ } catch (error) {
+ console.error('Ошибка при отправке запроса:', error);
+ res.json({ success: false, message: 'Ошибка при отправке запроса' });
+ }
+});
app.post("/getspeedarchive", async (req, res) => {
const { serial, datetime } = req.body;
diff --git a/static/styles/main.css b/static/styles/main.css
index 08c072b..445b8f8 100644
--- a/static/styles/main.css
+++ b/static/styles/main.css
@@ -1462,6 +1462,26 @@ input[type="datetime-local"] {
padding-bottom: 0;
}
+.speedometr .speed-bg {
+ z-index: 10;
+ position: absolute;
+ top: 0;
+ left: -20px;
+ border-radius: 15px;
+ background-color: #FFFFFF99;
+ width: 100%;
+ height: 100%;
+ overflow: hidden;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.speedometr .speed-bg h1 {
+ text-align: center;
+ margin: 0 10px;
+}
+
.report li {
list-style-type: none;
margin-bottom: 12px;
diff --git a/static/templates/videos/export.html b/static/templates/videos/export.html
index dbe7674..0385496 100644
--- a/static/templates/videos/export.html
+++ b/static/templates/videos/export.html
@@ -114,69 +114,69 @@
-
Запустить 1 камеру
+
Экспортировать 1 камеру
-
Запустить 2 камеру
+
Экспортировать 2 камеру
-
Запустить 3 камеру
+
Экспортировать 3 камеру
-
Запустить 4 камеру
+
Экспортировать 4 камеру
-
Запустить 5 камеру
+
Экспортировать 5 камеру
-
Запустить 6 камеру
+
Экспортировать 6 камеру
-
Запустить 7 камеру
+
Экспортировать 7 камеру
-
Запустить 8 камеру
+
Экспортировать 8 камеру
-
Запустить 9 камеру
+
Экспортировать 9 камеру
-
Запустить 10 камеру
+
Экспортировать 10 камеру
-
Запустить 11 камеру
+
Экспортировать 11 камеру
-
Запустить 12 камеру
+
Экспортировать 12 камеру
-
Запустить 13 камеру
+
Экспортировать 13 камеру
-
Запустить 14 камеру
+
Экспортировать 14 камеру
-
Запустить 15 камеру
+
Экспортировать 15 камеру
-
Запустить 16 камеру
+
Экспортировать 16 камеру
@@ -202,6 +202,9 @@
+
+
Данных для выбранного периода нет.
+
Скорость
км/ч
1 ч
@@ -211,7 +214,10 @@
+ с
+ до
+
@@ -267,117 +273,168 @@ function combineDateTime(dateString, timeString) {
return combinedDateTime;
}
-function sendPostRequest() {
+let HasData;
+let recordID;
+var selectedChannel = 1;
+
+
+
+async function sendPostRequest() {
// Получение данных из полей ввода
const selectedDate = document.getElementById("selectedDate").value;
const videoTime = document.getElementById("video-time").value;
+ const videoEndTime = document.getElementById("video-end-time").value;
const selectedSerial = document.querySelector('input[name="camera-serial"]:checked').value;
+
// Объединяем дату и время и преобразуем в нужный формат
const combinedDateTime = combineDateTime(selectedDate, videoTime);
- const requestData = {
- serial: selectedSerial,
- datetime: combinedDateTime,
- };
+ const response = await fetch(`/getData?serial=${selectedSerial}&selectedDate=${formatDate(selectedDate)}&selectedTime=${formatTime(videoTime)}&selectedChannel=${selectedChannel}`);
- fetch("/getspeedarchive", {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- },
- body: JSON.stringify(requestData),
- })
- .then((response) => response.json())
- .then((data) => {
+ const data = await response.json();
- const existingChart = Chart.getChart("speed");
+ HasData = data.success;
- if (existingChart) {
- existingChart.destroy();
- }
+ if (data.success) {
+ console.log(`Данные доступны. DATAID: ${data.dataId}`)
+ recordID = data.dataId;
+ const requestData = {
+ serial: selectedSerial,
+ datetime: combinedDateTime,
+ };
- const numberOfLabels = data.speeds.length;
- const labels = Array.from({ length: numberOfLabels }, () => "");
+ fetch("/getspeedarchive", {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify(requestData),
+ })
+ .then((response) => response.json())
+ .then((data) => {
- // Обновление данных графика
- const chart = new Chart("speed", {
- type: "line",
- data: {
- labels: labels,
- datasets: [
- {
- label: "Скорость",
- borderColor: "#8086F9",
- fill: false,
- data: data.speeds,
- pointStyle: false,
- pointRadius: 25,
- pointHoverRadius: 25,
- tension: 0.1,
- },
- ],
- },
- options: {
- plugins: {
- legend: {
- display: false,
- },
- },
- labelStep: "3",
- responsive: true,
- maintainAspectRatio: false,
- scales: {
- y: {
- stacked: true,
- grid: {
- display: true,
- color: "#D9D9D9",
- },
- ticks: {
- stepSize: 10,
- },
- },
- x: {
- grid: {
- display: false,
- },
- },
- },
- },
- });
+ const existingChart = Chart.getChart("speed");
+
+ if (existingChart) {
+ existingChart.destroy();
+ }
+
+ const numberOfLabels = data.speeds.length;
+ const labels = Array.from({ length: numberOfLabels }, () => "");
+
+ // Обновление данных графика
+ const chart = new Chart("speed", {
+ type: "line",
+ data: {
+ labels: labels,
+ datasets: [
+ {
+ label: "Скорость",
+ borderColor: "#8086F9",
+ fill: false,
+ data: data.speeds,
+ pointStyle: false,
+ pointRadius: 25,
+ pointHoverRadius: 25,
+ tension: 0.1,
+ },
+ ],
+ },
+ options: {
+ plugins: {
+ legend: {
+ display: false,
+ },
+ },
+ labelStep: "3",
+ responsive: true,
+ maintainAspectRatio: false,
+ scales: {
+ y: {
+ stacked: true,
+ grid: {
+ display: true,
+ color: "#D9D9D9",
+ },
+ ticks: {
+ stepSize: 10,
+ },
+ },
+ x: {
+ grid: {
+ display: false,
+ },
+ },
+ },
+ },
+ });
- const geoData = data.geo;
+ const geoData = data.geo;
- // Очищаем все слои на карте
-map.eachLayer(layer => {
- if (layer !== map) {
- map.removeLayer(layer);
- }
-});
+ // Очищаем все слои на карте
+ map.eachLayer(layer => {
+ if (layer !== map) {
+ map.removeLayer(layer);
+ }
+ });
-// Добавляем слой с плитками OpenStreetMap
-L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}').addTo(map);
+ // Добавляем слой с плитками OpenStreetMap
+ L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}').addTo(map);
-// Создаем слой для маршрута
-const routeLayer = L.layerGroup().addTo(map);
+ // Создаем слой для маршрута
+ const routeLayer = L.layerGroup().addTo(map);
-// Создаем слой для маркеров
-const markerLayer = L.layerGroup().addTo(map);
+ // Создаем слой для маркеров
+ const markerLayer = L.layerGroup().addTo(map);
-// Преобразуем координаты точек маршрута
-const routePoints = geoData.map(point => [point.latitude, point.longitude]);
+ // Преобразуем координаты точек маршрута
+ const routePoints = geoData.map(point => [point.latitude, point.longitude]);
-// Создаем линию маршрута
-const route = L.polyline(routePoints, { color: 'red',weight: 5 }).addTo(routeLayer);
+ // Создаем линию маршрута
+ const route = L.polyline(routePoints, { color: 'red',weight: 5 }).addTo(routeLayer);
- })
- .catch((error) => {
- console.error("Ошибка при отправке запроса:", error);
- });
+ })
+ .catch((error) => {
+ console.error("Ошибка при отправке запроса:", error);
+ });
+
+ const endResponse = await fetch(`/getData?serial=${selectedSerial}&selectedDate=${formatDate(selectedDate)}&selectedTime=${formatTime(videoEndTime)}&selectedChannel=${selectedChannel}`);
+
+ const endData = await endResponse.json();
+
+ if (endData.success) {
+ console.log(`Конечные данные доступны. DATAID: ${endData.dataId}`)
+ const speedBG = document.getElementById("speed-bg");
+ speedBG.style.display = 'none';
+ HasData = true;
+ if (data.dataId != endData.dataId) {
+ HasData = false;
+ var h1Element = document.querySelector('.speedometr h1');
+ h1Element.textContent = 'Временной диапазон находится в разных видео сессиях. Измените время.';
+ const speedBG = document.getElementById("speed-bg");
+ speedBG.style.display = 'flex';
+ }
+ } else {
+ HasData = false;
+ const speedBG = document.getElementById("speed-bg");
+ speedBG.style.display = 'flex';
+ var h1Element = document.querySelector('.speedometr h1');
+ h1Element.textContent = 'Данных для выбранного периода нет.';
+ }
+
+
+ } else {
+ var h1Element = document.querySelector('.speedometr h1');
+ h1Element.textContent = 'Данных для выбранного периода нет.';
+ const speedBG = document.getElementById("speed-bg");
+ speedBG.style.display = 'flex';
+ }
+
+
}
@@ -392,6 +449,9 @@ selectedDateInput.addEventListener("change", sendPostRequest);
const videoTimeInput = document.getElementById("video-time");
videoTimeInput.addEventListener("change", sendPostRequest);
+const endVideoTimeInput = document.getElementById("video-end-time");
+endVideoTimeInput.addEventListener("change", sendPostRequest);
+
@@ -400,6 +460,20 @@ videoTimeInput.addEventListener("change", sendPostRequest);
now.setHours(now.getHours() - 1);
var formattedTime = now.toISOString().substr(11, 8);
document.getElementById("video-time").value = formattedTime;
+ const startTimeInput = document.getElementById('video-time');
+ const endTimeInput = document.getElementById('video-end-time');
+
+ const startTime = new Date(`1970-01-01T${startTimeInput.value}Z`);
+
+ startTime.setHours(startTime.getHours() - 3);
+ startTime.setSeconds(startTime.getSeconds() + 10);
+
+ const hours = startTime.getHours().toString().padStart(2, '0');
+ const minutes = startTime.getMinutes().toString().padStart(2, '0');
+ const seconds = startTime.getSeconds().toString().padStart(2, '0');
+ const endTimeString = `${hours}:${minutes}:${seconds}`;
+
+ endTimeInput.value = endTimeString;
@@ -452,10 +526,11 @@ videoTimeInput.addEventListener("change", sendPostRequest);
selectedDate = new Date(currentDate.getFullYear(), currentDate.getMonth(), day);
renderCalendar();
selectedDateInput.value = selectedDate.toISOString();
+ sendPostRequest();
});
datesContainer.appendChild(dateCell);
}
- sendPostRequest();
+
}
// Перейти на предыдущий месяц
@@ -477,7 +552,7 @@ videoTimeInput.addEventListener("change", sendPostRequest);
diff --git a/static/templates/videos/playback.html b/static/templates/videos/playback.html
index af505c5..a19174e 100644
--- a/static/templates/videos/playback.html
+++ b/static/templates/videos/playback.html
@@ -68,7 +68,7 @@
@@ -202,6 +202,9 @@
+
+
Данных для выбранного периода нет.
+
Скорость
км/ч
1 ч
@@ -267,117 +270,134 @@ function combineDateTime(dateString, timeString) {
return combinedDateTime;
}
-function sendPostRequest() {
+let HasData;
+var selectedChannel = 1;
+
+async function sendPostRequest() {
// Получение данных из полей ввода
const selectedDate = document.getElementById("selectedDate").value;
const videoTime = document.getElementById("video-time").value;
const selectedSerial = document.querySelector('input[name="camera-serial"]:checked').value;
+
// Объединяем дату и время и преобразуем в нужный формат
const combinedDateTime = combineDateTime(selectedDate, videoTime);
- const requestData = {
- serial: selectedSerial,
- datetime: combinedDateTime,
- };
+ const response = await fetch(`/getData?serial=${selectedSerial}&selectedDate=${formatDate(selectedDate)}&selectedTime=${formatTime(videoTime)}&selectedChannel=${selectedChannel}`);
+ const data = await response.json();
- fetch("/getspeedarchive", {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- },
- body: JSON.stringify(requestData),
- })
- .then((response) => response.json())
- .then((data) => {
+ HasData = data.success;
- const existingChart = Chart.getChart("speed");
+ if (data.success) {
+ console.log(`Данные доступны. DATAID: ${data.dataId}`)
+ const requestData = {
+ serial: selectedSerial,
+ datetime: combinedDateTime,
+ };
- if (existingChart) {
- existingChart.destroy();
- }
+ fetch("/getspeedarchive", {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify(requestData),
+ })
+ .then((response) => response.json())
+ .then((data) => {
- const numberOfLabels = data.speeds.length;
- const labels = Array.from({ length: numberOfLabels }, () => "");
+ const existingChart = Chart.getChart("speed");
- // Обновление данных графика
- const chart = new Chart("speed", {
- type: "line",
- data: {
- labels: labels,
- datasets: [
- {
- label: "Скорость",
- borderColor: "#8086F9",
- fill: false,
- data: data.speeds,
- pointStyle: false,
- pointRadius: 25,
- pointHoverRadius: 25,
- tension: 0.1,
- },
- ],
- },
- options: {
- plugins: {
- legend: {
- display: false,
- },
- },
- labelStep: "3",
- responsive: true,
- maintainAspectRatio: false,
- scales: {
- y: {
- stacked: true,
- grid: {
- display: true,
- color: "#D9D9D9",
- },
- ticks: {
- stepSize: 10,
- },
- },
- x: {
- grid: {
- display: false,
- },
- },
- },
- },
- });
+ if (existingChart) {
+ existingChart.destroy();
+ }
+
+ const numberOfLabels = data.speeds.length;
+ const labels = Array.from({ length: numberOfLabels }, () => "");
+
+ // Обновление данных графика
+ const chart = new Chart("speed", {
+ type: "line",
+ data: {
+ labels: labels,
+ datasets: [
+ {
+ label: "Скорость",
+ borderColor: "#8086F9",
+ fill: false,
+ data: data.speeds,
+ pointStyle: false,
+ pointRadius: 25,
+ pointHoverRadius: 25,
+ tension: 0.1,
+ },
+ ],
+ },
+ options: {
+ plugins: {
+ legend: {
+ display: false,
+ },
+ },
+ labelStep: "3",
+ responsive: true,
+ maintainAspectRatio: false,
+ scales: {
+ y: {
+ stacked: true,
+ grid: {
+ display: true,
+ color: "#D9D9D9",
+ },
+ ticks: {
+ stepSize: 10,
+ },
+ },
+ x: {
+ grid: {
+ display: false,
+ },
+ },
+ },
+ },
+ });
- const geoData = data.geo;
+ const geoData = data.geo;
- // Очищаем все слои на карте
-map.eachLayer(layer => {
- if (layer !== map) {
- map.removeLayer(layer);
- }
-});
+ // Очищаем все слои на карте
+ map.eachLayer(layer => {
+ if (layer !== map) {
+ map.removeLayer(layer);
+ }
+ });
-// Добавляем слой с плитками OpenStreetMap
-L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}').addTo(map);
+ // Добавляем слой с плитками OpenStreetMap
+ L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}').addTo(map);
-// Создаем слой для маршрута
-const routeLayer = L.layerGroup().addTo(map);
+ // Создаем слой для маршрута
+ const routeLayer = L.layerGroup().addTo(map);
-// Создаем слой для маркеров
-const markerLayer = L.layerGroup().addTo(map);
+ // Создаем слой для маркеров
+ const markerLayer = L.layerGroup().addTo(map);
-// Преобразуем координаты точек маршрута
-const routePoints = geoData.map(point => [point.latitude, point.longitude]);
+ // Преобразуем координаты точек маршрута
+ const routePoints = geoData.map(point => [point.latitude, point.longitude]);
-// Создаем линию маршрута
-const route = L.polyline(routePoints, { color: 'red',weight: 5 }).addTo(routeLayer);
+ // Создаем линию маршрута
+ const route = L.polyline(routePoints, { color: 'red',weight: 5 }).addTo(routeLayer);
- })
- .catch((error) => {
- console.error("Ошибка при отправке запроса:", error);
- });
+ })
+ .catch((error) => {
+ console.error("Ошибка при отправке запроса:", error);
+ });
+ } else {
+ const speedBG = document.getElementById("speed-bg");
+ speedBG.style.display = 'flex';
+ }
+
+
}
@@ -452,10 +472,11 @@ videoTimeInput.addEventListener("change", sendPostRequest);
selectedDate = new Date(currentDate.getFullYear(), currentDate.getMonth(), day);
renderCalendar();
selectedDateInput.value = selectedDate.toISOString();
+ sendPostRequest();
});
datesContainer.appendChild(dateCell);
}
- sendPostRequest();
+
}
// Перейти на предыдущий месяц
@@ -508,6 +529,11 @@ videoTimeInput.addEventListener("change", sendPostRequest);
alert('Пожалуйста, выберите устройство из списка.');
return;
}
+ if (!HasData) {
+ alert('Пожалуйста, выберите другой временной период.');
+ return;
+ }
+
const startTimeInput = document.getElementById('video-time');
const selectedDateInput = document.getElementById('selectedDate');
@@ -518,6 +544,8 @@ videoTimeInput.addEventListener("change", sendPostRequest);
const serial = selectedDevice.value;
+ selectedChannel = channel;
+
const url = `http://localhost:8081/playback?url=http%3A%2F%2Fkrbl.ru%3A8080%2Fhttp%2Fplayback.flv%3Fserial%3D${serial}%26channel%3D${channel}%26quality%3D1%26queryTime%3D${selectedDate}%26startTime%3D${startTime}%26endTime%3D${endTime}`;
window.open(url, '_blank');
}