Compare commits

...

2 Commits

5 changed files with 295 additions and 27 deletions

View File

@ -57,6 +57,7 @@ struct modulator_settings_com{
bool is_carrier; bool is_carrier;
bool tx_is_on; bool tx_is_on;
bool is_cinc; bool is_cinc;
uint32_t modcod_tx;
}; };
struct modulator_state_com{ struct modulator_state_com{
@ -476,7 +477,7 @@ struct cmd_modulator_settings
archive(modulator_settings.attenuation,modulator_settings.baudrate, modulator_settings.central_freq_in_kGz, archive(modulator_settings.attenuation,modulator_settings.baudrate, modulator_settings.central_freq_in_kGz,
modulator_settings.is_carrier, modulator_settings.is_cinc, modulator_settings.is_carrier, modulator_settings.is_cinc,
modulator_settings.is_save_current_state, modulator_settings.is_test_data, modulator_settings.is_save_current_state, modulator_settings.is_test_data,
modulator_settings.rollof, modulator_settings.tx_is_on); modulator_settings.rollof, modulator_settings.tx_is_on, modulator_settings.modcod_tx);
} }
}; };

View File

@ -139,6 +139,7 @@ struct modulator_settings{
bool is_carrier; bool is_carrier;
bool tx_is_on; bool tx_is_on;
bool is_cinc; bool is_cinc;
uint32_t modcod_tx;
}; };
EXTERNC CP_Result CP_SetModulatorSettings(TSID sid, modulator_settings& settings); EXTERNC CP_Result CP_SetModulatorSettings(TSID sid, modulator_settings& settings);

View File

@ -267,6 +267,61 @@ public:
} }
})); }));
s.resources.emplace_back(std::make_unique<http::auth::AuthRequiredResource>("/api/set/cinc", this->auth, http::auth::User::EDIT_SETTINGS, [this](const auto& req, auto& rep) {
if (req.method != "POST") {
http::server::stockReply(http::server::bad_request, rep);
}
rep.status = http::server::ok;
rep.headers.clear();
rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::json)});
try {
std::stringstream ss;
ss.str(std::string(req.payload.begin(), req.payload.end()));
boost::property_tree::ptree pt;
read_json(ss, pt);
api->setCincSettings(pt);
std::string result = R"({"status":"ok","settings":)";
result += api->loadSettings();
result += "}";
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
} catch (std::exception& e) {
BOOST_LOG_TRIVIAL(error) << "WebHandle(/api/set/cinc): Can't set CinC settings: " << e.what();
const std::string result = R"({"status":"error"})";
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
}
}));
s.resources.emplace_back(std::make_unique<http::auth::AuthRequiredResource>("/api/set/rxtx", this->auth, http::auth::User::EDIT_SETTINGS, [this](const auto& req, auto& rep) {
if (req.method != "POST") {
http::server::stockReply(http::server::bad_request, rep);
}
rep.status = http::server::ok;
rep.headers.clear();
rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::json)});
try {
std::stringstream ss;
ss.str(std::string(req.payload.begin(), req.payload.end()));
boost::property_tree::ptree pt;
read_json(ss, pt);
api->setRxTxSettings(pt);
std::string result = R"({"status":"ok","settings":)";
result += api->loadSettings();
result += "}";
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
} catch (std::exception& e) {
BOOST_LOG_TRIVIAL(error) << "WebHandle(/api/set/rxtx): Can't set RX/TX settings: " << e.what();
const std::string result = R"({"status":"error"})";
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
}
}));
} }
~ServerResources() = default; ~ServerResources() = default;

View File

