рабочая генерация всех полей на вкладке настроек и Qos, осталось администрирование

This commit is contained in:
Vladislav Ostapov 2025-01-14 14:42:16 +03:00
parent bf2d374705
commit 25a3b11ba8
11 changed files with 553 additions and 595 deletions

View File

@ -46,14 +46,7 @@
{"widget": "number", "label": "Символьная скорость, Бод", "name": "rxBaudrate", "min": 0, "step": 1}, {"widget": "number", "label": "Символьная скорость, Бод", "name": "rxBaudrate", "min": 0, "step": 1},
{ {
"widget": "select", "label": "Roll-off", "name": "rxRolloff", "widget": "select", "label": "Roll-off", "name": "rxRolloff",
"values": [ "values": [{"label": "0.02", "value": "2"}, {"label": "0.05", "value": "5"}, {"label": "0.10", "value": "10"}, {"label": "0.15", "value": "15"}, {"label": "0.20", "value": "20"}, {"label": "0.25", "value": "25"}]
{"label": "0.02", "value": "2"},
{"label": "0.05", "value": "5"},
{"label": "0.10", "value": "10"},
{"label": "0.15", "value": "15"},
{"label": "0.20", "value": "20"},
{"label": "0.25", "value": "25"}
]
} }
] ]
} }
@ -108,18 +101,9 @@
] ]
}, },
"tabs": [ "tabs": [
{ {"name": "monitoring", "desc": "Мониторинг"},
"name": "monitoring", {"name": "setup", "desc": "Настройки"},
"desc": "Мониторинг" {"name": "admin", "desc": "Администрирование"}
},
{
"name": "setup",
"desc": "Настройки"
},
{
"name": "admin",
"desc": "Администрирование"
}
] ]
}, },
"scpc": { "scpc": {
@ -131,19 +115,8 @@
"widget": "settings-container", "widget": "settings-container",
"childs": [ "childs": [
{ {
"widget": "select", "widget": "select", "label": "Режим работы", "name": "isCinC",
"label": "Режим работы", "values": [{"label": "SCPC", "value": "false"}, {"label": "CinC", "value": "true"}]
"name": "isCinC",
"values": [
{
"label": "SCPC",
"value": "false"
},
{
"label": "CinC",
"value": "true"
}
]
} }
] ]
}, },
@ -153,21 +126,75 @@
{ {
"widget": "settings-container", "widget": "settings-container",
"childs": [ "childs": [
{ "widget": "h3", "label": "Настройки приема/передачи" }, {"widget": "h3", "label": "Настройки передатчика"},
{"widget": "checkbox", "label": "Включить передатчик", "name": "txEn"},
{"widget": "checkbox", "label": "Автоматический запуск передатчика", "name": "txAutoStart"},
{ {
"widget": "select", "widget": "select", "label": "Режим работы модулятора", "name": "txModulatorIsTest",
"label": "Режим работы", "values": [{"label": "Нормальный", "value": "false"}, {"label": "Тест (CW)", "value": "true"}]
"name": "isCinC",
"values": [
{
"label": "CinC",
"value": "true"
}, },
{ {
"label": "SCPC", "widget": "select", "label": "Входные данные", "name": "txIsTestInput",
"value": "false" "values": [{"label": "SCPC", "value": "false"}, {"label": "Тест", "value": "true"}]
} },
{"widget": "h3", "label": "Параметры передачи"},
{"widget": "number", "label": "Центральная частота, КГц", "name": "txCentralFreq", "min": 900000, "step": 1},
{"widget": "number", "label": "Символьная скорость, Бод", "name": "txBaudrate", "min": 0, "step": 1},
{
"widget": "select", "label": "Roll-off", "name": "txRolloff",
"values": [{"label": "0.02", "value": "2"}, {"label": "0.05", "value": "5"}, {"label": "0.10", "value": "10"}, {"label": "0.15", "value": "15"}, {"label": "0.20", "value": "20"}, {"label": "0.25", "value": "25"}]
},
{"widget": "number", "label": "Ослабление, дБ", "name": "txAttenuation", "min": 0, "step": 1}
] ]
},
{
"widget": "settings-container",
"childs": [
{"widget": "h3", "label": "Режим работы DVB-S2"},
{"widget": "number", "label": "Период служебных пакетов, сек", "name": "dvbServicePacketPeriod", "min": 0, "step": 1, "max": 60},
{
"widget": "select", "label": "Режим модуляции", "name": "dvbIsAcm",
"values": [{"label": "CCM", "value": "false"}, {"label": "ACM", "value": "true"}]
},
{
"widget": "select", "label": "Размер кадра", "name": "txFrameSizeNormal",
"values": [{"label": "normal", "value": "true"}, {"label": "short", "value": "false"}]
},
{"widget": "modulation-modcod", "label": "Модуляция", "name": "dvbCcm", "v_show": "paramRxtx.dvbIsAcm === false"},
{"widget": "modulation-speed", "label": "Скорость кода", "name": "dvbCcm", "v_show": "paramRxtx.dvbIsAcm === false"},
{"widget": "watch", "label": "Текущий модкод", "model": "statRx.modcod", "v_show": "paramRxtx.dvbIsAcm === true"},
{"widget": "modulation-modcod", "label": "Модуляция (мин. режим)", "name": "dvbAcmMin", "v_show": "paramRxtx.dvbIsAcm === true"},
{"widget": "modulation-speed", "label": "Скорость кода (мин. режим)", "name": "dvbAcmMin", "v_show": "paramRxtx.dvbIsAcm === true"},
{"widget": "modulation-modcod", "label": "Модуляция (макс. режим)", "name": "dvbAcmMax", "v_show": "paramRxtx.dvbIsAcm === true"},
{"widget": "modulation-speed", "label": "Скорость кода (макс. режим)", "name": "dvbAcmMax", "v_show": "paramRxtx.dvbIsAcm === true"},
{"widget": "number", "label": "Запас ОСШ, дБ", "name": "dvbSnrReserve", "min": 0, "step": 0.01, "max": 10}
]
},
{
"widget": "settings-container",
"childs": [
{"widget": "h3", "label": "Авто-регулировка мощности"},
{"widget": "checkbox", "label": "Авто-регулировка мощности", "name": "acmEn"},
{"widget": "number", "label": "Минимальное ослабление, дБ", "name": "acmMinAttenuation", "min": 0, "step": 0.01, "max": 10},
{"widget": "number", "label": "Максимальное ослабление, дБ", "name": "acmMaxAttenuation", "min": 0, "step": 0.01, "max": 10},
{"widget": "number", "label": "Требуемое ОСШ", "name": "acmRequiredSnr", "min": 0, "step": 0.01, "max": 10}
]
},
{
"widget": "settings-container",
"childs": [
{"widget": "h3", "label": "Настройки приемника"},
{
"widget": "select", "label": "Режим управления усилением", "name": "rxAgcEn",
"values": [{"label": "РРУ", "value": "false"}, {"label": "АРУ", "value": "true"}]
},
{"widget": "number", "label": "Усиление, дБ", "name": "rxManualGain", "min": -40, "step": 0.01, "max": 40, "v_show": "paramRxtx.rxAgcEn === false"},
{"widget": "checkbox", "label": "Инверсия спектра", "name": "rxSpectrumInversion"},
{"widget": "number", "label": "Центральная частота, КГц", "name": "rxCentralFreq", "min": 900000, "step": 1},
{"widget": "number", "label": "Символьная скорость, Бод", "name": "rxBaudrate", "min": 0, "step": 1},
{
"widget": "select", "label": "Roll-off", "name": "rxRolloff",
"values": [{"label": "0.02", "value": "2"}, {"label": "0.05", "value": "5"}, {"label": "0.10", "value": "10"}, {"label": "0.15", "value": "15"}, {"label": "0.20", "value": "20"}, {"label": "0.25", "value": "25"}]
} }
] ]
} }
@ -187,9 +214,9 @@
] ]
}, },
{"widget": "number", "label": "Полоса поиска, КГц ±", "name": "cincSearchBandwidth", "min": 0, "step": 1, "max": 100} {"widget": "number", "label": "Полоса поиска, КГц ±", "name": "cincSearchBandwidth", "min": 0, "step": 1, "max": 100}
] ]
} },
{"widget": "submit", "v_show": "paramRxtx.isCinC"}
], ],
"buclnb": [ "buclnb": [
{"widget": "h2", "label": "Настройки питания и опорного генератора"}, {"widget": "h2", "label": "Настройки питания и опорного генератора"},
@ -237,6 +264,16 @@
} }
] ]
} }
],
"tcpaccel": [
{"widget": "h2", "label": "Настройки TCP-акселерации"},
{
"widget": "settings-container",
"childs": [
{"widget": "checkbox", "label": "Активировать акселерацию", "name": "accelEn"},
{"widget": "number", "label": "Максимальное количество соединений", "name": "accelMaxConnections", "min": 0, "step": 1, "max": 4000}
]
}
] ]
}, },
"tabs": [ "tabs": [

View File

@ -18,6 +18,9 @@ def extract_param_names(mc):
case 'select': return [{"name": widget['name'], "initValue": widget['values'][0]['value']}] case 'select': return [{"name": widget['name'], "initValue": widget['values'][0]['value']}]
case 'checkbox': return [{"name": widget['name'], "initValue": 'false'}] case 'checkbox': return [{"name": widget['name'], "initValue": 'false'}]
case 'number': return [{"name": widget['name'], "initValue": widget['min'] if widget['min'] else '0'}] case 'number': return [{"name": widget['name'], "initValue": widget['min'] if widget['min'] else '0'}]
case 'modulation-modcod': return [{"name": widget['name'] + "Modulation", "initValue": '"QPSK"'}]
case 'modulation-speed': return [{"name": widget['name'] + "Speed", "initValue": '"1/4"'}]
case 'watch': return []
return [{"name": widget['name'], "initValue": 'null'}] return [{"name": widget['name'], "initValue": 'null'}]
return [] return []
@ -35,6 +38,28 @@ def extract_param_names(mc):
return result return result
def add_submit_widgets(params):
def find_submit(w):
if w['widget'] == 'submit':
return True
if 'childs' in w:
for c in w['childs']:
if find_submit(c):
return True
return False
for group in params:
wid_found = False
for wid in params[group]:
if find_submit(wid):
wid_found = True
break
if wid_found:
continue
params[group].append({"widget": "submit"})
def extract_param_groups(mc): def extract_param_groups(mc):
return [k for k in mc['params']] return [k for k in mc['params']]
@ -48,6 +73,8 @@ def build_modem_env(modem):
mc = config['modem_types'][modem] mc = config['modem_types'][modem]
add_submit_widgets(mc['params'])
return { return {
"modem": modem, "modem": modem,
"modem_name": mc['modem_name'], "modem_name": mc['modem_name'],

View File

@ -1,14 +1,8 @@
paramsQos: { submitStatusQos: false,
paramQos: {
en: false, en: false,
rt1: [], rt1: [],
rt2: [], rt2: [],
rt3: [], rt3: [],
cd: [], cd: [],
}, },
{% if 'tcpaccel' in params.paramGroupsList %}
paramsTcpAccel: {
en: false,
maxConnections: 128
},
{% endif %}

View File

@ -1,29 +1,6 @@
{% if 'tcpaccel' in params.paramGroupsList %}
submitTcpaccelSettings() {
if (this.submitStatus.tcpAccel) { return }
this.submitStatus.tcpAccel = true
fetch('/api/set/tcpAccel', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
"tcpAccel.en": this.param.tcpAccel.en,
"tcpAccel.maxConnections": this.param.tcpAccel.maxConnections
})
}).then(async (resp) => {
this.submitStatus.tcpAccel = false
this.updateNetworkSettings(await resp.json())
}).catch((reason) => {
this.submitStatus.tcpAccel = false
alert(`Ошибка при применении настроек: ${reason}`)
})
},
updateTcpaccelSettings(vals) { console.log('tcp accel setting update function has no impl! update backend and write this function') }
{% endif %}
settingsSubmitQoS() { settingsSubmitQoS() {
if (this.submitStatus.qos) { return } if (this.submitStatusQos) { return }
this.submitStatus.qos = true this.submitStatusQos = true
function _translateQosClass(trafficClass, qc) { function _translateQosClass(trafficClass, qc) {
let res = { let res = {
cir: qc['cir'], cir: qc['cir'],
@ -66,18 +43,18 @@
return res return res
} }
let query = { let query = {
"en": this.paramsQos.en, "en": this.paramQos.en,
"rt1": [], "rt1": [],
"rt2": [], "rt2": [],
"rt3": [], "rt3": [],
"cd": [] "cd": []
} }
for (let i = 0; i < this.paramsQos.rt1.length; i++) { query.rt1.push(_translateQosClass('rt', this.paramsQos.rt1[i])) } for (let i = 0; i < this.paramQos.rt1.length; i++) { query.rt1.push(_translateQosClass('rt', this.paramQos.rt1[i])) }
for (let i = 0; i < this.paramsQos.rt2.length; i++) { query.rt2.push(_translateQosClass('rt', this.paramsQos.rt2[i])) } for (let i = 0; i < this.paramQos.rt2.length; i++) { query.rt2.push(_translateQosClass('rt', this.paramQos.rt2[i])) }
for (let i = 0; i < this.paramsQos.rt3.length; i++) { query.rt3.push(_translateQosClass('rt', this.paramsQos.rt3[i])) } for (let i = 0; i < this.paramQos.rt3.length; i++) { query.rt3.push(_translateQosClass('rt', this.paramQos.rt3[i])) }
for (let i = 0; i < this.paramsQos.cd.length; i++) { query.cd.push(_translateQosClass('rt', this.paramsQos.cd[i])) } for (let i = 0; i < this.paramQos.cd.length; i++) { query.cd.push(_translateQosClass('rt', this.paramQos.cd[i])) }
console.log(query) //console.log(query)
fetch('/api/set/qos', { fetch('/api/set/qos', {
method: 'POST', method: 'POST',
headers: { headers: {
@ -85,24 +62,24 @@
}, },
body: JSON.stringify(query) body: JSON.stringify(query)
}).then(async (resp) => { }).then(async (resp) => {
this.submitStatus.qos = false this.submitStatusQos = false
this.updateQosSettings(await resp.json()) this.updateQosSettings(await resp.json())
}).catch((reason) => { }).catch((reason) => {
this.submitStatus.qos = false this.submitStatusQos = false
alert(`Ошибка при применении настроек: ${reason}`) alert(`Ошибка при применении настроек: ${reason}`)
}) })
}, },
updateQosSettings(vals) { updateQosSettings(vals) {
this.submitStatus.qos = false this.submitStatusQos = false
this.paramsQos.en = vals["settings"]["qos.enabled"] this.paramQos.en = vals["settings"]["qos.enabled"]
const qosProfile = vals["settings"]["qos.profile"] const qosProfile = vals["settings"]["qos.profile"]
if (qosProfile !== null && qosProfile !== undefined) { if (qosProfile !== null && qosProfile !== undefined) {
this.paramsQos.rt1 = [] // .splice(0, this.paramsQos.rt1.length) this.paramQos.rt1 = [] // .splice(0, this.paramQos.rt1.length)
this.paramsQos.rt2 = [] // .splice(0, this.paramsQos.rt2.length) this.paramQos.rt2 = [] // .splice(0, this.paramQos.rt2.length)
this.paramsQos.rt3 = [] // .splice(0, this.paramsQos.rt3.length) this.paramQos.rt3 = [] // .splice(0, this.paramQos.rt3.length)
this.paramsQos.cd = [] // .splice(0, this.paramsQos.cd.length) this.paramQos.cd = [] // .splice(0, this.paramQos.cd.length)
for (let trafficClass in qosProfile) { for (let trafficClass in qosProfile) {
if (['rt1', 'rt2', 'rt3', 'cd'].indexOf(trafficClass) < 0) { if (['rt1', 'rt2', 'rt3', 'cd'].indexOf(trafficClass) < 0) {
@ -137,10 +114,10 @@
}) })
} }
switch (trafficClass) { switch (trafficClass) {
case 'rt1': this.paramsQos.rt1.push(result); break case 'rt1': this.paramQos.rt1.push(result); break
case 'rt2': this.paramsQos.rt2.push(result); break case 'rt2': this.paramQos.rt2.push(result); break
case 'rt3': this.paramsQos.rt3.push(result); break case 'rt3': this.paramQos.rt3.push(result); break
case 'cd': this.paramsQos.cd.push(result); break case 'cd': this.paramQos.cd.push(result); break
} }
} }
} }
@ -157,10 +134,10 @@
filters: [] filters: []
} }
switch (name) { switch (name) {
case 'rt1': this.paramsQos.rt1.push(res); break case 'rt1': this.paramQos.rt1.push(res); break
case 'rt2': this.paramsQos.rt2.push(res); break case 'rt2': this.paramQos.rt2.push(res); break
case 'rt3': this.paramsQos.rt3.push(res); break case 'rt3': this.paramQos.rt3.push(res); break
case 'cd': this.paramsQos.cd.push(res); break case 'cd': this.paramQos.cd.push(res); break
} }
}, },
@ -176,28 +153,28 @@
dscp: "" dscp: ""
} }
switch (name) { switch (name) {
case 'rt1': this.paramsQos.rt1[index].filters.push(rule); break case 'rt1': this.paramQos.rt1[index].filters.push(rule); break
case 'rt2': this.paramsQos.rt2[index].filters.push(rule); break case 'rt2': this.paramQos.rt2[index].filters.push(rule); break
case 'rt3': this.paramsQos.rt3[index].filters.push(rule); break case 'rt3': this.paramQos.rt3[index].filters.push(rule); break
case 'cd': this.paramsQos.cd[index].filters.push(rule); break case 'cd': this.paramQos.cd[index].filters.push(rule); break
} }
}, },
qosDelClass(name, index) { qosDelClass(name, index) {
switch (name) { switch (name) {
case 'rt1': this.paramsQos.rt1.splice(index, 1); break case 'rt1': this.paramQos.rt1.splice(index, 1); break
case 'rt2': this.paramsQos.rt2.splice(index, 1); break case 'rt2': this.paramQos.rt2.splice(index, 1); break
case 'rt3': this.paramsQos.rt3.splice(index, 1); break case 'rt3': this.paramQos.rt3.splice(index, 1); break
case 'cd': this.paramsQos.cd.splice(index, 1); break case 'cd': this.paramQos.cd.splice(index, 1); break
} }
}, },
qosDelFilter(name, index, filterIndex) { qosDelFilter(name, index, filterIndex) {
switch (name) { switch (name) {
case 'rt1': this.paramsQos.rt1[index].filters.splice(filterIndex, 1); break case 'rt1': this.paramQos.rt1[index].filters.splice(filterIndex, 1); break
case 'rt2': this.paramsQos.rt2[index].filters.splice(filterIndex, 1); break case 'rt2': this.paramQos.rt2[index].filters.splice(filterIndex, 1); break
case 'rt3': this.paramsQos.rt3[index].filters.splice(filterIndex, 1); break case 'rt3': this.paramQos.rt3[index].filters.splice(filterIndex, 1); break
case 'cd': this.paramsQos.cd[index].filters.splice(filterIndex, 1); break case 'cd': this.paramQos.cd[index].filters.splice(filterIndex, 1); break
} }
}, },

