Use new settings API in recon and scanner (#1394)

* Use new settings in recon
* Trim on string value read, remove dupe entry
* Check update_range flag when setting values
* Add a few saved settings to scanner
* Add copywrite note
This commit is contained in:
Kyle Reed 2023-08-20 13:28:02 -07:00 committed by GitHub
parent c6424f1623
commit 564f76b47d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 72 additions and 128 deletions

View File

@ -2,6 +2,7 @@
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc. * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2016 Furrtek * Copyright (C) 2016 Furrtek
* Copyright (C) 2022 Arjan Onwezen * Copyright (C) 2022 Arjan Onwezen
* Copyright (C) 2023 Kyle Reed
* *
* This file is part of PortaPack. * This file is part of PortaPack.
* *
@ -58,7 +59,7 @@ void BoundSetting::parse(std::string_view value) {
parse_int(value, as<uint8_t>()); parse_int(value, as<uint8_t>());
break; break;
case SettingType::String: case SettingType::String:
as<std::string>() = std::string{value}; as<std::string>() = trim(value);
break; break;
case SettingType::Bool: { case SettingType::Bool: {
int parsed = 0; int parsed = 0;
@ -106,10 +107,18 @@ void BoundSetting::write(File& file) const {
SettingsStore::SettingsStore(std::string_view store_name, SettingBindings bindings) SettingsStore::SettingsStore(std::string_view store_name, SettingBindings bindings)
: store_name_{store_name}, bindings_{bindings} { : store_name_{store_name}, bindings_{bindings} {
load_settings(store_name_, bindings_); reload();
} }
SettingsStore::~SettingsStore() { SettingsStore::~SettingsStore() {
save();
}
void SettingsStore::reload() {
load_settings(store_name_, bindings_);
}
void SettingsStore::save() const {
save_settings(store_name_, bindings_); save_settings(store_name_, bindings_);
} }

View File

@ -94,6 +94,9 @@ class SettingsStore {
SettingsStore(std::string_view store_name, SettingBindings bindings); SettingsStore(std::string_view store_name, SettingBindings bindings);
~SettingsStore(); ~SettingsStore();
void reload();
void save() const;
private: private:
std::string_view store_name_; std::string_view store_name_;
SettingBindings bindings_; SettingBindings bindings_;

View File

@ -176,85 +176,16 @@ bool ReconView::recon_save_freq(const fs::path& path, size_t freq_index, bool wa
return true; return true;
} }
bool ReconView::recon_load_config_from_sd() { void ReconView::load_persisted_settings() {
make_new_directory(u"SETTINGS"); autostart = persistent_memory::recon_autostart_recon();
autosave = persistent_memory::recon_autosave_freqs();
File settings_file; continuous = persistent_memory::recon_continuous();
auto error = settings_file.open(RECON_CFG_FILE); filedelete = persistent_memory::recon_clear_output();
if (error) load_freqs = persistent_memory::recon_load_freqs();
return false; load_ranges = persistent_memory::recon_load_ranges();
load_hamradios = persistent_memory::recon_load_hamradios();
auto complete = false; update_ranges = persistent_memory::recon_update_ranges_when_recon();
auto line_nb = 0; auto_record_locked = persistent_memory::recon_auto_record_locked();
auto reader = FileLineReader(settings_file);
for (const auto& line : reader) {
switch (line_nb) {
case 0:
input_file = trim(line);
break;
case 1:
output_file = trim(line);
break;
case 2:
parse_int(line, recon_lock_duration);
break;
case 3:
parse_int(line, recon_lock_nb_match);
break;
case 4:
parse_int(line, squelch);
break;
case 5:
parse_int(line, recon_match_mode);
break;
case 6:
parse_int(line, wait);
break;
case 7:
if (!update_ranges) {
parse_int(line, frequency_range.min);
button_manual_start.set_text(to_string_short_freq(frequency_range.min));
}
break;
case 8:
if (!update_ranges) {
parse_int(line, frequency_range.max);
button_manual_end.set_text(to_string_short_freq(frequency_range.max));
}
complete = true; // NB: Last entry.
break;
default:
complete = false;
break;
}
if (complete) break;
line_nb++;
}
return complete;
}
bool ReconView::recon_save_config_to_sd() {
File settings_file;
make_new_directory(u"SETTINGS");
auto error = settings_file.create(RECON_CFG_FILE);
if (error)
return false;
settings_file.write_line(input_file);
settings_file.write_line(output_file);
settings_file.write_line(to_string_dec_uint(recon_lock_duration));
settings_file.write_line(to_string_dec_uint(recon_lock_nb_match));
settings_file.write_line(to_string_dec_int(squelch));
settings_file.write_line(to_string_dec_uint(recon_match_mode));
settings_file.write_line(to_string_dec_int(wait));
settings_file.write_line(to_string_dec_uint(frequency_range.min));
settings_file.write_line(to_string_dec_uint(frequency_range.max));
return true;
} }
void ReconView::audio_output_start() { void ReconView::audio_output_start() {
@ -337,7 +268,6 @@ void ReconView::focus() {
ReconView::~ReconView() { ReconView::~ReconView() {
recon_stop_recording(); recon_stop_recording();
recon_save_config_to_sd();
if (field_mode.selected_index_value() != SPEC_MODULATION) if (field_mode.selected_index_value() != SPEC_MODULATION)
audio::output::stop(); audio::output::stop();
receiver_model.disable(); receiver_model.disable();
@ -395,29 +325,17 @@ ReconView::ReconView(NavigationView& nav)
}; };
def_step = 0; def_step = 0;
// HELPER: Pre-setting a manual range, based on stored frequency load_persisted_settings();
rf::Frequency stored_freq = receiver_model.target_frequency();
if (stored_freq - OneMHz > 0)
frequency_range.min = stored_freq - OneMHz;
else
frequency_range.min = 0;
button_manual_start.set_text(to_string_short_freq(frequency_range.min));
if (stored_freq + OneMHz < MAX_UFREQ)
frequency_range.max = stored_freq + OneMHz;
else
frequency_range.max = MAX_UFREQ;
button_manual_end.set_text(to_string_short_freq(frequency_range.max));
// Loading settings // When update_ranges is set or range invalid, use the rx model frequency instead of the saved values.
autostart = persistent_memory::recon_autostart_recon(); if (update_ranges || frequency_range.max == 0) {
autosave = persistent_memory::recon_autosave_freqs(); rf::Frequency stored_freq = receiver_model.target_frequency();
continuous = persistent_memory::recon_continuous(); frequency_range.min = clip<rf::Frequency>(stored_freq - OneMHz, 0, MAX_UFREQ);
filedelete = persistent_memory::recon_clear_output(); frequency_range.max = clip<rf::Frequency>(stored_freq + OneMHz, 0, MAX_UFREQ);
load_freqs = persistent_memory::recon_load_freqs(); }
load_ranges = persistent_memory::recon_load_ranges();
load_hamradios = persistent_memory::recon_load_hamradios(); button_manual_start.set_text(to_string_short_freq(frequency_range.min));
update_ranges = persistent_memory::recon_update_ranges_when_recon(); button_manual_end.set_text(to_string_short_freq(frequency_range.max));
auto_record_locked = persistent_memory::recon_auto_record_locked();
button_manual_start.on_select = [this, &nav](ButtonWithEncoder& button) { button_manual_start.on_select = [this, &nav](ButtonWithEncoder& button) {
clear_freqlist_for_ui_action(); clear_freqlist_for_ui_action();
@ -717,16 +635,9 @@ ReconView::ReconView(NavigationView& nav)
input_file = result[0]; input_file = result[0];
output_file = result[1]; output_file = result[1];
freq_file_path = get_freqman_path(output_file).string(); freq_file_path = get_freqman_path(output_file).string();
recon_save_config_to_sd();
autosave = persistent_memory::recon_autosave_freqs(); load_persisted_settings();
autostart = persistent_memory::recon_autostart_recon(); ui_settings.save();
filedelete = persistent_memory::recon_clear_output();
load_freqs = persistent_memory::recon_load_freqs();
load_ranges = persistent_memory::recon_load_ranges();
load_hamradios = persistent_memory::recon_load_hamradios();
update_ranges = persistent_memory::recon_update_ranges_when_recon();
auto_record_locked = persistent_memory::recon_auto_record_locked();
frequency_file_load(false); frequency_file_load(false);
freqlist_cleared_for_ui_action = false; freqlist_cleared_for_ui_action = false;
@ -774,7 +685,6 @@ ReconView::ReconView(NavigationView& nav)
file_name.set("=>"); file_name.set("=>");
// Loading input and output file from settings // Loading input and output file from settings
recon_load_config_from_sd();
freq_file_path = get_freqman_path(output_file).string(); freq_file_path = get_freqman_path(output_file).string();
field_recon_match_mode.set_selected_index(recon_match_mode); field_recon_match_mode.set_selected_index(recon_match_mode);

View File

@ -68,7 +68,7 @@ class ReconView : public View {
RxRadioState radio_state_{}; RxRadioState radio_state_{};
app_settings::SettingsManager settings_{ app_settings::SettingsManager settings_{
"rx_recon", app_settings::Mode::RX}; "rx_recon"sv, app_settings::Mode::RX};
void check_update_ranges_from_current(); void check_update_ranges_from_current();
void set_loop_config(bool v); void set_loop_config(bool v);
@ -90,8 +90,7 @@ class ReconView : public View {
void handle_retune(); void handle_retune();
void handle_coded_squelch(const uint32_t value); void handle_coded_squelch(const uint32_t value);
void handle_remove_current_item(); void handle_remove_current_item();
bool recon_load_config_from_sd(); void load_persisted_settings();
bool recon_save_config_to_sd();
bool recon_save_freq(const std::filesystem::path& path, size_t index, bool warn_if_exists); bool recon_save_freq(const std::filesystem::path& path, size_t index, bool warn_if_exists);
// placeholder for possible void recon_start_recording(); // placeholder for possible void recon_start_recording();
void recon_stop_recording(); void recon_stop_recording();
@ -164,6 +163,21 @@ class ReconView : public View {
systime_t chrono_start{}; systime_t chrono_start{};
systime_t chrono_end{}; systime_t chrono_end{};
// Persisted settings.
SettingsStore ui_settings{
"recon"sv,
{
{"input_file"sv, &input_file},
{"output_file"sv, &output_file},
{"lock_duration"sv, &recon_lock_duration},
{"lock_nb_match"sv, &recon_lock_nb_match},
{"squelch_level"sv, &squelch},
{"match_mode"sv, &recon_match_mode},
{"match_wait"sv, &wait},
{"range_min"sv, &frequency_range.min},
{"range_max"sv, &frequency_range.max},
}};
std::unique_ptr<RecordView> record_view{}; std::unique_ptr<RecordView> record_view{};
Labels labels{ Labels labels{

View File

@ -319,7 +319,6 @@ ScannerView::ScannerView(
field_step.set_by_value(receiver_model.frequency_step()); // Default step interval (Hz) field_step.set_by_value(receiver_model.frequency_step()); // Default step interval (Hz)
change_mode((freqman_index_t)field_mode.selected_index_value()); change_mode((freqman_index_t)field_mode.selected_index_value());
// FUTURE: perhaps additional settings should be stored in persistent memory vs using defaults
rf::Frequency stored_freq = receiver_model.target_frequency(); rf::Frequency stored_freq = receiver_model.target_frequency();
frequency_range.min = stored_freq - 1000000; frequency_range.min = stored_freq - 1000000;
button_manual_start.set_text(to_string_short_freq(frequency_range.min)); button_manual_start.set_text(to_string_short_freq(frequency_range.min));
@ -522,13 +521,17 @@ ScannerView::ScannerView(
// PRE-CONFIGURATION: // PRE-CONFIGURATION:
field_browse_wait.on_change = [this](int32_t v) { browse_wait = v; }; field_browse_wait.on_change = [this](int32_t v) { browse_wait = v; };
field_browse_wait.set_value(5); field_browse_wait.set_value(browse_wait);
field_lock_wait.on_change = [this](int32_t v) { lock_wait = v; }; field_lock_wait.on_change = [this](int32_t v) { lock_wait = v; };
field_lock_wait.set_value(2); field_lock_wait.set_value(lock_wait);
field_squelch.on_change = [this](int32_t v) { squelch = v; }; field_squelch.on_change = [this](int32_t v) { squelch = v; };
field_squelch.set_value(-30); field_squelch.set_value(squelch);
// Disable squelch on the model because RSSI handler is where the
// actual squelching is applied for this app.
receiver_model.set_squelch_level(0);
// LOAD FREQUENCIES // LOAD FREQUENCIES
frequency_file_load(default_scan_file); frequency_file_load(default_scan_file);
@ -726,9 +729,6 @@ void ScannerView::change_mode(freqman_index_t new_mod) {
void ScannerView::start_scan_thread() { void ScannerView::start_scan_thread() {
receiver_model.enable(); receiver_model.enable();
// Disable squelch on the model because RSSI handler is where the
// actual squelching is applied for this app.
receiver_model.set_squelch_level(0);
show_max_index(); show_max_index();
// Start Scanner Thread // Start Scanner Thread

View File

@ -111,8 +111,19 @@ class ScannerView : public View {
private: private:
RxRadioState radio_state_{}; RxRadioState radio_state_{};
// Settings
uint32_t browse_wait{5};
uint32_t lock_wait{2};
int32_t squelch{-30};
app_settings::SettingsManager settings_{ app_settings::SettingsManager settings_{
"rx_scanner", app_settings::Mode::RX}; "rx_scanner"sv,
app_settings::Mode::RX,
{
{"browse_wait"sv, &browse_wait},
{"lock_wait"sv, &lock_wait},
{"scanner_squelch"sv, &squelch},
}};
NavigationView& nav_; NavigationView& nav_;
@ -132,14 +143,11 @@ class ScannerView : public View {
std::string loaded_filename() const; std::string loaded_filename() const;
scanner_range_t frequency_range{0, 0}; scanner_range_t frequency_range{0, 0};
int32_t squelch{0};
uint32_t browse_timer{0}; uint32_t browse_timer{0};
uint32_t lock_timer{0}; uint32_t lock_timer{0};
uint32_t color_timer{0}; uint32_t color_timer{0};
int32_t bigdisplay_current_color{-2}; int32_t bigdisplay_current_color{-2};
rf::Frequency bigdisplay_current_frequency{0}; rf::Frequency bigdisplay_current_frequency{0};
uint32_t browse_wait{0};
uint32_t lock_wait{0};
std::filesystem::path loaded_path{}; std::filesystem::path loaded_path{};
std::vector<scanner_entry_t> entries{}; std::vector<scanner_entry_t> entries{};