Compare commits

..

No commits in common. "77ba05e407d2864b20f407e2672d97c2e05f74e2" and "833374a80ec7cdf011bfe8dcdba6d6689a2b5de5" have entirely different histories.

11 changed files with 36 additions and 1849 deletions

View File

@ -1,75 +0,0 @@
{
"monitoring-params": {},
"params": {
"rxtx": {
"rx.en": {
"model": "w:switch",
"label": "Включить передатчик"
},
"rx.isTestInputData": {
"model": "w:select",
"label": "Включить передатчик",
"items": [
{"value": "false", "label": "Ethernet"},
{"value": "true", "label": "Тест (CW)"}
]
},
"rx.freqKhz": {
"model": "w:number",
"number.type": "int",
"number.step": 1,
"number.min": 500000,
"number.max": 15000000
}
}
},
"modem_types": {
"tdma": {
"modem_name": "RCSM-101 TDMA",
"groupsList": ["rxtx"],
"tabs": [
{
"name": "monitoring",
"desc": "Мониторинг"
},
{
"name": "setup",
"desc": "Настройки",
"widgets": [
{"group": "html", "name": "h3", "payload": "Настройки передатчика"},
{"group": "rxtx", "name": "rx.en"},
{"group": "rxtx", "name": "rx.isTestInputData"},
{"group": "html", "name": "h3", "payload": "Параметры передачи"},
{"group": "rxtx", "name": "rx.freqKhz"}
]
},
{
"name": "admin",
"desc": "Администрирование"
}
]
},
"scpc": {
"modem_name": "RCSM-101",
"groupsList": ["rxtx"],
"tabs": [
{
"name": "monitoring",
"desc": "Мониторинг"
},
{
"name": "setup",
"desc": "Настройки"
},
{
"name": "qos",
"desc": "QoS"
},
{
"name": "admin",
"desc": "Администрирование"
}
]
}
}
}

View File

@ -1,39 +0,0 @@
import json
from jinja2 import Environment, FileSystemLoader
import sys
def build_modem_env(modem):
with open('render-params.json') as f:
config = json.load(f)
if modem not in config['modem_types']:
raise RuntimeError(f"Modem '{modem}' is not exist in config!")
mc = config['modem_types'][modem]
return {
"modem_name": mc['modem_name'],
"header_tabs": mc['tabs'],
"js_tabs_array": str([t['name'] for t in mc['tabs']]),
"params": {"groupsList": mc["groupsList"]} | config["params"]
}
def render_modem(modem):
loader = FileSystemLoader('template')
env = Environment(loader=loader, trim_blocks=True, lstrip_blocks=True)
template = env.get_template('main.html')
context = build_modem_env(modem)
with open(f"main-{modem}.html", "w") as f:
f.write(template.render(context))
if __name__ == '__main__':
if len(sys.argv) != 2:
print(f"Usage: {sys.argv[0]} <scpc|tdma>")
render_modem(sys.argv[1])

View File

@ -1,139 +0,0 @@
{% raw %}// для обновления высоты хидера
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 defaultTab
}
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' }
}
{% endraw %}

File diff suppressed because it is too large Load Diff

View File