View File

@ -1,15 +1,16 @@
{% from 'common/widgets.j2' import build_widget %}
{% raw %} {% raw %}
<div class="tabs-body-item" v-if="activeTab === 'qos' && settingFetchComplete"> <div class="tabs-body-item" v-if="activeTab === 'qos' && settingFetchComplete">
<h2>Настройки QoS</h2> <h2>Настройки QoS</h2>
<div class="settings-set-container"> <div class="settings-set-container">
<label> <label>
<span>Активировать QoS</span> <span>Активировать QoS</span>
<span class="toggle-input"><input type="checkbox" v-model="paramsQos.en" /><span class="slider"></span></span> <span class="toggle-input"><input type="checkbox" v-model="paramQos.en" /><span class="slider"></span></span>
</label> </label>
</div> </div>
<div v-for="classesGroup in ['rt1', 'rt2', 'rt3', 'cd']"> <div v-for="classesGroup in ['rt1', 'rt2', 'rt3', 'cd']">
<h3>Классы {{ classesGroup.toUpperCase() }} <button class="action-button" @click="qosAddClass(classesGroup)"> + </button></h3> <h3>Классы {{ classesGroup.toUpperCase() }} <button class="action-button" @click="qosAddClass(classesGroup)"> + </button></h3>
<details v-for="(qosClass, index) in paramsQos[classesGroup]" :key="index" class="settings-set-container"> <details v-for="(qosClass, index) in paramQos[classesGroup]" :key="index" class="settings-set-container">
<summary> <summary>
<span v-if="classesGroup === 'cd'">#{{ index }} CIR={{ qosClass.cir }}кбит, PIR={{ qosClass.pir }}кбит {{ qosClass.description }}</span> <span v-if="classesGroup === 'cd'">#{{ index }} CIR={{ qosClass.cir }}кбит, PIR={{ qosClass.pir }}кбит {{ qosClass.description }}</span>
<span v-if="classesGroup !== 'cd'">#{{ index }} CBR={{ qosClass.cir }}кбит {{ qosClass.description }}</span> <span v-if="classesGroup !== 'cd'">#{{ index }} CBR={{ qosClass.cir }}кбит {{ qosClass.description }}</span>
@ -98,20 +99,9 @@
</div> </div>
</details> </details>
</div> </div>
<button class="action-button" @click="settingsSubmitQoS()">Применить <span class="submit-spinner" v-show="submitStatus.qos"></span></button> <button class="action-button" @click="settingsSubmitQoS()">Применить <span class="submit-spinner" v-show="submitStatusQos"></span></button>
{% endraw %}{% if 'tcpaccel' in params.paramGroupsList %}{% raw %} {% endraw %}{% if 'tcpaccel' in params %}
<h2>Настройки TCP-акселерации</h2> {% for w in params['tcpaccel'] %}{{ build_widget('tcpaccel', w) | indent(12, true) }}{% endfor %}
<div class="settings-set-container"> {% endif %}
<label>
<span>Активировать акселерацию</span>
<span class="toggle-input"><input type="checkbox" v-model="paramsTcpAccel.en" /><span class="slider"></span></span>
</label>
<label>
<span>Максимальное количество соединений</span>
<input type="number" v-model="paramsTcpAccel.maxConnections" min="1" max="10000" />
</label>
</div> </div>
<button class="action-button" @click="settingsSubmitTcpAccel()">Применить <span class="submit-spinner" v-show="submitStatus.tcpAccel"></span></button>
</div>
{% endraw %}{% endif %}

