diff --git a/docs.md b/docs.md new file mode 100644 index 0000000..60c8c38 --- /dev/null +++ b/docs.md @@ -0,0 +1,15 @@ +# Документация + +## HTTP(s) Запросы + +В этом разделе будет документация на запросы сервера и ответы сервера. + +### Статические файлы + +Такие расположены по следующим адресам (веб адрес - путь в файловой системе): +* `/favicon.ico` - `static/favicon.png` +* `/js/vue.js` - `static/vue.js` +* `/style.css` - `static/style.css` + +На эти ресурсы можно ходить только запросом `GET`. Любой другой + diff --git a/src/main.cpp b/src/main.cpp index b30a8d2..9896c63 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -80,6 +80,7 @@ static void initResources(http::server::Server& s, std::shared_ptr("/images/krokodil_vzryvaetsya_hd.gif", "static/krokodil.gif", mime_types::image_gif)); s.resources.emplace_back(std::make_unique("/style.css", "static/style.css", mime_types::text_css)); + s.resources.emplace_back(std::make_unique("/fields.css", "static/fields.css", mime_types::text_css)); s.resources.emplace_back(std::make_unique("/js/vue.js", "static/js/vue.js", mime_types::javascript)); s.resources.emplace_back(std::make_unique("/api/statistics", [](const auto& req, auto& rep) { @@ -94,7 +95,7 @@ static void initResources(http::server::Server& s, std::shared_ptr("/api/mainStatistics", [api](const auto& req, auto& rep) { + s.resources.emplace_back(std::make_unique("/api/get/statistics", [api](const auto& req, auto& rep) { if (req.method != "GET") { http::server::stockReply(http::server::bad_request, rep); } @@ -107,6 +108,33 @@ static void initResources(http::server::Server& s, std::shared_ptr("/api/resetPacketStatistics", [api](const auto& req, auto& rep) { + if (req.method != "POST") { + http::server::stockReply(http::server::bad_request, rep); + } + api->resetPacketStatistics(); + + rep.status = http::server::ok; + rep.headers.clear(); + rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::json)}); + const std::string result = R"({"status":"ok")"; + rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size()); + })); + + s.resources.emplace_back(std::make_unique("/api/get/settings", [api](const auto& req, auto& rep) { + if (req.method != "GET") { + http::server::stockReply(http::server::bad_request, rep); + } + + rep.status = http::server::ok; + rep.headers.clear(); + rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::json)}); + std::string result = R"({"settings":)"; + result += api->loadSettings(); + result += "}"; + rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size()); + })); } int main(int argc, char *argv[]) { diff --git a/src/terminal_api_driver.cpp b/src/terminal_api_driver.cpp index 5d5ce56..19c4376 100644 --- a/src/terminal_api_driver.cpp +++ b/src/terminal_api_driver.cpp @@ -181,26 +181,8 @@ std::string api_driver::ApiDriver::loadTerminalState() { CP_GetDemodulatorParams(sid, "dummy_cnt", &tmpu32); result << ",\"rx.packetsDummy\":" << tmpu32; - - // auto reset_btn = m_lay->addWidget(std::make_unique("Обновить"), 3, 0); - // reset_btn->setMaximumSize(95, 50); - // reset_btn->clicked().connect([=] - // { - // std::string var = ""; - // CP_GetDmaDebug(sid, "reset_cnt_rx", &var); - // }); } - /* - stat_cinc: { - occ: '?', - correlator: '?', - correlatorFails: '?', - freqErr: '?', freqErrAcc: '?', - channelDelay: '?' - }, - */ - // формируем структуру для CinC { std::string tmps; @@ -256,4 +238,13 @@ std::string api_driver::ApiDriver::loadTerminalState() { } +void api_driver::ApiDriver::resetPacketStatistics() const { + std::string tmp; + CP_GetDmaDebug(sid, "reset_cnt_rx", &tmp); +} + +std::string api_driver::ApiDriver::loadSettings() { + return "{}"; +} + api_driver::ApiDriver::~ApiDriver() = default; diff --git a/src/terminal_api_driver.h b/src/terminal_api_driver.h index 8a3d406..8e4a3cb 100644 --- a/src/terminal_api_driver.h +++ b/src/terminal_api_driver.h @@ -20,10 +20,11 @@ namespace api_driver { std::string loadTerminalState(); /** - * Запросить статистику модулятора, демодулятора, CicC и температурные датчики - * @return + * Сбросить статистику пакетов */ - std::string loadDeviceStatistics(); + void resetPacketStatistics() const; + + std::string loadSettings(); ~ApiDriver(); diff --git a/static/fields.css b/static/fields.css new file mode 100644 index 0000000..96741d5 --- /dev/null +++ b/static/fields.css @@ -0,0 +1,124 @@ +.tabs-header { + margin: 0.5em 0; + background: var(--brand-bg); +} +.tabs-header > * { + display: inline-block; +} +.tabs-btn { + text-decoration: none; + font-size: 18px; + border: none; + padding: 10px 25px; + text-align: center; + cursor: pointer; + margin-bottom: -3px; + border-bottom: 3px solid #eee; +} +.tabs-btn.active { + color: var(--brand-text); + border-bottom: 3px solid var(--brand-text); +} +.tabs-body-item { + 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; +} + +.nav-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 > *, .settings-set-container { + 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; +} + +form label * { + display: block; +} +form label { + margin: 1em 0; + display: block; + background: var(--bg-selected); + color: var(--text-color2); +} +form input { + margin-top: 0.5em; + border: none; + border-bottom: solid 2px var(--text-color); + width: 100%; + box-sizing: border-box; +} + +form input:focus { + outline: none; + border: none; + border-bottom: solid 2px var(--brand-text); +} + +/*********************** Стили для красивых 'switch' ***********************/ + +.toggle-input { + display: inline-block; + position: relative; + margin: 5px 10px; + width: 50px; + height: 16px; + background-color: var(--bg-element); + border-radius: 16px; + cursor: pointer; + transition: background-color 0.3s; +} + +.toggle-input input[type="checkbox"] { + display: none; +} + +.toggle-input .slider { + position: absolute; + top: -4px; + left: 0; + width: 25px; + height: 25px; + background-color: var(--text-color); + border-radius: 50%; + transition: left 0.3s; +} + +.toggle-input input[type="checkbox"]:checked + .slider { + left: 25px; + background-color: var(--brand-text); +} + +.toggle-input input[type="checkbox"]:checked + .slider:before { + left: 10px; +} diff --git a/static/main.html b/static/main.html index 4ad27b5..0639e3b 100644 --- a/static/main.html +++ b/static/main.html @@ -5,79 +5,15 @@ RSCM-101 - + -
-
-