@ -1,181 +0,0 @@
isCinC: false,
// false - означает что статистика не отправляется, true - отправляется
submitStatus: {
{% for pg in params.groupsList %}
{{ pg }}: false,
{% endfor %}
firmwareUpload: false,
firmwareUpgrade: false,
// когда модем перезагружается, тут должен быть счетчик. Направление счета - к нулю
modemReboot: null
},
stat: {
}
stat_rx: {
// индикаторы
state: '?', // общее состояние
sym_sync_lock: '?', // захват символьной
freq_search_lock: '?', // Захват поиска по частоте
afc_lock: '?', // захват ФАПЧ
pkt_sync: '?', // захват пакетной синхронизации
// куча других параметров, идет в том же порядке, что и в таблице
snr: '?', rssi: '?',
modcod: '?', frameSizeNormal: '?',
isPilots: '?',
symError: '?',
freqErr: '?', freqErrAcc: '?',
inputSignalLevel: '?',
pllError: '?',
speedOnRxKbit: '?',
speedOnIifKbit: '?',
// статистика пакетов
packetsOk: '?', packetsBad: '?', packetsDummy: '?',
},
stat_tx: {
// состояние
state: '?',
// прочие поля
snr: '?', modcod: '?', frameSizeNormal: '?', isPilots: '?', speedOnTxKbit: '?', speedOnIifKbit: '?',
},
stat_cinc: {
occ: '?',
correlator: null,
correlatorFails: '?',
freqErr: '?', freqErrAcc: '?',
channelDelay: '?'
},
stat_device: { // температурные датчики
adrv: 0, zynq: 0, fpga: 0
},
param: {
general: {
isCinC: Boolean,
txEn: Boolean, // включен/выключен
modulatorMode: 'normal', // режим работы модулятора
autoStartTx: Boolean, // было "режим работы передатчика"
isTestInputData: Boolean, // входные данные: eth или test
},
tx: {
attenuation: Number, // ослабление
rolloff: Number,
cymRate: Number,
centerFreq: Number,
},
dvbs2: {
mode: null, // ccm/acm
frameSizeNormal: null, // 'normal' / 'short'
// isPilots: false,
// CCM
ccm_modulation: null,
ccm_speed: null,
// ACM
acm_maxModulation: null,
acm_maxSpeed: null,
acm_minModulation: null,
acm_minSpeed: null,
snrReserve: null,
servicePacketPeriod: null,
},
// авто-регулировка мощности
acm: {
en: false,
maxAttenuation: null,
minAttenuation: null,
requiredSnr: null,
},
rx: {
gainMode: null, // 'auto'/'manual' режим управления усилением
manualGain: 0, // усиление, только для ручного режима
spectrumInversion: false,
rolloff: 0,
cymRate: 100000,
centerFreq: 1200000.0,
},
cinc: {
mode: null, // 'positional' | 'delay'
searchBandwidth: 0, // полоса поиска в кГц
position: {
station: {
latitude: 0,
longitude: 0
},
satelliteLongitude: 0,
},
delayMin: 0,
delayMax: 0
},
buc: {
refClk10M: false, // подача опоры 10MHz
powering: 0 // 0, 24, 48
},
lnb: {
refClk10M: false, // подача опоры 10MHz
powering: 0 // 0, 13, 18, 24
},
serviceSettings: {
refClk10M: false, // подача опоры 10MHz
autoStart: false
},
network: {
managementIp: '', // 0.0.0.0/24
managementGateway: '',
mode: String, // l2 | l3
dataIp: '', //
dataMtu: 1500
},
debugSend: {
en: false,
receiverIp: '0.0.0.0', // 0.0.0.0
portCinC: 0,
portData: 0,
timeout: 0
},
qos: {
en: false,
rt1: [],
rt2: [],
rt3: [],
cd: [],
},
tcpAccel: {
en: false,
maxConnections: 128
},
},
uploadFw: {
progress: null,
filename: null,
sha256: null
},
// эти "настройки" - read only
about: {
firmwareVersion: '?',
modemUid: '?',
modemSn: '?',
macManagement: '?',
macData: '?',
},
testState: false,
initState: '',
lastUpdateTime: new Date(),
activeTab: getCurrentTab(),
settingFetchComplete: false,

View File