View File

@ -3,7 +3,6 @@
{% for cat in ['rxtx', 'cinc', 'buclnb'] %} {% for cat in ['rxtx', 'cinc', 'buclnb'] %}
{% if cat in params %} {% if cat in params %}
{% for w in params[cat] %}{{ build_widget(cat, w) | indent(12, true) }}{% endfor %} {% for w in params[cat] %}{{ build_widget(cat, w) | indent(12, true) }}{% endfor %}
<button class="action-button" @click="settingsSubmit{{ cat | title }}()">Сохранить <span class="submit-spinner" v-show="submitStatus.{{ cat }}"></span></button>
{% endif %} {% endif %}
{% endfor %} {% endfor %}
</div> </div>

View File

@ -13,6 +13,25 @@
</select> </select>
</label>{% endmacro %} </label>{% endmacro %}
{% macro build_widget_watch(param_group, widget) %}<label{% if widget.v_show %} v-show="{{ widget.v_show }}"{% endif %}><span>{{ widget.label }}</span><input type="text" readonly v-model="{{ widget.model }}"/></label>{% endmacro %}
{% macro build_widget_modulation_modcod(param_group, widget) %}<label{% if widget.v_show %} v-show="{{ widget.v_show }}"{% endif %}>
<span>{{ widget.label }}</span>
<select v-model="param{{ param_group | title }}.{{ widget.name }}Modulation" @change="param{{ param_group | title }}.{{ widget.name }}Speed = correctModcodSpeed(param{{ param_group | title }}.{{ widget.name }}Modulation, param{{ param_group | title }}.{{ widget.name }}Speed)">
<option :value="'qpsk'">QPSK</option>
<option :value="'8psk'">8PSK</option>
<option :value="'16apsk'">16APSK</option>
<option :value="'32apsk'">32APSK</option>
</select>
</label>{% endmacro %}
{% macro build_widget_modulation_speed(param_group, widget) %}<label{% if widget.v_show %} v-show="{{ widget.v_show }}"{% endif %}>
<span>{{ widget.label }}</span>
<select v-model="param{{ param_group | title }}.{{ widget.name }}Speed">
<option v-for="speed in getAvailableModcods(param{{ param_group | title }}.{{ widget.name }}Modulation)" v-bind:value="speed">{{ '{{' }} speed {{ '}}' }}</option>
</select>
</label>{% endmacro %}
{% macro build_widget_flex_container(param_group, widget) %}<div class="tabs-item-flex-container"{% if widget.v_show %} v-show="{{ widget.v_show }}"{% endif %}> {% macro build_widget_flex_container(param_group, widget) %}<div class="tabs-item-flex-container"{% if widget.v_show %} v-show="{{ widget.v_show }}"{% endif %}>
{% for w in widget.childs %}{{ build_widget(param_group, w) | indent(4, true) }}{% endfor %} {% for w in widget.childs %}{{ build_widget(param_group, w) | indent(4, true) }}{% endfor %}
</div>{% endmacro %} </div>{% endmacro %}
@ -26,9 +45,13 @@
{% elif widget.widget == 'settings-container' %}{{ build_widget_settings_container(param_group, widget) }} {% elif widget.widget == 'settings-container' %}{{ build_widget_settings_container(param_group, widget) }}
{% elif widget.widget == 'h2' %}<h2{% if widget.v_show %} v-show="{{ widget.v_show }}"{% endif %}>{{ widget.label }}</h2> {% elif widget.widget == 'h2' %}<h2{% if widget.v_show %} v-show="{{ widget.v_show }}"{% endif %}>{{ widget.label }}</h2>
{% elif widget.widget == 'h3' %}<h3{% if widget.v_show %} v-show="{{ widget.v_show }}"{% endif %}>{{ widget.label }}</h3> {% elif widget.widget == 'h3' %}<h3{% if widget.v_show %} v-show="{{ widget.v_show }}"{% endif %}>{{ widget.label }}</h3>
{% elif widget.widget == 'submit' %}<button class="action-button" @click="settingsSubmit{{ param_group | title }}()"{% if widget.v_show %} v-show="{{ widget.v_show }}"{% endif %}>Сохранить <span class="submit-spinner" v-show="submitStatus.{{ param_group }}"></span></button>
{% elif widget.widget == 'checkbox' %}{{ build_widget_checkbox(param_group, widget) }} {% elif widget.widget == 'checkbox' %}{{ build_widget_checkbox(param_group, widget) }}
{% elif widget.widget == 'number' %}{{ build_widget_number(param_group, widget) }} {% elif widget.widget == 'number' %}{{ build_widget_number(param_group, widget) }}
{% elif widget.widget == 'watch' %}{{ build_widget_watch(param_group, widget) }}
{% elif widget.widget == 'select' %}{{ build_widget_select(param_group, widget) }} {% elif widget.widget == 'select' %}{{ build_widget_select(param_group, widget) }}
{% elif widget.widget == 'modulation-modcod' %}{{ build_widget_modulation_modcod(param_group, widget) }}
{% elif widget.widget == 'modulation-speed' %}{{ build_widget_modulation_speed(param_group, widget) }}
{% else %}<p>Widget '{{ widget.widget }}' not defined!</p><p>{{ widget }}</p> {% else %}<p>Widget '{{ widget.widget }}' not defined!</p><p>{{ widget }}</p>
{% endif %} {% endif %}
{% endmacro %} {% endmacro %}

View File

