This commit is contained in:
2026-07-15 07:55:56 +03:00
parent 132c867dd9
commit f4f49c3e19
34 changed files with 1977 additions and 181 deletions
+15
View File
@@ -4572,6 +4572,21 @@ document.getElementById('btnCmdApply').onclick = () => {
postCommand(document.getElementById('cmdTargetSelect').value, 'at', { lines: buildMacroLines() });
setCmdFormDirty(false);
};
document.getElementById('btnCmdApplySymmetric')?.addEventListener('click', async () => {
const params = buildMacroParams();
const { tx, rx } = getTxRxDevices(lastDevices);
if (!tx?.device_id || !rx?.device_id) {
alert('Нужны два online-устройства с ролями TX и RX');
return;
}
const txOk = await postCommand(tx.device_id, 'at', {
lines: macroLinesFromParams({ ...params, role: 'TX' })
});
const rxOk = await postCommand(rx.device_id, 'at', {
lines: macroLinesFromParams({ ...params, role: 'RX' })
});
if (txOk && rxOk) setCmdFormDirty(false);
});
document.getElementById('btnMacroPresetApply')?.addEventListener('click', () => {
applySelectedMacroPreset().catch(e => alert(e.message || String(e)));
});
+1
View File
@@ -210,6 +210,7 @@
<label class="muted">Роль</label>
<select id="cmdRole"><option value=""></option><option value="TX">TX</option><option value="RX">RX</option></select>
<button type="button" id="btnCmdApply" style="width:100%;margin-top:6px;padding:6px;background:#e94560;color:#fff;border:none;border-radius:4px;font-weight:600;cursor:pointer">Применить</button>
<button type="button" id="btnCmdApplySymmetric" style="width:100%;margin-top:6px;padding:6px;background:#16213e;color:#fff;border:1px solid #e94560;border-radius:4px;font-weight:600;cursor:pointer">Симметрично TX+RX</button>
<button type="button" id="btnPairedStart" style="width:100%;margin-top:8px;padding:6px;background:#00ff88;color:#111;border:none;border-radius:4px;font-weight:600;cursor:pointer">Старт трека (оба)</button>
<div id="pairedStatus"></div>
</div>
+4
View File
@@ -145,6 +145,8 @@
if (o.gold_error != null) snap.goldError = Number(o.gold_error);
if (o.gold_all_error != null) snap.goldAllError = Number(o.gold_all_error);
if (o.sync_word_valid != null) snap.syncWordValid = Number(o.sync_word_valid);
if (o.crc_ok != null) snap.extraFields.crc_ok = String(o.crc_ok);
if (o.kor_level != null) snap.extraFields.kor_level = String(o.kor_level);
if (o.fields && typeof o.fields === 'object') {
for (const [k, v] of Object.entries(o.fields)) {
if (!isKnownLabel(k)) snap.extraFields[k] = String(v);
@@ -196,6 +198,8 @@
{ key: 'packetTotal', label: 'Всего', fmt: s => s.packetTotal != null ? String(s.packetTotal) : '—' },
{ key: 'packetError', label: 'Ошибки', fmt: s => s.packetError != null ? String(s.packetError) : '—' },
{ key: 'crcError', label: 'CRC err', fmt: s => s.crcError != null ? String(s.crcError) : '—' },
{ key: 'crcOk', label: 'CRC OK', fmt: s => s.extraFields?.crc_ok != null ? s.extraFields.crc_ok : '—' },
{ key: 'korLevel', label: 'KorLevel', fmt: s => s.extraFields?.kor_level != null ? s.extraFields.kor_level : '—' },
{ key: 'noise', label: 'Noice', fmt: s => s.noiseDbm != null ? String(s.noiseDbm) : '—' },
{ key: 'goldError', label: 'Golda Error', fmt: s => s.goldError != null ? String(s.goldError) : '—' },
{ key: 'goldAllError', label: 'Golda All Error', fmt: s => s.goldAllError != null ? String(s.goldAllError) : '—' },