Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package chirp for openSUSE:Factory checked 
in at 2026-09-10 11:48:52
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/chirp (Old)
 and      /work/SRC/openSUSE:Factory/.chirp.new.1265 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "chirp"

Thu Sep 10 11:48:52 2026 rev:78 rq:1376752 version:20260904

Changes:
--------
--- /work/SRC/openSUSE:Factory/chirp/chirp.changes      2026-08-21 
22:17:46.880926295 +0200
+++ /work/SRC/openSUSE:Factory/.chirp.new.1265/chirp.changes    2026-09-10 
11:51:54.641897587 +0200
@@ -1,0 +2,8 @@
+Wed Sep 09 19:37:20 UTC 2026 - Andreas Stieger <[email protected]>
+
+- Update to version 20260904:
+  * Fix RB28/RB628 tone and DTCS index mapping
+  * Retevis RB28/RB628: Fix Busy Channel Lockout display
+  * various bug fixes
+
+-------------------------------------------------------------------

Old:
----
  chirp-20260821.obscpio

New:
----
  chirp-20260904.obscpio

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ chirp.spec ++++++
--- /var/tmp/diff_new_pack.PB4ahm/_old  2026-09-10 11:51:56.358969599 +0200
+++ /var/tmp/diff_new_pack.PB4ahm/_new  2026-09-10 11:51:56.363969809 +0200
@@ -20,7 +20,7 @@
 
 %define pythons python3
 Name:           chirp
-Version:        20260821
+Version:        20260904
 Release:        0
 Summary:        Tool for programming amateur radio sets
 License:        GPL-3.0-only

++++++ _service ++++++
--- /var/tmp/diff_new_pack.PB4ahm/_old  2026-09-10 11:51:56.433972745 +0200
+++ /var/tmp/diff_new_pack.PB4ahm/_new  2026-09-10 11:51:56.442973122 +0200
@@ -4,8 +4,8 @@
     <param name="scm">git</param>
     <param name="changesgenerate">enable</param>
     <param name="filename">chirp</param>
-    <param name="versionformat">20260821</param>
-    <param name="revision">fa27a491d275f88b452d0488a51b4c85d4f7062a</param>
+    <param name="versionformat">20260904</param>
+    <param name="revision">3af0eda7d60f6a79120097c4f3caccb6bb2d74dd</param>
   </service>
   <service mode="manual" name="set_version"/>
   <service name="tar" mode="buildtime"/>

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.PB4ahm/_old  2026-09-10 11:51:56.505975765 +0200
+++ /var/tmp/diff_new_pack.PB4ahm/_new  2026-09-10 11:51:56.513976100 +0200
@@ -1,7 +1,7 @@
 <servicedata>
   <service name="tar_scm">
     <param name="url">https://github.com/kk7ds/chirp.git</param>
-    <param 
name="changesrevision">fa27a491d275f88b452d0488a51b4c85d4f7062a</param>
+    <param 
name="changesrevision">3af0eda7d60f6a79120097c4f3caccb6bb2d74dd</param>
   </service>
 </servicedata>
 (No newline at EOF)

++++++ chirp-20260821.obscpio -> chirp-20260904.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/chirp-20260821/chirp/drivers/ft4.py 
new/chirp-20260904/chirp/drivers/ft4.py
--- old/chirp-20260821/chirp/drivers/ft4.py     2026-08-19 02:25:46.000000000 
+0200
+++ new/chirp-20260904/chirp/drivers/ft4.py     2026-08-30 20:43:53.000000000 
+0200
@@ -280,14 +280,9 @@
         if not response:
             if cmd == PROGRAM_CMD:
                 raise errors.RadioNoResponse()
-            raise errors.RadioError("No response from radio")
-        if len(response) != response_len:
-            raise errors.RadioError("Incomplete response from radio")
     else:
         response = b""
     ack = pipe.read(1)
-    if not ack:
-        raise errors.RadioError("No response from radio")
     if ack != b'\x06':
         if retry < 5:
             LOG.debug("retry: " + str(retry))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/chirp-20260821/chirp/drivers/kenwood_live.py 
