diff --git a/front-generator/render-params.json b/front-generator/render-params.json
index 40ce5a8..4a260a9 100644
--- a/front-generator/render-params.json
+++ b/front-generator/render-params.json
@@ -133,7 +133,8 @@
"tabs": [
{"name": "monitoring", "desc": "Мониторинг"},
{"name": "setup", "desc": "Настройки"},
- {"name": "admin", "desc": "Администрирование"}
+ {"name": "admin", "desc": "Администрирование"},
+ {"name": "logs", "desc": "Журнал"}
]
},
"scpc": {
diff --git a/front-generator/template/common/admin-methods.js.j2 b/front-generator/template/common/admin-methods.js.j2
index a54ff3d..b085236 100644
--- a/front-generator/template/common/admin-methods.js.j2
+++ b/front-generator/template/common/admin-methods.js.j2
@@ -1,217 +1,218 @@
- async settingsUploadUpdate() {
- if (!this.uploadFw.filename) {
- alert('Выберите файл для загрузки');
- return;
- }
+async settingsUploadUpdate() {
+ if (!this.uploadFw.filename) {
+ alert('Выберите файл для загрузки');
+ return;
+ }
- async function readFileAsArrayBuffer(fileName) {
- return new Promise((resolve, reject) => {
- if (!fileName) { reject(`Файл не выбран`); return }
- const reader = new FileReader();
- reader.onload = (e) => { resolve(reader.result) }
- reader.onerror = (e) => { reject(e) }
- reader.readAsArrayBuffer(fileName)
- })
- }
+ async function readFileAsArrayBuffer(fileName) {
+ return new Promise((resolve, reject) => {
+ if (!fileName) { reject(`Файл не выбран`); return }
+ const reader = new FileReader();
+ reader.onload = (e) => { resolve(reader.result) }
+ reader.onerror = (e) => { reject(e) }
+ reader.readAsArrayBuffer(fileName)
+ })
+ }
+ try {
+ this.submitStatus.firmwareUpload = true
+ this.uploadFw.progress = 0
+ const blob = await readFileAsArrayBuffer(this.uploadFw.filename)
+
+ const xhr = new XMLHttpRequest();
+ await new Promise((resolve) => {
+ xhr.upload.addEventListener("progress", (event) => {
+ if (event.lengthComputable) {
+ this.uploadFw.progress = Math.round((event.loaded / event.total) * 1000) / 10;
+ }
+ });
+ xhr.addEventListener("loadend", () => {
+ this.uploadFw.progress = 100
+ const rep = JSON.parse(xhr.responseText);
+ this.uploadFw.sha256 = rep['sha256']
+ resolve(xhr.readyState === 4 && xhr.status === 200);
+ });
+ xhr.open("PUT", "/api/firmwareUpdate", true);
+ xhr.setRequestHeader("Content-Type", "application/octet-stream");
+ xhr.send(blob);
+ });
+ } catch (e) {
+ alert(`Ошибка загрузки файла: ${e}`);
+ }
+ this.submitStatus.firmwareUpload = false
+},
+
+async settingsPerformFirmwareUpgrade() {
+ if (this.submitStatus.firmwareUpgrade) { return }
+ this.submitStatus.firmwareUpgrade = true
+ try {
+ await fetch('/api/doFirmwareUpgrade', { method: 'POST' })
+ } catch (e) {
+ console.log("failed to perform upgrade firmware: ", e)
+ }
+ this.submitStatus.firmwareUpgrade = false
+},
+{% if modem == 'tdma' %}
+async settingsPerformFirmwareUpgradeOta() {
+ if (this.submitStatus.firmwareUpgradeOta) { return }
+ this.submitStatus.firmwareUpgradeOta = true
+ try {
+ await fetch('/api/doFirmwareUpgrade?ota=1', { method: 'POST' })
+ } catch (e) {
+ console.log("failed to perform upgrade firmware: ", e)
+ }
+ this.submitStatus.firmwareUpgradeOta = false
+},
+async settingsPerformSetCesPassword() {
+ if (this.submitStatus.cesPassword) { return }
+ this.submitStatus.cesPassword = true
+ try {
+ await fetch('/api/set/cesPassword', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({'password': this.cesPasswordValue})
+ })
+ } catch (e) {
+ console.log("failed to perform set CES password: ", e)
+ }
+ this.submitStatus.cesPassword = false
+},
+{% endif %}
+
+doModemReboot() {
+ if (this.submitStatus.modemReboot !== null) {
+ return
+ }
+ this.submitStatus.modemReboot = 30
+ fetch('/api/reboot', { method: 'POST' }).then((r) => {})
+},
+async restoreAllSettings() {
+ // Порядок применения настроек
+ const settingsApplyOrder = ['qos', 'tcpaccel', 'dpdi', 'rxtx', 'buclnb', 'network'];
+
+ // 1. Чтение JSON-файла, выбранного пользователем
+ const fileInput = document.createElement('input');
+ fileInput.type = 'file';
+ fileInput.accept = '.json';
+
+ const filePromise = new Promise((resolve, reject) => {
+ fileInput.onchange = e => {
+ const file = e.target.files[0];
+ if (!file) {
+ reject(new Error('Файл не выбран'));
+ return;
+ }
+
+ const reader = new FileReader();
+ reader.onload = event => {
try {
- this.submitStatus.firmwareUpload = true
- this.uploadFw.progress = 0
- const blob = await readFileAsArrayBuffer(this.uploadFw.filename)
-
- const xhr = new XMLHttpRequest();
- await new Promise((resolve) => {
- xhr.upload.addEventListener("progress", (event) => {
- if (event.lengthComputable) {
- this.uploadFw.progress = Math.round((event.loaded / event.total) * 1000) / 10;
- }
- });
- xhr.addEventListener("loadend", () => {
- this.uploadFw.progress = 100
- const rep = JSON.parse(xhr.responseText);
- this.uploadFw.sha256 = rep['sha256']
- resolve(xhr.readyState === 4 && xhr.status === 200);
- });
- xhr.open("PUT", "/api/firmwareUpdate", true);
- xhr.setRequestHeader("Content-Type", "application/octet-stream");
- xhr.send(blob);
- });
- } catch (e) {
- alert(`Ошибка загрузки файла: ${e}`);
+ const jsonData = JSON.parse(event.target.result);
+ resolve(jsonData);
+ } catch (error) {
+ reject(new Error('Ошибка парсинга JSON'));
}
- this.submitStatus.firmwareUpload = false
- },
+ };
+ reader.onerror = () => reject(new Error('Ошибка чтения файла'));
+ reader.readAsText(file);
+ };
+ fileInput.click();
+ });
- async settingsPerformFirmwareUpgrade() {
- if (this.submitStatus.firmwareUpgrade) { return }
- this.submitStatus.firmwareUpgrade = true
- try {
- await fetch('/api/doFirmwareUpgrade', { method: 'POST' })
- } catch (e) {
- console.log("failed to perform upgrade firmware: ", e)
- }
- this.submitStatus.firmwareUpgrade = false
- },
- {% if modem == 'tdma' %}
- async settingsPerformFirmwareUpgradeOta() {
- if (this.submitStatus.firmwareUpgradeOta) { return }
- this.submitStatus.firmwareUpgradeOta = true
- try {
- await fetch('/api/doFirmwareUpgrade?ota=1', { method: 'POST' })
- } catch (e) {
- console.log("failed to perform upgrade firmware: ", e)
- }
- this.submitStatus.firmwareUpgradeOta = false
- },
- async settingsPerformSetCesPassword() {
- if (this.submitStatus.cesPassword) { return }
- this.submitStatus.cesPassword = true
- try {
- await fetch('/api/set/cesPassword', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({'password': this.cesPasswordValue})
- })
- } catch (e) {
- console.log("failed to perform set CES password: ", e)
- }
- this.submitStatus.cesPassword = false
- },
- {% endif %}
+ try {
+ const settingsToApply = await filePromise;
+ const errors = [];
- doModemReboot() {
- if (this.submitStatus.modemReboot !== null) {
- return
- }
- this.submitStatus.modemReboot = 30
- fetch('/api/reboot', { method: 'POST' }).then((r) => {})
- },
- async restoreAllSettings() {
- // Порядок применения настроек
- const settingsApplyOrder = ['qos', 'tcpaccel', 'dpdi', 'rxtx', 'buclnb', 'network'];
+ // 2. Перебор групп параметров в заданном порядке
+ for (const groupName of settingsApplyOrder) {
+ if (!settingsToApply.hasOwnProperty(groupName)) {
+ continue; // Пропускаем группы, которых нет в файле
+ }
- // 1. Чтение JSON-файла, выбранного пользователем
- const fileInput = document.createElement('input');
- fileInput.type = 'file';
- fileInput.accept = '.json';
+ const groupSettings = settingsToApply[groupName];
+ if (typeof groupSettings !== 'object' || groupSettings === null) {
+ continue;
+ }
- const filePromise = new Promise((resolve, reject) => {
- fileInput.onchange = e => {
- const file = e.target.files[0];
- if (!file) {
- reject(new Error('Файл не выбран'));
- return;
- }
-
- const reader = new FileReader();
- reader.onload = event => {
- try {
- const jsonData = JSON.parse(event.target.result);
- resolve(jsonData);
- } catch (error) {
- reject(new Error('Ошибка парсинга JSON'));
- }
- };
- reader.onerror = () => reject(new Error('Ошибка чтения файла'));
- reader.readAsText(file);
- };
- fileInput.click();
+ try {
+ // 2.1. POST-запрос для применения группы параметров
+ const postResponse = await fetch(`/api/set/${groupName}`, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(groupSettings)
});
- try {
- const settingsToApply = await filePromise;
- const errors = [];
-
- // 2. Перебор групп параметров в заданном порядке
- for (const groupName of settingsApplyOrder) {
- if (!settingsToApply.hasOwnProperty(groupName)) {
- continue; // Пропускаем группы, которых нет в файле
- }
-
- const groupSettings = settingsToApply[groupName];
- if (typeof groupSettings !== 'object' || groupSettings === null) {
- continue;
- }
-
- try {
- // 2.1. POST-запрос для применения группы параметров
- const postResponse = await fetch(`/api/set/${groupName}`, {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify(groupSettings)
- });
-
- if (!postResponse.ok) {
- throw new Error(`HTTP error ${postResponse.status}`);
- }
-
- const postResult = await postResponse.json();
- if (postResult.status !== 'ok') {
- throw new Error(`API error: ${postResult.message || 'unknown error'}`);
- }
-
- // 2.2. Проверка примененных параметров
- const getResponse = await fetch('/api/get/settings', { method: 'GET' });
- if (!getResponse.ok) {
- throw new Error(`HTTP error ${getResponse.status}`);
- }
-
- const fetchSettingsResult = await getResponse.json();
- if (fetchSettingsResult.status !== 'ok') {
- throw new Error('Не удалось получить текущие настройки');
- }
-
- // Проверка соответствия параметров
- const appliedGroup = fetchSettingsResult.settings[groupName] || {};
- const failedSettings = [];
-
- for (const [key, value] of Object.entries(groupSettings)) {
- if (appliedGroup[key] !== value) {
- failedSettings.push(`${key} (ожидалось: ${value}, получено: ${appliedGroup[key]})`);
- }
- }
-
- if (failedSettings.length > 0) {
- throw new Error(`Не совпадают параметры: ${failedSettings.join(', ')}`);
- }
-
- } catch (groupError) {
- errors.push(`Группа ${groupName}: ${groupError.message}`);
- }
- }
-
- // 3. Показ ошибок, если они есть
- if (errors.length > 0) {
- const errorMessage = errors.join('\n\n') +
- '\n\nНекоторые настройки могли примениться некорректно.\nСтраница будет перезагружена.';
- alert(errorMessage);
- }
-
- } catch (error) {
- alert(`Ошибка при восстановлении настроек: ${error.message}`);
- return;
+ if (!postResponse.ok) {
+ throw new Error(`HTTP error ${postResponse.status}`);
}
- // 4. Перезагрузка страницы
- location.reload();
- },
- async dumpAllSettings() {
- function downloadAsFile(data, filename) {
- let a = document.createElement("a");
- let file = new Blob([data], {type: 'application/json'});
- a.href = URL.createObjectURL(file);
- a.download = filename;
- a.click();
+ const postResult = await postResponse.json();
+ if (postResult.status !== 'ok') {
+ throw new Error(`API error: ${postResult.message || 'unknown error'}`);
}
- const response = await fetch('/api/get/settings', { method: 'GET' })
- if (response.ok) {
- const jres = await response.json()
- if (jres["status"] === "ok") {
- downloadAsFile(JSON.stringify(jres["settings"], null, 4), "backup-" + this.about.firmwareVersion + "-" + this.about.modemSn + ".json")
+
+ // 2.2. Проверка примененных параметров
+ const getResponse = await fetch('/api/get/settings', { method: 'GET' });
+ if (!getResponse.ok) {
+ throw new Error(`HTTP error ${getResponse.status}`);
+ }
+
+ const fetchSettingsResult = await getResponse.json();
+ if (fetchSettingsResult.status !== 'ok') {
+ throw new Error('Не удалось получить текущие настройки');
+ }
+
+ // Проверка соответствия параметров
+ const appliedGroup = fetchSettingsResult.settings[groupName] || {};
+ const failedSettings = [];
+
+ for (const [key, value] of Object.entries(groupSettings)) {
+ if (appliedGroup[key] !== value) {
+ failedSettings.push(`${key} (ожидалось: ${value}, получено: ${appliedGroup[key]})`);
}
}
- },
+
+ if (failedSettings.length > 0) {
+ throw new Error(`Не совпадают параметры: ${failedSettings.join(', ')}`);
+ }
+
+ } catch (groupError) {
+ errors.push(`Группа ${groupName}: ${groupError.message}`);
+ }
+ }
+
+ // 3. Показ ошибок, если они есть
+ if (errors.length > 0) {
+ const errorMessage = errors.join('\n\n') +
+ '\n\nНекоторые настройки могли примениться некорректно.\nСтраница будет перезагружена.';
+ alert(errorMessage);
+ }
+
+ } catch (error) {
+ alert(`Ошибка при восстановлении настроек: ${error.message}`);
+ return;
+ }
+
+ // 4. Перезагрузка страницы
+ location.reload();
+},
+async dumpAllSettings() {
+ function downloadAsFile(data, filename) {
+ let a = document.createElement("a");
+ let file = new Blob([data], {type: 'application/json'});
+ a.href = URL.createObjectURL(file);
+ a.download = filename;
+ a.click();
+ }
+ const response = await fetch('/api/get/settings', { method: 'GET' })
+ if (response.ok) {
+ const jres = await response.json()
+ if (jres["status"] === "ok") {
+ downloadAsFile(JSON.stringify(jres["settings"], null, 4), "backup-" + this.about.firmwareVersion + "-" + this.about.modemSn + ".json")
+ }
+ }
+},
+
diff --git a/front-generator/template/common/admin.html.j2 b/front-generator/template/common/admin.html.j2
index a5eafff..9505230 100644
--- a/front-generator/template/common/admin.html.j2
+++ b/front-generator/template/common/admin.html.j2
@@ -1,52 +1,53 @@
{% from 'common/widgets.j2' import build_widget %}
-
- {% if 'network' in params %}
- {% for w in params['network'] %}{{ build_widget('network', w) | indent(12, true) }}{% endfor %}
- {% endif %}
- {% raw %}
-
Система
-
-
-
- Версия ПО {{ about.firmwareVersion }}
- ID модема {{ about.modemUid }}
- Серийный номер {{ about.modemSn }}
- MAC интерфейса управления {{ about.macManagement }}
- MAC интерфейса данных {{ about.macData }}
-
-
-
- Перезагрузить модем
-
-
- Сбросить модем до заводских настроек
-
-
Сохранить бекап конфигурации
-
Восстановить бекап конфигурации
-
{% endraw %}{% if modem == 'tdma' %}
-
-
Вход в сеть ЦЗС
-
-
- Хеш-строка пароля (выдается оператором NMS)
-
-
- Установить пароль
-
{% endif %}{% raw %}
-
-
Обновление ПО
-
-
Ручное обновление
-
- Файл {{ this.uploadFw.progress !== null ? `(${this.uploadFw.progress}%)` : '' }}
- { this.uploadFw.filename = e.target.files[0] }">
- SHA256: {{ uploadFw.sha256 }}
-
- Загрузить
- Обновить встроенное ПО
- {% endraw %}{% if modem == 'tdma' %}
- Обновление "по воздуху"
- Обновить встроенное ПО
- {% endif %}
-
+
+ {% if 'network' in params %}
+ {% for w in params['network'] %}{{ build_widget('network', w) | indent(4, true) }}{% endfor %}
+ {% endif %}
+ {% raw %}
+
Система
+
+
+
+ Версия ПО {{ about.firmwareVersion }}
+ ID модема {{ about.modemUid }}
+ Серийный номер {{ about.modemSn }}
+ MAC интерфейса управления {{ about.macManagement }}
+ MAC интерфейса данных {{ about.macData }}
+
+
+
+ Перезагрузить модем
+
+ Сбросить модем до заводских настроек
+
+
Сохранить бекап конфигурации
+
Восстановить бекап конфигурации
+
{% endraw %}{% if modem == 'tdma' %}
+
+
Вход в сеть ЦЗС
+
+
+ Хеш-строка пароля (выдается оператором NMS)
+
+
+ Установить пароль
+
{% endif %}{% raw %}
+
+
Обновление ПО
+
+
Ручное обновление
+
+ Файл {{ this.uploadFw.progress !== null ? `(${this.uploadFw.progress}%)` : '' }}
+ { this.uploadFw.filename = e.target.files[0] }">
+ SHA256: {{ uploadFw.sha256 }}
+
+ Загрузить
+ Обновить встроенное ПО
+ {% endraw %}{% if modem == 'tdma' %}
+ Обновление "по воздуху"
+ Обновить встроенное ПО
+ {% endif %}
+
+
+
diff --git a/front-generator/template/common/all-params-data.js.j2 b/front-generator/template/common/all-params-data.js.j2
index 02445a9..153f37d 100644
--- a/front-generator/template/common/all-params-data.js.j2
+++ b/front-generator/template/common/all-params-data.js.j2
@@ -1,7 +1,7 @@
{% for g in paramGroups %}
- param{{ g['group'] | title }}: {
- {% for p in g['params'] %}
- {{ p['name'] }}: {{ p['initValue'] }},
- {% endfor %}
- },
+param{{ g['group'] | title }}: {
+ {% for p in g['params'] %}
+ {{ p['name'] }}: {{ p['initValue'] }},
+ {% endfor %}
+},
{% endfor %}
\ No newline at end of file
diff --git a/front-generator/template/common/all-params-methods.js.j2 b/front-generator/template/common/all-params-methods.js.j2
index 48d47f1..296e052 100644
--- a/front-generator/template/common/all-params-methods.js.j2
+++ b/front-generator/template/common/all-params-methods.js.j2
@@ -1,30 +1,30 @@
{% from 'common/widgets.j2' import build_getter_js, build_setter_js %}
- {% for g in paramGroups %}
- settingsSubmit{{ g['group'] | title }}() {
- if (this.submitStatus.{{ g['group'] }}) { return }
- {% if g['group'] in dangerousParamGroups %}
- { if (!confirm("{{ dangerousParamGroups[g['group']] }}")) return }
- {% endif %}
+{% for g in paramGroups %}
+settingsSubmit{{ g['group'] | title }}() {
+ if (this.submitStatus.{{ g['group'] }}) { return }
+ {% if g['group'] in dangerousParamGroups %}
+ { if (!confirm("{{ dangerousParamGroups[g['group']] }}")) return }
+ {% endif %}
- let query = {
- {% for p in g['params'] %}
- "{{ p['name'] }}": {{ build_getter_js(g['group'], p) }},
- {% endfor %}
- }
+ let query = {
+ {% for p in g['params'] %}
+ "{{ p['name'] }}": {{ build_getter_js(g['group'], p) }},
+ {% endfor %}
+ }
- this.submitStatus.{{ g['group'] }} = true
- fetch('/api/set/{{ g["group"] }}', {method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(query), credentials: 'same-origin' })
- .then(async (resp) => { let vals = await resp.json(); if (vals['status'] !== 'ok') { throw new Error(vals['error'] ? vals['error'] : "Server returns undefined error") } this.update{{ g['group'] | title }}Settings(vals) })
- .catch((reason) => { alert(`Ошибка при применении настроек: ${reason}`) })
- .finally(() => { this.submitStatus.{{ g['group'] }} = false })
- },
- {% endfor %}
+ this.submitStatus.{{ g['group'] }} = true
+ fetch('/api/set/{{ g["group"] }}', {method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(query), credentials: 'same-origin' })
+ .then(async (resp) => { let vals = await resp.json(); if (vals['status'] !== 'ok') { throw new Error(vals['error'] ? vals['error'] : "Server returns undefined error") } this.update{{ g['group'] | title }}Settings(vals) })
+ .catch((reason) => { alert(`Ошибка при применении настроек: ${reason}`) })
+ .finally(() => { this.submitStatus.{{ g['group'] }} = false })
+},
+{% endfor %}
- {% for g in paramGroups %}
- update{{ g['group'] | title }}Settings(vals) {
- this.submitStatus.{{ g['group'] }} = false
- {% for p in g['params'] %}
- {{ build_setter_js(g['group'], p, "vals[\"settings\"][\"" ~ g['group'] ~ "\"][\"" ~ p['name'] ~ "\"]") }}
- {% endfor %}
- },
- {% endfor %}
\ No newline at end of file
+{% for g in paramGroups %}
+update{{ g['group'] | title }}Settings(vals) {
+ this.submitStatus.{{ g['group'] }} = false
+ {% for p in g['params'] %}
+ {{ build_setter_js(g['group'], p, "vals[\"settings\"][\"" ~ g['group'] ~ "\"][\"" ~ p['name'] ~ "\"]") }}
+ {% endfor %}
+},
+{% endfor %}
\ No newline at end of file
diff --git a/front-generator/template/common/logs-data.js.j2 b/front-generator/template/common/logs-data.js.j2
new file mode 100644
index 0000000..4f77ff4
--- /dev/null
+++ b/front-generator/template/common/logs-data.js.j2
@@ -0,0 +1,7 @@
+paramLogs: {
+ submitClearLogs: false,
+ submitUpdateLogs: false,
+ data: "",
+ level: ""
+},
+
diff --git a/front-generator/template/common/logs-methods.js.j2 b/front-generator/template/common/logs-methods.js.j2
new file mode 100644
index 0000000..3ccb510
--- /dev/null
+++ b/front-generator/template/common/logs-methods.js.j2
@@ -0,0 +1,12 @@
+logsUpdate() {
+ if (this.paramLogs.submitUpdateLogs) { return }
+ this.paramLogs.submitUpdateLogs = true
+ fetch(`/api/get/manager.log?preview=1`, {method: 'GET', credentials: 'same-origin' })
+ .then(async (resp) => {
+ this.paramLogs.data = await resp.text()
+ })
+ .catch((reason) => { this.paramLogs.data = `Ошибка при чтении логов: ${reason}` })
+ .finally(() => { this.paramLogs.submitUpdateLogs = false })
+},
+
+
diff --git a/front-generator/template/common/logs.html.j2 b/front-generator/template/common/logs.html.j2
new file mode 100644
index 0000000..fade68e
--- /dev/null
+++ b/front-generator/template/common/logs.html.j2
@@ -0,0 +1,17 @@
+{% from 'common/widgets.j2' import build_widget %}
+
+
Журнал manager
+
+{{ build_widget('logs', {
+ "widget": "select", "label": "Фильтрация лога (отображение)", "name": "level",
+ "values": [{"label": "Без фильтрации", "value": "''"}, {"label": "Информация", "value": "'info'"}, {"label": "Предупреждение", "value": "'warning'"}, {"label": "Ошибка", "value": "'error'"}, {"label": "Фатальная ошибка", "value": "'fatal'"}]
+ }) | indent(8, true) }}
+
Обновить (последние 1000 строк)
+
Скачать все
+
{{ '{{ paramLogs.data }}' }}
+
Обновить (последние 1000 строк)
+
+
+
diff --git a/front-generator/template/common/monitoring-data.js.j2 b/front-generator/template/common/monitoring-data.js.j2
index 65a6c48..5431379 100644
--- a/front-generator/template/common/monitoring-data.js.j2
+++ b/front-generator/template/common/monitoring-data.js.j2
@@ -1,50 +1,48 @@
- statRx: {
- // индикаторы
- state: '?', // общее состояние
- sym_sync_lock: '?', // захват символьной
- freq_search_lock: '?', // Захват поиска по частоте
- afc_lock: '?', // захват ФАПЧ
- pkt_sync: '?', // захват пакетной синхронизации
+statRx: {
+ // индикаторы
+ state: '?', // общее состояние
+ sym_sync_lock: '?', // захват символьной
+ freq_search_lock: '?', // Захват поиска по частоте
+ afc_lock: '?', // захват ФАПЧ
+ pkt_sync: '?', // захват пакетной синхронизации
- // куча других параметров, идет в том же порядке, что и в таблице
- snr: '?', rssi: '?',
- modcod: '?', frameSizeNormal: '?',
- isPilots: '?',
- symError: '?',
- freqErr: '?', freqErrAcc: '?',
- inputSignalLevel: '?',
- pllError: '?',
- speedOnRxKbit: '?',
- speedOnIifKbit: '?',
+ // куча других параметров, идет в том же порядке, что и в таблице
+ snr: '?', rssi: '?',
+ modcod: '?', frameSizeNormal: '?',
+ isPilots: '?',
+ symError: '?',
+ freqErr: '?', freqErrAcc: '?',
+ inputSignalLevel: '?',
+ pllError: '?',
+ speedOnRxKbit: '?',
+ speedOnIifKbit: '?',
- // статистика пакетов
- packetsOk: '?', packetsBad: '?', packetsDummy: '?',
- },
- statTx: {
- // состояние
- state: '?',
+ // статистика пакетов
+ packetsOk: '?', packetsBad: '?', packetsDummy: '?',
+},
+statTx: {
+ // состояние
+ state: '?',
- // прочие поля
- {% if modem == 'scpc' %}
- snr: '?', modcod: '?', frameSizeNormal: '?', isPilots: '?', speedOnTxKbit: '?', speedOnIifKbit: '?'
- {% else %}
- modcod: '?', speedOnTxKbit: '?', speedOnIifKbit: '?', centerFreq: '?', symSpeed: '?'
- {% endif %}
- },
- {% if modem == 'scpc' %}
- statCinc: {
- occ: '?',
- correlator: null,
- correlatorFails: '?',
- freqErr: '?', freqErrAcc: '?',
- channelDelay: '?'
- },
- {% endif %}
- statDevice: { // температурные датчики
- adrv: 0, zynq: 0, fpga: 0
- {% if modem == 'tdma' %},
- upgradeStatus: "", upgradePercent: 0, upgradeImage: ""
- {% endif %}
- },
- statOs: {uptime: '?', load1: '?', load5: '?', load15: '?', totalram: '?', freeram: '?'},
+ // прочие поля
+ {% if modem == 'scpc' %}
+ snr: '?', modcod: '?', frameSizeNormal: '?', isPilots: '?', speedOnTxKbit: '?', speedOnIifKbit: '?'
+ {% else %}
+ modcod: '?', speedOnTxKbit: '?', speedOnIifKbit: '?', centerFreq: '?', symSpeed: '?'
+ {% endif %}
+},
+{% if modem == 'scpc' %}
+statCinc: {
+ occ: '?',
+ correlator: null,
+ correlatorFails: '?',
+ freqErr: '?', freqErrAcc: '?',
+ channelDelay: '?'
+},
+{% endif %}
+statDevice: { // температурные датчики
+ adrv: 0, zynq: 0, fpga: 0{% if modem == 'tdma' %}, upgradeStatus: "", upgradePercent: 0, upgradeImage: ""{% endif %}
+
+},
+statOs: {uptime: '?', load1: '?', load5: '?', load15: '?', totalram: '?', freeram: '?'},
diff --git a/front-generator/template/common/monitoring-methods.js.j2 b/front-generator/template/common/monitoring-methods.js.j2
index 24255e3..22d6af5 100644
--- a/front-generator/template/common/monitoring-methods.js.j2
+++ b/front-generator/template/common/monitoring-methods.js.j2
@@ -1,110 +1,110 @@
- updateStatistics(vals) {
- function modcodToStr(modcod) {
- // модкоды из раздела 5.5.2.2 https://www.etsi.org/deliver/etsi_en/302300_302399/302307/01.01.02_60/en_302307v010102p.pdf
- const modcods = [
- "DUMMY",
- "QPSK 1/4", "QPSK 1/3", "QPSK 2/5", "QPSK 1/2", "QPSK 3/5", "QPSK 2/3", "QPSK 3/4", "QPSK 4/5", "QPSK 5/6", "QPSK 8/9", "QPSK 9/10",
- "8PSK 3/5", "8PSK 2/3", "8PSK 3/4", "8PSK 5/6", "8PSK 8/9", "8PSK 9/10",
- "16APSK 2/3", "16APSK 3/4", "16APSK 4/5", "16APSK 5/6", "16APSK 8/9", "16APSK 9/10",
- "32APSK 3/4", "32APSK 4/5", "32APSK 5/6", "32APSK 8/9", "32APSK 9/10",
- ]
- if (typeof modcod != "number") {
- return "?";
- }
- if (modcod < 0 || modcod >= modcods.length) {
- return `? (${modcod})`
- }
- return modcods[modcod]
- }
+updateStatistics(vals) {
+ function modcodToStr(modcod) {
+ // модкоды из раздела 5.5.2.2 https://www.etsi.org/deliver/etsi_en/302300_302399/302307/01.01.02_60/en_302307v010102p.pdf
+ const modcods = [
+ "DUMMY",
+ "QPSK 1/4", "QPSK 1/3", "QPSK 2/5", "QPSK 1/2", "QPSK 3/5", "QPSK 2/3", "QPSK 3/4", "QPSK 4/5", "QPSK 5/6", "QPSK 8/9", "QPSK 9/10",
+ "8PSK 3/5", "8PSK 2/3", "8PSK 3/4", "8PSK 5/6", "8PSK 8/9", "8PSK 9/10",
+ "16APSK 2/3", "16APSK 3/4", "16APSK 4/5", "16APSK 5/6", "16APSK 8/9", "16APSK 9/10",
+ "32APSK 3/4", "32APSK 4/5", "32APSK 5/6", "32APSK 8/9", "32APSK 9/10",
+ ]
+ if (typeof modcod != "number") {
+ return "?";
+ }
+ if (modcod < 0 || modcod >= modcods.length) {
+ return `? (${modcod})`
+ }
+ return modcods[modcod]
+ }
- this.lastUpdateTime = new Date();
- this.initState = vals["state"]["initState"]
- this.testState = vals["state"]["testState"]
- {% if modem == 'scpc' %}
- this.isCinC = vals["state"]["isCinC"]
- {% endif %}
+ this.lastUpdateTime = new Date();
+ this.initState = vals["state"]["initState"]
+ this.testState = vals["state"]["testState"]
+ {% if modem == 'scpc' %}
+ this.isCinC = vals["state"]["isCinC"]
+ {% endif %}
- this.statRx.state = vals["state"]["rx"]["state"]
- this.statRx.sym_sync_lock = vals["state"]["rx"]["sym_sync_lock"]
- this.statRx.freq_search_lock = vals["state"]["rx"]["freq_search_lock"]
- this.statRx.afc_lock = vals["state"]["rx"]["afc_lock"]
- this.statRx.pkt_sync = vals["state"]["rx"]["pkt_sync"]
- this.statRx.snr = Math.round(vals["state"]["rx"]["snr"] * 10) / 10
- this.statRx.rssi = Math.round(vals["state"]["rx"]["rssi"] * 10) / 10
- this.statRx.modcod = modcodToStr(vals["state"]["rx"]["modcod"])
- this.statRx.frameSizeNormal = vals["state"]["rx"]["frameSizeNormal"]
- this.statRx.isPilots = vals["state"]["rx"]["isPilots"]
- this.statRx.symError = vals["state"]["rx"]["symError"]
- this.statRx.freqErr = Math.round(vals["state"]["rx"]["freqErr"] * 100) / 100
- this.statRx.freqErrAcc = Math.round(vals["state"]["rx"]["freqErrAcc"] * 100) / 100
- this.statRx.inputSignalLevel = vals["state"]["rx"]["inputSignalLevel"]
- this.statRx.pllError = Math.round(vals["state"]["rx"]["pllError"] * 100) / 100
- this.statRx.speedOnRxKbit = Math.round(vals["state"]["rx"]["speedOnRxKbit"] * 100) / 100
- this.statRx.speedOnIifKbit = Math.round(vals["state"]["rx"]["speedOnIifKbit"] * 100) / 100
- this.statRx.packetsOk = vals["state"]["rx"]["packetsOk"]
- this.statRx.packetsBad = vals["state"]["rx"]["packetsBad"]
- this.statRx.packetsDummy = vals["state"]["rx"]["packetsDummy"]
+ this.statRx.state = vals["state"]["rx"]["state"]
+ this.statRx.sym_sync_lock = vals["state"]["rx"]["sym_sync_lock"]
+ this.statRx.freq_search_lock = vals["state"]["rx"]["freq_search_lock"]
+ this.statRx.afc_lock = vals["state"]["rx"]["afc_lock"]
+ this.statRx.pkt_sync = vals["state"]["rx"]["pkt_sync"]
+ this.statRx.snr = Math.round(vals["state"]["rx"]["snr"] * 10) / 10
+ this.statRx.rssi = Math.round(vals["state"]["rx"]["rssi"] * 10) / 10
+ this.statRx.modcod = modcodToStr(vals["state"]["rx"]["modcod"])
+ this.statRx.frameSizeNormal = vals["state"]["rx"]["frameSizeNormal"]
+ this.statRx.isPilots = vals["state"]["rx"]["isPilots"]
+ this.statRx.symError = vals["state"]["rx"]["symError"]
+ this.statRx.freqErr = Math.round(vals["state"]["rx"]["freqErr"] * 100) / 100
+ this.statRx.freqErrAcc = Math.round(vals["state"]["rx"]["freqErrAcc"] * 100) / 100
+ this.statRx.inputSignalLevel = vals["state"]["rx"]["inputSignalLevel"]
+ this.statRx.pllError = Math.round(vals["state"]["rx"]["pllError"] * 100) / 100
+ this.statRx.speedOnRxKbit = Math.round(vals["state"]["rx"]["speedOnRxKbit"] * 100) / 100
+ this.statRx.speedOnIifKbit = Math.round(vals["state"]["rx"]["speedOnIifKbit"] * 100) / 100
+ this.statRx.packetsOk = vals["state"]["rx"]["packetsOk"]
+ this.statRx.packetsBad = vals["state"]["rx"]["packetsBad"]
+ this.statRx.packetsDummy = vals["state"]["rx"]["packetsDummy"]
- {% if modem == 'scpc' %}
- this.statTx.state = vals["state"]["tx"]["state"]
- this.statTx.snr = Math.round(vals["state"]["tx"]["snr"] * 100) / 100
- this.statTx.modcod = modcodToStr(vals["state"]["tx"]["modcod"])
- this.statTx.frameSizeNormal = vals["state"]["tx"]["frameSizeNormal"]
- this.statTx.isPilots = vals["state"]["tx"]["isPilots"]
- this.statTx.speedOnTxKbit = Math.round(vals["state"]["tx"]["speedOnTxKbit"] * 100) / 100
- this.statTx.speedOnIifKbit = Math.round(vals["state"]["tx"]["speedOnIifKbit"] * 100) / 100
+ {% if modem == 'scpc' %}
+ this.statTx.state = vals["state"]["tx"]["state"]
+ this.statTx.snr = Math.round(vals["state"]["tx"]["snr"] * 100) / 100
+ this.statTx.modcod = modcodToStr(vals["state"]["tx"]["modcod"])
+ this.statTx.frameSizeNormal = vals["state"]["tx"]["frameSizeNormal"]
+ this.statTx.isPilots = vals["state"]["tx"]["isPilots"]
+ this.statTx.speedOnTxKbit = Math.round(vals["state"]["tx"]["speedOnTxKbit"] * 100) / 100
+ this.statTx.speedOnIifKbit = Math.round(vals["state"]["tx"]["speedOnIifKbit"] * 100) / 100
- this.statCinc.occ = vals["state"]["cinc"]["occ"]
- this.statCinc.correlator = vals["state"]["cinc"]["correlator"]
- this.statCinc.correlatorFails = vals["state"]["cinc"]["correlatorFails"]
- this.statCinc.freqErr = Math.round(vals["state"]["cinc"]["freqErr"] * 100) / 100
- this.statCinc.freqErrAcc = Math.round(vals["state"]["cinc"]["freqErrAcc"] * 100) / 100
- this.statCinc.channelDelay = vals["state"]["cinc"]["channelDelay"]
- {% else %}
- this.statTx.state = vals["state"]["tx"]["state"]
- this.statTx.modcod = modcodToStr(vals["state"]["tx"]["modcod"])
- this.statTx.speedOnTxKbit = Math.round(vals["state"]["tx"]["speedOnTxKbit"] * 100) / 100
- this.statTx.speedOnIifKbit = Math.round(vals["state"]["tx"]["speedOnIifKbit"] * 100) / 100
- this.statTx.centerFreq = vals["state"]["tx"]["centerFreq"]
- this.statTx.symSpeed = vals["state"]["tx"]["symSpeed"]
- {% endif %}
+ this.statCinc.occ = vals["state"]["cinc"]["occ"]
+ this.statCinc.correlator = vals["state"]["cinc"]["correlator"]
+ this.statCinc.correlatorFails = vals["state"]["cinc"]["correlatorFails"]
+ this.statCinc.freqErr = Math.round(vals["state"]["cinc"]["freqErr"] * 100) / 100
+ this.statCinc.freqErrAcc = Math.round(vals["state"]["cinc"]["freqErrAcc"] * 100) / 100
+ this.statCinc.channelDelay = vals["state"]["cinc"]["channelDelay"]
+ {% else %}
+ this.statTx.state = vals["state"]["tx"]["state"]
+ this.statTx.modcod = modcodToStr(vals["state"]["tx"]["modcod"])
+ this.statTx.speedOnTxKbit = Math.round(vals["state"]["tx"]["speedOnTxKbit"] * 100) / 100
+ this.statTx.speedOnIifKbit = Math.round(vals["state"]["tx"]["speedOnIifKbit"] * 100) / 100
+ this.statTx.centerFreq = vals["state"]["tx"]["centerFreq"]
+ this.statTx.symSpeed = vals["state"]["tx"]["symSpeed"]
+ {% endif %}
- this.statDevice.adrv = vals["state"]["device"]["adrv"]
- this.statDevice.zynq = vals["state"]["device"]["zynq"]
- this.statDevice.fpga = vals["state"]["device"]["fpga"]
- {% if modem == 'tdma' %}
- this.statDevice.upgradeStatus = vals["state"]["device"]["upgradeStatus"]
- this.statDevice.upgradePercent = vals["state"]["device"]["upgradePercent"]
- this.statDevice.upgradeImage = vals["state"]["device"]["upgradeImage"]
- {% endif %}
+ this.statDevice.adrv = vals["state"]["device"]["adrv"]
+ this.statDevice.zynq = vals["state"]["device"]["zynq"]
+ this.statDevice.fpga = vals["state"]["device"]["fpga"]
+ {% if modem == 'tdma' %}
+ this.statDevice.upgradeStatus = vals["state"]["device"]["upgradeStatus"]
+ this.statDevice.upgradePercent = vals["state"]["device"]["upgradePercent"]
+ this.statDevice.upgradeImage = vals["state"]["device"]["upgradeImage"]
+ {% endif %}
- // аптайм приходит в секундах, надо преобразовать его в человеко-читаемый вид
- let uptime = vals["state"]["device"]["uptime"]
- if (uptime) {
- let secs = uptime % 60; uptime = Math.floor(uptime / 60)
- let mins = uptime % 60; uptime = Math.floor(uptime / 60)
- let hours = uptime % 24
- uptime = Math.floor( uptime / 24)
- let res = `${hours}:${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`
- if (uptime > 0) { res = `${uptime} дней, ` + res }
- this.statOs.uptime = res
- } else {
- this.statOs.uptime = '?'
- }
- this.statOs.load1 = Math.round(vals["state"]["device"]["load1min"] * 100) / 100
- this.statOs.load5 = Math.round(vals["state"]["device"]["load5min"] * 100) / 100
- this.statOs.load15 = Math.round(vals["state"]["device"]["load15min"] * 100) / 100
- this.statOs.totalram = vals["state"]["device"]["totalram"]
- this.statOs.freeram = vals["state"]["device"]["freeram"]
- },
+ // аптайм приходит в секундах, надо преобразовать его в человеко-читаемый вид
+ let uptime = vals["state"]["device"]["uptime"]
+ if (uptime) {
+ let secs = uptime % 60; uptime = Math.floor(uptime / 60)
+ let mins = uptime % 60; uptime = Math.floor(uptime / 60)
+ let hours = uptime % 24
+ uptime = Math.floor( uptime / 24)
+ let res = `${hours}:${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`
+ if (uptime > 0) { res = `${uptime} дней, ` + res }
+ this.statOs.uptime = res
+ } else {
+ this.statOs.uptime = '?'
+ }
+ this.statOs.load1 = Math.round(vals["state"]["device"]["load1min"] * 100) / 100
+ this.statOs.load5 = Math.round(vals["state"]["device"]["load5min"] * 100) / 100
+ this.statOs.load15 = Math.round(vals["state"]["device"]["load15min"] * 100) / 100
+ this.statOs.totalram = vals["state"]["device"]["totalram"]
+ this.statOs.freeram = vals["state"]["device"]["freeram"]
+},
- resetPacketsStatistics() {
- fetch('/api/resetPacketStatistics', {
- method: 'POST', credentials: 'same-origin'
- }).then(() => {
- this.statRx.packetsOk = 0
- this.statRx.packetsBad = 0
- this.statRx.packetsDummy = 0
- })
- },
+resetPacketsStatistics() {
+ fetch('/api/resetPacketStatistics', {
+ method: 'POST', credentials: 'same-origin'
+ }).then(() => {
+ this.statRx.packetsOk = 0
+ this.statRx.packetsBad = 0
+ this.statRx.packetsDummy = 0
+ })
+},
diff --git a/front-generator/template/common/monitoring.html.j2 b/front-generator/template/common/monitoring.html.j2
index 2f6e927..09f4854 100644
--- a/front-generator/template/common/monitoring.html.j2
+++ b/front-generator/template/common/monitoring.html.j2
@@ -1,103 +1,102 @@
- {% raw %}
-
-
-
Статистика приема
-
- {% endraw %}{% if modem != 'shps' %}{% raw %}
- Прием
- Захват символьной
- Захват ФАПЧ
- Захват поиска по частоте
- Захват пакетной синхр.
- ОСШ/RSSI {{ statRx.snr }} / {{ statRx.rssi }}
- Modcod {{ statRx.modcod }}
- Размер кадра {{ statRx.frameSizeNormal ? 'normal' : 'short' }}
- Пилот-символы {{ statRx.isPilots ? 'pilots' : 'no pilots' }}
- Символьная ошибка {{ statRx.symError }}
- Грубая/точная част. ошибка, Гц {{ statRx.freqErr }} / {{ statRx.freqErrAcc }}
- Ур. входного сигнала {{ statRx.inputSignalLevel }}
- Ошибка ФАПЧ {{ statRx.pllError }}
- Инф. скорость на приеме {{ statRx.speedOnRxKbit }} кбит/с
- Инф. скорость на интерфейсе {{ statRx.speedOnIifKbit }} кбит/с
- Статистика пакетов
- Качественных пакетов {{ statRx.packetsOk }}
- Поврежденных пакетов {{ statRx.packetsBad }}
- DUMMY {{ statRx.packetsDummy }} {% endraw %}{% else %}{% raw %}
- Прием
- ОСШ/RSSI {{ statRx.snr }} / {{ statRx.rssi }}
- Частотная ошибка, Гц {{ statRx.freqErrAcc }}
- Ур. входного сигнала {{ statRx.inputSignalLevel }}
- Ошибка ФАПЧ {{ statRx.pllError }}
- Инф. скорость на приеме {{ statRx.speedOnRxKbit }} кбит/с
- Инф. скорость на интерфейсе {{ statRx.speedOnIifKbit }} кбит/с
- Статистика пакетов
- Качественных пакетов {{ statRx.packetsOk }}
- Поврежденных пакетов {{ statRx.packetsBad }} {% endraw %}{% endif %}{% raw %}
-
-
-
Сброс статистики
-
-
-
Статистика передачи {% endraw %}{% if modem == 'scpc' %}{% raw %}
-
-
- Передача
- ОСШ дальнего приема {{ statTx.snr }}
- Modcod {{ statTx.modcod }}
- Размер кадра {{ statTx.frameSizeNormal ? 'normal' : 'short' }}
- Пилот-символы {{ statTx.isPilots ? 'pilots' : 'no pilots' }}
- Инф. скорость на передаче {{ statTx.speedOnTxKbit }} кбит/с
- Инф. скорость на интерфейсе {{ statTx.speedOnIifKbit }} кбит/с
-
-
{% endraw %}{% elif modem == 'tdma' %}{% raw %}
-
-
- Передача
- Modcod {{ statTx.modcod }}
- Инф. скорость на передаче {{ statTx.speedOnTxKbit }} кбит/с
- Инф. скорость на интерфейсе {{ statTx.speedOnIifKbit }} кбит/с
- Центральная частота {{ statTx.centerFreq }} кГц
- Символьная скорость {{ statTx.symSpeed }} ksymb
-
-
{% endraw %}{% elif modem == 'shps' %}{% raw %}
-
-
- Передача
- Инф. скорость на передаче {{ statTx.speedOnTxKbit }} кбит/с
- Инф. скорость на интерфейсе {{ statTx.speedOnIifKbit }} кбит/с
- Центральная частота {{ statTx.centerFreq }} кГц
- Символьная скорость {{ statTx.symSpeed }} ksymb
-
-
{% endraw %}{% endif %}{% raw %}
-
{% endraw %}{% if modem == 'scpc' %}{% raw %}
-
-
Статистика режима CinC
-
-
- ОСС {{ statCinc.occ }}
- Захват коррелятора
- Кол-во срывов коррелятора {{ statCinc.correlatorFails }}
- Грубая/точная част. ошибка, Гц {{ statCinc.freqErr }} / {{ statCinc.freqErrAcc }}
- Задержка в канале, мс {{ statCinc.channelDelay }}
-
-
-
{% endraw %}{% endif %}{% raw %}
-
-
Состояние устройства
-
-
- Температура ADRV {{ statDevice.adrv }} °C
- Температура ZYNQ {{ statDevice.zynq }} °C
- Температура FPGA {{ statDevice.fpga }} °C
- Время работы устройства {{ statOs.uptime }}
- Средняя загрузка ЦП (1/5/15 мин.) {{ statOs.load1 }}% {{ statOs.load5 }}% {{ statOs.load15 }}%
- ОЗУ всего/свободно {{ statOs.totalram }}МБ/{{ statOs.freeram }}МБ {% endraw %}{% if modem == 'tdma' %}{% raw %}
- Статус обновления
- Статус {{ statDevice.upgradeStatus }}
- Прогресс {{ statDevice.upgradePercent }}%
- Имя образа {{ statDevice.upgradeImage }}
{% endraw %}{% endif %}{% raw %}
-
-
-
-
- {% endraw %}
\ No newline at end of file
+{% raw %}
+
+
Статистика приема
+
+ {% endraw %}{% if modem != 'shps' %}{% raw %}
+ Прием
+ Захват символьной
+ Захват ФАПЧ
+ Захват поиска по частоте
+ Захват пакетной синхр.
+ ОСШ/RSSI {{ statRx.snr }} / {{ statRx.rssi }}
+ Modcod {{ statRx.modcod }}
+ Размер кадра {{ statRx.frameSizeNormal ? 'normal' : 'short' }}
+ Пилот-символы {{ statRx.isPilots ? 'pilots' : 'no pilots' }}
+ Символьная ошибка {{ statRx.symError }}
+ Грубая/точная част. ошибка, Гц {{ statRx.freqErr }} / {{ statRx.freqErrAcc }}
+ Ур. входного сигнала {{ statRx.inputSignalLevel }}
+ Ошибка ФАПЧ {{ statRx.pllError }}
+ Инф. скорость на приеме {{ statRx.speedOnRxKbit }} кбит/с
+ Инф. скорость на интерфейсе {{ statRx.speedOnIifKbit }} кбит/с
+ Статистика пакетов
+ Качественных пакетов {{ statRx.packetsOk }}
+ Поврежденных пакетов {{ statRx.packetsBad }}
+ DUMMY {{ statRx.packetsDummy }} {% endraw %}{% else %}{% raw %}
+ Прием
+ ОСШ/RSSI {{ statRx.snr }} / {{ statRx.rssi }}
+ Частотная ошибка, Гц {{ statRx.freqErrAcc }}
+ Ур. входного сигнала {{ statRx.inputSignalLevel }}
+ Ошибка ФАПЧ {{ statRx.pllError }}
+ Инф. скорость на приеме {{ statRx.speedOnRxKbit }} кбит/с
+ Инф. скорость на интерфейсе {{ statRx.speedOnIifKbit }} кбит/с
+ Статистика пакетов
+ Качественных пакетов {{ statRx.packetsOk }}
+ Поврежденных пакетов {{ statRx.packetsBad }} {% endraw %}{% endif %}{% raw %}
+
+
+
Сброс статистики
+
+
+
Статистика передачи {% endraw %}{% if modem == 'scpc' %}{% raw %}
+
+
+ Передача
+ ОСШ дальнего приема {{ statTx.snr }}
+ Modcod {{ statTx.modcod }}
+ Размер кадра {{ statTx.frameSizeNormal ? 'normal' : 'short' }}
+ Пилот-символы {{ statTx.isPilots ? 'pilots' : 'no pilots' }}
+ Инф. скорость на передаче {{ statTx.speedOnTxKbit }} кбит/с
+ Инф. скорость на интерфейсе {{ statTx.speedOnIifKbit }} кбит/с
+
+
{% endraw %}{% elif modem == 'tdma' %}{% raw %}
+
+
+ Передача
+ Modcod {{ statTx.modcod }}
+ Инф. скорость на передаче {{ statTx.speedOnTxKbit }} кбит/с
+ Инф. скорость на интерфейсе {{ statTx.speedOnIifKbit }} кбит/с
+ Центральная частота {{ statTx.centerFreq }} кГц
+ Символьная скорость {{ statTx.symSpeed }} ksymb
+
+
{% endraw %}{% elif modem == 'shps' %}{% raw %}
+
+
+ Передача
+ Инф. скорость на передаче {{ statTx.speedOnTxKbit }} кбит/с
+ Инф. скорость на интерфейсе {{ statTx.speedOnIifKbit }} кбит/с
+ Центральная частота {{ statTx.centerFreq }} кГц
+ Символьная скорость {{ statTx.symSpeed }} ksymb
+
+
{% endraw %}{% endif %}{% raw %}
+
{% endraw %}{% if modem == 'scpc' %}{% raw %}
+
+
Статистика режима CinC
+
+
+ ОСС {{ statCinc.occ }}
+ Захват коррелятора
+ Кол-во срывов коррелятора {{ statCinc.correlatorFails }}
+ Грубая/точная част. ошибка, Гц {{ statCinc.freqErr }} / {{ statCinc.freqErrAcc }}
+ Задержка в канале, мс {{ statCinc.channelDelay }}
+
+
+
{% endraw %}{% endif %}{% raw %}
+
+
Состояние устройства
+
+
+ Температура ADRV {{ statDevice.adrv }} °C
+ Температура ZYNQ {{ statDevice.zynq }} °C
+ Температура FPGA {{ statDevice.fpga }} °C
+ Время работы устройства {{ statOs.uptime }}
+ Средняя загрузка ЦП (1/5/15 мин.) {{ statOs.load1 }}% {{ statOs.load5 }}% {{ statOs.load15 }}%
+ ОЗУ всего/свободно {{ statOs.totalram }}МБ/{{ statOs.freeram }}МБ {% endraw %}{% if modem == 'tdma' %}{% raw %}
+ Статус обновления
+ Статус {{ statDevice.upgradeStatus }}
+ Прогресс {{ statDevice.upgradePercent }}%
+ Имя образа {{ statDevice.upgradeImage }}
{% endraw %}{% endif %}{% raw %}
+
+
+
+
+{% endraw %}
\ No newline at end of file
diff --git a/front-generator/template/common/qos-data.js.j2 b/front-generator/template/common/qos-data.js.j2
index 31da867..6b3935a 100644
--- a/front-generator/template/common/qos-data.js.j2
+++ b/front-generator/template/common/qos-data.js.j2
@@ -1,8 +1,9 @@
- submitStatusQos: false,
- paramQos: {
- en: false,
- rt1: [],
- rt2: [],
- rt3: [],
- cd: [],
- },
+submitStatusQos: false,
+paramQos: {
+ en: false,
+ rt1: [],
+ rt2: [],
+ rt3: [],
+ cd: [],
+},
+
diff --git a/front-generator/template/common/qos-methods.js.j2 b/front-generator/template/common/qos-methods.js.j2
index 869f340..2199f35 100644
--- a/front-generator/template/common/qos-methods.js.j2
+++ b/front-generator/template/common/qos-methods.js.j2
@@ -1,224 +1,224 @@
- settingsSubmitQoS() {
- if (this.submitStatusQos) { return }
- this.submitStatusQos = true
- function _translateQosClass(trafficClass, qc) {
- let res = {
+settingsSubmitQoS() {
+ if (this.submitStatusQos) { return }
+ this.submitStatusQos = true
+ function _translateQosClass(trafficClass, qc) {
+ let res = {
+ cir: qc['cir'],
+ description: qc['description'],
+ filters: []
+ }
+ if (trafficClass === 'cd') {
+ res.pir = qc.pir
+ }
+ if (!qc.isEnabled) {
+ res.disabled = true
+ }
+ for (const fi in qc.filters) {
+ let filter = {}
+ if (qc['filters'][fi].vlan !== "") { filter['vlan'] = qc['filters'][fi].vlan }
+ if (qc['filters'][fi].proto.length > 0) {
+ let tmp = "";
+ for (let pid = 0; pid < qc['filters'][fi].proto.length; pid++) {
+ if (pid !== 0) { tmp += ',' }
+ tmp += qc['filters'][fi].proto[pid]
+ }
+ filter['proto'] = tmp
+ }
+ if (qc['filters'][fi].sport !== "") { filter['sport'] = qc['filters'][fi].sport }
+ if (qc['filters'][fi].dport !== "") { filter['dport'] = qc['filters'][fi].dport }
+ if (qc['filters'][fi].ip_src !== "") { filter['ip_src'] = qc['filters'][fi].ip_src }
+ if (qc['filters'][fi].ip_dest !== "") { filter['ip_dest'] = qc['filters'][fi].ip_dest }
+ if (qc['filters'][fi].dscp !== "") { filter['dscp'] = qc['filters'][fi].dscp }
+
+ if (Object.keys(filter).length === 0) { continue }
+ if (!qc.filters[fi].isEnabled) { filter['disabled'] = true }
+
+ res.filters.push(filter)
+ }
+ if (res.filters.length === 0) {
+ // автоматическое выключение класса, если правил нет
+ res.disabled = true
+ }
+
+ return res
+ }
+ let query = {
+ "en": this.paramQos.en,
+ "profile": {
+ "rt1": [],
+ "rt2": [],
+ "rt3": [],
+ "cd": []
+ }
+ }
+ for (let i = 0; i < this.paramQos.rt1.length; i++) { query.profile.rt1.push(_translateQosClass('rt', this.paramQos.rt1[i])) }
+ for (let i = 0; i < this.paramQos.rt2.length; i++) { query.profile.rt2.push(_translateQosClass('rt', this.paramQos.rt2[i])) }
+ for (let i = 0; i < this.paramQos.rt3.length; i++) { query.profile.rt3.push(_translateQosClass('rt', this.paramQos.rt3[i])) }
+ for (let i = 0; i < this.paramQos.cd.length; i++) { query.profile.cd.push(_translateQosClass('rt', this.paramQos.cd[i])) }
+
+ //console.log(query)
+ fetch('/api/set/qos', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify(query), credentials: 'same-origin'
+ }).then(async (resp) => {
+ this.submitStatusQos = false
+ if (resp['error']) { throw new Error(resp['error']) }
+ this.updateQosSettings(await resp.json())
+ }).catch((reason) => {
+ this.submitStatusQos = false
+ alert(`Ошибка при применении настроек: ${reason}`)
+ })
+},
+
+updateQosSettings(vals) {
+ this.submitStatusQos = false
+ this.paramQos.en = vals["settings"]["qos"]["en"]
+
+ const qosProfile = vals["settings"]["qos"]["profile"]
+ if (qosProfile !== null && qosProfile !== undefined) {
+ this.paramQos.rt1 = [] // .splice(0, this.paramQos.rt1.length)
+ this.paramQos.rt2 = [] // .splice(0, this.paramQos.rt2.length)
+ this.paramQos.rt3 = [] // .splice(0, this.paramQos.rt3.length)
+ this.paramQos.cd = [] // .splice(0, this.paramQos.cd.length)
+
+ for (let trafficClass in qosProfile) {
+ if (['rt1', 'rt2', 'rt3', 'cd'].indexOf(trafficClass) < 0) {
+ continue
+ }
+
+ if (Array.isArray(qosProfile[trafficClass])) {
+ for (let i = 0; i < qosProfile[trafficClass].length; i++) {
+ const qc = qosProfile[trafficClass][i]
+ let result = {
+ isEnabled: !qc.hasOwnProperty('disabled'),
cir: qc['cir'],
+ pir: 0,
description: qc['description'],
filters: []
}
if (trafficClass === 'cd') {
- res.pir = qc.pir
- }
- if (!qc.isEnabled) {
- res.disabled = true
- }
- for (const fi in qc.filters) {
- let filter = {}
- if (qc['filters'][fi].vlan !== "") { filter['vlan'] = qc['filters'][fi].vlan }
- if (qc['filters'][fi].proto.length > 0) {
- let tmp = "";
- for (let pid = 0; pid < qc['filters'][fi].proto.length; pid++) {
- if (pid !== 0) { tmp += ',' }
- tmp += qc['filters'][fi].proto[pid]
- }
- filter['proto'] = tmp
- }
- if (qc['filters'][fi].sport !== "") { filter['sport'] = qc['filters'][fi].sport }
- if (qc['filters'][fi].dport !== "") { filter['dport'] = qc['filters'][fi].dport }
- if (qc['filters'][fi].ip_src !== "") { filter['ip_src'] = qc['filters'][fi].ip_src }
- if (qc['filters'][fi].ip_dest !== "") { filter['ip_dest'] = qc['filters'][fi].ip_dest }
- if (qc['filters'][fi].dscp !== "") { filter['dscp'] = qc['filters'][fi].dscp }
-
- if (Object.keys(filter).length === 0) { continue }
- if (!qc.filters[fi].isEnabled) { filter['disabled'] = true }
-
- res.filters.push(filter)
- }
- if (res.filters.length === 0) {
- // автоматическое выключение класса, если правил нет
- res.disabled = true
- }
-
- return res
- }
- let query = {
- "en": this.paramQos.en,
- "profile": {
- "rt1": [],
- "rt2": [],
- "rt3": [],
- "cd": []
- }
- }
- for (let i = 0; i < this.paramQos.rt1.length; i++) { query.profile.rt1.push(_translateQosClass('rt', this.paramQos.rt1[i])) }
- for (let i = 0; i < this.paramQos.rt2.length; i++) { query.profile.rt2.push(_translateQosClass('rt', this.paramQos.rt2[i])) }
- for (let i = 0; i < this.paramQos.rt3.length; i++) { query.profile.rt3.push(_translateQosClass('rt', this.paramQos.rt3[i])) }
- for (let i = 0; i < this.paramQos.cd.length; i++) { query.profile.cd.push(_translateQosClass('rt', this.paramQos.cd[i])) }
-
- //console.log(query)
- fetch('/api/set/qos', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json'
- },
- body: JSON.stringify(query), credentials: 'same-origin'
- }).then(async (resp) => {
- this.submitStatusQos = false
- if (resp['error']) { throw new Error(resp['error']) }
- this.updateQosSettings(await resp.json())
- }).catch((reason) => {
- this.submitStatusQos = false
- alert(`Ошибка при применении настроек: ${reason}`)
- })
- },
-
- updateQosSettings(vals) {
- this.submitStatusQos = false
- this.paramQos.en = vals["settings"]["qos"]["en"]
-
- const qosProfile = vals["settings"]["qos"]["profile"]
- if (qosProfile !== null && qosProfile !== undefined) {
- this.paramQos.rt1 = [] // .splice(0, this.paramQos.rt1.length)
- this.paramQos.rt2 = [] // .splice(0, this.paramQos.rt2.length)
- this.paramQos.rt3 = [] // .splice(0, this.paramQos.rt3.length)
- this.paramQos.cd = [] // .splice(0, this.paramQos.cd.length)
-
- for (let trafficClass in qosProfile) {
- if (['rt1', 'rt2', 'rt3', 'cd'].indexOf(trafficClass) < 0) {
- continue
- }
-
- if (Array.isArray(qosProfile[trafficClass])) {
- for (let i = 0; i < qosProfile[trafficClass].length; i++) {
- const qc = qosProfile[trafficClass][i]
- let result = {
- isEnabled: !qc.hasOwnProperty('disabled'),
- cir: qc['cir'],
- pir: 0,
- description: qc['description'],
- filters: []
- }
- if (trafficClass === 'cd') {
- if (qc['pir']) {
- result.pir = qc['pir']
- }
- }
- for (let fi = 0; fi < qc['filters'].length; fi++) {
- result.filters.push({
- isEnabled: !qc['filters'][fi].hasOwnProperty('disabled'),
- vlan: qc['filters'][fi].hasOwnProperty('vlan') ? qc['filters'][fi]['vlan'] : '',
- proto: qc['filters'][fi].hasOwnProperty('proto') ? qc['filters'][fi]['proto'].split(',') : [],
- sport: qc['filters'][fi].hasOwnProperty('sport') ? qc['filters'][fi]['sport'] : '',
- dport: qc['filters'][fi].hasOwnProperty('dport') ? qc['filters'][fi]['dport'] : '',
- ip_src: qc['filters'][fi].hasOwnProperty('ip_src') ? qc['filters'][fi]['ip_src'] : '',
- ip_dest: qc['filters'][fi].hasOwnProperty('ip_dest') ? qc['filters'][fi]['ip_dest'] : '',
- dscp: qc['filters'][fi].hasOwnProperty('dscp') ? qc['filters'][fi]['dscp'] : ''
- })
- }
- switch (trafficClass) {
- case 'rt1': this.paramQos.rt1.push(result); break
- case 'rt2': this.paramQos.rt2.push(result); break
- case 'rt3': this.paramQos.rt3.push(result); break
- case 'cd': this.paramQos.cd.push(result); break
- }
- }
+ if (qc['pir']) {
+ result.pir = qc['pir']
}
}
- }
- },
-
- qosAddClass(name) {
- let res = {
- isEnabled: true,
- cir: 0,
- pir: 0,
- description: "",
- filters: []
- }
- switch (name) {
- case 'rt1': this.paramQos.rt1.push(res); break
- case 'rt2': this.paramQos.rt2.push(res); break
- case 'rt3': this.paramQos.rt3.push(res); break
- case 'cd': this.paramQos.cd.push(res); break
- }
- },
-
- qosClassAddRule(name, index) {
- let rule = {
- isEnabled: true,
- vlan: "",
- proto: [],
- sport: "",
- dport: "",
- ip_src: "",
- ip_dest: "",
- dscp: ""
- }
- switch (name) {
- case 'rt1': this.paramQos.rt1[index].filters.push(rule); break
- case 'rt2': this.paramQos.rt2[index].filters.push(rule); break
- case 'rt3': this.paramQos.rt3[index].filters.push(rule); break
- case 'cd': this.paramQos.cd[index].filters.push(rule); break
- }
- },
-
- qosDelClass(name, index) {
- switch (name) {
- case 'rt1': this.paramQos.rt1.splice(index, 1); break
- case 'rt2': this.paramQos.rt2.splice(index, 1); break
- case 'rt3': this.paramQos.rt3.splice(index, 1); break
- case 'cd': this.paramQos.cd.splice(index, 1); break
- }
- },
-
- qosDelFilter(name, index, filterIndex) {
- switch (name) {
- case 'rt1': this.paramQos.rt1[index].filters.splice(filterIndex, 1); break
- case 'rt2': this.paramQos.rt2[index].filters.splice(filterIndex, 1); break
- case 'rt3': this.paramQos.rt3[index].filters.splice(filterIndex, 1); break
- case 'cd': this.paramQos.cd[index].filters.splice(filterIndex, 1); break
- }
- },
-
- qosGenerateRuleDescription(filter) {
- // попытка 1: просто отобразить все фильтры
- let result = ""
- let isFirst = true;
- for (const key in filter) {
- if (key === "isEnabled" || !filter[key] || (key === "proto" && filter['proto'].length === 0)) {
- continue
+ for (let fi = 0; fi < qc['filters'].length; fi++) {
+ result.filters.push({
+ isEnabled: !qc['filters'][fi].hasOwnProperty('disabled'),
+ vlan: qc['filters'][fi].hasOwnProperty('vlan') ? qc['filters'][fi]['vlan'] : '',
+ proto: qc['filters'][fi].hasOwnProperty('proto') ? qc['filters'][fi]['proto'].split(',') : [],
+ sport: qc['filters'][fi].hasOwnProperty('sport') ? qc['filters'][fi]['sport'] : '',
+ dport: qc['filters'][fi].hasOwnProperty('dport') ? qc['filters'][fi]['dport'] : '',
+ ip_src: qc['filters'][fi].hasOwnProperty('ip_src') ? qc['filters'][fi]['ip_src'] : '',
+ ip_dest: qc['filters'][fi].hasOwnProperty('ip_dest') ? qc['filters'][fi]['ip_dest'] : '',
+ dscp: qc['filters'][fi].hasOwnProperty('dscp') ? qc['filters'][fi]['dscp'] : ''
+ })
}
- if (isFirst) {
- isFirst = false;
- } else {
- result += '; '
- }
- result += `${key}: ${filter[key]}`
- }
- if (result === "") {
- return "пустой"
- }
-
- const maxResultLen = 60
-
- if (result.length > maxResultLen) {
- // попытка 2, отобразить что вообще в этом фильтре использовалось
- result = ""
- isFirst = true;
- for (const key in filter) {
- if (key === "isEnabled" || !filter[key] || (key === "proto" && filter['proto'].length === 0)) {
- continue
- }
- if (isFirst) {
- isFirst = false;
- } else {
- result += ', '
- }
- result += `${key}`
+ switch (trafficClass) {
+ case 'rt1': this.paramQos.rt1.push(result); break
+ case 'rt2': this.paramQos.rt2.push(result); break
+ case 'rt3': this.paramQos.rt3.push(result); break
+ case 'cd': this.paramQos.cd.push(result); break
}
}
+ }
+ }
+ }
+},
- return result
- },
+qosAddClass(name) {
+ let res = {
+ isEnabled: true,
+ cir: 0,
+ pir: 0,
+ description: "",
+ filters: []
+ }
+ switch (name) {
+ case 'rt1': this.paramQos.rt1.push(res); break
+ case 'rt2': this.paramQos.rt2.push(res); break
+ case 'rt3': this.paramQos.rt3.push(res); break
+ case 'cd': this.paramQos.cd.push(res); break
+ }
+},
+
+qosClassAddRule(name, index) {
+ let rule = {
+ isEnabled: true,
+ vlan: "",
+ proto: [],
+ sport: "",
+ dport: "",
+ ip_src: "",
+ ip_dest: "",
+ dscp: ""
+ }
+ switch (name) {
+ case 'rt1': this.paramQos.rt1[index].filters.push(rule); break
+ case 'rt2': this.paramQos.rt2[index].filters.push(rule); break
+ case 'rt3': this.paramQos.rt3[index].filters.push(rule); break
+ case 'cd': this.paramQos.cd[index].filters.push(rule); break
+ }
+},
+
+qosDelClass(name, index) {
+ switch (name) {
+ case 'rt1': this.paramQos.rt1.splice(index, 1); break
+ case 'rt2': this.paramQos.rt2.splice(index, 1); break
+ case 'rt3': this.paramQos.rt3.splice(index, 1); break
+ case 'cd': this.paramQos.cd.splice(index, 1); break
+ }
+},
+
+qosDelFilter(name, index, filterIndex) {
+ switch (name) {
+ case 'rt1': this.paramQos.rt1[index].filters.splice(filterIndex, 1); break
+ case 'rt2': this.paramQos.rt2[index].filters.splice(filterIndex, 1); break
+ case 'rt3': this.paramQos.rt3[index].filters.splice(filterIndex, 1); break
+ case 'cd': this.paramQos.cd[index].filters.splice(filterIndex, 1); break
+ }
+},
+
+qosGenerateRuleDescription(filter) {
+ // попытка 1: просто отобразить все фильтры
+ let result = ""
+ let isFirst = true;
+ for (const key in filter) {
+ if (key === "isEnabled" || !filter[key] || (key === "proto" && filter['proto'].length === 0)) {
+ continue
+ }
+ if (isFirst) {
+ isFirst = false;
+ } else {
+ result += '; '
+ }
+ result += `${key}: ${filter[key]}`
+ }
+ if (result === "") {
+ return "пустой"
+ }
+
+ const maxResultLen = 60
+
+ if (result.length > maxResultLen) {
+ // попытка 2, отобразить что вообще в этом фильтре использовалось
+ result = ""
+ isFirst = true;
+ for (const key in filter) {
+ if (key === "isEnabled" || !filter[key] || (key === "proto" && filter['proto'].length === 0)) {
+ continue
+ }
+ if (isFirst) {
+ isFirst = false;
+ } else {
+ result += ', '
+ }
+ result += `${key}`
+ }
+ }
+
+ return result
+},
diff --git a/front-generator/template/common/qos.html.j2 b/front-generator/template/common/qos.html.j2
index 26ba039..4d441d3 100644
--- a/front-generator/template/common/qos.html.j2
+++ b/front-generator/template/common/qos.html.j2
@@ -1,107 +1,107 @@
{% from 'common/widgets.j2' import build_widget %}
{% raw %}
-
-
Настройки QoS
-
-
- Активировать QoS
-
-
-
-
-
Классы {{ classesGroup.toUpperCase() }} +
-
-
- #{{ index }} CIR={{ qosClass.cir }}кбит, PIR={{ qosClass.pir }}кбит {{ qosClass.description }}
- #{{ index }} CBR={{ qosClass.cir }}кбит {{ qosClass.description }}
-
-
-
-
-
-
-
+
+
Настройки QoS
+
+
+ Активировать QoS
+
+
+
+
\ No newline at end of file
+
+ Удалить класс QoS
+
+
+
+ Применить
+
+ {% endraw %}{% if 'tcpaccel' in params %}
+ {% for w in params['tcpaccel'] %}{{ build_widget('tcpaccel', w) | indent(4, true) }}{% endfor %}
+ {% endif %}
+
\ No newline at end of file
diff --git a/front-generator/template/common/setup-methods.js.j2 b/front-generator/template/common/setup-methods.js.j2
index c39017f..dbad835 100644
--- a/front-generator/template/common/setup-methods.js.j2
+++ b/front-generator/template/common/setup-methods.js.j2
@@ -1,34 +1,34 @@
{% if 'rxtx' in params and modem == 'scpc' %}
- calcRequiredSnr(frameSizeNormal, modulation, speed) {
- const snrValues = [
- {fs: true, mod: 'qpsk', speed: '1/4', snr: 2.6}, {fs: true, mod: 'qpsk', speed: '1/3', snr: 2.6}, {fs: true, mod: 'qpsk', speed: '2/5', snr: 2.6}, {fs: true, mod: 'qpsk', speed: '1/2', snr: 2.6}, {fs: true, mod: 'qpsk', speed: '3/5', snr: 3.1}, {fs: true, mod: 'qpsk', speed: '2/3', snr: 3.8}, {fs: true, mod: 'qpsk', speed: '3/4', snr: 4.5}, {fs: true, mod: 'qpsk', speed: '4/5', snr: 5.2}, {fs: true, mod: 'qpsk', speed: '5/6', snr: 5.5}, {fs: true, mod: 'qpsk', speed: '8/9', snr: 6.4}, {fs: true, mod: 'qpsk', speed: '9/10', snr: 6.7},
- {fs: true, mod: '8psk', speed: '3/5', snr: 7.4}, {fs: true, mod: '8psk', speed: '2/3', snr: 8.4}, {fs: true, mod: '8psk', speed: '3/4', snr: 8.7}, {fs: true, mod: '8psk', speed: '5/6', snr: 10}, {fs: true, mod: '8psk', speed: '8/9', snr: 10.9}, {fs: true, mod: '8psk', speed: '9/10', snr: 11.1},
- {fs: true, mod: '16apsk', speed: '2/3', snr: 11.2}, {fs: true, mod: '16apsk', speed: '3/4', snr: 11.3}, {fs: true, mod: '16apsk', speed: '4/5', snr: 12.4}, {fs: true, mod: '16apsk', speed: '5/6', snr: 12.7}, {fs: true, mod: '16apsk', speed: '8/9', snr: 13.1}, {fs: true, mod: '16apsk', speed: '9/10', snr: 13.9},
- {fs: true, mod: '32apsk', speed: '3/4', snr: 14.5}, {fs: true, mod: '32apsk', speed: '4/5', snr: 14.7}, {fs: true, mod: '32apsk', speed: '5/6', snr: 14.9}, {fs: true, mod: '32apsk', speed: '8/9', snr: 16.1}, {fs: true, mod: '32apsk', speed: '9/10', snr: 16.6},
+calcRequiredSnr(frameSizeNormal, modulation, speed) {
+ const snrValues = [
+ {fs: true, mod: 'qpsk', speed: '1/4', snr: 2.6}, {fs: true, mod: 'qpsk', speed: '1/3', snr: 2.6}, {fs: true, mod: 'qpsk', speed: '2/5', snr: 2.6}, {fs: true, mod: 'qpsk', speed: '1/2', snr: 2.6}, {fs: true, mod: 'qpsk', speed: '3/5', snr: 3.1}, {fs: true, mod: 'qpsk', speed: '2/3', snr: 3.8}, {fs: true, mod: 'qpsk', speed: '3/4', snr: 4.5}, {fs: true, mod: 'qpsk', speed: '4/5', snr: 5.2}, {fs: true, mod: 'qpsk', speed: '5/6', snr: 5.5}, {fs: true, mod: 'qpsk', speed: '8/9', snr: 6.4}, {fs: true, mod: 'qpsk', speed: '9/10', snr: 6.7},
+ {fs: true, mod: '8psk', speed: '3/5', snr: 7.4}, {fs: true, mod: '8psk', speed: '2/3', snr: 8.4}, {fs: true, mod: '8psk', speed: '3/4', snr: 8.7}, {fs: true, mod: '8psk', speed: '5/6', snr: 10}, {fs: true, mod: '8psk', speed: '8/9', snr: 10.9}, {fs: true, mod: '8psk', speed: '9/10', snr: 11.1},
+ {fs: true, mod: '16apsk', speed: '2/3', snr: 11.2}, {fs: true, mod: '16apsk', speed: '3/4', snr: 11.3}, {fs: true, mod: '16apsk', speed: '4/5', snr: 12.4}, {fs: true, mod: '16apsk', speed: '5/6', snr: 12.7}, {fs: true, mod: '16apsk', speed: '8/9', snr: 13.1}, {fs: true, mod: '16apsk', speed: '9/10', snr: 13.9},
+ {fs: true, mod: '32apsk', speed: '3/4', snr: 14.5}, {fs: true, mod: '32apsk', speed: '4/5', snr: 14.7}, {fs: true, mod: '32apsk', speed: '5/6', snr: 14.9}, {fs: true, mod: '32apsk', speed: '8/9', snr: 16.1}, {fs: true, mod: '32apsk', speed: '9/10', snr: 16.6},
- {fs: false, mod: 'qpsk', speed: '1/4', snr: 4.1}, {fs: false, mod: 'qpsk', speed: '1/3', snr: 4.1}, {fs: false, mod: 'qpsk', speed: '2/5', snr: 4.1}, {fs: false, mod: 'qpsk', speed: '1/2', snr: 4.1}, {fs: false, mod: 'qpsk', speed: '3/5', snr: 4.6}, {fs: false, mod: 'qpsk', speed: '2/3', snr: 5.1}, {fs: false, mod: 'qpsk', speed: '3/4', snr: 5.3}, {fs: false, mod: 'qpsk', speed: '4/5', snr: 6.8}, {fs: false, mod: 'qpsk', speed: '5/6', snr: 7.8}, {fs: false, mod: 'qpsk', speed: '8/9', snr: 8.5},
- {fs: false, mod: '8psk', speed: '3/5', snr: 9.5}, {fs: false, mod: '8psk', speed: '2/3', snr: 9.9}, {fs: false, mod: '8psk', speed: '3/4', snr: 10.5}, {fs: false, mod: '8psk', speed: '5/6', snr: 11.1}, {fs: false, mod: '8psk', speed: '8/9', snr: 11.3},
- {fs: false, mod: '16apsk', speed: '2/3', snr: 11.6}, {fs: false, mod: '16apsk', speed: '3/4', snr: 11.8}, {fs: false, mod: '16apsk', speed: '4/5', snr: 12}, {fs: false, mod: '16apsk', speed: '5/6', snr: 12.3}, {fs: false, mod: '16apsk', speed: '8/9', snr: 13.4},
- {fs: false, mod: '32apsk', speed: '3/4', snr: 14.1}, {fs: false, mod: '32apsk', speed: '4/5', snr: 14.7}, {fs: false, mod: '32apsk', speed: '5/6', snr: 15.3}, {fs: false, mod: '32apsk', speed: '8/9', snr: 16.5},
- ]
- for (let i = 0; i < snrValues.length; i++) {
- if (snrValues[i].fs === frameSizeNormal && snrValues[i].mod === modulation && snrValues[i].speed === speed) { return snrValues[i].snr }
- }
- return '?'
- },
- calcInterfaceSpeedKb(baud, modulation, speed, frameSizeNormal) {
- const mBaud = parseInt(baud.replace(/[^0-9]/g, ''))
- const mMod = Math.max(2, ['', '', 'qpsk', '8psk', '16apsk', '32apsk'].indexOf(modulation))
- const speedVals = {'1/4': 0.25, '1/3': 0.333, '2/5': 0.4, '1/2': 0.5, '3/5': 0.6, '2/3': 0.666, '3/4': 0.75, '4/5': 0.8, '5/6': 0.833, '8/9': 0.888, '9/10': 0.9}
- const mSpeed = speed in speedVals ? speedVals[speed] : 1
- const result = (mBaud * mMod * mSpeed) / 1024
- const calcSnr = this.calcRequiredSnr(frameSizeNormal, modulation, speed)
- let snr;
- if (isNaN(calcSnr)) { snr = `ОСШ=?` } else { snr=`ОСШ=${calcSnr}` }
- if (result > 1024) {
- return toLocaleStringWithSpaces(result / 1024) + ' Мбит/с; ' + snr
- } else {
- return toLocaleStringWithSpaces(result) + ' кбит/с; ' + snr
- }
- },
+ {fs: false, mod: 'qpsk', speed: '1/4', snr: 4.1}, {fs: false, mod: 'qpsk', speed: '1/3', snr: 4.1}, {fs: false, mod: 'qpsk', speed: '2/5', snr: 4.1}, {fs: false, mod: 'qpsk', speed: '1/2', snr: 4.1}, {fs: false, mod: 'qpsk', speed: '3/5', snr: 4.6}, {fs: false, mod: 'qpsk', speed: '2/3', snr: 5.1}, {fs: false, mod: 'qpsk', speed: '3/4', snr: 5.3}, {fs: false, mod: 'qpsk', speed: '4/5', snr: 6.8}, {fs: false, mod: 'qpsk', speed: '5/6', snr: 7.8}, {fs: false, mod: 'qpsk', speed: '8/9', snr: 8.5},
+ {fs: false, mod: '8psk', speed: '3/5', snr: 9.5}, {fs: false, mod: '8psk', speed: '2/3', snr: 9.9}, {fs: false, mod: '8psk', speed: '3/4', snr: 10.5}, {fs: false, mod: '8psk', speed: '5/6', snr: 11.1}, {fs: false, mod: '8psk', speed: '8/9', snr: 11.3},
+ {fs: false, mod: '16apsk', speed: '2/3', snr: 11.6}, {fs: false, mod: '16apsk', speed: '3/4', snr: 11.8}, {fs: false, mod: '16apsk', speed: '4/5', snr: 12}, {fs: false, mod: '16apsk', speed: '5/6', snr: 12.3}, {fs: false, mod: '16apsk', speed: '8/9', snr: 13.4},
+ {fs: false, mod: '32apsk', speed: '3/4', snr: 14.1}, {fs: false, mod: '32apsk', speed: '4/5', snr: 14.7}, {fs: false, mod: '32apsk', speed: '5/6', snr: 15.3}, {fs: false, mod: '32apsk', speed: '8/9', snr: 16.5},
+ ]
+ for (let i = 0; i < snrValues.length; i++) {
+ if (snrValues[i].fs === frameSizeNormal && snrValues[i].mod === modulation && snrValues[i].speed === speed) { return snrValues[i].snr }
+ }
+ return '?'
+},
+calcInterfaceSpeedKb(baud, modulation, speed, frameSizeNormal) {
+ const mBaud = parseInt(baud.replace(/[^0-9]/g, ''))
+ const mMod = Math.max(2, ['', '', 'qpsk', '8psk', '16apsk', '32apsk'].indexOf(modulation))
+ const speedVals = {'1/4': 0.25, '1/3': 0.333, '2/5': 0.4, '1/2': 0.5, '3/5': 0.6, '2/3': 0.666, '3/4': 0.75, '4/5': 0.8, '5/6': 0.833, '8/9': 0.888, '9/10': 0.9}
+ const mSpeed = speed in speedVals ? speedVals[speed] : 1
+ const result = (mBaud * mMod * mSpeed) / 1024
+ const calcSnr = this.calcRequiredSnr(frameSizeNormal, modulation, speed)
+ let snr;
+ if (isNaN(calcSnr)) { snr = `ОСШ=?` } else { snr=`ОСШ=${calcSnr}` }
+ if (result > 1024) {
+ return toLocaleStringWithSpaces(result / 1024) + ' Мбит/с; ' + snr
+ } else {
+ return toLocaleStringWithSpaces(result) + ' кбит/с; ' + snr
+ }
+},
{% endif %}
diff --git a/front-generator/template/common/setup.html.j2 b/front-generator/template/common/setup.html.j2
index 9d79feb..1745dc3 100644
--- a/front-generator/template/common/setup.html.j2
+++ b/front-generator/template/common/setup.html.j2
@@ -1,8 +1,8 @@
{% from 'common/widgets.j2' import build_widget %}
-
- {% for cat in ['rxtx', 'dpdi', 'buclnb'] %}
- {% if cat in params %}
- {% for w in params[cat] %}{{ build_widget(cat, w) | indent(12, true) }}{% endfor %}
- {% endif %}
- {% endfor %}
-
\ No newline at end of file
+
+ {% for cat in ['rxtx', 'dpdi', 'buclnb'] %}
+ {% if cat in params %}
+ {% for w in params[cat] %}{{ build_widget(cat, w) | indent(4, true) }}{% endfor %}
+ {% endif %}
+ {% endfor %}
+
\ No newline at end of file
diff --git a/front-generator/template/main.html b/front-generator/template/main.html
index 40bce1e..5ca3439 100644
--- a/front-generator/template/main.html
+++ b/front-generator/template/main.html
@@ -1,5 +1,18 @@
+{% macro include_macro(file) %}
+// ========== include from '{{ file }}'
+{% include file %}
+// ========== include end from '{{ file }}'
+{% endmacro %}
+{% macro include_macro_no_comment(file) %}
+{% include file %}
+{% endmacro %}
+{% macro include_macro_ignore_missing(file) %}
+// ========== include from '{{ file }}'
+{% include file ignore missing %}
+// ========== include end from '{{ file }}'
+{% endmacro %}
@@ -53,7 +66,7 @@
- {% for tab in header_tabs %}{% include 'common/' ~ tab.name ~ '.html.j2' %}{% endfor %}
+ {% for tab in header_tabs %}{{ include_macro_no_comment('common/' ~ tab.name ~ '.html.j2') | indent(8, true) }}{% endfor %}
{% raw %}
Последнее обновление статистики: {{ lastUpdateTime }}
@@ -108,15 +121,9 @@
cesPasswordValue: '',
{% endif %}
- // ========== include from 'common/all-params-data.js.j2'
- {% include 'common/all-params-data.js.j2' %}
- // ========== include end from 'common/all-params-data.js.j2'
-
+{{ include_macro('common/all-params-data.js.j2') | indent(16, true) }}
{% for tab in header_tabs %}
- // ========== include from '{{ 'common/' ~ tab.name ~ '-data.js.j2' }}'
- {% include 'common/' ~ tab.name ~ '-data.js.j2' ignore missing %}
- // ========== include end from '{{ 'common/' ~ tab.name ~ '-data.js.j2' }}'
-
+{{ include_macro_ignore_missing('common/' ~ tab.name ~ '-data.js.j2') | indent(16, true) }}
{% endfor %}
uploadFw: {
progress: null,
@@ -183,15 +190,9 @@
return toLocaleStringWithSpaces(result)
},
- // ========== include from 'common/all-params-methods.js.j2'
- {% include 'common/all-params-methods.js.j2' %}
- // ========== include end from 'common/all-params-methods.js.j2'
-
+{{ include_macro('common/all-params-methods.js.j2') | indent(12, true) }}
{% for tab in header_tabs %}
- // ========== include from '{{ 'common/' ~ tab.name ~ '-methods.js.j2' }}'
- {% include 'common/' ~ tab.name ~ '-methods.js.j2' ignore missing %}
- // ========== include end from '{{ 'common/' ~ tab.name ~ '-methods.js.j2' }}'
-
+{{ include_macro_ignore_missing('common/' ~ tab.name ~ '-methods.js.j2') | indent(12, true) }}
{% endfor %}
performUpdateSettings() {
diff --git a/src/api-driver/stricts-enable.h b/src/api-driver/stricts-enable.h
index 325aa51..0c9bbdf 100644
--- a/src/api-driver/stricts-enable.h
+++ b/src/api-driver/stricts-enable.h
@@ -26,5 +26,9 @@
#define API_OBJECT_BUCLNB_SETTINGS_ENABLE
#endif
+#if defined(MODEM_IS_TDMA)
+#define API_OBJECT_MANAGER_LOGS_ENABLE
+#endif
+
#endif //API_DRIVER_STRICTS_ENABLE_H
diff --git a/static/main-scpc.html b/static/main-scpc.html
index b43f079..54adfe2 100644
--- a/static/main-scpc.html
+++ b/static/main-scpc.html
@@ -52,7 +52,6 @@