сделал частично работающую статистику
This commit is contained in:
parent
e8eeee3755
commit
a7f323a07c
@ -36,6 +36,8 @@ add_executable(terminal-web-server
|
|||||||
src/server/resource.h
|
src/server/resource.h
|
||||||
src/terminal_api_driver.h
|
src/terminal_api_driver.h
|
||||||
src/terminal_api_driver.cpp
|
src/terminal_api_driver.cpp
|
||||||
|
src/auth/resources.cpp
|
||||||
|
src/auth/resources.h
|
||||||
)
|
)
|
||||||
|
|
||||||
find_package(Boost 1.53.0 COMPONENTS system thread filesystem log log_setup REQUIRED)
|
find_package(Boost 1.53.0 COMPONENTS system thread filesystem log log_setup REQUIRED)
|
||||||
|
5
src/auth/resources.cpp
Normal file
5
src/auth/resources.cpp
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
//
|
||||||
|
// Created by vlad on 31.10.2024.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "resources.h"
|
28
src/auth/resources.h
Normal file
28
src/auth/resources.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#ifndef RESOURCES_H
|
||||||
|
#define RESOURCES_H
|
||||||
|
#include "../server/resource.h"
|
||||||
|
|
||||||
|
namespace http::auth {
|
||||||
|
/**
|
||||||
|
* Класс пользовательских разрешений,
|
||||||
|
*/
|
||||||
|
class UserPremision{};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Класс пользователя, содержит логин/хеш_пароля/настройки пользователя/права
|
||||||
|
*/
|
||||||
|
class User{};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Класс аутентификации. Управляет всеми сессиями, создает новые при логине, удаляет при логауте.
|
||||||
|
* @note Класс устанавливает заголовок 'Set-Cookie' в ответе, и этот заголовок должен дойти до пользователя!
|
||||||
|
*/
|
||||||
|
class AuthProvider {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class NeedAuentificationResource: public resource::BasicResource {};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //RESOURCES_H
|
@ -75,7 +75,10 @@ void init_logging() {
|
|||||||
static void initResources(http::server::Server& s, std::shared_ptr<api_driver::ApiDriver>& api) {
|
static void initResources(http::server::Server& s, std::shared_ptr<api_driver::ApiDriver>& api) {
|
||||||
s.resources.emplace_back(std::make_unique<http::resource::StaticFileResource>("/", "static/main.html", mime_types::text_html));
|
s.resources.emplace_back(std::make_unique<http::resource::StaticFileResource>("/", "static/main.html", mime_types::text_html));
|
||||||
s.resources.emplace_back(std::make_unique<http::resource::StaticFileResource>("/login", "static/login.html", mime_types::text_html));
|
s.resources.emplace_back(std::make_unique<http::resource::StaticFileResource>("/login", "static/login.html", mime_types::text_html));
|
||||||
|
|
||||||
s.resources.emplace_back(std::make_unique<http::resource::StaticFileResource>("/favicon.ico", "static/favicon.png", mime_types::image_png));
|
s.resources.emplace_back(std::make_unique<http::resource::StaticFileResource>("/favicon.ico", "static/favicon.png", mime_types::image_png));
|
||||||
|
s.resources.emplace_back(std::make_unique<http::resource::StaticFileResource>("/images/krokodil_vzryvaetsya_hd.gif", "static/krokodil.gif", mime_types::image_gif));
|
||||||
|
|
||||||
s.resources.emplace_back(std::make_unique<http::resource::StaticFileResource>("/style.css", "static/style.css", mime_types::text_css));
|
s.resources.emplace_back(std::make_unique<http::resource::StaticFileResource>("/style.css", "static/style.css", mime_types::text_css));
|
||||||
s.resources.emplace_back(std::make_unique<http::resource::StaticFileResource>("/js/vue.js", "static/js/vue.js", mime_types::javascript));
|
s.resources.emplace_back(std::make_unique<http::resource::StaticFileResource>("/js/vue.js", "static/js/vue.js", mime_types::javascript));
|
||||||
|
|
||||||
|
@ -2,6 +2,36 @@
|
|||||||
#include "terminal_api/ControlProtoCInterface.h"
|
#include "terminal_api/ControlProtoCInterface.h"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
/*
|
||||||
|
timer_->timeout().connect([=]{
|
||||||
|
double txpwd = 0;
|
||||||
|
CP_GetGain(sid, "TXPWD", &txpwd);
|
||||||
|
transmitt_active->set_end(!txpwd);
|
||||||
|
CP_GetLevelDemod(sid, "modcod_tx", &txpwd);
|
||||||
|
modcod_tx->setText(std::to_string(static_cast<uint32_t>(txpwd) >> 2));
|
||||||
|
uint8_t type_pack = static_cast<uint8_t>(txpwd);
|
||||||
|
type_pack = type_pack & 0b00000010;
|
||||||
|
if(type_pack)
|
||||||
|
type_pack_lbl->setText("short");
|
||||||
|
else
|
||||||
|
type_pack_lbl->setText("normal");
|
||||||
|
|
||||||
|
uint8_t is_pilots = static_cast<uint8_t>(txpwd);
|
||||||
|
is_pilots = is_pilots & 0b00000001;
|
||||||
|
if(is_pilots)
|
||||||
|
pilot_lbl->setText("pilots");
|
||||||
|
else
|
||||||
|
pilot_lbl->setText("no pilots");
|
||||||
|
|
||||||
|
CP_GetLevelDemod(sid, "snr_acm", &txpwd);
|
||||||
|
std::stringstream buf_double;
|
||||||
|
buf_double << std::fixed <<
|
||||||
|
std::setprecision(2) << txpwd;
|
||||||
|
snr_acm->setText(buf_double.str());
|
||||||
|
});
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
api_driver::ApiDriver::ApiDriver() {
|
api_driver::ApiDriver::ApiDriver() {
|
||||||
CP_Login("admin", "pass", &sid, &access);
|
CP_Login("admin", "pass", &sid, &access);
|
||||||
}
|
}
|
||||||
@ -26,7 +56,45 @@ std::string api_driver::ApiDriver::loadTerminalState() {
|
|||||||
std::stringstream result;
|
std::stringstream result;
|
||||||
result << "{";
|
result << "{";
|
||||||
|
|
||||||
result << "\"txState\":" << boolAsStr(DriverCP_GetGain(sid, "TXPWD"));
|
{
|
||||||
|
// формируем структуру TX
|
||||||
|
|
||||||
|
result << "\"tx.state\":" << boolAsStr(DriverCP_GetGain(sid, "TXPWD"));
|
||||||
|
|
||||||
|
double tmp = 0;
|
||||||
|
char tmpStr[64];
|
||||||
|
|
||||||
|
CP_GetLevelDemod(sid, "snr_acm", &tmp);
|
||||||
|
sprintf(tmpStr, "%.2f", tmp);
|
||||||
|
result << ",\"tx.snr\":" << tmpStr;
|
||||||
|
|
||||||
|
CP_GetLevelDemod(sid, "modcod_tx", &tmp);
|
||||||
|
result << ",\"tx.modcod\":" << (static_cast<uint32_t>(tmp) >> 2);
|
||||||
|
|
||||||
|
if (static_cast<uint8_t>(tmp) & 0b00000010) {
|
||||||
|
result << R"(,"tx.frameSize":"short")";
|
||||||
|
} else {
|
||||||
|
result << R"(,"tx.frameSize":"normal")";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (static_cast<uint8_t>(tmp) & 0b00000001) {
|
||||||
|
result << R"(,"tx.pilots":"pilots")";
|
||||||
|
} else {
|
||||||
|
result << R"(,"tx.pilots":"no pilots")";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string speed;
|
||||||
|
CP_GetDmaDebug(sid, "speed_tx", &speed);
|
||||||
|
sprintf(tmpStr, "%.3f", std::atof(speed.c_str()) / 128.0);
|
||||||
|
result << ",\"tx.speedOnTxKbit\":" << tmpStr;
|
||||||
|
|
||||||
|
CP_GetDmaDebug(sid, "speed_tx_iface", &speed);
|
||||||
|
sprintf(tmpStr, "%.3f", std::atof(speed.c_str()) / 128.0);
|
||||||
|
result << ",\"tx.speedOnIifKbit\":" << tmpStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// формируем структуру RX
|
||||||
|
|
||||||
const auto sym_sync_lock = DriverCP_GetLevelDemod(sid, "sym_sync_lock"); // захват символьной
|
const auto sym_sync_lock = DriverCP_GetLevelDemod(sid, "sym_sync_lock"); // захват символьной
|
||||||
const auto freq_search_lock = DriverCP_GetLevelDemod(sid, "freq_lock"); // Захват поиска по частоте
|
const auto freq_search_lock = DriverCP_GetLevelDemod(sid, "freq_lock"); // Захват поиска по частоте
|
||||||
@ -34,40 +102,120 @@ std::string api_driver::ApiDriver::loadTerminalState() {
|
|||||||
const auto pkt_sync = DriverCP_GetLevelDemod(sid, "pkt_sync"); // захват пакетной синхронизации
|
const auto pkt_sync = DriverCP_GetLevelDemod(sid, "pkt_sync"); // захват пакетной синхронизации
|
||||||
const auto receive_active = sym_sync_lock && freq_search_lock && afc_lock && pkt_sync;
|
const auto receive_active = sym_sync_lock && freq_search_lock && afc_lock && pkt_sync;
|
||||||
|
|
||||||
result << ",\"rxState\":" << boolAsStr(receive_active);
|
result << ",\"rx.state\":" << boolAsStr(receive_active);
|
||||||
result << ",\"rx.sym_sync_lock\":" << boolAsStr(sym_sync_lock);
|
result << ",\"rx.sym_sync_lock\":" << boolAsStr(sym_sync_lock);
|
||||||
result << ",\"rx.freq_search_lock\":" << boolAsStr(freq_search_lock);
|
result << ",\"rx.freq_search_lock\":" << boolAsStr(freq_search_lock);
|
||||||
result << ",\"rx.afc_lock\":" << boolAsStr(afc_lock);
|
result << ",\"rx.afc_lock\":" << boolAsStr(afc_lock);
|
||||||
result << ",\"rx.pkt_sync\":" << boolAsStr(pkt_sync);
|
result << ",\"rx.pkt_sync\":" << boolAsStr(pkt_sync);
|
||||||
|
|
||||||
result << "}";
|
double tmpd = 0; uint32_t tmpu32 = 0;
|
||||||
|
char tmpStr[64];
|
||||||
|
|
||||||
// return R"({"rxState":0,"txState":0,"testState":0})";
|
/*
|
||||||
return result.str();
|
rx: {
|
||||||
|
// индикаторы
|
||||||
|
state: '?', // общее состояние
|
||||||
|
sym_sync_lock: '?', // захват символьной
|
||||||
|
freq_search_lock: '?', // Захват поиска по частоте
|
||||||
|
afc_lock: '?', // захват ФАПЧ
|
||||||
|
pkt_sync: '?', // захват пакетной синхронизации
|
||||||
|
|
||||||
|
// куча других параметров, идет в том же порядке, что и в таблице
|
||||||
|
snr: 0, rssi: -105,
|
||||||
|
modcod: 0, frameSize: 0,
|
||||||
|
pilots: '?',
|
||||||
|
symError: 0.0,
|
||||||
|
freqErr: 0, freqErrAcc: 0,
|
||||||
|
inputSignalLevel: 0,
|
||||||
|
pllError: 0,
|
||||||
|
speedOnRxKbit: 0,
|
||||||
|
speedOnIifKbit: 0,
|
||||||
|
|
||||||
|
// статистика пакетов
|
||||||
|
packetsOk: 0,
|
||||||
|
packetsBad: 0,
|
||||||
|
packetsDummy: 0,
|
||||||
|
},
|
||||||
|
|
||||||
|
testState: '?'
|
||||||
|
*/
|
||||||
|
|
||||||
|
CP_GetLevelDemod(sid, "snr", &tmpd);
|
||||||
|
sprintf(tmpStr, "%.2f", tmpd);
|
||||||
|
result << ",\"rx.snr\":" << tmpStr;
|
||||||
|
|
||||||
|
CP_GetLevelDemod(sid, "rssi", &tmpd);
|
||||||
|
sprintf(tmpStr, "%.2f", tmpd);
|
||||||
|
result << ",\"rx.rssi\":" << tmpStr;
|
||||||
|
|
||||||
|
CP_GetDemodulatorParams(sid, "modcod", &tmpu32);
|
||||||
|
result << ",\"rx.modcod\":" << tmpu32;
|
||||||
|
|
||||||
|
CP_GetDemodulatorParams(sid, "type_pack", &tmpu32);
|
||||||
|
if (tmpu32) {
|
||||||
|
result << R"(,"rx.frameSize":"short")";
|
||||||
|
} else {
|
||||||
|
result << R"(,"rx.frameSize":"normal")";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string api_driver::ApiDriver::loadDeviceStatistics() {
|
CP_GetDemodulatorParams(sid, "is_pilots", &tmpu32);
|
||||||
std::stringstream result;
|
if (tmpu32) {
|
||||||
result << "{";
|
result << R"(,"rx.pilots":"pilots")";
|
||||||
|
} else {
|
||||||
|
result << R"(,"rx.pilots":"no pilots")";
|
||||||
|
}
|
||||||
|
|
||||||
result << "\"txState\":" << boolAsStr(DriverCP_GetGain(sid, "TXPWD"));
|
CP_GetLevelDemod(sid, "sym_err", &tmpd);
|
||||||
|
sprintf(tmpStr, "%.2f", tmpd);
|
||||||
|
result << ",\"rx.symError\":" << tmpStr;
|
||||||
|
|
||||||
const auto sym_sync_lock = DriverCP_GetLevelDemod(sid, "sym_sync_lock"); // захват символьной
|
CP_GetLevelDemod(sid, "crs_freq_err", &tmpd); // freqErr
|
||||||
const auto freq_search_lock = DriverCP_GetLevelDemod(sid, "freq_lock"); // Захват поиска по частоте
|
sprintf(tmpStr, "%.2f", tmpd);
|
||||||
const auto afc_lock = DriverCP_GetLevelDemod(sid, "afc_lock"); // захват ФАПЧ
|
result << ",\"rx.freqErr\":" << tmpStr;
|
||||||
const auto pkt_sync = DriverCP_GetLevelDemod(sid, "pkt_sync"); // захват пакетной синхронизации
|
|
||||||
const auto receive_active = sym_sync_lock && freq_search_lock && afc_lock && pkt_sync;
|
CP_GetLevelDemod(sid, "fine_freq_err", &tmpd); // freqErrAcc
|
||||||
|
sprintf(tmpStr, "%.2f", tmpd);
|
||||||
|
result << ",\"rx.freqErrAcc\":" << tmpStr;
|
||||||
|
|
||||||
|
CP_GetModulatorParams(sid, "if_overload", &tmpu32); // inputSignalLevel
|
||||||
|
result << ",\"rx.inputSignalLevel\":" << tmpStr;
|
||||||
|
|
||||||
|
CP_GetLevelDemod(sid, "afc_err", &tmpd); // PLL
|
||||||
|
sprintf(tmpStr, "%.2f", tmpd);
|
||||||
|
result << ",\"rx.pllError\":" << tmpStr;
|
||||||
|
|
||||||
|
std::string speed;
|
||||||
|
CP_GetDmaDebug(sid, "speed_rx", &speed);
|
||||||
|
sprintf(tmpStr, "%.3f", std::atof(speed.c_str()) / 128.0);
|
||||||
|
result << ",\"rx.speedOnRxKbit\":" << tmpStr;
|
||||||
|
|
||||||
|
speed.clear(); CP_GetDmaDebug(sid, "speed_rx_iface", &speed);
|
||||||
|
sprintf(tmpStr, "%.3f", std::atof(speed.c_str()) / 128.0);
|
||||||
|
result << ",\"rx.speedOnIifKbit\":" << tmpStr;
|
||||||
|
|
||||||
|
speed.clear(); CP_GetDmaDebug(sid, "packet_ok_rx", &speed);
|
||||||
|
result << ",\"rx.packetsOk\":" << std::atoi(speed.c_str());
|
||||||
|
|
||||||
|
speed.clear(); CP_GetDmaDebug(sid, "drop_bad_rx", &speed);
|
||||||
|
result << ",\"rx.packetsBad\":" << std::atoi(speed.c_str());
|
||||||
|
|
||||||
|
CP_GetDemodulatorParams(sid, "dummy_cnt", &tmpu32);
|
||||||
|
result << ",\"rx.packetsDummy\":" << tmpu32;
|
||||||
|
|
||||||
|
// auto reset_btn = m_lay->addWidget(std::make_unique<Wt::WPushButton>("Обновить"), 3, 0);
|
||||||
|
// reset_btn->setMaximumSize(95, 50);
|
||||||
|
// reset_btn->clicked().connect([=]
|
||||||
|
// {
|
||||||
|
// std::string var = "";
|
||||||
|
// CP_GetDmaDebug(sid, "reset_cnt_rx", &var);
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
|
||||||
result << ",\"rxState\":" << boolAsStr(receive_active);
|
|
||||||
result << ",\"rx.sym_sync_lock\":" << boolAsStr(sym_sync_lock);
|
|
||||||
result << ",\"rx.freq_search_lock\":" << boolAsStr(freq_search_lock);
|
|
||||||
result << ",\"rx.afc_lock\":" << boolAsStr(afc_lock);
|
|
||||||
result << ",\"rx.pkt_sync\":" << boolAsStr(pkt_sync);
|
|
||||||
|
|
||||||
result << "}";
|
result << "}";
|
||||||
|
|
||||||
// return R"({"rxState":0,"txState":0,"testState":0})";
|
|
||||||
return result.str();
|
return result.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
api_driver::ApiDriver::~ApiDriver() = default;
|
api_driver::ApiDriver::~ApiDriver() = default;
|
||||||
|
BIN
static/krokodil.gif
Normal file
BIN
static/krokodil.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 MiB |
99
static/login-failed.html
Normal file
99
static/login-failed.html
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>RSCM-101 | Вход</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/style.css">
|
||||||
|
<style>
|
||||||
|
#form-wrapper {
|
||||||
|
overflow: hidden;
|
||||||
|
max-width: 27em;
|
||||||
|
margin: 5em auto;
|
||||||
|
height: auto;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-row {
|
||||||
|
padding: 4px 0;
|
||||||
|
margin: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-row * {
|
||||||
|
font-size: 1em;
|
||||||
|
text-align: left;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-row label {
|
||||||
|
line-height: 2em;
|
||||||
|
font-weight: bolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-row input {
|
||||||
|
padding: 8px;
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border: none;
|
||||||
|
border-bottom: var(--brand-bg) 2px solid;
|
||||||
|
background-color: var(--bg-color);
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
min-height: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-row input:focus {
|
||||||
|
outline: none;
|
||||||
|
border: none;
|
||||||
|
border-bottom: var(--brand-text) 2px solid;
|
||||||
|
background-color: var(--bg-selected);
|
||||||
|
}
|
||||||
|
|
||||||
|
#submit {
|
||||||
|
border: none;
|
||||||
|
font-weight: bolder;
|
||||||
|
background: var(--bg-action);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div id="form-wrapper">
|
||||||
|
<h1> Вход </h1>
|
||||||
|
<form method="POST" id="login-form">
|
||||||
|
{% csrf_token %}
|
||||||
|
<div class="form-row value-bad">
|
||||||
|
Неверный логин или пароль
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-row">
|
||||||
|
<label for="username">Имя пользователя</label>
|
||||||
|
<input type="text" name="username" id="username" required/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-row">
|
||||||
|
<label for="password">Пароль</label>
|
||||||
|
<input type="password" name="password" id="password" required/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-row">
|
||||||
|
<input id="submit" type="submit" value="Войти">
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.getElementById("username").onkeydown = (e) => {
|
||||||
|
if (e.key === 'Enter') {
|
||||||
|
document.getElementById("password").focus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById("password").onkeydown = (e) => {
|
||||||
|
if (e.key === 'Enter') {
|
||||||
|
document.getElementById("login-form").submit()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -3,7 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Вход</title>
|
<title>RSCM-101 | Вход</title>
|
||||||
<link rel="stylesheet" type="text/css" href="/style.css">
|
<link rel="stylesheet" type="text/css" href="/style.css">
|
||||||
<style>
|
<style>
|
||||||
#form-wrapper {
|
#form-wrapper {
|
||||||
@ -62,13 +62,12 @@
|
|||||||
<div id="form-wrapper">
|
<div id="form-wrapper">
|
||||||
<h1> Вход </h1>
|
<h1> Вход </h1>
|
||||||
<form method="POST" id="login-form">
|
<form method="POST" id="login-form">
|
||||||
{% csrf_token %}
|
<!-- {% csrf_token %}-->
|
||||||
|
<!-- {% if message %}-->
|
||||||
{% if message %}
|
<!-- <div class="form-row value-bad">-->
|
||||||
<div class="form-row value-bad">
|
<!-- {{ message }}-->
|
||||||
{{ message }}
|
<!-- </div>-->
|
||||||
</div>
|
<!-- {% endif %}-->
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label for="username">Имя пользователя</label>
|
<label for="username">Имя пользователя</label>
|
||||||
|
275
static/main.html
275
static/main.html
@ -3,7 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Главная</title>
|
<title>RSCM-101</title>
|
||||||
<link rel="stylesheet" type="text/css" href="/style.css">
|
<link rel="stylesheet" type="text/css" href="/style.css">
|
||||||
<style>
|
<style>
|
||||||
.tabs-header {
|
.tabs-header {
|
||||||
@ -14,6 +14,7 @@
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
.tabs-btn {
|
.tabs-btn {
|
||||||
|
text-decoration: none;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
border: none;
|
border: none;
|
||||||
padding: 10px 25px;
|
padding: 10px 25px;
|
||||||
@ -23,89 +24,283 @@
|
|||||||
border-bottom: 3px solid #eee;
|
border-bottom: 3px solid #eee;
|
||||||
}
|
}
|
||||||
.tabs-btn.active {
|
.tabs-btn.active {
|
||||||
color: #5fa03a;
|
color: var(--brand-text);
|
||||||
border-bottom: 3px solid #5fa03a;
|
border-bottom: 3px solid var(--brand-text);
|
||||||
}
|
}
|
||||||
.tabs-body-item {
|
.tabs-body-item {
|
||||||
padding: 20px 0;
|
padding: 20px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.indicator_bad {
|
||||||
|
background: var(--text-bad);
|
||||||
|
}
|
||||||
|
.indicator_good {
|
||||||
|
background: var(--text-good);
|
||||||
|
}
|
||||||
|
.indicator {
|
||||||
|
display: inline-block;
|
||||||
|
width: 1em;
|
||||||
|
height: 1em;
|
||||||
|
border: solid 1px var(--text-color2);
|
||||||
|
border-radius: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.state-bar-element {
|
||||||
|
margin: 0.5em;
|
||||||
|
border-bottom: 2px solid var(--text-color2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabs-item-flex-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabs-item-flex-container > div {
|
||||||
|
padding: 1em;
|
||||||
|
margin: 1em;
|
||||||
|
border: 1px solid var(--text-color2);
|
||||||
|
border-radius: 0.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabs-item-flex-container th {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.tabs-item-flex-container h2 {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="app" hidden>
|
<div id="app" hidden>
|
||||||
<div>
|
<div>
|
||||||
<h1>Общее состояние</h1>
|
<span class="state-bar-element">Прием: <span :class="{ indicator_bad: rx.state === true, indicator_good: rx.state === false, indicator: true }"></span></span>
|
||||||
<ul>
|
<span class="state-bar-element">Передача: <span :class="{ indicator_bad: tx.state === true, indicator_good: tx.state === false, indicator: true }"></span></span>
|
||||||
<li>Прием: {{ rxState }}</li>
|
<span class="state-bar-element">Тест: <span :class="{ indicator_bad: testState === true, indicator_good: testState === false, indicator: true }"></span></span>
|
||||||
<li>Передача: {{ txState }}</li>
|
<!-- Последнее обновление: {{ lastUpdateTime }}-->
|
||||||
<li>Тест: {{ testState }}</li>
|
|
||||||
<li>Последнее обновление: {{ lastUpdateTime }}</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="tabs">
|
<div class="tabs">
|
||||||
<div class="tabs-header">
|
<div class="tabs-header">
|
||||||
<span style="font-weight:bold">RSCM-101</span>
|
<span style="font-weight:bold">RSCM-101</span>
|
||||||
<button class="tabs-btn" @click="activeTab = 1" :class="{ active: activeTab === 1 }">Мониторинг</button>
|
<a href="#monitoring" class="tabs-btn" @click="activeTab = 'monitoring'" :class="{ active: activeTab === 'monitoring' }">Мониторинг</a>
|
||||||
<button class="tabs-btn" @click="activeTab = 2" :class="{ active: activeTab === 2 }">Прием/Передача</button>
|
<a href="#setup" class="tabs-btn" @click="activeTab = 'setup'" :class="{ active: activeTab === 'setup' }">Настройки</a>
|
||||||
<button class="tabs-btn" @click="activeTab = 3" :class="{ active: activeTab === 3 }">Настройки CinC</button>
|
<a href="#admin" class="tabs-btn" @click="activeTab = 'admin'" :class="{ active: activeTab === 'admin' }">Администрирование</a>
|
||||||
<button class="tabs-btn" @click="activeTab = 4" :class="{ active: activeTab === 4 }">Настройки питания и опорного генератора</button>
|
|
||||||
<button class="tabs-btn" @click="activeTab = 5" :class="{ active: activeTab === 5 }">Администрирование</button>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="tabs-body">
|
<div class="tabs-body">
|
||||||
<div class="tabs-body-item" v-show="activeTab === 1">
|
<div class="tabs-body-item tabs-item-flex-container" v-show="activeTab === 'monitoring'">
|
||||||
|
<div>
|
||||||
|
<h2>Статистика приема</h2>
|
||||||
|
<table>
|
||||||
|
<tbody>
|
||||||
|
<tr><th>Прием</th><td><span :class="{ indicator_bad: rx.state === true, indicator_good: rx.state === false, indicator: true }"></span></td></tr>
|
||||||
|
<tr><th>Захват символьной</th><td><span :class="{ indicator_bad: rx.sym_sync_lock === true, indicator_good: rx.sym_sync_lock === false, indicator: true }"></span></td></tr>
|
||||||
|
<tr><th>Захват ФАПЧ</th><td><span :class="{ indicator_bad: rx.freq_search_lock === true, indicator_good: rx.freq_search_lock === false, indicator: true }"></span></td></tr>
|
||||||
|
<tr><th>Захват поиска по частоте</th><td><span :class="{ indicator_bad: rx.afc_lock === true, indicator_good: rx.afc_lock === false, indicator: true }"></span></td></tr>
|
||||||
|
<tr><th>Захват пакетной синхр.</th><td><span :class="{ indicator_bad: rx.pkt_sync === true, indicator_good: rx.pkt_sync === false, indicator: true }"></span></td></tr>
|
||||||
|
<tr><th>ОСШ/RSSI</th><td>{{ rx.snr }} / {{ rx.rssi }}</td></tr>
|
||||||
|
<tr><th>Modcod/размер кадра</th><td>{{ rx.modcod }} / {{ rx.frameSize }}</td></tr>
|
||||||
|
<tr><th>Пилот-символы</th><td>{{ rx.pilots }}</td></tr>
|
||||||
|
<tr><th>Символьная ошибка</th><td>{{ rx.symError }}</td></tr>
|
||||||
|
<tr><th>Грубая/точная част. ошибка, Гц</th><td>{{ rx.freqErr }} / {{ rx.freqErrAcc }}</td></tr>
|
||||||
|
<tr><th>Ур. входного сигнала</th><td>{{ rx.inputSignalLevel }}</td></tr>
|
||||||
|
<tr><th>Ошибка ФАПЧ</th><td>{{ rx.pllError }}</td></tr>
|
||||||
|
<tr><th>Инф. скорость на приеме</th><td>{{ rx.speedOnRx }} kbit/s</td></tr>
|
||||||
|
<tr><th>Инф. скорость на интерфейсе</th><td>{{ rx.speedOnIif }} kbit/s</td></tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<p> Статистика пакетов </p>
|
||||||
|
<table>
|
||||||
|
<tbody>
|
||||||
|
<tr><th>Качественных пакетов</th><td>{{ rx.packetsOk }}</td></tr>
|
||||||
|
<tr><th>Поврежденных пакетов</th><td>{{ rx.packetsBad }}</td></tr>
|
||||||
|
<tr><th>DUMMY</th><td>{{ rx.packetsDummy }}</td></tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<button> Сброс статистики </button>
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h2>Статистика передачи</h2>
|
<h2>Статистика передачи</h2>
|
||||||
|
<table>
|
||||||
|
<tbody>
|
||||||
|
<tr><th>Передача</th><td><span :class="{ indicator_bad: tx.state === true, indicator_good: tx.state === false, indicator: true }"></span></td></tr>
|
||||||
|
<tr><th>ОСШ дальнего приема</th><td>{{ tx.snr }}</td></tr>
|
||||||
|
<tr><th>Modcod</th><td>{{ tx.modcod }}</td></tr>
|
||||||
|
<tr><th>Размер кадра</th><td>{{ tx.frameSize }}</td></tr>
|
||||||
|
<tr><th>Пилот-символы</th><td>{{ tx.pilots }}</td></tr>
|
||||||
|
<tr><th>Инф. скорость на передаче</th><td>{{ tx.speedOnTx }} kbit/s</td></tr>
|
||||||
|
<tr><th>Инф. скорость на интерфейсе</th><td>{{ tx.speedOnIif }} kbit/s</td></tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h2>Статистика режима CinC</h2>
|
||||||
|
<table>
|
||||||
|
<tbody>
|
||||||
|
<tr><th>ОСС</th><td class="value-bad">indcator</td></tr>
|
||||||
|
<tr><th>Захват коррелятора</th><td class="value-bad"><span :class="{ indicator: true }"></span> bool</td></tr>
|
||||||
|
<tr><th>Кол-во срывов коррелятора</th><td class="value-bad">indcator</td></tr>
|
||||||
|
<tr><th>Грубая/точная част. ошибка, Гц</th><td class="value-bad">indcator/indicator</td></tr>
|
||||||
|
<tr><th>Задержка в канале, мс</th><td class="value-bad">indcator</td></tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h2>Состояние устройства</h2>
|
||||||
|
<table>
|
||||||
|
<tbody>
|
||||||
|
<tr><th>Температура ADRV</th><td class="value-bad">indcator °C</td></tr>
|
||||||
|
<tr><th>Температура ZYNC</th><td class="value-bad">indcator °C</td></tr>
|
||||||
|
<tr><th>Температура FPGA</th><td class="value-bad">indcator °C</td></tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="tabs-body-item" v-show="activeTab === 2">
|
<div class="tabs-body-item tabs-item-flex-container" v-show="activeTab === 'setup'">
|
||||||
Содержимое вкладки 2
|
<div>
|
||||||
|
<h2>Настройка передатчика</h2>
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
...
|
||||||
</div>
|
</div>
|
||||||
<div class="tabs-body-item" v-show="activeTab === 3">
|
<h3>Параметры передачи</h3>
|
||||||
Содержимое вкладки 3
|
<div>
|
||||||
|
...
|
||||||
</div>
|
</div>
|
||||||
<div class="tabs-body-item" v-show="activeTab === 4">
|
<h3>Режим работы DVB-S2</h3>
|
||||||
Содержимое вкладки 4
|
<div>
|
||||||
|
...
|
||||||
</div>
|
</div>
|
||||||
<div class="tabs-body-item" v-show="activeTab === 5">
|
</div>
|
||||||
Содержимое вкладки 5
|
</div>
|
||||||
|
<div>
|
||||||
|
<h2>Настройка приемника</h2>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h2>Настройки режима CinC</h2>
|
||||||
|
<p>CinC пока нельзя настроить, но скоро разработчик это поправит)</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h2>Настройки питания и опорного генератора</h2>
|
||||||
|
<p>Эти настройки пока недоступны, но скоро разработчик это поправит)</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="tabs-body-item" v-show="activeTab === 'admin'">
|
||||||
|
<p>
|
||||||
|
Эти настройки пока недоступны, но скоро разработчик это поправит. А пока смотри на крокодила
|
||||||
|
</p>
|
||||||
|
<img src="/images/krokodil_vzryvaetsya_hd.gif" alt="krokodil">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="mainState" hidden>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="status-header"></div>
|
|
||||||
|
|
||||||
<!-- Версия для разработки включает в себя возможность вывода в консоль полезных уведомлений -->
|
<!-- Версия для разработки включает в себя возможность вывода в консоль полезных уведомлений -->
|
||||||
<script src="/js/vue.js"></script>
|
<script src="/js/vue.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
// const router = useRouter();
|
||||||
|
const availableTabs = ['monitoring', 'setup', 'admin']
|
||||||
|
const defaultTab = availableTabs[0]
|
||||||
|
|
||||||
|
function getCurrentTab() {
|
||||||
|
const sl = window.location.hash.slice(1)
|
||||||
|
if (availableTabs.indexOf(sl) >= 0) {
|
||||||
|
return sl
|
||||||
|
}
|
||||||
|
return defaultTab
|
||||||
|
}
|
||||||
|
|
||||||
const app = new Vue({
|
const app = new Vue({
|
||||||
el: '#app',
|
el: '#app',
|
||||||
data: {
|
data: {
|
||||||
activeTab: 1,
|
rx: {
|
||||||
rxState: '?',
|
// индикаторы
|
||||||
txState: '?',
|
state: '?', // общее состояние
|
||||||
|
sym_sync_lock: '?', // захват символьной
|
||||||
|
freq_search_lock: '?', // Захват поиска по частоте
|
||||||
|
afc_lock: '?', // захват ФАПЧ
|
||||||
|
pkt_sync: '?', // захват пакетной синхронизации
|
||||||
|
|
||||||
|
// куча других параметров, идет в том же порядке, что и в таблице
|
||||||
|
snr: 0, rssi: -105,
|
||||||
|
modcod: 0, frameSize: 0,
|
||||||
|
pilots: '?',
|
||||||
|
symError: 0.0,
|
||||||
|
freqErr: 0, freqErrAcc: 0,
|
||||||
|
inputSignalLevel: 0,
|
||||||
|
pllError: 0,
|
||||||
|
speedOnRx: 0,
|
||||||
|
speedOnIif: 0,
|
||||||
|
|
||||||
|
// статистика пакетов
|
||||||
|
packetsOk: 0,
|
||||||
|
packetsBad: 0,
|
||||||
|
packetsDummy: 0,
|
||||||
|
},
|
||||||
|
|
||||||
|
tx: {
|
||||||
|
// состояние
|
||||||
|
state: '?',
|
||||||
|
|
||||||
|
// прочие поля
|
||||||
|
snr: -90,
|
||||||
|
modcod: -90,
|
||||||
|
frameSize: 'normal',
|
||||||
|
pilots: 'no pilots',
|
||||||
|
speedOnTx: 0,
|
||||||
|
speedOnIif: 0,
|
||||||
|
},
|
||||||
|
|
||||||
testState: '?',
|
testState: '?',
|
||||||
lastUpdateTime: new Date()
|
lastUpdateTime: new Date(),
|
||||||
|
|
||||||
|
activeTab: getCurrentTab()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
updateMainState(vals) {
|
updateMainState(vals) {
|
||||||
this.lastUpdateTime = new Date();
|
this.lastUpdateTime = new Date();
|
||||||
this.rxState = vals["mainState"]["rxState"]
|
|
||||||
this.txState = vals["mainState"]["txState"]
|
this.rx.state = vals["mainState"]["rx.state"]
|
||||||
|
this.rx.sym_sync_lock = vals["mainState"]["rx.sym_sync_lock"]
|
||||||
|
this.rx.freq_search_lock = vals["mainState"]["rx.freq_search_lock"]
|
||||||
|
this.rx.afc_lock = vals["mainState"]["rx.afc_lock"]
|
||||||
|
this.rx.pkt_sync = vals["mainState"]["rx.pkt_sync"]
|
||||||
|
this.rx.snr = vals["mainState"]["rx.snr"]
|
||||||
|
this.rx.rssi = vals["mainState"]["rx.rssi"]
|
||||||
|
this.rx.modcod = vals["mainState"]["rx.modcod"]
|
||||||
|
this.rx.frameSize = vals["mainState"]["rx.frameSize"]
|
||||||
|
this.rx.pilots = vals["mainState"]["rx.pilots"]
|
||||||
|
this.rx.symError = vals["mainState"]["rx.symError"]
|
||||||
|
this.rx.freqErr = vals["mainState"]["rx.freqErr"]
|
||||||
|
this.rx.freqErrAcc = vals["mainState"]["rx.freqErrAcc"]
|
||||||
|
this.rx.inputSignalLevel = vals["mainState"]["rx.inputSignalLevel"]
|
||||||
|
this.rx.pllError = vals["mainState"]["rx.pllError"]
|
||||||
|
this.rx.speedOnRxKbit = vals["mainState"]["rx.speedOnRxKbit"]
|
||||||
|
this.rx.speedOnIifKbit = vals["mainState"]["rx.speedOnIifKbit"]
|
||||||
|
this.rx.packetsOk = vals["mainState"]["rx.packetsOk"]
|
||||||
|
this.rx.packetsBad = vals["mainState"]["rx.packetsBad"]
|
||||||
|
this.rx.packetsDummy = vals["mainState"]["rx.packetsDummy"]
|
||||||
|
|
||||||
|
this.tx.state = vals["mainState"]["tx.state"]
|
||||||
|
this.tx.snr = vals["mainState"]["rx.snr"]
|
||||||
|
this.tx.modcod = vals["mainState"]["rx.modcod"]
|
||||||
|
this.tx.frameSize = vals["mainState"]["rx.frameSize"]
|
||||||
|
this.tx.pilots = vals["mainState"]["rx.pilots"]
|
||||||
|
this.tx.speedOnTxKbit = vals["mainState"]["rx.speedOnTxKbit"]
|
||||||
|
this.tx.speedOnIifKbit = vals["mainState"]["rx.speedOnIifKbit"]
|
||||||
|
|
||||||
this.testState = vals["mainState"]["testState"]
|
this.testState = vals["mainState"]["testState"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
setInterval(() => {
|
const doFetch = async () => {
|
||||||
fetch("/api/mainStatistics").then(async (val) => {
|
let d = await fetch("/api/mainStatistics")
|
||||||
this.updateMainState(await val.json())
|
this.updateMainState(await d.json())
|
||||||
|
}
|
||||||
|
|
||||||
|
doFetch().then(() => {
|
||||||
|
setInterval(() => { doFetch().then(() => {}) }, 1000);
|
||||||
});
|
});
|
||||||
}, 1000);
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user