new/chirp-20260904/chirp/drivers/kenwood_live.py
--- old/chirp-20260821/chirp/drivers/kenwood_live.py    2026-08-19 
02:25:46.000000000 +0200
+++ new/chirp-20260904/chirp/drivers/kenwood_live.py    2026-08-30 
20:43:53.000000000 +0200
@@ -410,6 +410,8 @@
         rf.valid_tuning_steps = STEPS
         rf.has_sub_devices = True
         rf.memory_bounds = (1, self._upper)
+        rf.valid_bands = [(144000000, 148000000),
+                          (420000000, 450000000)]
         return rf
 
     def _make_mem_spec(self, mem):
@@ -502,7 +504,7 @@
     MODEL = "TM-G707"
 
     def get_features(self):
-        rf = TMV7Radio.get_features(self)
+        rf = super().get_features()
         rf.has_sub_devices = False
         rf.memory_bounds = (1, 180)
         rf.valid_bands = [(118000000, 174000000),
@@ -520,7 +522,7 @@
     MODEL = "TH-G71"
 
     def get_features(self):
-        rf = TMV7Radio.get_features(self)
+        rf = super().get_features()
         rf.has_tuning_step = True
         rf.valid_tuning_steps = list(THG71_STEPS)
         rf.valid_name_length = 6
@@ -1051,9 +1053,59 @@
     """Kenwood TH-K2"""
     MODEL = "TH-K2"
     HARDWARE_FLOW = False
+    _probe_memory = 99
 
     _kenwood_valid_tones = list(KENWOOD_TONES)
 
+    def __init__(self, *a, **k):
+        self._has_name = True
+        super().__init__(*a, **k)
+        if self.pipe:
+            self._probe_layout()
+
+    def _probe_layout(self):
+        """Determine if the radio is in 100+alpha or 200 channel mode"""
+        rf = self.get_features()
+        wasempty = None
+        try:
+            LOG.debug('Getting memory %i', self._probe_memory)
+            m = self.get_memory(self._probe_memory)
+            wasempty = m.empty
+            if wasempty:
+                m.freq = rf.valid_bands[0][0]
+                m.empty = False
+                LOG.debug('Memory %i was empty using %s to probe',
+                          self._probe_memory, m)
+            else:
+                LOG.debug('Memory %i was set: %s', self._probe_memory, m)
+            # This either sets the probe memory over itself, or creates one
+            # at the lower limit frequency. Note that in order for this to
+            # work, we need _has_name=True here so that we can detect if we
+            # failed to set the memory (because 199 is out of range) or the
+            # memory name (because 199 is in range, but names are not
+            # supported).
+            self.set_memory(m)
+            LOG.error('Unexpectedly successful at setting probe memory %s', m)
+        except errors.InvalidDataError as e:
+            LOG.debug('Probe response was %s', e)
+            if 'name' in str(e):
+                # Radio is configured for max channels, refused the name
+                self._has_name = False
+                LOG.info('Radio determined to be in max-channel mode')
+            else:
+                # Radio is configured for alpha channels, as it refused the
+                # whole thing
+                self._has_name = True
+                LOG.info('Radio determined to be in channel+alpha mode')
+        finally:
+            if wasempty:
+                LOG.debug('Erasing probe memory %s', m)
+                # This needs to do the raw command because of the memory
+                # caching in set_memory()
+                self.command(self.pipe, *self._cmd_set_memory(
+                    self._probe_memory, ""))
+            LOG.debug('Done probing layout')
+
     def get_features(self):
         rf = chirp_common.RadioFeatures()
         rf.can_odd_split = False
@@ -1068,7 +1120,7 @@
         rf.valid_bands = [(136000000, 173990000)]
         rf.valid_skips = ["", "S"]
         rf.valid_tuning_steps = [5.0]
-        rf.memory_bounds = (0, 49)
+        rf.memory_bounds = (0, 49 if self._has_name else 99)
         return rf
 
     def _cmd_get_memory(self, number):
@@ -1139,6 +1191,7 @@
 class TM271Radio(THK2Radio):
     """Kenwood TM-271"""
     MODEL = "TM-271"
+    _probe_memory = 199
 
     def get_features(self):
         rf = chirp_common.RadioFeatures()
@@ -1146,6 +1199,7 @@
         rf.has_dtcs_polarity = False
         rf.has_bank = False
         rf.has_tuning_step = False
+        rf.has_name = self._has_name
         rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS"]
         rf.valid_modes = THK2_MODES
         rf.valid_duplexes = THK2_DUPLEX
@@ -1154,7 +1208,7 @@
         rf.valid_bands = [(137000000, 173990000)]
         rf.valid_skips = ["", "S"]
         rf.valid_tuning_steps = list(TM271_STEPS)
-        rf.memory_bounds = (0, 99)
+        rf.memory_bounds = (0, 99 if self._has_name else 199)
         return rf
 
     def _cmd_get_memory(self, number):
@@ -1178,25 +1232,13 @@
 
 
 @directory.register
-class TM471Radio(THK2Radio):
+class TM471Radio(TM271Radio):
     """Kenwood TM-471"""
     MODEL = "TM-471"
 
     def get_features(self):
-        rf = chirp_common.RadioFeatures()
-        rf.can_odd_split = False
-        rf.has_dtcs_polarity = False
-        rf.has_bank = False
-        rf.has_tuning_step = False
-        rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS"]
-        rf.valid_modes = THK2_MODES
-        rf.valid_duplexes = THK2_DUPLEX
-        rf.valid_characters = THK2_CHARS
-        rf.valid_name_length = 6
+        rf = super().get_features()
         rf.valid_bands = [(444000000, 479990000)]
-        rf.valid_skips = ["", "S"]
-        rf.valid_tuning_steps = [5.0]
-        rf.memory_bounds = (0, 99)
         return rf
 
     def _cmd_get_memory(self, number):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/chirp-20260821/chirp/drivers/retevis_rb28.py 
new/chirp-20260904/chirp/drivers/retevis_rb28.py
--- old/chirp-20260821/chirp/drivers/retevis_rb28.py    2026-08-19 
02:25:46.000000000 +0200
+++ new/chirp-20260904/chirp/drivers/retevis_rb28.py    2026-08-30 
20:43:53.000000000 +0200
@@ -140,17 +140,23 @@
 VOXD_LIST = ["0.5", "1.0", "1.5", "2.0", "2.5", "3.0"]
 VOXL_LIST = ["OFF"] + ["%s" % x for x in range(1, 10)]
 
-PMR_TONES = tuple(
-    set(chirp_common.TONES) - set([69.3, 159.8, 165.5, 171.3, 177.3,
-                                   183.5, 189.9, 196.6, 199.5, 206.5,
-                                   229.1, 254.1]))
-
-PMR_DTCS_CODES = tuple(
-    set(chirp_common.DTCS_CODES) - set([36,  53, 122, 145, 212,
-                                        225, 246, 252, 255, 266,
-                                        274, 325, 332, 356, 446,
-                                        452, 454, 455, 462, 523,
-                                        526]))
+# Sort to preserve chirp_common ordering because these tuples are used for
+# positional tone/DTCS index mapping when decoding the radio image.
+PMR_TONES = tuple(sorted(
+    set(chirp_common.TONES) - set([
+        69.3, 159.8, 165.5, 171.3, 177.3,
+        183.5, 189.9, 196.6, 199.5, 206.5,
+        229.1, 254.1
+    ])
+))
+
+PMR_DTCS_CODES = tuple(sorted(
+    set(chirp_common.DTCS_CODES) - set([
+        36, 53, 122, 145, 212, 225, 246, 252, 255,
+        266, 274, 325, 332, 356, 446, 452, 454, 455,
+        462, 523, 526
+    ])
+))
 
 
 def _enter_programming_mode(radio):
@@ -464,8 +470,9 @@
         mem.extra.append(rset)
 
         _obj = self._memobj.bclo
-        key = "chnl_%i" % (mem.number)
-        rs = RadioSettingValueBoolean(getattr(_obj, "chnl_%i" % (mem.number)))
+        key = "bclo"
+        rs = RadioSettingValueBoolean(
+            getattr(_obj, "chnl_%i" % mem.number))
         rset = RadioSetting(key, "Busy Channel Lockout", rs)
         mem.extra.append(rset)
 
@@ -575,8 +582,9 @@
         _mem.highpower = mem.power == self.POWER_LEVELS[0]
 
         for setting in mem.extra:
-            if setting.get_name().startswith("chnl_"):
-                setattr(self._memobj.bclo, setting.get_name(), setting.value)
+            if setting.get_name() == "bclo":
+                setattr(self._memobj.bclo,
+                        "chnl_%i" % mem.number, setting.value)
             else:
                 setattr(_mem, setting.get_name(), setting.value)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/chirp-20260821/chirp/wxui/bugreport.py 
new/chirp-20260904/chirp/wxui/bugreport.py
--- old/chirp-20260821/chirp/wxui/bugreport.py  2026-08-19 02:25:46.000000000 
+0200
+++ new/chirp-20260904/chirp/wxui/bugreport.py  2026-08-30 20:43:53.000000000 
+0200
@@ -41,6 +41,7 @@
 CONF = config.get()
 BASE = (CONF.get('baseurl', 'chirpmyradio') or
         'https://data.chirpmyradio.com/redmine')
+USER_BASE = 'https://chirpmyradio.com'
 LOG = logging.getLogger(__name__)
 ReportThreadEvent, EVT_REPORT_THREAD = wx.lib.newevent.NewCommandEvent()
 
@@ -252,8 +253,8 @@
     def _build(self, vbox):
         vbox.Add(
             wx.adv.HyperlinkCtrl(
-                self, label=BASE + '/account/register',
-                url=BASE + '/account/register'),
+                self, label=USER_BASE + '/account/register',
+                url=USER_BASE + '/account/register'),
             0, border=20, flag=wx.ALIGN_CENTER)
 
         panel = wx.Panel(self)