@ -1,141 +0,0 @@
{% raw %}// default-js.js
// для обновления высоты хидера
function updateHeaderHeight() { const header = document.querySelector('header'); document.body.style.setProperty('--header-height', `${header.offsetHeight}px`); }
window.addEventListener('load', updateHeaderHeight); window.addEventListener('resize', updateHeaderHeight);
function getCurrentTab() {
const sl = window.location.hash.slice(1)
if (availableTabs.indexOf(sl) >= 0) {
return sl
}
return availableTabs[0]
}
function modcodToStr(modcod) {
// модкоды из раздела 5.5.2.2 https://www.etsi.org/deliver/etsi_en/302300_302399/302307/01.01.02_60/en_302307v010102p.pdf
// NOTE модкоды со скоростью хода 3/5 не работают
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" || modcod < 0 || modcod >= modcod.length) {
return "?";
}
return modcods[modcod]
}
function toModcod(modulation, speed) {
switch (modulation.toLowerCase()) {
case 'qpsk':
switch (speed) {
case '1/4': return 1
case '1/3': return 2
case '2/5': return 3
case '1/2': return 4
case '3/5': return 5 // отключено
case '2/3': return 6
case '3/4': return 7
case '4/5': return 8
case '5/6': return 9
case '8/9': return 10
case '9/10': return 11
default: return 1 // минимальная скорость
}
case '8psk':
switch (speed) {
case '3/5': return 12 // отключено
case '2/3': return 13
case '3/4': return 14
case '5/6': return 15
case '8/9': return 16
case '9/10': return 17
default: return 13 // минимальная скорость
}
case '16apsk':
switch (speed) {
case '2/3': return 18
case '3/4': return 19
case '4/5': return 20
case '5/6': return 21
case '8/9': return 22
case '9/10': return 23
default: return 18 // минимальная скорость
}
case '32apsk':
switch (speed) {
case '3/4': return 24
case '4/5': return 25
case '5/6': return 26
case '8/9': return 27
case '9/10': return 28
default: return 24
}
}
}
function extractModulationAndSpeedFromModcod(modcod) {
switch (modcod) {
case 1: return { modulation: 'qpsk', speed: '1/4' }
case 2: return { modulation: 'qpsk', speed: '1/3' }
case 3: return { modulation: 'qpsk', speed: '2/5' }
case 4: return { modulation: 'qpsk', speed: '1/2' }
case 5: return { modulation: 'qpsk', speed: '3/5' }
case 6: return { modulation: 'qpsk', speed: '2/3' }
case 7: return { modulation: 'qpsk', speed: '3/4' }
case 8: return { modulation: 'qpsk', speed: '4/5' }
case 9: return { modulation: 'qpsk', speed: '5/6' }
case 10: return { modulation: 'qpsk', speed: '8/9' }
case 11: return { modulation: 'qpsk', speed: '9/10' }
case 12: return { modulation: '8psk', speed: '3/5' }
case 13: return { modulation: '8psk', speed: '2/3' }
case 14: return { modulation: '8psk', speed: '3/4' }
case 15: return { modulation: '8psk', speed: '5/6' }
case 16: return { modulation: '8psk', speed: '8/9' }
case 17: return { modulation: '8psk', speed: '9/10' }
case 18: return { modulation: '16apsk', speed: '2/3' }
case 19: return { modulation: '16apsk', speed: '3/4' }
case 20: return { modulation: '16apsk', speed: '4/5' }
case 21: return { modulation: '16apsk', speed: '5/6' }
case 22: return { modulation: '16apsk', speed: '8/9' }
case 23: return { modulation: '16apsk', speed: '9/10' }
case 24: return { modulation: '32apsk', speed: '3/4' }
case 25: return { modulation: '32apsk', speed: '4/5' }
case 26: return { modulation: '32apsk', speed: '5/6' }
case 27: return { modulation: '32apsk', speed: '8/9' }
case 28: return { modulation: '32apsk', speed: '9/10' }
}
return { modulation: 'qpsk', speed: '1/4' }
}
// default-js.js end
{% endraw %}

View File

