From 43f6ad60dc3128e2b2090aeebd50bc66fc6c63ac Mon Sep 17 00:00:00 2001 From: Dan Smith Date: Mon, 9 Sep 2024 18:38:40 -0700 Subject: [PATCH] Prioritize radio-supplied tuning steps This makes the UI consider the radio's tuning steps, if defined as the first course of action. The existing code tried the standard set followed by the radio's set, assuming the radio's would be a subset, which is of course not always true. This also makes required_step() consider the radio-specific steps after the standard ones, if there are any strange ones to allow the radio to define ones that are not in the standard list. Related to #10968 --- chirp/chirp_common.py | 17 ++++++++++++++++- chirp/wxui/memedit.py | 14 ++++---------- tests/unit/test_chirp_common.py | 5 +++++ 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/chirp/chirp_common.py b/chirp/chirp_common.py index 3ec4f371..49a21988 100644 --- a/chirp/chirp_common.py +++ b/chirp/chirp_common.py @@ -814,6 +814,10 @@ def LIST(v): assert hasattr(v, '__iter__') +def LIST_NONZERO_INT(v): + assert all(x > 0 for x in v) + + def INT(min=0, max=None): def checkint(v): assert isinstance(v, int) @@ -865,7 +869,7 @@ class RadioFeatures: "valid_modes": LIST, "valid_tmodes": LIST, "valid_duplexes": LIST, - "valid_tuning_steps": LIST, + "valid_tuning_steps": LIST_NONZERO_INT, "valid_bands": LIST, "valid_skips": LIST, "valid_power_levels": LIST, @@ -1736,10 +1740,21 @@ def required_step(freq, allowed=None): 8.33: is_8_33, } + # Try the above "standard" steps first in order for step, validate in steps.items(): if step in allowed and validate(freq): return step + # Try any additional steps in the allowed list + for step in allowed: + if step in steps: + # Already tried + continue + if make_is(int(step * 1000))(freq): + LOG.debug('Chose non-standard step %s for %s' % ( + step, format_freq(freq))) + return step + raise errors.InvalidDataError("Unable to find a supported " + "tuning step for %s" % format_freq(freq)) diff --git a/chirp/wxui/memedit.py b/chirp/wxui/memedit.py index fcebc0da..50503a10 100644 --- a/chirp/wxui/memedit.py +++ b/chirp/wxui/memedit.py @@ -1337,18 +1337,12 @@ class ChirpMemEdit(common.ChirpEditor, common.ChirpSyncEditor): else: want_tuning_step = 5.0 try: - # First calculate the needed step in case it is not supported - # by the radio. If we fail to find one the radio supports, - # we will use this one and then the error message about it - # being unsupported will be accurate. - want_tuning_step = chirp_common.required_step(mem.freq) - - # Now try to find a suitable one that the radio supports. + # Try to find a tuning step for the frequency that the radio + # supports, or with the default set want_tuning_step = chirp_common.required_step( - mem.freq, features.valid_tuning_steps) - LOG.debug('Chose radio-supported step %s' % want_tuning_step) + mem.freq, features.valid_tuning_steps or None) except errors.InvalidDataError as e: - LOG.warning(e) + LOG.warning('Failed to find step: %s' % e) if 'tuning_step' in only and want_tuning_step: mem.tuning_step = want_tuning_step diff --git a/tests/unit/test_chirp_common.py b/tests/unit/test_chirp_common.py index 458a1268..92f062f4 100644 --- a/tests/unit/test_chirp_common.py +++ b/tests/unit/test_chirp_common.py @@ -503,6 +503,11 @@ class TestStepFunctions(base.BaseTest): self.assertEqual(2.5, chirp_common.required_step(self._005[0], allowed=[2.5])) + def test_required_step_finds_radio_specific(self): + # Make sure we find a radio-specific step, 10Hz in this case + self.assertEqual(0.01, chirp_common.required_step( + 146000010, allowed=[5.0, 10.0, 0.01, 20.0])) + def test_required_step_fail(self): self.assertRaises(errors.InvalidDataError, chirp_common.required_step,