@@ -418,9 +419,10 @@
             wx.adv.HyperlinkCtrl(
                 panel,
                 label=_('searched for duplicate issues'),
-                url=BASE + ('/projects/chirp/search?utf8=%E2%9C%93&'
-                            'q=&scope=&all_words=&all_words=1&titles_only=&'
-                            'issues=1&attachments=0&options=0&commit=Search')),
+                url=USER_BASE + (
+                    '/projects/chirp/search?utf8=%E2%9C%93&'
+                    'q=&scope=&all_words=&all_words=1&titles_only=&'
+                    'issues=1&attachments=0&options=0&commit=Search')),
             0)
         hbox.AddStretchSpacer(1)
 
@@ -591,7 +593,7 @@
                                     style=wx.TE_CENTER)
         vbox.Add(self.result, 0, border=20, flag=wx.EXPAND | wx.ALL)
 
-        self.issuelink = wx.adv.HyperlinkCtrl(self, url=BASE)
+        self.issuelink = wx.adv.HyperlinkCtrl(self, url=USER_BASE)
         self.issuelink.Hide()
         vbox.Add(self.issuelink, 0, border=20, flag=wx.EXPAND | wx.ALL)
 
@@ -731,7 +733,7 @@
             self.result.SetLabel(
                 _('Successfully sent bug report:'))
             self.FindWindowById(wx.ID_BACKWARD).Enable(False)
