# HG changeset patch # User Tom Hayward tom@tomh.us # Date 1333642041 21600 # Node ID 29d6d9465751b8b6047282ddea4e236d9e7efab7 # Parent dff9491d46eba6a3e50f17c63af21f7c65b8a424 Add import support for Kenwood *.hmk files. Feature #102
diff -r dff9491d46eb -r 29d6d9465751 chirp/kenwood_hmk.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/chirp/kenwood_hmk.py Thu Apr 05 10:07:21 2012 -0600 @@ -0,0 +1,121 @@ +# Copyright 2008 Dan Smith dsmith@danplanet.com +# Copyright 2012 Tom Haywward tom@tomh.us +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. + +import os +import csv + +from chirp import chirp_common, errors, directory, generic_csv + +class OmittedHeaderError(Exception): + pass + +@directory.register +class HMKRadio(generic_csv.CSVRadio): + VENDOR = "Kenwood" + MODEL = "HMK" + FILE_EXTENSION = "hmk" + + DUPLEX_MAP = { + " ": "", + "S": "split", + "+": "+", + "-": "-", + } + + SKIP_MAP = { + "Off": "", + "On": "S", + } + + TMODE_MAP = { + "Off": "", + "T": "Tone", + "CT": "TSQL", + "DCS": "DTCS", + "": "Cross", + } + + ATTR_MAP = { + "!!Ch" : (int, "number"), + "M.Name" : (str, "name"), + "Rx Freq." : (chirp_common.parse_freq, "freq"), + "Shift/Split" : (lambda v: HMKRadio.DUPLEX_MAP[v], "duplex"), + "Offset" : (chirp_common.parse_freq, "offset"), + "T/CT/DCS" : (lambda v: HMKRadio.TMODE_MAP[v], "tmode"), + "TO Freq." : (float, "rtone"), + "CT Freq." : (float, "ctone"), + "DCS Code" : (int, "dtcs"), + "Mode" : (str, "mode"), + "Rx Step" : (float, "tuning_step"), + "L.Out" : (lambda v: HMKRadio.SKIP_MAP[v], "skip"), + } + + def load(self, filename=None): + if filename is None and self._filename is None: + raise errors.RadioError("Need a location to load from") + + if filename: + self._filename = filename + + self._blank() + + f = file(self._filename, "r") + for line in f: + if line.strip() == "// Memory Channels": + break + + reader = csv.reader(f, delimiter=chirp_common.SEPCHAR, quotechar='"') + + good = 0 + lineno = 0 + for line in reader: + lineno += 1 + if lineno == 1: + header = line + continue + + if len(header) > len(line): + print "Line %i has %i columns, expected %i" % (lineno, + len(line), + len(header)) + self.errors.append("Column number mismatch on line %i" % lineno) + continue + + # hmk stores Tx Freq. in its own field, but Chirp expects the Tx + # Freq. for odd-split channels to be in the Offset field. + # If channel is odd-split, copy Tx Freq. field to Offset field. + if line[header.index('Shift/Split')] == "S": + line[header.index('Offset')] = line[header.index('Tx Freq.')] + + # fix EU decimal + line = [i.replace(',','.') for i in line] + + try: + mem = self._parse_csv_data_line(header, line) + if mem.number is None: + raise Exception("Invalid Location field" % lineno) + except Exception, e: + print "Line %i: %s" % (lineno, e) + self.errors.append("Line %i: %s" % (lineno, e)) + continue + + self._grow(mem.number) + self.memories[mem.number] = mem + good += 1 + + if not good: + print self.errors + raise errors.InvalidDataError("No channels found") diff -r dff9491d46eb -r 29d6d9465751 chirpui/mainapp.py --- a/chirpui/mainapp.py Thu Apr 05 10:07:13 2012 -0600 +++ b/chirpui/mainapp.py Thu Apr 05 10:07:21 2012 -0600 @@ -667,6 +667,7 @@ (_("CSV Files") + " (*.csv)", "*.csv"), (_("EVE Files (VX5)") + " (*.eve)", "*.eve"), (_("ICF Files") + " (*.icf)", "*.icf"), + (_("Kenwood HMK Files") + " (*.hmk)", "*.hmk"), (_("VX5 Commander Files") + " (*.vx5)", "*.vx5"), (_("VX7 Commander Files") + " (*.vx7)", "*.vx7")] filen = platform.get_platform().gui_open_file(types=types)