@ -524,7 +524,7 @@ public:
void setQosSettings(bool enabled, const std::string& str, bool readback = true) { void setQosSettings(bool enabled, const std::string& str, bool readback = true) {
std::lock_guard lock(this->cpApiMutex); std::lock_guard lock(this->cpApiMutex);
logCpApiError("api_driver::TerminalApiDaemon::setQosSettings()->CP_SetDmaDebug(begin_save_config)", CP_SetDmaDebug(sid, "begin_save_config", "")); logCpApiError("api_driver::TerminalApiDaemon::setQosSettings()->CP_SetDmaDebug()", CP_SetDmaDebug(sid, "begin_save_config", ""));
logCpApiError("api_driver::TerminalApiDaemon::setQosSettings()->CP_SetQoSSettings()", CP_SetQoSSettings(this->sid, str, enabled)); logCpApiError("api_driver::TerminalApiDaemon::setQosSettings()->CP_SetQoSSettings()", CP_SetQoSSettings(this->sid, str, enabled));
if (readback) { if (readback) {
bool tmp1; std::string tmp2; bool tmp1; std::string tmp2;
@ -535,7 +535,7 @@ public:
this->qosClassesJson = tmp2.empty() ? DEFAULT_QOS_CLASSES : tmp2; this->qosClassesJson = tmp2.empty() ? DEFAULT_QOS_CLASSES : tmp2;
} }
} }
logCpApiError("api_driver::TerminalApiDaemon::setQosSettings()->CP_SetDmaDebug(save_config)", CP_SetDmaDebug(sid, "save_config", "")); logCpApiError("api_driver::TerminalApiDaemon::setQosSettings()->CP_SetDmaDebug()", CP_SetDmaDebug(sid, "save_config", ""));
} }
void setNetworkSettings(TerminalNetworkSettings& s, bool readback = true) { void setNetworkSettings(TerminalNetworkSettings& s, bool readback = true) {
@ -799,7 +799,7 @@ std::string api_driver::ApiDriver::loadSettings() const {
result << ",\"tx.cymRate\":" << modSettings.baudrate; result << ",\"tx.cymRate\":" << modSettings.baudrate;
result << ",\"tx.centerFreq\":"; writeDouble(result, modSettings.central_freq_in_kGz, 3); result << ",\"tx.centerFreq\":"; writeDouble(result, modSettings.central_freq_in_kGz, 3);
result << ",\"dvbs2.frameSizeNormal\":" << boolAsStr(!(modSettings.modcod_tx & 2)); result << ",\"dvbs2.frameSizeNormal\":" << boolAsStr(!(modSettings.modcod_tx & 2));
result << ",\"dvbs2.ccm_modcod\":" << (modSettings.modcod_tx >> 2); result << ",\"dvbs2.ccm_modcod\":" << (modSettings.modcod_tx >> 4);
// result << ",\"dvbs2.isPilots\":" << "null"; // result << ",\"dvbs2.isPilots\":" << "null";
result << ",\n\"dvbs2.isAcm\":" << boolAsStr(acmSettings.enable); result << ",\n\"dvbs2.isAcm\":" << boolAsStr(acmSettings.enable);
@ -985,8 +985,6 @@ void api_driver::ApiDriver::setCincSettings(boost::property_tree::ptree &pt) {
s.max_delay = pt.get<uint32_t>(json_path("cinc.delayMax", '/')); s.max_delay = pt.get<uint32_t>(json_path("cinc.delayMax", '/'));
s.min_delay = pt.get<uint32_t>(json_path("cinc.delayMin", '/')); s.min_delay = pt.get<uint32_t>(json_path("cinc.delayMin", '/'));
s.freq_offset = pt.get<uint32_t>(json_path("cinc.searchBandwidth", '/'));
this->daemon->setSettingsCinc(s); this->daemon->setSettingsCinc(s);
} }
#endif #endif

View File

@ -7,6 +7,7 @@
} }
.tabs-btn { .tabs-btn {
text-decoration: none; text-decoration: none;
font-size: 18px;
border: none; border: none;
padding: 10px 25px; padding: 10px 25px;
text-align: center; text-align: center;
@ -86,7 +87,6 @@
.settings-set-container th { .settings-set-container th {
text-align: left; text-align: left;
font-weight: normal;
padding-right: 1em; padding-right: 1em;
} }
.settings-set-container td { .settings-set-container td {

View File

@ -161,7 +161,7 @@
<span>Входные данные</span> <span>Входные данные</span>
<select v-model="param.general.isTestInputData"> <select v-model="param.general.isTestInputData">
<option :value="false">Ethernet</option> <option :value="false">Ethernet</option>
<option :value="true">Тест</option> <option :value="true">Тест (CW)</option>
</select> </select>
</label> </label>
<h3>Параметры передачи</h3> <h3>Параметры передачи</h3>
@ -176,7 +176,6 @@
<label> <label>
<span>Roll-off</span> <span>Roll-off</span>
<select v-model="param.tx.rolloff"> <select v-model="param.tx.rolloff">
<option :value="2">0.02</option>
<option :value="5">0.05</option> <option :value="5">0.05</option>
<option :value="10">0.10</option> <option :value="10">0.10</option>
<option :value="15">0.15</option> <option :value="15">0.15</option>
@ -326,7 +325,6 @@
<label> <label>
<span>Roll-off</span> <span>Roll-off</span>
<select v-model="param.rx.rolloff"> <select v-model="param.rx.rolloff">
<option :value="2">0.02</option>
<option :value="5">0.05</option> <option :value="5">0.05</option>
<option :value="10">0.10</option> <option :value="10">0.10</option>
<option :value="15">0.15</option> <option :value="15">0.15</option>
@ -347,10 +345,6 @@
<option value="delay">Окном задержки</option> <option value="delay">Окном задержки</option>
</select> </select>
</label> </label>
<label>
<span>Полоса поиска, кгц ±</span>
<input v-model="param.cinc.searchBandwidth" type="number" min="0" max="100" step="1"/>
</label>
<h3 v-show="param.cinc.mode === 'positional'">Настройки позиционирования</h3> <h3 v-show="param.cinc.mode === 'positional'">Настройки позиционирования</h3>
<label v-show="param.cinc.mode === 'positional'"> <label v-show="param.cinc.mode === 'positional'">
@ -617,16 +611,13 @@
<tr><th>Версия ПО</th><td>{{ about.firmwareVersion }}</td></tr> <tr><th>Версия ПО</th><td>{{ about.firmwareVersion }}</td></tr>
<tr><th>ID модема</th><td>{{ about.modemUid }}</td></tr> <tr><th>ID модема</th><td>{{ about.modemUid }}</td></tr>
<tr><th>Серийный номер</th><td>{{ about.modemSn }}</td></tr> <tr><th>Серийный номер</th><td>{{ about.modemSn }}</td></tr>
<tr><th>MAC интерфейса менеджмента</th><td>{{ about.macManagement }}</td></tr> <tr><th>MAC интерфейса управления</th><td>{{ about.macManagement }}</td></tr>
<tr><th>MAC интерфейса управления</th><td>{{ about.macData }}</td></tr> <tr><th>MAC интерфейса управления</th><td>{{ about.macData }}</td></tr>
</tbody> </tbody>
</table> </table>
<div> <div>
<button class="dangerous-button" @click="doModemReboot()">Перезагрузить модем <span class="submit-spinner" v-show="submitStatus.modemReboot !== null"></span></button> <button class="dangerous-button" @click="doModemReboot()">Перезагрузить модем <span class="submit-spinner" v-show="submitStatus.modemReboot !== null"></span></button>
</div> </div>
<div hidden> <!-- v-show="submitStatus.modemReboot !== null" -->
<img src="/internet.jpg" loading="lazy" alt="internet"/>
</div>
<div> <div>
<button class="dangerous-button" onclick="fetch('/api/resetSettings', { method: 'POST' }).then((r) => { window.location.reload(); })">Сбросить модем до заводских настроек</button> <button class="dangerous-button" onclick="fetch('/api/resetSettings', { method: 'POST' }).then((r) => { window.location.reload(); })">Сбросить модем до заводских настроек</button>
</div> </div>
@ -1206,10 +1197,10 @@
"rt3": [], "rt3": [],
"cd": [] "cd": []
} }
for (let i = 0; i < this.param.qos.rt1.length; i++) { query.rt1.push(_translateQosClass('rt1', this.param.qos.rt1[i])) } for (let i = 0; i < this.param.qos.rt1.length; i++) { query.rt1.push(_translateQosClass('rt', this.param.qos.rt1[i])) }
for (let i = 0; i < this.param.qos.rt2.length; i++) { query.rt2.push(_translateQosClass('rt2', this.param.qos.rt2[i])) } for (let i = 0; i < this.param.qos.rt2.length; i++) { query.rt2.push(_translateQosClass('rt', this.param.qos.rt2[i])) }
for (let i = 0; i < this.param.qos.rt3.length; i++) { query.rt3.push(_translateQosClass('rt3', this.param.qos.rt3[i])) } for (let i = 0; i < this.param.qos.rt3.length; i++) { query.rt3.push(_translateQosClass('rt', this.param.qos.rt3[i])) }
for (let i = 0; i < this.param.qos.cd.length; i++) { query.cd.push(_translateQosClass('cd', this.param.qos.cd[i])) } for (let i = 0; i < this.param.qos.cd.length; i++) { query.cd.push(_translateQosClass('rt', this.param.qos.cd[i])) }
console.log(query) console.log(query)
fetch('/api/set/qos', { fetch('/api/set/qos', {

View File

@ -125,7 +125,7 @@
<span>Входные данные</span> <span>Входные данные</span>
<select v-model="param.tx.isTestInputData"> <select v-model="param.tx.isTestInputData">
<option :value="false">Ethernet</option> <option :value="false">Ethernet</option>
<option :value="true">Тест</option> <option :value="true">Тест (CW)</option>
</select> </select>
</label> </label>
<h3>Параметры передачи</h3> <h3>Параметры передачи</h3>
@ -418,7 +418,7 @@
<tr><th>Версия ПО</th><td>{{ about.firmwareVersion }}</td></tr> <tr><th>Версия ПО</th><td>{{ about.firmwareVersion }}</td></tr>
<tr><th>ID модема</th><td>{{ about.modemUid }}</td></tr> <tr><th>ID модема</th><td>{{ about.modemUid }}</td></tr>
<tr><th>Серийный номер</th><td>{{ about.modemSn }}</td></tr> <tr><th>Серийный номер</th><td>{{ about.modemSn }}</td></tr>
<tr><th>MAC интерфейса менеджмента</th><td>{{ about.macManagement }}</td></tr> <tr><th>MAC интерфейса управления</th><td>{{ about.macManagement }}</td></tr>
<tr><th>MAC интерфейса управления</th><td>{{ about.macData }}</td></tr> <tr><th>MAC интерфейса управления</th><td>{{ about.macData }}</td></tr>
</tbody> </tbody>
</table> </table>

View File

@ -53,13 +53,6 @@ body {
margin: 0.5em; margin: 0.5em;
} }
/* увеличение размера шрифтов */
* { font-size: large; }
h1 { font-size: xxx-large; }
h2 { font-size: xx-large; }
h3 { font-size: larger; }
/* ========== MAIN STYLES ========== */ /* ========== MAIN STYLES ========== */
.value-good { .value-good {