[chirp_devel] [PATCH 2 of 3] [csv] Add support for reading CSV generated by RT Systems software. #477

Tom Hayward
Sat Feb 9 12:44:56 PST 2013


# HG changeset patch
# User Tom Hayward <tom at tomh.us>
# Date 1360440250 28800
# Node ID 26774d27b348c139a013114d3588173617d3ad1d
# Parent  f501ac229f9b1be1c24dab889b75ac40f27efd16
[csv] Add support for reading CSV generated by RT Systems software. #477

diff -r f501ac229f9b -r 26774d27b348 chirp/chirp_common.py
--- a/chirp/chirp_common.py	Sat Feb 09 11:45:20 2013 -0800
+++ b/chirp/chirp_common.py	Sat Feb 09 12:04:10 2013 -0800
@@ -185,6 +185,13 @@
 
 def parse_freq(freqstr):
     """Parse a frequency string and return the value in integral Hz"""
+    if freqstr == " ":
+        return 0
+    elif freqstr.endswith(" MHz"):
+        return parse_freq(freqstr.split(" ")[0])
+    elif freqstr.endswith(" kHz"):
+        return int(freqstr.split(" ")[0]) * 1000
+
     if "." in freqstr:
         mhz, khz = freqstr.split(".")
     else:
diff -r f501ac229f9b -r 26774d27b348 chirp/generic_csv.py
--- a/chirp/generic_csv.py	Sat Feb 09 11:45:20 2013 -0800
+++ b/chirp/generic_csv.py	Sat Feb 09 12:04:10 2013 -0800
@@ -255,6 +255,93 @@
             ",".join(self.memories[number].to_csv())
 
     @classmethod
-    def match_model(cls, _filedata, filename):
+    def match_model(cls, filedata, filename):
         """Match files ending in .CSV"""
-        return filename.lower().endswith("." + cls.FILE_EXTENSION)
+        return filename.lower().endswith("." + cls.FILE_EXTENSION) and \
+            (filedata.startswith("Location,") or filedata == "")
+
+
+ at directory.register
+class RTCSVRadio(CSVRadio):
+    """A driver for reading CSV files generated by RT Systems software"""
+    VENDOR = "RT Systems"
+    MODEL = "CSV"
+    FILE_EXTENSION = "csv"
+
+    DUPLEX_MAP = {
+        "Minus":    "-",
+        "Plus":     "+",
+        "Simplex":  "",
+        "Split":    "split",
+    }
+    
+    SKIP_MAP = {
+        "Off":    "",
+        "On":     "S",
+        "P Scan": "P",
+        "Skip":   "S",
+        }
+
+    TMODE_MAP = {
+        "None":     "",
+        "T Sql":    "TSQL",
+    }
+
+    BOOL_MAP = {
+        "Off":  False,
+        "On":   True,
+    }
+
+    ATTR_MAP = {
+        "Channel Number":   (int,   "number"),
+        "Receive Frequency":(chirp_common.parse_freq, "freq"),
+        "Offset Frequency": (chirp_common.parse_freq, "offset"),
+        "Offset Direction": (lambda v: RTCSVRadio.DUPLEX_MAP.get(v, v), "duplex"),
+        "Operating Mode":   (str,   "mode"),
+        "Name":             (str,   "name"),
+        "Tone Mode":        (lambda v: RTCSVRadio.TMODE_MAP.get(v, v), "tmode"),
+        "CTCSS":            (lambda v: float(v.split(" ")[0]), "rtone"),
+        "DCS":              (int,   "dtcs"),
+        "Skip":             (lambda v: RTCSVRadio.SKIP_MAP.get(v, v), "skip"),
+        "Step":             (lambda v: float(v.split(" ")[0]), "tuning_step"),
+        "Mask":             (lambda v: RTCSVRadio.BOOL_MAP.get(v, v), "empty",),
+        "Comment":          (str,   "comment"),
+        }
+
+    def _clean_duplex(self, headers, line, mem):
+        if mem.duplex == "split":
+            try:
+                val = get_datum_by_header(headers, line, "Transmit Frequency")
+                val = chirp_common.parse_freq(val)
+                mem.offset = val
+            except OmittedHeaderError:
+                pass
+
+        return mem
+
+    def _clean_mode(self, headers, line, mem):
+        if mem.mode == "FM":
+            try:
+                val = get_datum_by_header(headers, line, "Half Dev")
+                if self.BOOL_MAP[val]:
+                    mem.mode = "FMN"
+            except OmittedHeaderError:
+                pass
+
+        return mem
+
+    def _clean_ctone(self, headers, line, mem):
+        # RT Systems only stores a single tone value
+        mem.ctone = mem.rtone
+        return mem
+
+    @classmethod
+    def match_model(cls, filedata, filename):
+        """Match files ending in .csv and using RT Systems column names."""
+        # RT Systems provides a different set of columns for each radio.
+        # We attempt to match only the first few columns, hoping they are
+        # consistent across radio models.
+        return filename.lower().endswith("." + cls.FILE_EXTENSION) and \
+            filedata.startswith("Channel Number,Receive Frequency,"
+                "Transmit Frequency,Offset Frequency,Offset Direction,"
+                "Operating Mode,Name,Tone Mode,CTCSS,DCS")



More information about the chirp_devel mailing list