<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>RSCM-101</title>
    <link rel="stylesheet" type="text/css" href="/style.css">
    <link rel="stylesheet" type="text/css" href="/fields.css">
</head>
<body>

<div id="app" hidden>
    <div>
        <span class="nav-bar-element">Прием: <span :class="{ indicator_bad: stat_rx.state === true, indicator_good: stat_rx.state === false, indicator: true }"></span></span>
        <span class="nav-bar-element">Передача: <span :class="{ indicator_bad: stat_tx.state === true, indicator_good: stat_tx.state === false, indicator: true }"></span></span>
        <span class="nav-bar-element">Тест: <span :class="{ indicator_bad: testState === true, indicator_good: testState === false, indicator: true }"></span></span>
<!--        Последнее обновление: {{ lastUpdateTime }}-->
    </div>
    <div class="tabs">
        <div class="tabs-header">
            <span style="font-weight:bold">RSCM-101</span>
            <a href="#monitoring" class="tabs-btn" @click="activeTab = 'monitoring'" :class="{ active: activeTab === 'monitoring' }">Мониторинг</a>
            <a href="#setup" class="tabs-btn" @click="activeTab = 'setup'" :class="{ active: activeTab === 'setup' }">Настройки</a>
            <a href="#admin" class="tabs-btn" @click="activeTab = 'admin'" :class="{ active: activeTab === 'admin' }">Администрирование</a>
        </div>
        <div class="tabs-body">
            <div class="tabs-body-item tabs-item-flex-container" v-show="activeTab === 'monitoring'">
                <div>
                    <h2>Статистика приема</h2>
                    <table>
                        <tbody>
                        <tr><th>Прием</th><td><span :class="{ indicator_bad: stat_rx.state === true, indicator_good: stat_rx.state === false, indicator: true }"></span></td></tr>
                        <tr><th>Захват символьной</th><td><span :class="{ indicator_bad: stat_rx.sym_sync_lock === true, indicator_good: stat_rx.sym_sync_lock === false, indicator: true }"></span></td></tr>
                        <tr><th>Захват ФАПЧ</th><td><span :class="{ indicator_bad: stat_rx.afc_lock === true, indicator_good: stat_rx.afc_lock === false, indicator: true }"></span></td></tr>
                        <tr><th>Захват поиска по частоте</th><td><span :class="{ indicator_bad: stat_rx.freq_search_lock === true, indicator_good: stat_rx.freq_search_lock === false, indicator: true }"></span></td></tr>
                        <tr><th>Захват пакетной синхр.</th><td><span :class="{ indicator_bad: stat_rx.pkt_sync === true, indicator_good: stat_rx.pkt_sync === false, indicator: true }"></span></td></tr>
                        <tr><th>ОСШ/RSSI</th><td>{{ stat_rx.snr }} / {{ stat_rx.rssi }}</td></tr>
                        <tr><th>Modcod/размер кадра</th><td>{{ stat_rx.modcod }} / {{ stat_rx.frameSize }}</td></tr>
                        <tr><th>Пилот-символы</th><td>{{ stat_rx.pilots }}</td></tr>
                        <tr><th>Символьная ошибка</th><td>{{ stat_rx.symError }}</td></tr>
                        <tr><th>Грубая/точная част. ошибка, Гц</th><td>{{ stat_rx.freqErr }} / {{ stat_rx.freqErrAcc }}</td></tr>
                        <tr><th>Ур. входного сигнала</th><td>{{ stat_rx.inputSignalLevel }}</td></tr>
                        <tr><th>Ошибка ФАПЧ</th><td>{{ stat_rx.pllError }}</td></tr>
                        <tr><th>Инф. скорость на приеме</th><td>{{ stat_rx.speedOnRxKbit }} kbit/s</td></tr>
                        <tr><th>Инф. скорость на интерфейсе</th><td>{{ stat_rx.speedOnIifKbit }} kbit/s</td></tr>
                        </tbody>
                    </table>
                    <p> Статистика пакетов </p>
                    <table>
                        <tbody>
                        <tr><th>Качественных пакетов</th><td>{{ stat_rx.packetsOk }}</td></tr>
                        <tr><th>Поврежденных пакетов</th><td>{{ stat_rx.packetsBad }}</td></tr>
                        <tr><th>DUMMY</th><td>{{ stat_rx.packetsDummy }}</td></tr>
                        </tbody>
                    </table>
                    <button @click="resetPacketsStatistics()"> Сброс статистики </button>
                </div>
                <div>
                    <h2>Статистика передачи</h2>
                    <table>
                        <tbody>
                        <tr><th>Передача</th><td><span :class="{ indicator_bad: stat_tx.state === true, indicator_good: stat_tx.state === false, indicator: true }"></span></td></tr>
                        <tr><th>ОСШ дальнего приема</th><td>{{ stat_tx.snr }}</td></tr>
                        <tr><th>Modcod</th><td>{{ stat_tx.modcod }}</td></tr>
                        <tr><th>Размер кадра</th><td>{{ stat_tx.frameSize }}</td></tr>
                        <tr><th>Пилот-символы</th><td>{{ stat_tx.pilots }}</td></tr>
                        <tr><th>Инф. скорость на передаче</th><td>{{ stat_tx.speedOnTxKbit }} kbit/s</td></tr>
                        <tr><th>Инф. скорость на интерфейсе</th><td>{{ stat_tx.speedOnIifKbit }} kbit/s</td></tr>
                        </tbody>
                    </table>
                </div>
                <div v-if="isCinC === true">
                    <h2>Статистика режима CinC</h2>
                    <table>
                        <tbody>
                        <tr><th>ОСС</th><td>{{ stat_cinc.occ }}</td></tr>
                        <tr><th>Захват коррелятора</th><td><span :class="{ indicator_bad: stat_cinc.correlator === true, indicator_good: stat_cinc.correlator === false, indicator: true }"></span></td></tr>
                        <tr><th>Кол-во срывов коррелятора</th><td>{{ stat_cinc.correlatorFails }}</td></tr>
                        <tr><th>Грубая/точная част. ошибка, Гц</th><td>{{ stat_cinc.freqErr }} / {{ stat_cinc.freqErrAcc }}</td></tr>
                        <tr><th>Задержка в канале, мс</th><td>{{ stat_cinc.channelDelay }}</td></tr>
                        </tbody>
                    </table>
                </div>
                <div>
                    <h2>Состояние устройства</h2>
                    <table>
                        <tbody>
                        <tr><th>Температура ADRV</th><td>{{ stat_device.adrv }} °C</td></tr>
                        <tr><th>Температура ZYNC</th><td>{{ stat_device.zync }} °C</td></tr>
                        <tr><th>Температура FPGA</th><td>{{ stat_device.fpga }} °C</td></tr>
                        </tbody>
                    </table>
                </div>
            </div>
            <div class="tabs-body-item" v-show="activeTab === 'setup' && settingFetchComplete">
                <h2>Настройки приема/передачи</h2>
                <form method="POST" onsubmit="" class="settings-set-container">
                    <label>
                        <span>Режим работы</span>
                        <select v-model="param.general.mode">
                            <option value="scpc">SCPC</option>
                            <option value="cinc">CinC</option>
                        </select>
                    </label>
                    <button type="submit">Сохранить</button>
                </form>
                <div class="tabs-item-flex-container">
                    <form>
                        <h2>Настройки передатчика</h2>
                        <label>
                            <span>Включить передатчик</span>
                            <span class="toggle-input">
                                <input type="checkbox" v-model="param.general.txEn" />
                                <span class="slider"></span>
                            </span>
                        </label>
                        <label>
                            <span>Автоматический запуск передатчика</span>
                            <span class="toggle-input">
                                <input type="checkbox" v-model="param.general.autoStartTx" />
                                <span class="slider"></span>
                            </span>
                        </label>
                        <label>
                            <span>Режим работы модулятора</span>
                            <select v-model="param.general.modulatorMode">
                                <option value="normal">Нормальный</option>
                                <option value="test">Тест (CW)</option>
                            </select>
                        </label>
                        <label>
                            <span>Входные данные</span>
                            <select v-model="param.general.inputData">
                                <option value="eth">Ethernet</option>
                                <option value="test">Тест (CW)</option>
                            </select>
                        </label>
                        <button type="submit">Сохранить</button>
                    </form>
                    <form>
                        <h2>Параметры передачи</h2>
                        <label>
                            <span>Центральная частота, кГц</span>
                            <input v-model="param.tx.centerFreq"/>
                        </label>
                        <label>
                            <span>Символьная скорость, Бод</span>
                            <input v-model="param.tx.cymRate"/>
                        </label>
                        <label>
                            <span>Roll-off</span>
                            <select v-model="param.tx.rolloff">
                                <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>
                            <select v-model="param.tx.goldan">
                                <option value="0">0</option>
                                <option value="1">1</option>
                            </select>
                        </label>
                        <label>
                            <span>Ослабление, dB</span>
                            <input v-model="param.tx.attenuation"/>
                        </label>
                        <button type="submit">Сохранить</button>
                    </form>
                    <form>
                        <h2>Режим работы DVB-S2</h2>
                        <label>
                            <span>Режим</span>
                            <select v-model="param.dvbs2.mode">
                                <option value="ccm">CCM</option>
                                <option value="acm">ACM</option>
                            </select>
                        </label>
                        <label>
                            <span>Размер кадра</span>
                            <select v-model="param.dvbs2.frameSize">
                                <option value="normal">normal</option>
                                <option value="short">short</option>
                            </select>
                        </label>
                        <label>
                            <span>Пилот-символы</span>
                            <select v-model="param.dvbs2.pilots">
                                <option value="true">pilots</option>
                                <option value="false">no pilots</option>
                            </select>
                        </label>

                        <label v-show="param.dvbs2.mode === 'ccm'">
                            <span>Модуляция</span>
                            <select v-model="param.dvbs2.ccm_modulation">
                                <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="param.dvbs2.mode === 'ccm'">
                            <span>Скорость кода</span>
                            <select v-model="param.dvbs2.ccm_speed">
                                <option value="1/4">1/4</option>
                                <option value="1/3">1/3</option>
                                <option value="2/5">2/5</option>
                                <option value="1/2">1/2</option>
                                <option value="2/3">2/3</option>
                                <option value="3/4">3/4</option>
                                <option value="4/5">4/5</option>
                                <option value="5/6">5/6</option>
                                <option value="8/9">8/9</option>
                                <option value="9/10">9/10</option>
                            </select>
                        </label>

                        <label v-show="param.dvbs2.mode === 'acm'">
                            <span>Модуляция (макс. режим)</span>
                            <select v-model="param.dvbs2.acm_maxModulation">
                                <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="param.dvbs2.mode === 'acm'">
                            <span>Скорость кода (макс. режим)</span>
                            <select v-model="param.dvbs2.acm_maxSpeed">
                                <option value="1/4">1/4</option>
                                <option value="1/3">1/3</option>
                                <option value="2/5">2/5</option>
                                <option value="1/2">1/2</option>
                                <option value="2/3">2/3</option>
                                <option value="3/4">3/4</option>
                                <option value="4/5">4/5</option>
                                <option value="5/6">5/6</option>
                                <option value="8/9">8/9</option>
                                <option value="9/10">9/10</option>
                            </select>
                        </label>
                        <label v-show="param.dvbs2.mode === 'acm'">
                            <span>Модуляция (мин. режим)</span>
                            <select v-model="param.dvbs2.acm_minModulation">
                                <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="param.dvbs2.mode === 'acm'">
                            <span>Скорость кода (мин. режим)</span>
                            <select v-model="param.dvbs2.acm_minSpeed">
                                <option value="'1/4'">1/4</option>
                                <option value="'1/3'">1/3</option>
                                <option value="'2/5'">2/5</option>
                                <option value="'1/2'">1/2</option>
                                <option value="'2/3'">2/3</option>
                                <option value="'3/4'">3/4</option>
                                <option value="'4/5'">4/5</option>
                                <option value="'5/6'">5/6</option>
                                <option value="'8/9'">8/9</option>
                                <option value="'9/10'">9/10</option>
                            </select>
                        </label>

                        <button type="submit">Сохранить</button>
                    </form>
                    <form>
                        <h2>Настройки авто-регулировки мощности</h2>
                        <label>
                            <span>Авто-регулировка мощности</span>
                            <span class="toggle-input">
                                <input type="checkbox" v-model="param.acp.en" />
                                <span class="slider"></span>
                            </span>
                        </label>
                        <label>
                            <span>Максимальное ослабление</span>
                            <input v-model="param.acp.maxAttenuation"/>
                        </label>
                        <label>
                            <span>Минимальное ослабление</span>
                            <input v-model="param.acp.minAttenuation"/>
                        </label>
                        <label>
                            <span>Требуемое ОСШ</span>
                            <input v-model="param.acp.requiredSnr"/>
                        </label>
                        <button type="submit">Сохранить</button>
                    </form>
                    <form>
                        <h2>Настройка приемника</h2>
                        <label>
                            <span>Режим управления усилением</span>
                            <select v-model="param.rx.gainMode">
                                <option value="auto">АРУ</option>
                                <option value="manual">РРУ</option>
                            </select>
                        </label>
                        <label v-show="param.rx.gainMode === 'manual'">
                            <span>Усиление, dB</span>
                            <input v-model="param.rx.manualGain"/>
                        </label>
                        <label>
                            <span>Инверсия спектра</span>
                            <span class="toggle-input">
                                <input type="checkbox" v-model="param.rx.spectrumInversion" />
                                <span class="slider"></span>
                            </span>
                        </label>
                        <label>
                            <span>Центральная частота, кГц</span>
                            <input v-model="param.rx.centerFreq"/>
                        </label>
                        <label>
                            <span>Символьная скорость, Бод</span>
                            <input v-model="param.rx.cymRate"/>
                        </label>
                        <label>
                            <span>Roll-off</span>
                            <select v-model="param.rx.rolloff">
                                <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>
                            <select v-model="param.rx.goldan">
                                <option value="0">0</option>
                                <option value="1">1</option>
                            </select>
                        </label>
                        <label>
                            <span>Ослабление, dB</span>
                            <input v-model="param.rx.attenuation"/>
                        </label>
                        <button type="submit">Сохранить</button>
                    </form>
                </div>
                <div v-show="param.general.mode === 'cinc'">
                    <h2>Настройки режима CinC</h2>
                    <p>CinC пока нельзя настроить, но скоро разработчик это поправит)</p>
                </div>
                <div>
                    <h2>Настройки питания и опорного генератора</h2>
                    <p>Эти настройки пока недоступны, но скоро разработчик это поправит)</p>
                </div>
            </div>
            <div class="tabs-body-item" v-show="activeTab === 'admin'">
                <p>
                    Эти настройки пока недоступны, но скоро разработчик это поправит. А пока смотри на крокодила
                </p>
                <img loading="lazy" src="/images/krokodil_vzryvaetsya_hd.gif" alt="krokodil">
            </div>
        </div>
        <p>Последнее обновление статистики: {{ lastUpdateTime }}</p>
    </div>
