fix(ui): мастер настройки больше не отправляет set radio с нулевыми значениями

- applyRadio() отправлял команду всегда, в том числе при выходе из меню, если
  в этой сессии не открывали ни один радиопункт: рабочая копия (_radio_*) оставалась
  нулевой, устройство отвечало Error, invalid radio params
- добавлен признак _radio_dirty: команда уходит только после реальной правки
  частоты, полосы, SF или CR; при успешном применении признак сбрасывается
- перед отправкой значения перечитываются из настроек узла (loadRadio), а при
  каждом входе в мастер рабочая копия обновляется (_radio_loaded = false)
- README: запись в журнале изменений

Проверено сборкой: heltec_v4_repeater_mqtt, Meshadventurer_sx1262_repeater_mqtt,
Generic_E22_sx1262_repeater_mqtt (без дисплея)
This commit is contained in:
shade committed 2026-10-16 11:03:21 +03:00
1 parent 1e751a85d4
commit 8f27aa9202
3 files changed
+16 -2

No files matched your search

+1
View File
@@ -397,6 +397,7 @@ MQTT-репитер использует:
**Исправлено**
- мастер настройки: при выходе из меню отправлялась команда `set radio` с нулевыми значениями рабочей копии, если в этой сессии не открывали ни один радиопункт (например сразу `Save & exit`) — устройство отвечало `Error, invalid radio params`. Теперь радиопараметры отправляются только когда их действительно правили, значения перед отправкой перечитываются из настроек узла, а при каждом входе в мастер рабочая копия обновляется;
- `set mqtt.meshcoretel on|off` не срабатывал: обработчик сравнивался со строкой `set mqtt.mqtt.meshcoretel `. Алиас `set mqtt.meshcoretel.ru on|off` читает значение по правильному смещению;
- `setEndpointEnabled` маскировал сохранённую маску брокеров значением `0x07` и терял бит собственного брокера при переключении любого другого;
- на странице логина веб-панели незакрытый тег `</div` съедал абзац-подсказку про пароль администратора;
+14 -2
View File
@@ -168,6 +168,7 @@ void UITask::openMenu() {
_screen = SCREEN_MENU;
_menu_index = 0;
_menu_top = 0;
_radio_loaded = false; // при каждом входе перечитываем радио из настроек узла
_auto_off = millis() + WIZARD_AUTO_OFF_MILLIS;
}
@@ -182,10 +183,17 @@ void UITask::loadRadio() {
_radio_loaded = true;
}
// Отправка радиопараметров. Вызывается только когда их действительно правили:
// иначе на выходе из мастера уходила команда с нулевыми значениями рабочей копии
// и устройство отвечало "Error, invalid radio params".
void UITask::applyRadio() {
if (!_radio_dirty) return;
loadRadio(); // на случай, если правка шла без открытия пункта
char cmd[96];
snprintf(cmd, sizeof(cmd), "set radio %.3f,%.2f,%d,%d", _radio_freq, _radio_bw, _radio_sf, _radio_cr);
runCommand(cmd);
if (runCommand(cmd)) {
_radio_dirty = false;
}
}
void UITask::beginFreqEdit() {
@@ -268,6 +276,7 @@ void UITask::applyDigits() {
return;
}
_radio_bw = digitValue();
_radio_dirty = true;
applyRadio();
}
@@ -348,10 +357,12 @@ void UITask::applyField() {
switch (_menu_index) {
case MENU_CR:
_radio_cr = _value;
_radio_dirty = true;
applyRadio();
return;
case MENU_SF:
_radio_sf = _value;
_radio_dirty = true;
applyRadio();
return;
case MENU_TX:
@@ -450,7 +461,7 @@ void UITask::handleButton(int ev) {
_menu_index = (uint8_t)((_menu_index + MENU_COUNT - 1) % MENU_COUNT);
} else if (ev == BUTTON_EVENT_LONG_PRESS) {
if (_menu_index == MENU_EXIT) {
applyRadio(); // на случай правок частоты/полосы/SF/CR
applyRadio(); // применит радио, только если его правили в этой сессии
_screen = SCREEN_STATUS;
} else {
openField(_menu_index);
@@ -561,6 +572,7 @@ void UITask::handleButton(int ev) {
} else if (ev == BUTTON_EVENT_LONG_PRESS) {
if (_freq_index == FREQ_SAVE_POS) { // Save & exit
_radio_freq = freqValue();
_radio_dirty = true;
applyRadio();
_screen = SCREEN_MENU;
} else {
+1
View File
@@ -48,6 +48,7 @@ private:
// радиопараметры: рабочая копия, пока мастер открыт
bool _radio_loaded = false;
bool _radio_dirty = false; // правили ли частоту/полосу/SF/CR в этой сессии
double _radio_freq = 0;
double _radio_bw = 0;
int _radio_sf = 0;