@ -208,19 +208,49 @@ public:
json = this->qosClassesJson; json = this->qosClassesJson;
} }
void setStrringsRxTx(bool readback = true) {} void setSettingsRxTx(modulator_settings& mod, demodulator_settings& demod, ACM_parameters_serv_& acm, bool readback = true) {
void setStrringsCinc(bool readback = true) {}
void setStrringsBucLnb(const buc_lnb_settings& bucLnb, bool readback = true) {
buc_lnb_settings tmp = bucLnb;
std::lock_guard lock(this->cpApiMutex); std::lock_guard lock(this->cpApiMutex);
CP_SetDmaDebug(sid, "begin_save_config", ""); CP_SetDmaDebug(sid, "begin_save_config", "");
CP_SetBUC_LNB_settings(this->sid, tmp); CP_SetModulatorSettings(this->sid, mod);
CP_SetDemodulatorSettings(this->sid, demod);
CP_SetAcmParams(this->sid, acm);
if (readback) { if (readback) {
CP_GetBUC_LNB_settings(this->sid, tmp); CP_GetModulatorSettings(this->sid, mod);
CP_GetDemodulatorSettings(this->sid, demod);
CP_GetAcmParams(this->sid, &acm);
{ {
std::lock_guard lock2{this->settingsMutex}; std::lock_guard lock2{this->settingsMutex};
this->bucLnbSettings = tmp; this->modSettings = mod;
this->demodSettings = demod;
this->acmSettings = acm;
}
}
CP_SetDmaDebug(sid, "save_config", "");
}
void setSettingsCinc(DPDI_parmeters& s, bool readback = true) {
std::lock_guard lock(this->cpApiMutex);
CP_SetDmaDebug(sid, "begin_save_config", "");
CP_SetDpdiParams(sid, s);
if (readback) {
CP_GetDpdiParams(this->sid, &s);
{
std::lock_guard lock2{this->settingsMutex};
this->dpdiSettings = s;
}
}
CP_SetDmaDebug(sid, "save_config", "");
}
void setSettingsBucLnb(buc_lnb_settings& bucLnb, bool readback = true) {
std::lock_guard lock(this->cpApiMutex);
CP_SetDmaDebug(sid, "begin_save_config", "");
CP_SetBUC_LNB_settings(this->sid, bucLnb);
if (readback) {
CP_GetBUC_LNB_settings(this->sid, bucLnb);
{
std::lock_guard lock2{this->settingsMutex};
this->bucLnbSettings = bucLnb;
} }
} }
CP_SetDmaDebug(sid, "save_config", ""); CP_SetDmaDebug(sid, "save_config", "");
@ -426,12 +456,12 @@ std::string api_driver::ApiDriver::loadSettings() const {
buc_lnb_settings bucLnb{}; buc_lnb_settings bucLnb{};
daemon->getSettings(&modSettings, &demodSettings, &acmSettings, &dpdiSettings, &bucLnb); daemon->getSettings(&modSettings, &demodSettings, &acmSettings, &dpdiSettings, &bucLnb);
uint32_t modulatorModcod; // uint32_t modulatorModcod;
{ // {
modulator_state ms{}; // modulator_state ms{};
daemon->getStatistics(&ms, nullptr, nullptr); // daemon->getStatistics(&ms, nullptr, nullptr);
modulatorModcod = ms.modcod; // modulatorModcod = ms.modcod;
} // }
std::stringstream result; std::stringstream result;
result << "{\n\"general.isCinC\":" << boolAsStr(modSettings.is_cinc); result << "{\n\"general.isCinC\":" << boolAsStr(modSettings.is_cinc);
@ -439,25 +469,24 @@ std::string api_driver::ApiDriver::loadSettings() const {
result << ",\"general.modulatorMode\":" << (modSettings.is_carrier ? "\"normal\"" : "\"test\""); result << ",\"general.modulatorMode\":" << (modSettings.is_carrier ? "\"normal\"" : "\"test\"");
result << ",\"general.autoStartTx\":" << boolAsStr(modSettings.is_save_current_state); result << ",\"general.autoStartTx\":" << boolAsStr(modSettings.is_save_current_state);
result << ",\"general.isTestInputData\":" << boolAsStr(modSettings.is_test_data); result << ",\"general.isTestInputData\":" << boolAsStr(modSettings.is_test_data);
result << ",\n\"tx.attenuation\":"; writeDouble(result, modSettings.attenuation); result << ",\n\"tx.attenuation\":"; writeDouble(result, modSettings.attenuation);
result << ",\"tx.rolloff\":" << static_cast<int>(modSettings.rollof * 100); result << ",\"tx.rolloff\":" << static_cast<int>(modSettings.rollof * 100);
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.ccm_modcod\":" << (modSettings.modcod_tx >> 4);
result << ",\n\"dvbs2.isAcm\":" << boolAsStr(acmSettings.enable);
result << ",\"dvbs2.frameSizeNormal\":" << boolAsStr(!(modulatorModcod & 2));
// result << ",\"dvbs2.isPilots\":" << "null"; // result << ",\"dvbs2.isPilots\":" << "null";
result << ",\"dvbs2.ccm_modcod\":" << (modulatorModcod >> 4); result << ",\n\"dvbs2.isAcm\":" << boolAsStr(acmSettings.enable);
result << ",\"dvbs2.acm_maxModcod\":" << (acmSettings.max_modcod >> 2); result << ",\"dvbs2.acm_maxModcod\":" << (acmSettings.max_modcod >> 2);
result << ",\"dvbs2.acm_minModcod\":" << (acmSettings.min_modcod >> 2); result << ",\"dvbs2.acm_minModcod\":" << (acmSettings.min_modcod >> 2);
result << ",\"dvbs2.snrReserve\":"; writeDouble(result, acmSettings.min_attenuation); result << ",\"dvbs2.snrReserve\":"; writeDouble(result, acmSettings.snr_treashold_acm);
result << ",\"dvbs2.servicePacketPeriod\":" << acmSettings.period_pack; result << ",\"dvbs2.servicePacketPeriod\":" << acmSettings.period_pack;
result << ",\n\"acm.en\":" << boolAsStr(acmSettings.enable_auto_atten); result << ",\n\"acm.en\":" << boolAsStr(acmSettings.enable_auto_atten);
result << ",\"acm.maxAttenuation\":"; writeDouble(result, acmSettings.max_attenuation); result << ",\"acm.maxAttenuation\":"; writeDouble(result, acmSettings.max_attenuation);
result << ",\"acm.minAttenuation\":"; writeDouble(result, acmSettings.min_attenuation); result << ",\"acm.minAttenuation\":"; writeDouble(result, acmSettings.min_attenuation);
result << ",\"acm.requiredSnr\":"; writeDouble(result, acmSettings.snr_treashold_acm); result << ",\"acm.requiredSnr\":"; writeDouble(result, acmSettings.snr_treashold);
result << ",\n\"rx.gainMode\":" << (demodSettings.is_aru_on ? "\"auto\"" : "\"manual\""); result << ",\n\"rx.gainMode\":" << (demodSettings.is_aru_on ? "\"auto\"" : "\"manual\"");
result << ",\"rx.manualGain\":"; writeDouble(result, demodSettings.gain); result << ",\"rx.manualGain\":"; writeDouble(result, demodSettings.gain);
@ -502,9 +531,79 @@ std::string api_driver::ApiDriver::loadSettings() const {
} }
void api_driver::ApiDriver::setRxTxSettings(boost::property_tree::ptree &pt) { void api_driver::ApiDriver::setRxTxSettings(boost::property_tree::ptree &pt) {
modulator_settings mod{};
demodulator_settings demod{};
ACM_parameters_serv_ acm{};
// для модулятора
mod.is_cinc = pt.get<bool>(json_path("general.isCinC", '/'));
mod.tx_is_on = pt.get<bool>(json_path("general.txEn", '/'));
auto tmp = pt.get<std::string>(json_path("general.modulatorMode", '/'));
if (tmp == "normal") { mod.is_carrier = true; }
else if (tmp == "test") { mod.is_carrier = false; }
else { throw std::runtime_error("api_driver::ApiDriver::setRxTxSettings(): Wrong carrier mode: " + tmp); }
mod.is_save_current_state = pt.get<bool>(json_path("general.autoStartTx", '/'));
mod.is_test_data = pt.get<bool>(json_path("general.isTestInputData", '/'));
mod.attenuation = pt.get<double>(json_path("tx.attenuation", '/'));
mod.rollof = pt.get<double>(json_path("tx.rolloff", '/')) / 100.0;
mod.baudrate = pt.get<uint32_t>(json_path("tx.cymRate", '/'));
mod.central_freq_in_kGz = pt.get<double>(json_path("tx.centerFreq", '/'));
const bool acmIsShortFrame = pt.get<bool>(json_path("dvbs2.frameSizeNormal", '/'));
mod.modcod_tx = (pt.get<uint32_t>(json_path("dvbs2.ccm_modcod", '/')) << 2) | (acmIsShortFrame ? 2 : 0);
// демодулятор
tmp = pt.get<std::string>(json_path("rx.gainMode", '/'));
if (tmp == "normal") { demod.is_aru_on = true; }
else if (tmp == "test") { demod.is_aru_on = false; }
else { throw std::runtime_error("api_driver::ApiDriver::setRxTxSettings(): Wrong gain mode: " + tmp); }
demod.gain = pt.get<double>(json_path("rx.manualGain", '/'));
demod.baudrate = pt.get<uint32_t>(json_path("rx.cymRate", '/'));
demod.is_rvt_iq = pt.get<bool>(json_path("rx.spectrumInversion", '/'));
demod.rollof = pt.get<double>(json_path("rx.rolloff", '/')) / 100.0;
demod.central_freq_in_kGz = pt.get<double>(json_path("rx.centerFreq", '/'));
// ACM
acm.enable = pt.get<bool>(json_path("dvbs2.isAcm", '/'));
acm.max_modcod = (pt.get<uint32_t>(json_path("dvbs2.acm_maxModcod", '/')) << 2) | (acmIsShortFrame ? 2 : 0);
acm.min_modcod = (pt.get<uint32_t>(json_path("dvbs2.acm_minModcod", '/')) << 2) | (acmIsShortFrame ? 2 : 0);
acm.snr_treashold_acm = pt.get<double>(json_path("dvbs2.snrReserve", '/')); // запас ОСШ
acm.period_pack = pt.get<uint32_t>(json_path("dvbs2.servicePacketPeriod", '/'));
acm.enable_auto_atten = pt.get<bool>(json_path("acm.en", '/'));
acm.max_attenuation = pt.get<double>(json_path("dvbs2.maxAttenuation", '/'));
acm.min_attenuation = pt.get<double>(json_path("dvbs2.minAttenuation", '/'));
acm.snr_treashold = pt.get<double>(json_path("dvbs2.requiredSnr", '/')); // требуемый ОСШ
daemon->setSettingsRxTx(mod, demod, acm);
} }
void api_driver::ApiDriver::setCincSettings(boost::property_tree::ptree &pt) { void api_driver::ApiDriver::setCincSettings(boost::property_tree::ptree &pt) {
DPDI_parmeters s{};
//result << ",\n\"cinc.mode\":" << (dpdiSettings.is_delay_window ? "\"delay\"" : "\"positional\"");
auto tmp = pt.get<std::string>(json_path("cinc.mode", '/'));
if (tmp == "delay") { s.is_delay_window = true; }
else if (tmp == "positional") { s.is_delay_window = false; }
else {
throw std::runtime_error("Wrong CinC mode: " + tmp);
}
auto ctmp = translateCoordinates(pt.get<double>(json_path("cinc.position.station.latitude", '/')));
s.latitude_station_grad = std::get<0>(ctmp);
s.latitude_station_minute = std::get<1>(ctmp);
ctmp = translateCoordinates(pt.get<double>(json_path("cinc.position.station.longitude", '/')));
s.longitude_station_grad = std::get<0>(ctmp);
s.longitude_station_minute = std::get<1>(ctmp);
ctmp = translateCoordinates(pt.get<double>(json_path("cinc.position.satelliteLongitude", '/')));
s.longitude_sattelite_grad = std::get<0>(ctmp);
s.longitude_sattelite_minute = std::get<1>(ctmp);
s.max_delay = pt.get<uint32_t>(json_path("cinc.delayMax", '/'));
s.min_delay = pt.get<uint32_t>(json_path("cinc.delayMin", '/'));
this->daemon->setSettingsCinc(s);
} }
void api_driver::ApiDriver::setBucLnbSettings(boost::property_tree::ptree &pt) { void api_driver::ApiDriver::setBucLnbSettings(boost::property_tree::ptree &pt) {
@ -536,7 +635,7 @@ void api_driver::ApiDriver::setBucLnbSettings(boost::property_tree::ptree &pt) {
s.is_ref_10MHz_output = pt.get<bool>(json_path("serviceSettings.refClk10M", '/')); s.is_ref_10MHz_output = pt.get<bool>(json_path("serviceSettings.refClk10M", '/'));
s.is_save_current_state = pt.get<bool>(json_path("serviceSettings.autoStart", '/')); s.is_save_current_state = pt.get<bool>(json_path("serviceSettings.autoStart", '/'));
this->daemon->setStrringsBucLnb(s); this->daemon->setSettingsBucLnb(s);
} }
void api_driver::ApiDriver::setQosSettings(boost::property_tree::ptree &pt) { void api_driver::ApiDriver::setQosSettings(boost::property_tree::ptree &pt) {

View File

@ -154,8 +154,6 @@
<option value="true">Тест (CW)</option> <option value="true">Тест (CW)</option>
</select> </select>
</label> </label>
</div>
<div class="settings-set-container">
<h3>Параметры передачи</h3> <h3>Параметры передачи</h3>
<label> <label>
<span>Центральная частота, КГц</span> <span>Центральная частота, КГц</span>
@ -179,8 +177,8 @@
<span>Ослабление, дБ</span> <span>Ослабление, дБ</span>
<input v-model="param.tx.attenuation" type="number"/> <input v-model="param.tx.attenuation" type="number"/>
</label> </label>
</div> </div>
<div class="settings-set-container"> <div class="settings-set-container">
<h3>Режим работы DVB-S2</h3> <h3>Режим работы DVB-S2</h3>
<label> <label>
@ -264,8 +262,7 @@
<span>Запас ОСШ</span> <span>Запас ОСШ</span>
<input v-model="param.dvbs2.snrReserve" type="number"> <input v-model="param.dvbs2.snrReserve" type="number">
</label> </label>
</div>
<div class="settings-set-container">
<h3>Авто-регулировка мощности</h3> <h3>Авто-регулировка мощности</h3>
<label> <label>
<span>Авто-регулировка мощности</span> <span>Авто-регулировка мощности</span>
@ -598,6 +595,55 @@
return modcods[modcod] 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/1': 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 12 // минимальная скорость
}
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) { function extractModulationAndSpeedFromModcod(modcod) {
switch (modcod) { switch (modcod) {
case 1: return { modulation: 'qpsk', speed: '1/4' } case 1: return { modulation: 'qpsk', speed: '1/4' }
@ -851,12 +897,78 @@
settingsSubmitRxTx() { settingsSubmitRxTx() {
if (this.submitStatus.rxTx) { return } if (this.submitStatus.rxTx) { return }
// потом добавить: "dvbs2.isPilots": this.param.dvbs2.isPilots
let query = {
"general.isCinC": this.param.general.isCinC,
"general.txEn": this.param.general.txEn,
"general.modulatorMode": this.param.general.modulatorMode,
"general.autoStartTx": this.param.general.autoStartTx,
"general.isTestInputData": this.param.general.isTestInputData,
"tx.attenuation": this.param.tx.attenuation,
"tx.rolloff": this.param.tx.rolloff,
"tx.cymRate": this.param.tx.cymRate,
"tx.centerFreq": this.param.tx.centerFreq,
"dvbs2.isAcm": this.param.dvbs2.mode === 'acm',
"dvbs2.frameSizeNormal": this.param.dvbs2.frameSizeNormal,
"dvbs2.ccm_modcod": toModcod(this.param.dvbs2.ccm_modulation, this.param.dvbs2.ccm_speed),
"dvbs2.acm_minModcod": toModcod(this.param.dvbs2.acm_minModulation, this.param.dvbs2.acm_minSpeed),
"dvbs2.acm_maxModcod": toModcod(this.param.dvbs2.acm_maxModulation, this.param.dvbs2.acm_maxSpeed),
"dvbs2.snrReserve": this.param.dvbs2.snrReserve,
"dvbs2.servicePacketPeriod": this.param.dvbs2.servicePacketPeriod,
"acm.en": this.param.acm.en,
"acm.maxAttenuation": this.param.acm.maxAttenuation,
"acm.minAttenuation": this.param.acm.minAttenuation,
"acm.requiredSnr": this.param.acm.requiredSnr,
"rx.gainMode": this.param.rx.gainMode,
"rx.manualGain": this.param.rx.manualGain,
"rx.spectrumInversion": this.param.rx.spectrumInversion,
"rx.rolloff": this.param.rx.rolloff,
"rx.cymRate": this.param.rx.cymRate,
"rx.centerFreq": this.param.rx.centerFreq
}
this.submitStatus.rxTx = true this.submitStatus.rxTx = true
fetch('/api/set/rxtx', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(query)
}).then(async (resp) => {
this.submitStatus.rxTx = false
this.updateCincSettings(await resp.json())
}).catch((reason) => {
this.submitStatus.rxTx = false
alert(`Ошибка при применении настроек: ${reason}`)
})
}, },
settingsSubmitCinC() { settingsSubmitCinC() {
if (this.submitStatus.cinc) { return } if (this.submitStatus.cinc) { return }
let query = {
"cinc.mode": this.param.cinc.mode,
"cinc.searchBandwidth": parseInt(this.param.cinc.searchBandwidth),
"cinc.position.station.latitude": parseFloat(this.param.cinc.position.station.latitude),
"cinc.position.station.longitude": parseFloat(this.param.cinc.position.station.longitude),
"cinc.position.satelliteLongitude": parseFloat(this.param.cinc.position.satelliteLongitude),
"cinc.delayMin": parseInt(this.param.cinc.delayMin),
"cinc.delayMax": parseInt(this.param.cinc.delayMax)
}
this.submitStatus.cinc = true this.submitStatus.cinc = true
fetch('/api/set/cinc', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(query)
}).then(async (resp) => {
this.submitStatus.cinc = false
this.updateCincSettings(await resp.json())
}).catch((reason) => {
this.submitStatus.cinc = false
alert(`Ошибка при применении настроек: ${reason}`)
})
}, },
settingsSubmitBucLnb() { settingsSubmitBucLnb() {