@ -63,18 +63,24 @@
<script> <script>
const availableTabs = ['{{ tab_names_array | join("', '") }}'] const availableTabs = ['{{ tab_names_array | join("', '") }}']
{% include 'default-js.js' %} // для обновления высоты хидера
function updateHeaderHeight() { const header = document.querySelector('header'); document.body.style.setProperty('--header-height', `${header.offsetHeight}px`); }
window.addEventListener('load', updateHeaderHeight); window.addEventListener('resize', updateHeaderHeight);
function getCurrentTab() {
const sl = window.location.hash.slice(1)
if (availableTabs.indexOf(sl) >= 0) {
return sl
}
return availableTabs[0]
}
const app = Vue.createApp({ const app = Vue.createApp({
data() { data() {
return { return {
{% if modem == 'scpc' %}
isCinC: false,
{% endif %}
// false - означает что статистика не отправляется, true - отправляется // false - означает что статистика не отправляется, true - отправляется
submitStatus: { submitStatus: {
{% for pg in params.paramGroupsList %} {% for pg in paramGroupsList %}
{{ pg }}: false, {{ pg }}: false,
{% endfor %} {% endfor %}
firmwareUpload: false, firmwareUpload: false,
@ -132,6 +138,21 @@
} }
return "" return ""
}, },
getAvailableModcods(modulation) {
// NOTE модкоды со скоростью хода 3/5 не работают
switch (modulation) {
case 'qpsk':
return ['1/4', '1/3', '2/5', '1/2', '3/5', '2/3', '3/4', '4/5', '5/6', '8/9', '9/10']
case '8psk':
return ['3/5', '2/3', '3/4', '5/6', '8/9', '9/10']
case '16apsk':
return ['2/3', '3/4', '4/5', '5/6', '8/9', '9/10']
case '32apsk':
return ['3/4', '4/5', '5/6', '8/9', '9/10']
default:
return []
}
},
// ========== include from 'common/all-params-methods.js.j2' // ========== include from 'common/all-params-methods.js.j2'
{% include 'common/all-params-methods.js.j2' %} {% include 'common/all-params-methods.js.j2' %}
@ -149,9 +170,12 @@
let d = await fetch("/api/get/settings") let d = await fetch("/api/get/settings")
let vals = await d.json() let vals = await d.json()
this.settingFetchComplete = true this.settingFetchComplete = true
{% for pg in params.paramGroupsList %} {% for pg in paramGroupsList %}
this.update{{ pg | capitalize }}Settings(vals) this.update{{ pg | capitalize }}Settings(vals)
{% endfor %} {% endfor %}
{% if 'qos' in tab_names_array %}
this.updateQosSettings(vals)
{% endif %}
} }
doFetchSettings().then(() => {}) doFetchSettings().then(() => {})

View File

@ -135,12 +135,145 @@
</div> </div>
<div class="tabs-item-flex-container"> <div class="tabs-item-flex-container">
<div class="settings-set-container"> <div class="settings-set-container">
<h3>Настройки приема/передачи</h3> <h3>Настройки передатчика</h3>
<label> <label>
<span>Режим работы</span> <span>Включить передатчик</span>
<select v-model="paramRxtx.isCinC"> <span class="toggle-input"><input type="checkbox" v-model="paramRxtx.txEn" /><span class="slider"></span></span>
<option :value="true">CinC</option> </label>
<label>
<span>Автоматический запуск передатчика</span>
<span class="toggle-input"><input type="checkbox" v-model="paramRxtx.txAutoStart" /><span class="slider"></span></span>
</label>
<label>
<span>Режим работы модулятора</span>
<select v-model="paramRxtx.txModulatorIsTest">
<option :value="false">Нормальный</option>
<option :value="true">Тест (CW)</option>
</select>
</label>
<label>
<span>Входные данные</span>
<select v-model="paramRxtx.txIsTestInput">
<option :value="false">SCPC</option> <option :value="false">SCPC</option>
<option :value="true">Тест</option>
</select>
</label>
<h3>Параметры передачи</h3>
<label><span>Центральная частота, КГц</span><input type="number" v-model="paramRxtx.txCentralFreq" min="900000" step="1"/></label>
<label><span>Символьная скорость, Бод</span><input type="number" v-model="paramRxtx.txBaudrate" step="1"/></label>
<label>
<span>Roll-off</span>
<select v-model="paramRxtx.txRolloff">
<option :value="2">0.02</option>
<option :value="5">0.05</option>
<option :value="10">0.10</option>
<option :value="15">0.15</option>
<option :value="20">0.20</option>
<option :value="25">0.25</option>
</select>
</label>
<label><span>Ослабление, дБ</span><input type="number" v-model="paramRxtx.txAttenuation" step="1"/></label>
</div>
<div class="settings-set-container">
<h3>Режим работы DVB-S2</h3>
<label><span>Период служебных пакетов, сек</span><input type="number" v-model="paramRxtx.dvbServicePacketPeriod" max="60" step="1"/></label>
<label>
<span>Режим модуляции</span>
<select v-model="paramRxtx.dvbIsAcm">
<option :value="false">CCM</option>
<option :value="true">ACM</option>
</select>
</label>
<label>
<span>Размер кадра</span>
<select v-model="paramRxtx.txFrameSizeNormal">
<option :value="true">normal</option>
<option :value="false">short</option>
</select>
</label>
<label v-show="paramRxtx.dvbIsAcm === false">
<span>Модуляция</span>
<select v-model="paramRxtx.dvbCcmModulation" @change="paramRxtx.dvbCcmSpeed = correctModcodSpeed(paramRxtx.dvbCcmModulation, paramRxtx.dvbCcmSpeed)">
<option :value="'qpsk'">QPSK</option>
<option :value="'8psk'">8PSK</option>
<option :value="'16apsk'">16APSK</option>
<option :value="'32apsk'">32APSK</option>
</select>
</label>
<label v-show="paramRxtx.dvbIsAcm === false">
<span>Скорость кода</span>
<select v-model="paramRxtx.dvbCcmSpeed">
<option v-for="speed in getAvailableModcods(paramRxtx.dvbCcmModulation)" v-bind:value="speed">{{ speed }}</option>
</select>
</label>
<label v-show="paramRxtx.dvbIsAcm === true"><span>Текущий модкод</span><input type="text" readonly v-model="statRx.modcod"/></label>
<label v-show="paramRxtx.dvbIsAcm === true">
<span>Модуляция (мин. режим)</span>
<select v-model="paramRxtx.dvbAcmMinModulation" @change="paramRxtx.dvbAcmMinSpeed = correctModcodSpeed(paramRxtx.dvbAcmMinModulation, paramRxtx.dvbAcmMinSpeed)">
<option :value="'qpsk'">QPSK</option>
<option :value="'8psk'">8PSK</option>
<option :value="'16apsk'">16APSK</option>
<option :value="'32apsk'">32APSK</option>
</select>
</label>
<label v-show="paramRxtx.dvbIsAcm === true">
<span>Скорость кода (мин. режим)</span>
<select v-model="paramRxtx.dvbAcmMinSpeed">
<option v-for="speed in getAvailableModcods(paramRxtx.dvbAcmMinModulation)" v-bind:value="speed">{{ speed }}</option>
</select>
</label>
<label v-show="paramRxtx.dvbIsAcm === true">
<span>Модуляция (макс. режим)</span>
<select v-model="paramRxtx.dvbAcmMaxModulation" @change="paramRxtx.dvbAcmMaxSpeed = correctModcodSpeed(paramRxtx.dvbAcmMaxModulation, paramRxtx.dvbAcmMaxSpeed)">
<option :value="'qpsk'">QPSK</option>
<option :value="'8psk'">8PSK</option>
<option :value="'16apsk'">16APSK</option>
<option :value="'32apsk'">32APSK</option>
</select>
</label>
<label v-show="paramRxtx.dvbIsAcm === true">
<span>Скорость кода (макс. режим)</span>
<select v-model="paramRxtx.dvbAcmMaxSpeed">
<option v-for="speed in getAvailableModcods(paramRxtx.dvbAcmMaxModulation)" v-bind:value="speed">{{ speed }}</option>
</select>
</label>
<label><span>Запас ОСШ, дБ</span><input type="number" v-model="paramRxtx.dvbSnrReserve" max="10" step="0.01"/></label>
</div>
<div class="settings-set-container">
<h3>Авто-регулировка мощности</h3>
<label>
<span>Авто-регулировка мощности</span>
<span class="toggle-input"><input type="checkbox" v-model="paramRxtx.acmEn" /><span class="slider"></span></span>
</label>
<label><span>Минимальное ослабление, дБ</span><input type="number" v-model="paramRxtx.acmMinAttenuation" max="10" step="0.01"/></label>
<label><span>Максимальное ослабление, дБ</span><input type="number" v-model="paramRxtx.acmMaxAttenuation" max="10" step="0.01"/></label>
<label><span>Требуемое ОСШ</span><input type="number" v-model="paramRxtx.acmRequiredSnr" max="10" step="0.01"/></label>
</div>
<div class="settings-set-container">
<h3>Настройки приемника</h3>
<label>
<span>Режим управления усилением</span>
<select v-model="paramRxtx.rxAgcEn">
<option :value="false">РРУ</option>
<option :value="true">АРУ</option>
</select>
</label>
<label v-show="paramRxtx.rxAgcEn === false"><span>Усиление, дБ</span><input type="number" v-model="paramRxtx.rxManualGain" min="-40" max="40" step="0.01"/></label>
<label>
<span>Инверсия спектра</span>
<span class="toggle-input"><input type="checkbox" v-model="paramRxtx.rxSpectrumInversion" /><span class="slider"></span></span>
</label>
<label><span>Центральная частота, КГц</span><input type="number" v-model="paramRxtx.rxCentralFreq" min="900000" step="1"/></label>
<label><span>Символьная скорость, Бод</span><input type="number" v-model="paramRxtx.rxBaudrate" step="1"/></label>
<label>
<span>Roll-off</span>
<select v-model="paramRxtx.rxRolloff">
<option :value="2">0.02</option>
<option :value="5">0.05</option>
<option :value="10">0.10</option>
<option :value="15">0.15</option>
<option :value="20">0.20</option>
<option :value="25">0.25</option>
</select> </select>
</label> </label>
</div> </div>
@ -157,7 +290,7 @@
</label> </label>
<label><span>Полоса поиска, КГц ±</span><input type="number" v-model="paramCinc.cincSearchBandwidth" max="100" step="1"/></label> <label><span>Полоса поиска, КГц ±</span><input type="number" v-model="paramCinc.cincSearchBandwidth" max="100" step="1"/></label>
</div> </div>
<button class="action-button" @click="settingsSubmitCinc()">Сохранить <span class="submit-spinner" v-show="submitStatus.cinc"></span></button> <button class="action-button" @click="settingsSubmitCinc()" v-show="paramRxtx.isCinC">Сохранить <span class="submit-spinner" v-show="submitStatus.cinc"></span></button>
<h2>Настройки питания и опорного генератора</h2> <h2>Настройки питания и опорного генератора</h2>
<div class="tabs-item-flex-container"> <div class="tabs-item-flex-container">
<div class="settings-set-container"> <div class="settings-set-container">
@ -210,12 +343,12 @@
<div class="settings-set-container"> <div class="settings-set-container">
<label> <label>
<span>Активировать QoS</span> <span>Активировать QoS</span>
<span class="toggle-input"><input type="checkbox" v-model="paramsQos.en" /><span class="slider"></span></span> <span class="toggle-input"><input type="checkbox" v-model="paramQos.en" /><span class="slider"></span></span>
</label> </label>
</div> </div>
<div v-for="classesGroup in ['rt1', 'rt2', 'rt3', 'cd']"> <div v-for="classesGroup in ['rt1', 'rt2', 'rt3', 'cd']">
<h3>Классы {{ classesGroup.toUpperCase() }} <button class="action-button" @click="qosAddClass(classesGroup)"> + </button></h3> <h3>Классы {{ classesGroup.toUpperCase() }} <button class="action-button" @click="qosAddClass(classesGroup)"> + </button></h3>
<details v-for="(qosClass, index) in paramsQos[classesGroup]" :key="index" class="settings-set-container"> <details v-for="(qosClass, index) in paramQos[classesGroup]" :key="index" class="settings-set-container">
<summary> <summary>
<span v-if="classesGroup === 'cd'">#{{ index }} CIR={{ qosClass.cir }}кбит, PIR={{ qosClass.pir }}кбит {{ qosClass.description }}</span> <span v-if="classesGroup === 'cd'">#{{ index }} CIR={{ qosClass.cir }}кбит, PIR={{ qosClass.pir }}кбит {{ qosClass.description }}</span>
<span v-if="classesGroup !== 'cd'">#{{ index }} CBR={{ qosClass.cir }}кбит {{ qosClass.description }}</span> <span v-if="classesGroup !== 'cd'">#{{ index }} CBR={{ qosClass.cir }}кбит {{ qosClass.description }}</span>
@ -304,9 +437,18 @@
</div> </div>
</details> </details>
</div> </div>
<button class="action-button" @click="settingsSubmitQoS()">Применить <span class="submit-spinner" v-show="submitStatus.qos"></span></button> <button class="action-button" @click="settingsSubmitQoS()">Применить <span class="submit-spinner" v-show="submitStatusQos"></span></button>
<h2>Настройки TCP-акселерации</h2>
<div class="settings-set-container">
<label>
<span>Активировать акселерацию</span>
<span class="toggle-input"><input type="checkbox" v-model="paramTcpaccel.accelEn" /><span class="slider"></span></span>
</label>
<label><span>Максимальное количество соединений</span><input type="number" v-model="paramTcpaccel.accelMaxConnections" max="4000" step="1"/></label>
</div>
<button class="action-button" @click="settingsSubmitTcpaccel()">Сохранить <span class="submit-spinner" v-show="submitStatus.tcpaccel"></span></button>
</div>
<p>Последнее обновление статистики: {{ lastUpdateTime }}</p> <p>Последнее обновление статистики: {{ lastUpdateTime }}</p>
</div> </div>
</div> </div>
@ -314,7 +456,6 @@
<script> <script>
const availableTabs = ['monitoring', 'setup', 'qos'] const availableTabs = ['monitoring', 'setup', 'qos']
// default-js.js
// для обновления высоты хидера // для обновления высоты хидера
function updateHeaderHeight() { const header = document.querySelector('header'); document.body.style.setProperty('--header-height', `${header.offsetHeight}px`); } function updateHeaderHeight() { const header = document.querySelector('header'); document.body.style.setProperty('--header-height', `${header.offsetHeight}px`); }
window.addEventListener('load', updateHeaderHeight); window.addEventListener('resize', updateHeaderHeight); window.addEventListener('load', updateHeaderHeight); window.addEventListener('resize', updateHeaderHeight);
@ -327,141 +468,15 @@
return availableTabs[0] return availableTabs[0]
} }
function modcodToStr(modcod) {
// модкоды из раздела 5.5.2.2 https://www.etsi.org/deliver/etsi_en/302300_302399/302307/01.01.02_60/en_302307v010102p.pdf
// NOTE модкоды со скоростью хода 3/5 не работают
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" || modcod < 0 || modcod >= modcod.length) {
return "?";
}
return modcods[modcod]
}
function toModcod(modulation, speed) {
switch (modulation.toLowerCase()) {
case 'qpsk':
switch (speed) {
case '1/4': return 1
case '1/3': return 2
case '2/5': return 3
case '1/2': return 4
case '3/5': return 5 // отключено
case '2/3': return 6
case '3/4': return 7
case '4/5': return 8
case '5/6': return 9
case '8/9': return 10
case '9/10': return 11
default: return 1 // минимальная скорость
}
case '8psk':
switch (speed) {
case '3/5': return 12 // отключено
case '2/3': return 13
case '3/4': return 14
case '5/6': return 15
case '8/9': return 16
case '9/10': return 17
default: return 13 // минимальная скорость
}
case '16apsk':
switch (speed) {
case '2/3': return 18
case '3/4': return 19
case '4/5': return 20
case '5/6': return 21
case '8/9': return 22
case '9/10': return 23
default: return 18 // минимальная скорость
}
case '32apsk':
switch (speed) {
case '3/4': return 24
case '4/5': return 25
case '5/6': return 26
case '8/9': return 27
case '9/10': return 28
default: return 24
}
}
}
function extractModulationAndSpeedFromModcod(modcod) {
switch (modcod) {
case 1: return { modulation: 'qpsk', speed: '1/4' }
case 2: return { modulation: 'qpsk', speed: '1/3' }
case 3: return { modulation: 'qpsk', speed: '2/5' }
case 4: return { modulation: 'qpsk', speed: '1/2' }
case 5: return { modulation: 'qpsk', speed: '3/5' }
case 6: return { modulation: 'qpsk', speed: '2/3' }
case 7: return { modulation: 'qpsk', speed: '3/4' }
case 8: return { modulation: 'qpsk', speed: '4/5' }
case 9: return { modulation: 'qpsk', speed: '5/6' }
case 10: return { modulation: 'qpsk', speed: '8/9' }
case 11: return { modulation: 'qpsk', speed: '9/10' }
case 12: return { modulation: '8psk', speed: '3/5' }
case 13: return { modulation: '8psk', speed: '2/3' }
case 14: return { modulation: '8psk', speed: '3/4' }
case 15: return { modulation: '8psk', speed: '5/6' }
case 16: return { modulation: '8psk', speed: '8/9' }
case 17: return { modulation: '8psk', speed: '9/10' }
case 18: return { modulation: '16apsk', speed: '2/3' }
case 19: return { modulation: '16apsk', speed: '3/4' }
case 20: return { modulation: '16apsk', speed: '4/5' }
case 21: return { modulation: '16apsk', speed: '5/6' }
case 22: return { modulation: '16apsk', speed: '8/9' }
case 23: return { modulation: '16apsk', speed: '9/10' }
case 24: return { modulation: '32apsk', speed: '3/4' }
case 25: return { modulation: '32apsk', speed: '4/5' }
case 26: return { modulation: '32apsk', speed: '5/6' }
case 27: return { modulation: '32apsk', speed: '8/9' }
case 28: return { modulation: '32apsk', speed: '9/10' }
}
return { modulation: 'qpsk', speed: '1/4' }
}
// default-js.js end
const app = Vue.createApp({ const app = Vue.createApp({
data() { data() {
return { return {
isCinC: false,
// false - означает что статистика не отправляется, true - отправляется // false - означает что статистика не отправляется, true - отправляется
submitStatus: { submitStatus: {
rxtx: false,
cinc: false,
buclnb: false,
tcpaccel: false,
firmwareUpload: false, firmwareUpload: false,
firmwareUpgrade: false, firmwareUpgrade: false,
// когда модем перезагружается, тут должен быть счетчик. Направление счета - к нулю // когда модем перезагружается, тут должен быть счетчик. Направление счета - к нулю
@ -470,8 +485,35 @@
// ========== include from 'common/all-params-data.js.j2' // ========== include from 'common/all-params-data.js.j2'
paramRxtx: { paramRxtx: {
acmEn: false,
acmMaxAttenuation: 0,
acmMinAttenuation: 0,
acmRequiredSnr: 0,
dvbAcmMaxModulation: "QPSK",
dvbAcmMaxSpeed: "1/4",
dvbAcmMinModulation: "QPSK",
dvbAcmMinSpeed: "1/4",
dvbCcmModulation: "QPSK",
dvbCcmSpeed: "1/4",
dvbIsAcm: false,
dvbServicePacketPeriod: 0,
dvbSnrReserve: 0,
isCinC: false, isCinC: false,
isCinC: true, rxAgcEn: false,
rxBaudrate: 0,
rxCentralFreq: 900000,
rxManualGain: -40,
rxRolloff: 2,
rxSpectrumInversion: false,
txAttenuation: 0,
txAutoStart: false,
txBaudrate: 0,
txCentralFreq: 900000,
txEn: false,
txFrameSizeNormal: true,
txIsTestInput: false,
txModulatorIsTest: false,
txRolloff: 2,
}, },
paramCinc: { paramCinc: {
cincIsPositional: true, cincIsPositional: true,
@ -485,6 +527,10 @@
lnbRefClk10M: false, lnbRefClk10M: false,
srvRefClk10M: false, srvRefClk10M: false,
}, },
paramTcpaccel: {
accelEn: false,
accelMaxConnections: 0,
},
// ========== include end from 'common/all-params-data.js.j2' // ========== include end from 'common/all-params-data.js.j2'
// ========== include from 'common/monitoring-data.js.j2' // ========== include from 'common/monitoring-data.js.j2'
@ -534,14 +580,14 @@
// ========== include end from 'common/setup-data.js.j2' // ========== include end from 'common/setup-data.js.j2'
// ========== include from 'common/qos-data.js.j2' // ========== include from 'common/qos-data.js.j2'
paramsQos: { submitStatusQos: false,
paramQos: {
en: false, en: false,
rt1: [], rt1: [],
rt2: [], rt2: [],
rt3: [], rt3: [],
cd: [], cd: [],
}, }, // ========== include end from 'common/qos-data.js.j2'
// ========== include end from 'common/qos-data.js.j2'
uploadFw: { uploadFw: {
progress: null, progress: null,
@ -582,14 +628,56 @@
} }
return "" return ""
}, },
getAvailableModcods(modulation) {
// NOTE модкоды со скоростью хода 3/5 не работают
switch (modulation) {
case 'qpsk':
return ['1/4', '1/3', '2/5', '1/2', '3/5', '2/3', '3/4', '4/5', '5/6', '8/9', '9/10']
case '8psk':
return ['3/5', '2/3', '3/4', '5/6', '8/9', '9/10']
case '16apsk':
return ['2/3', '3/4', '4/5', '5/6', '8/9', '9/10']
case '32apsk':
return ['3/4', '4/5', '5/6', '8/9', '9/10']
default:
return []
}
},
// ========== include from 'common/all-params-methods.js.j2' // ========== include from 'common/all-params-methods.js.j2'
settingsSubmitRxtx() { settingsSubmitRxtx() {
if (this.submitStatus.rxtx) { return } if (this.submitStatus.rxtx) { return }
let query = { let query = {
"acmEn": this.paramRxtx.acmEn,
"acmMaxAttenuation": this.paramRxtx.acmMaxAttenuation,
"acmMinAttenuation": this.paramRxtx.acmMinAttenuation,
"acmRequiredSnr": this.paramRxtx.acmRequiredSnr,
"dvbAcmMaxModulation": this.paramRxtx.dvbAcmMaxModulation,
"dvbAcmMaxSpeed": this.paramRxtx.dvbAcmMaxSpeed,
"dvbAcmMinModulation": this.paramRxtx.dvbAcmMinModulation,
"dvbAcmMinSpeed": this.paramRxtx.dvbAcmMinSpeed,
"dvbCcmModulation": this.paramRxtx.dvbCcmModulation,
"dvbCcmSpeed": this.paramRxtx.dvbCcmSpeed,
"dvbIsAcm": this.paramRxtx.dvbIsAcm,
"dvbServicePacketPeriod": this.paramRxtx.dvbServicePacketPeriod,
"dvbSnrReserve": this.paramRxtx.dvbSnrReserve,
"isCinC": this.paramRxtx.isCinC, "isCinC": this.paramRxtx.isCinC,
"isCinC": this.paramRxtx.isCinC, "rxAgcEn": this.paramRxtx.rxAgcEn,
"rxBaudrate": this.paramRxtx.rxBaudrate,
"rxCentralFreq": this.paramRxtx.rxCentralFreq,
"rxManualGain": this.paramRxtx.rxManualGain,
"rxRolloff": this.paramRxtx.rxRolloff,
"rxSpectrumInversion": this.paramRxtx.rxSpectrumInversion,
"txAttenuation": this.paramRxtx.txAttenuation,
"txAutoStart": this.paramRxtx.txAutoStart,
"txBaudrate": this.paramRxtx.txBaudrate,
"txCentralFreq": this.paramRxtx.txCentralFreq,
"txEn": this.paramRxtx.txEn,
"txFrameSizeNormal": this.paramRxtx.txFrameSizeNormal,
"txIsTestInput": this.paramRxtx.txIsTestInput,
"txModulatorIsTest": this.paramRxtx.txModulatorIsTest,
"txRolloff": this.paramRxtx.txRolloff,
} }
this.submitStatus.rxtx = true this.submitStatus.rxtx = true
@ -630,11 +718,52 @@
.catch((reason) => { alert(`Ошибка при применении настроек: ${reason}`) }) .catch((reason) => { alert(`Ошибка при применении настроек: ${reason}`) })
.finally(() => { this.submitStatus.buclnb = false }) .finally(() => { this.submitStatus.buclnb = false })
}, },
settingsSubmitTcpaccel() {
if (this.submitStatus.tcpaccel) { return }
let query = {
"accelEn": this.paramTcpaccel.accelEn,
"accelMaxConnections": this.paramTcpaccel.accelMaxConnections,
}
this.submitStatus.tcpaccel = true
fetch('/api/set/tcpaccel', {method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(query) })
.then(async (resp) => { this.updateTcpaccelSettings(await resp.json()) })
.catch((reason) => { alert(`Ошибка при применении настроек: ${reason}`) })
.finally(() => { this.submitStatus.tcpaccel = false })
},
updateRxtxSettings(vals) { updateRxtxSettings(vals) {
this.submitStatus.rxtx = false this.submitStatus.rxtx = false
this.paramRxtx.acmEn = vals["settings"]["acmEn"]
this.paramRxtx.acmMaxAttenuation = vals["settings"]["acmMaxAttenuation"]
this.paramRxtx.acmMinAttenuation = vals["settings"]["acmMinAttenuation"]
this.paramRxtx.acmRequiredSnr = vals["settings"]["acmRequiredSnr"]
this.paramRxtx.dvbAcmMaxModulation = vals["settings"]["dvbAcmMaxModulation"]
this.paramRxtx.dvbAcmMaxSpeed = vals["settings"]["dvbAcmMaxSpeed"]
this.paramRxtx.dvbAcmMinModulation = vals["settings"]["dvbAcmMinModulation"]
this.paramRxtx.dvbAcmMinSpeed = vals["settings"]["dvbAcmMinSpeed"]
this.paramRxtx.dvbCcmModulation = vals["settings"]["dvbCcmModulation"]
this.paramRxtx.dvbCcmSpeed = vals["settings"]["dvbCcmSpeed"]
this.paramRxtx.dvbIsAcm = vals["settings"]["dvbIsAcm"]
this.paramRxtx.dvbServicePacketPeriod = vals["settings"]["dvbServicePacketPeriod"]
this.paramRxtx.dvbSnrReserve = vals["settings"]["dvbSnrReserve"]
this.paramRxtx.isCinC = vals["settings"]["isCinC"] this.paramRxtx.isCinC = vals["settings"]["isCinC"]
this.paramRxtx.isCinC = vals["settings"]["isCinC"] this.paramRxtx.rxAgcEn = vals["settings"]["rxAgcEn"]
this.paramRxtx.rxBaudrate = vals["settings"]["rxBaudrate"]
this.paramRxtx.rxCentralFreq = vals["settings"]["rxCentralFreq"]
this.paramRxtx.rxManualGain = vals["settings"]["rxManualGain"]
this.paramRxtx.rxRolloff = vals["settings"]["rxRolloff"]
this.paramRxtx.rxSpectrumInversion = vals["settings"]["rxSpectrumInversion"]
this.paramRxtx.txAttenuation = vals["settings"]["txAttenuation"]
this.paramRxtx.txAutoStart = vals["settings"]["txAutoStart"]
this.paramRxtx.txBaudrate = vals["settings"]["txBaudrate"]
this.paramRxtx.txCentralFreq = vals["settings"]["txCentralFreq"]
this.paramRxtx.txEn = vals["settings"]["txEn"]
this.paramRxtx.txFrameSizeNormal = vals["settings"]["txFrameSizeNormal"]
this.paramRxtx.txIsTestInput = vals["settings"]["txIsTestInput"]
this.paramRxtx.txModulatorIsTest = vals["settings"]["txModulatorIsTest"]
this.paramRxtx.txRolloff = vals["settings"]["txRolloff"]
}, },
updateCincSettings(vals) { updateCincSettings(vals) {
this.submitStatus.cinc = false this.submitStatus.cinc = false
@ -650,6 +779,11 @@
this.paramBuclnb.lnbRefClk10M = vals["settings"]["lnbRefClk10M"] this.paramBuclnb.lnbRefClk10M = vals["settings"]["lnbRefClk10M"]
this.paramBuclnb.srvRefClk10M = vals["settings"]["srvRefClk10M"] this.paramBuclnb.srvRefClk10M = vals["settings"]["srvRefClk10M"]
}, },
updateTcpaccelSettings(vals) {
this.submitStatus.tcpaccel = false
this.paramTcpaccel.accelEn = vals["settings"]["accelEn"]
this.paramTcpaccel.accelMaxConnections = vals["settings"]["accelMaxConnections"]
},
// ========== include end from 'common/all-params-methods.js.j2' // ========== include end from 'common/all-params-methods.js.j2'
// ========== include from 'common/monitoring-methods.js.j2' // ========== include from 'common/monitoring-methods.js.j2'
@ -730,8 +864,8 @@
// ========== include from 'common/qos-methods.js.j2' // ========== include from 'common/qos-methods.js.j2'
settingsSubmitQoS() { settingsSubmitQoS() {
if (this.submitStatus.qos) { return } if (this.submitStatusQos) { return }
this.submitStatus.qos = true this.submitStatusQos = true
function _translateQosClass(trafficClass, qc) { function _translateQosClass(trafficClass, qc) {
let res = { let res = {
cir: qc['cir'], cir: qc['cir'],
@ -774,18 +908,18 @@
return res return res
} }
let query = { let query = {
"en": this.paramsQos.en, "en": this.paramQos.en,
"rt1": [], "rt1": [],
"rt2": [], "rt2": [],
"rt3": [], "rt3": [],
"cd": [] "cd": []
} }
for (let i = 0; i < this.paramsQos.rt1.length; i++) { query.rt1.push(_translateQosClass('rt', this.paramsQos.rt1[i])) } for (let i = 0; i < this.paramQos.rt1.length; i++) { query.rt1.push(_translateQosClass('rt', this.paramQos.rt1[i])) }
for (let i = 0; i < this.paramsQos.rt2.length; i++) { query.rt2.push(_translateQosClass('rt', this.paramsQos.rt2[i])) } for (let i = 0; i < this.paramQos.rt2.length; i++) { query.rt2.push(_translateQosClass('rt', this.paramQos.rt2[i])) }
for (let i = 0; i < this.paramsQos.rt3.length; i++) { query.rt3.push(_translateQosClass('rt', this.paramsQos.rt3[i])) } for (let i = 0; i < this.paramQos.rt3.length; i++) { query.rt3.push(_translateQosClass('rt', this.paramQos.rt3[i])) }
for (let i = 0; i < this.paramsQos.cd.length; i++) { query.cd.push(_translateQosClass('rt', this.paramsQos.cd[i])) } for (let i = 0; i < this.paramQos.cd.length; i++) { query.cd.push(_translateQosClass('rt', this.paramQos.cd[i])) }
console.log(query) //console.log(query)
fetch('/api/set/qos', { fetch('/api/set/qos', {
method: 'POST', method: 'POST',
headers: { headers: {
@ -793,24 +927,24 @@
}, },
body: JSON.stringify(query) body: JSON.stringify(query)
}).then(async (resp) => { }).then(async (resp) => {
this.submitStatus.qos = false this.submitStatusQos = false
this.updateQosSettings(await resp.json()) this.updateQosSettings(await resp.json())
}).catch((reason) => { }).catch((reason) => {
this.submitStatus.qos = false this.submitStatusQos = false
alert(`Ошибка при применении настроек: ${reason}`) alert(`Ошибка при применении настроек: ${reason}`)
}) })
}, },
updateQosSettings(vals) { updateQosSettings(vals) {
this.submitStatus.qos = false this.submitStatusQos = false
this.paramsQos.en = vals["settings"]["qos.enabled"] this.paramQos.en = vals["settings"]["qos.enabled"]
const qosProfile = vals["settings"]["qos.profile"] const qosProfile = vals["settings"]["qos.profile"]
if (qosProfile !== null && qosProfile !== undefined) { if (qosProfile !== null && qosProfile !== undefined) {
this.paramsQos.rt1 = [] // .splice(0, this.paramsQos.rt1.length) this.paramQos.rt1 = [] // .splice(0, this.paramQos.rt1.length)
this.paramsQos.rt2 = [] // .splice(0, this.paramsQos.rt2.length) this.paramQos.rt2 = [] // .splice(0, this.paramQos.rt2.length)
this.paramsQos.rt3 = [] // .splice(0, this.paramsQos.rt3.length) this.paramQos.rt3 = [] // .splice(0, this.paramQos.rt3.length)
this.paramsQos.cd = [] // .splice(0, this.paramsQos.cd.length) this.paramQos.cd = [] // .splice(0, this.paramQos.cd.length)
for (let trafficClass in qosProfile) { for (let trafficClass in qosProfile) {
if (['rt1', 'rt2', 'rt3', 'cd'].indexOf(trafficClass) < 0) { if (['rt1', 'rt2', 'rt3', 'cd'].indexOf(trafficClass) < 0) {
@ -845,10 +979,10 @@
}) })
} }
switch (trafficClass) { switch (trafficClass) {
case 'rt1': this.paramsQos.rt1.push(result); break case 'rt1': this.paramQos.rt1.push(result); break
case 'rt2': this.paramsQos.rt2.push(result); break case 'rt2': this.paramQos.rt2.push(result); break
case 'rt3': this.paramsQos.rt3.push(result); break case 'rt3': this.paramQos.rt3.push(result); break
case 'cd': this.paramsQos.cd.push(result); break case 'cd': this.paramQos.cd.push(result); break
} }
} }
} }
@ -865,10 +999,10 @@
filters: [] filters: []
} }
switch (name) { switch (name) {
case 'rt1': this.paramsQos.rt1.push(res); break case 'rt1': this.paramQos.rt1.push(res); break
case 'rt2': this.paramsQos.rt2.push(res); break case 'rt2': this.paramQos.rt2.push(res); break
case 'rt3': this.paramsQos.rt3.push(res); break case 'rt3': this.paramQos.rt3.push(res); break
case 'cd': this.paramsQos.cd.push(res); break case 'cd': this.paramQos.cd.push(res); break
} }
}, },
@ -884,28 +1018,28 @@
dscp: "" dscp: ""
} }
switch (name) { switch (name) {
case 'rt1': this.paramsQos.rt1[index].filters.push(rule); break case 'rt1': this.paramQos.rt1[index].filters.push(rule); break
case 'rt2': this.paramsQos.rt2[index].filters.push(rule); break case 'rt2': this.paramQos.rt2[index].filters.push(rule); break
case 'rt3': this.paramsQos.rt3[index].filters.push(rule); break case 'rt3': this.paramQos.rt3[index].filters.push(rule); break
case 'cd': this.paramsQos.cd[index].filters.push(rule); break case 'cd': this.paramQos.cd[index].filters.push(rule); break
} }
}, },
qosDelClass(name, index) { qosDelClass(name, index) {
switch (name) { switch (name) {
case 'rt1': this.paramsQos.rt1.splice(index, 1); break case 'rt1': this.paramQos.rt1.splice(index, 1); break
case 'rt2': this.paramsQos.rt2.splice(index, 1); break case 'rt2': this.paramQos.rt2.splice(index, 1); break
case 'rt3': this.paramsQos.rt3.splice(index, 1); break case 'rt3': this.paramQos.rt3.splice(index, 1); break
case 'cd': this.paramsQos.cd.splice(index, 1); break case 'cd': this.paramQos.cd.splice(index, 1); break
} }
}, },
qosDelFilter(name, index, filterIndex) { qosDelFilter(name, index, filterIndex) {
switch (name) { switch (name) {
case 'rt1': this.paramsQos.rt1[index].filters.splice(filterIndex, 1); break case 'rt1': this.paramQos.rt1[index].filters.splice(filterIndex, 1); break
case 'rt2': this.paramsQos.rt2[index].filters.splice(filterIndex, 1); break case 'rt2': this.paramQos.rt2[index].filters.splice(filterIndex, 1); break
case 'rt3': this.paramsQos.rt3[index].filters.splice(filterIndex, 1); break case 'rt3': this.paramQos.rt3[index].filters.splice(filterIndex, 1); break
case 'cd': this.paramsQos.cd[index].filters.splice(filterIndex, 1); break case 'cd': this.paramQos.cd[index].filters.splice(filterIndex, 1); break
} }
}, },
@ -957,6 +1091,11 @@
let d = await fetch("/api/get/settings") let d = await fetch("/api/get/settings")
let vals = await d.json() let vals = await d.json()
this.settingFetchComplete = true this.settingFetchComplete = true
this.updateRxtxSettings(vals)
this.updateCincSettings(vals)
this.updateBuclnbSettings(vals)
this.updateTcpaccelSettings(vals)
this.updateQosSettings(vals)
} }
doFetchSettings().then(() => {}) doFetchSettings().then(() => {})