-            link = BASE + '/issues/%s' % self.context.bugnum
+            link = USER_BASE + '/issues/%s' % self.context.bugnum
             self.issuelink.SetLabel(link)
             self.issuelink.SetURL(link)
             self.issuelink.Show()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/chirp-20260821/chirp/wxui/common.py 
new/chirp-20260904/chirp/wxui/common.py
--- old/chirp-20260821/chirp/wxui/common.py     2026-08-19 02:25:46.000000000 
+0200
+++ new/chirp-20260904/chirp/wxui/common.py     2026-08-30 20:43:53.000000000 
+0200
@@ -40,6 +40,26 @@
 LOG = logging.getLogger(__name__)
 CONF = config.get()
 
+
+def pg_action_edit():
+    # wxPython >= 4.3 replaced the PG_ACTION_* integer constants with
+    # the PGKeyboardAction enum. Look this up lazily (i.e. not at
+    # module import time) since by the time a settings grid is
+    # actually built, something will have already imported
+    # wx.propgrid for real; doing it ourselves at import time with an
+    # explicit `import wx.propgrid` breaks tests that stub out `wx`
+    # wholesale with a Mock.
+    if hasattr(wx.propgrid, 'PG_ACTION_EDIT'):
+        return wx.propgrid.PG_ACTION_EDIT
+    return wx.propgrid.PGKeyboardAction.Edit
+
+
+def pg_action_next_property():
+    if hasattr(wx.propgrid, 'PG_ACTION_NEXT_PROPERTY'):
+        return wx.propgrid.PG_ACTION_NEXT_PROPERTY
+    return wx.propgrid.PGKeyboardAction.NextProperty
+
+
 CHIRP_DATA_MEMORY = wx.DataFormat('x-chirp/memory-channel')
 EditorChanged, EVT_EDITOR_CHANGED = wx.lib.newevent.NewCommandEvent()
 StatusMessage, EVT_STATUS_MESSAGE = wx.lib.newevent.NewCommandEvent()