Настройка передатчика

-
-
- ... -
-

Параметры передачи

-
- ... -
-

Режим работы DVB-S2

-
- ... -
-
+
+

Настройки приема/передачи

+
+ + +
+
+
+

Настройки передатчика

+ + + + + +
+
+

Параметры передачи

+ + + + + + +
+
+

Режим работы DVB-S2

+ + + + + + + + + + + + + +
+
+

Настройки авто-регулировки мощности

+ + + + + +
+
+

Настройка приемника

+ + + + + + + + + +
-
-

Настройка приемника

-
-
+

Настройки режима CinC

CinC пока нельзя настроить, но скоро разработчик это поправит)

@@ -189,7 +358,7 @@

Эти настройки пока недоступны, но скоро разработчик это поправит. А пока смотри на крокодила

- krokodil + krokodil

Последнее обновление статистики: {{ lastUpdateTime }}

@@ -211,6 +380,9 @@ return defaultTab } + // TODO: взять модкоды из раздела 5.5.2.2 https://www.etsi.org/deliver/etsi_en/302300_302399/302307/01.01.02_60/en_302307v010102p.pdf + // и прикрутить декодинг модкода + const app = new Vue({ el: '#app', data: { @@ -256,12 +428,73 @@ adrv: 0, zync: 0, fpga: 0 }, + param: { + general: { + mode: 'scpc', + txEn: false, // включен/выключен + modulatorMode: 'normal', // режим работы модулятора + autoStartTx: false, // было "режим работы передатчика" + inputData: 'eth', // входные данные: eth или test + }, + tx: { + attenuation: -3.0, // ослабление + goldan: '0', + rolloff: 20, + cymRate: 100000, + centerFreq: 1200000.0, + }, + dvbs2: { + mode: 'ccm', + frameSize: 'normal', + pilots: false, + + // CCM + ccm_modulation: 'qpsk', + ccm_speed: '1/2', + + // ACM + acm_maxModulation: 'qpsk', + acm_maxSpeed: '1/2', + acm_minModulation: 'qpsk', + acm_minSpeed: '1/2', + + snrReserve: 0.5, + servicePacketPeriod: 15, + }, + // авто-регулировка мощности + acp: { + en: false, + maxAttenuation: -2.0, + minAttenuation: -3.0, + requiredSnr: -10, + }, + rx: { + gainMode: 'auto', // режим управления усилением + manualGain: 70, // усиление, только для ручного режима + spectrumInversion: false, + + goldan: '0', + rolloff: 20, + cymRate: 100000, + centerFreq: 1200000.0, + }, + + buc: { + + }, + lnb: {}, + serviceSettings: {}, + }, + + message: "", + testState: '?', lastUpdateTime: new Date(), - activeTab: getCurrentTab() + activeTab: getCurrentTab(), + settingFetchComplete: false }, methods: { - updateMainState(vals) { + updateStatistics(vals) { this.lastUpdateTime = new Date(); this.isCinC = vals["mainState"]["isCinC"] @@ -306,19 +539,40 @@ this.stat_device.fpga = vals["mainState"]["device.fpga"] this.testState = vals["mainState"]["testState"] + }, + + resetPacketsStatistics() { + fetch('/api/resetPacketStatistics', { + method: 'POST' + }).then(() => { + this.stat_rx.packetsOk = 0 + this.stat_rx.packetsBad = 0 + this.stat_rx.packetsDummy = 0 + }) + }, + + updateSettings(vals) { + this.settingFetchComplete = true } }, mounted() { - const doFetch = async () => { - let d = await fetch("/api/mainStatistics") - this.updateMainState(await d.json()) + const doFetchStatistics = async () => { + let d = await fetch("/api/get/statistics") + this.updateStatistics(await d.json()) setTimeout(() => { - doFetch() + doFetchStatistics() }, 1000) } - doFetch().then(() => {}) + doFetchStatistics().then(() => {}) + + const doFetchSettings = async () => { + let d = await fetch("/api/get/settings") + this.updateSettings(await d.json()) + } + + doFetchSettings().then(() => {}) document.getElementById("app").removeAttribute("hidden") } diff --git a/static/style.css b/static/style.css index a352425..e64303b 100644 --- a/static/style.css +++ b/static/style.css @@ -10,6 +10,7 @@ body { --bg-color: #FEFEFE; --bg-selected: #F1F1F1; + --bg-element: #a7a7a7; --bg-action: #5181fe; } @@ -26,6 +27,7 @@ body { --bg-color: #2d2c33; --bg-selected: #424248; + --bg-element: #626268; --bg-action: #4a70d5; } }