View File

@ -298,7 +298,6 @@
<script> <script>
const availableTabs = ['monitoring', 'setup', 'admin'] const availableTabs = ['monitoring', 'setup', 'admin']
// default-js.js
// для обновления высоты хидера // для обновления высоты хидера
function updateHeaderHeight() { const header = document.querySelector('header'); document.body.style.setProperty('--header-height', `${header.offsetHeight}px`); } function updateHeaderHeight() { const header = document.querySelector('header'); document.body.style.setProperty('--header-height', `${header.offsetHeight}px`); }
window.addEventListener('load', updateHeaderHeight); window.addEventListener('resize', updateHeaderHeight); window.addEventListener('load', updateHeaderHeight); window.addEventListener('resize', updateHeaderHeight);
@ -311,140 +310,13 @@
return availableTabs[0] return availableTabs[0]
} }
function modcodToStr(modcod) {
// модкоды из раздела 5.5.2.2 https://www.etsi.org/deliver/etsi_en/302300_302399/302307/01.01.02_60/en_302307v010102p.pdf
// NOTE модкоды со скоростью хода 3/5 не работают
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" || modcod < 0 || modcod >= modcod.length) {
return "?";
}
return modcods[modcod]
}
function toModcod(modulation, speed) {
switch (modulation.toLowerCase()) {
case 'qpsk':
switch (speed) {
case '1/4': return 1
case '1/3': return 2
case '2/5': return 3
case '1/2': return 4
case '3/5': return 5 // отключено
case '2/3': return 6
case '3/4': return 7
case '4/5': return 8
case '5/6': return 9
case '8/9': return 10
case '9/10': return 11
default: return 1 // минимальная скорость
}
case '8psk':
switch (speed) {
case '3/5': return 12 // отключено
case '2/3': return 13
case '3/4': return 14
case '5/6': return 15
case '8/9': return 16
case '9/10': return 17
default: return 13 // минимальная скорость
}
case '16apsk':
switch (speed) {
case '2/3': return 18
case '3/4': return 19
case '4/5': return 20
case '5/6': return 21
case '8/9': return 22
case '9/10': return 23
default: return 18 // минимальная скорость
}
case '32apsk':
switch (speed) {
case '3/4': return 24
case '4/5': return 25
case '5/6': return 26
case '8/9': return 27
case '9/10': return 28
default: return 24
}
}
}
function extractModulationAndSpeedFromModcod(modcod) {
switch (modcod) {
case 1: return { modulation: 'qpsk', speed: '1/4' }
case 2: return { modulation: 'qpsk', speed: '1/3' }
case 3: return { modulation: 'qpsk', speed: '2/5' }
case 4: return { modulation: 'qpsk', speed: '1/2' }
case 5: return { modulation: 'qpsk', speed: '3/5' }
case 6: return { modulation: 'qpsk', speed: '2/3' }
case 7: return { modulation: 'qpsk', speed: '3/4' }
case 8: return { modulation: 'qpsk', speed: '4/5' }
case 9: return { modulation: 'qpsk', speed: '5/6' }
case 10: return { modulation: 'qpsk', speed: '8/9' }
case 11: return { modulation: 'qpsk', speed: '9/10' }
case 12: return { modulation: '8psk', speed: '3/5' }
case 13: return { modulation: '8psk', speed: '2/3' }
case 14: return { modulation: '8psk', speed: '3/4' }
case 15: return { modulation: '8psk', speed: '5/6' }
case 16: return { modulation: '8psk', speed: '8/9' }
case 17: return { modulation: '8psk', speed: '9/10' }
case 18: return { modulation: '16apsk', speed: '2/3' }
case 19: return { modulation: '16apsk', speed: '3/4' }
case 20: return { modulation: '16apsk', speed: '4/5' }
case 21: return { modulation: '16apsk', speed: '5/6' }
case 22: return { modulation: '16apsk', speed: '8/9' }
case 23: return { modulation: '16apsk', speed: '9/10' }
case 24: return { modulation: '32apsk', speed: '3/4' }
case 25: return { modulation: '32apsk', speed: '4/5' }
case 26: return { modulation: '32apsk', speed: '5/6' }
case 27: return { modulation: '32apsk', speed: '8/9' }
case 28: return { modulation: '32apsk', speed: '9/10' }
}
return { modulation: 'qpsk', speed: '1/4' }
}
// default-js.js end
const app = Vue.createApp({ const app = Vue.createApp({
data() { data() {
return { return {
// false - означает что статистика не отправляется, true - отправляется // false - означает что статистика не отправляется, true - отправляется
submitStatus: { submitStatus: {
rxtx: false,
buclnb: false,
firmwareUpload: false, firmwareUpload: false,
firmwareUpgrade: false, firmwareUpgrade: false,
// когда модем перезагружается, тут должен быть счетчик. Направление счета - к нулю // когда модем перезагружается, тут должен быть счетчик. Направление счета - к нулю
@ -556,6 +428,21 @@
} }
return "" return ""
}, },
getAvailableModcods(modulation) {
// NOTE модкоды со скоростью хода 3/5 не работают
switch (modulation) {
case 'qpsk':
return ['1/4', '1/3', '2/5', '1/2', '3/5', '2/3', '3/4', '4/5', '5/6', '8/9', '9/10']
case '8psk':
return ['3/5', '2/3', '3/4', '5/6', '8/9', '9/10']
case '16apsk':
return ['2/3', '3/4', '4/5', '5/6', '8/9', '9/10']
case '32apsk':
return ['3/4', '4/5', '5/6', '8/9', '9/10']
default:
return []
}
},
// ========== include from 'common/all-params-methods.js.j2' // ========== include from 'common/all-params-methods.js.j2'
settingsSubmitRxtx() { settingsSubmitRxtx() {
@ -833,6 +720,8 @@
let d = await fetch("/api/get/settings") let d = await fetch("/api/get/settings")
let vals = await d.json() let vals = await d.json()
this.settingFetchComplete = true this.settingFetchComplete = true
this.updateRxtxSettings(vals)
this.updateBuclnbSettings(vals)
} }
doFetchSettings().then(() => {}) doFetchSettings().then(() => {})