[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