@@ -403,8 +423,8 @@
         self.pg.DedicateKey(wx.WXK_RETURN)
         self.pg.DedicateKey(wx.WXK_UP)
         self.pg.DedicateKey(wx.WXK_DOWN)
-        self.pg.AddActionTrigger(wx.propgrid.PG_ACTION_EDIT, wx.WXK_RETURN)
-        self.pg.AddActionTrigger(wx.propgrid.PG_ACTION_NEXT_PROPERTY,
+        self.pg.AddActionTrigger(pg_action_edit(), wx.WXK_RETURN)
+        self.pg.AddActionTrigger(pg_action_next_property(),
                                  wx.WXK_RETURN)
 
         sizer = wx.BoxSizer(wx.VERTICAL)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/chirp-20260821/chirp/wxui/memedit.py 
new/chirp-20260904/chirp/wxui/memedit.py
--- old/chirp-20260821/chirp/wxui/memedit.py    2026-08-19 02:25:46.000000000 
+0200
+++ new/chirp-20260904/chirp/wxui/memedit.py    2026-08-30 20:43:53.000000000 
+0200
@@ -2918,8 +2918,8 @@
         self._pg.DedicateKey(wx.WXK_RETURN)
         self._pg.DedicateKey(wx.WXK_UP)
         self._pg.DedicateKey(wx.WXK_DOWN)
-        self._pg.AddActionTrigger(wx.propgrid.PG_ACTION_EDIT, wx.WXK_RETURN)
-        self._pg.AddActionTrigger(wx.propgrid.PG_ACTION_NEXT_PROPERTY,
+        self._pg.AddActionTrigger(common.pg_action_edit(), wx.WXK_RETURN)
+        self._pg.AddActionTrigger(common.pg_action_next_property(),
                                   wx.WXK_RETURN)
 
         self._tabs.InsertPage(0, self._pg, _('Values'))

++++++ chirp.obsinfo ++++++
--- /var/tmp/diff_new_pack.PB4ahm/_old  2026-09-10 11:51:58.194046561 +0200
+++ /var/tmp/diff_new_pack.PB4ahm/_new  2026-09-10 11:51:58.198046728 +0200
@@ -1,5 +1,5 @@
 name: chirp
-version: 20260821
-mtime: 1787099146
-commit: fa27a491d275f88b452d0488a51b4c85d4f7062a
+version: 20260904
+mtime: 1788115433
+commit: 3af0eda7d60f6a79120097c4f3caccb6bb2d74dd
 

Reply via email to