</div>

<!-- Версия для разработки включает в себя возможность вывода в консоль полезных уведомлений -->
<script src="/js/vue.js"></script>
<script>
    // const router = useRouter();
    const availableTabs = ['monitoring', 'setup', 'admin']
    const defaultTab = availableTabs[0]

    function getCurrentTab() {
        const sl = window.location.hash.slice(1)
        if (availableTabs.indexOf(sl) >= 0) {
            return sl
        }
        return defaultTab
    }

    // TODO: взять модкоды из раздела 5.5.2.2 https://www.etsi.org/deliver/etsi_en/302300_302399/302307/01.01.02_60/en_302307v010102p.pdf
    // и прикрутить декодинг модкода

    const app = new Vue({
        el: '#app',
        data: {
            isCinC: null,

            stat_rx: {
                // индикаторы
                state: '?', // общее состояние
                sym_sync_lock: '?', // захват символьной
                freq_search_lock: '?', // Захват поиска по частоте
                afc_lock: '?', // захват ФАПЧ
                pkt_sync: '?', // захват пакетной синхронизации

                // куча других параметров, идет в том же порядке, что и в таблице
                snr: '?', rssi: '?',
                modcod: '?', frameSize: '?',
                pilots: '?',
                symError: '?',
                freqErr: '?', freqErrAcc: '?',
                inputSignalLevel: '?',
                pllError: '?',
                speedOnRxKbit: '?',
                speedOnIifKbit: '?',

                // статистика пакетов
                packetsOk: '?', packetsBad: '?', packetsDummy: '?',
            },
            stat_tx: {
                // состояние
                state: '?',

                // прочие поля
                snr: '?', modcod: '?', frameSize: '?', pilots: '?', speedOnTxKbit: '?', speedOnIifKbit: '?',
            },
            stat_cinc: {
                occ: '?',
                correlator: null,
                correlatorFails: '?',
                freqErr: '?', freqErrAcc: '?',
                channelDelay: '?'
            },
            stat_device: { // температурные датчики
                adrv: 0, zync: 0, fpga: 0
            },

            param: {
                general: {
                    mode: 'scpc',
                    txEn: false, // включен/выключен
                    modulatorMode: 'normal', // режим работы модулятора
                    autoStartTx: false, // было "режим работы передатчика"
                    inputData: 'eth', // входные данные: eth или test
                },
                tx: {
                    attenuation: -3.0, // ослабление
                    goldan: '0',
                    rolloff: 20,
                    cymRate: 100000,
                    centerFreq: 1200000.0,
                },
                dvbs2: {
                    mode: 'ccm',
                    frameSize: 'normal',
                    pilots: false,

                    // CCM
                    ccm_modulation: 'qpsk',
                    ccm_speed: '1/2',

                    // ACM
                    acm_maxModulation: 'qpsk',
                    acm_maxSpeed: '1/2',
                    acm_minModulation: 'qpsk',
                    acm_minSpeed: '1/2',

                    snrReserve: 0.5,
                    servicePacketPeriod: 15,
                },
                // авто-регулировка мощности
                acp: {
                    en: false,
                    maxAttenuation: -2.0,
                    minAttenuation: -3.0,
                    requiredSnr: -10,
                },
                rx: {
                    gainMode: 'auto', // режим управления усилением
                    manualGain: 70, // усиление, только для ручного режима
                    spectrumInversion: false,

                    goldan: '0',
                    rolloff: 20,
                    cymRate: 100000,
                    centerFreq: 1200000.0,
                },

                buc: {

                },
                lnb: {},
                serviceSettings: {},
            },

            message: "<err>",

            testState: '?',
            lastUpdateTime: new Date(),
            activeTab: getCurrentTab(),
            settingFetchComplete: false
        },
        methods: {
            updateStatistics(vals) {
                this.lastUpdateTime = new Date();
                this.isCinC = vals["mainState"]["isCinC"]

                this.stat_rx.state = vals["mainState"]["rx.state"]
                this.stat_rx.sym_sync_lock = vals["mainState"]["rx.sym_sync_lock"]
                this.stat_rx.freq_search_lock = vals["mainState"]["rx.freq_search_lock"]
                this.stat_rx.afc_lock = vals["mainState"]["rx.afc_lock"]
                this.stat_rx.pkt_sync = vals["mainState"]["rx.pkt_sync"]
                this.stat_rx.snr = vals["mainState"]["rx.snr"]
                this.stat_rx.rssi = vals["mainState"]["rx.rssi"]
                this.stat_rx.modcod = vals["mainState"]["rx.modcod"]
                this.stat_rx.frameSize = vals["mainState"]["rx.frameSize"]
                this.stat_rx.pilots = vals["mainState"]["rx.pilots"]
                this.stat_rx.symError = vals["mainState"]["rx.symError"]
                this.stat_rx.freqErr = vals["mainState"]["rx.freqErr"]
                this.stat_rx.freqErrAcc = vals["mainState"]["rx.freqErrAcc"]
                this.stat_rx.inputSignalLevel = vals["mainState"]["rx.inputSignalLevel"]
                this.stat_rx.pllError = vals["mainState"]["rx.pllError"]
                this.stat_rx.speedOnRxKbit = vals["mainState"]["rx.speedOnRxKbit"]
                this.stat_rx.speedOnIifKbit = vals["mainState"]["rx.speedOnIifKbit"]
                this.stat_rx.packetsOk = vals["mainState"]["rx.packetsOk"]
                this.stat_rx.packetsBad = vals["mainState"]["rx.packetsBad"]
                this.stat_rx.packetsDummy = vals["mainState"]["rx.packetsDummy"]

                this.stat_tx.state = vals["mainState"]["tx.state"]
                this.stat_tx.snr = vals["mainState"]["rx.snr"]
                this.stat_tx.modcod = vals["mainState"]["rx.modcod"]
                this.stat_tx.frameSize = vals["mainState"]["rx.frameSize"]
                this.stat_tx.pilots = vals["mainState"]["rx.pilots"]
                this.stat_tx.speedOnTxKbit = vals["mainState"]["tx.speedOnTxKbit"]
                this.stat_tx.speedOnIifKbit = vals["mainState"]["rx.speedOnIifKbit"]

                this.stat_cinc.occ = vals["mainState"]["cinc.occ"]
                this.stat_cinc.correlator = vals["mainState"]["cinc.correlator"]
                this.stat_cinc.correlatorFails = vals["mainState"]["cinc.correlatorFails"]
                this.stat_cinc.freqErr = vals["mainState"]["cinc.freqErr"]
                this.stat_cinc.freqErrAcc = vals["mainState"]["cinc.freqErrAcc"]
                this.stat_cinc.channelDelay = vals["mainState"]["cinc.channelDelay"]

                this.stat_device.adrv = vals["mainState"]["device.adrv"]
                this.stat_device.zync = vals["mainState"]["device.zync"]
                this.stat_device.fpga = vals["mainState"]["device.fpga"]

                this.testState = vals["mainState"]["testState"]
            },

            resetPacketsStatistics() {
                fetch('/api/resetPacketStatistics', {
                    method: 'POST'
                }).then(() => {
                    this.stat_rx.packetsOk = 0
                    this.stat_rx.packetsBad = 0
                    this.stat_rx.packetsDummy = 0
                })
            },

            updateSettings(vals) {
                this.settingFetchComplete = true
            }
        },
        mounted() {
            const doFetchStatistics = async () => {
                let d = await fetch("/api/get/statistics")
                this.updateStatistics(await d.json())

                setTimeout(() => {
                    doFetchStatistics()
                }, 1000)
            }

            doFetchStatistics().then(() => {})

            const doFetchSettings = async () => {
                let d = await fetch("/api/get/settings")
                this.updateSettings(await d.json())
            }

            doFetchSettings().then(() => {})

            document.getElementById("app").removeAttribute("hidden")
        }
    })

    // import MyComponent from './modules/header'
    // const sh = new Vue(MyComponent)
</script>
</body>
</html>