Developers
Threads by month
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
June 2017
- 17 participants
- 28 discussions
[chirp_devel] [PATCH] Support pySerial 3+. Fixes #3167 #3209 #3521 #3671 #3703
by Tom Hayward 03 Feb '18
by Tom Hayward 03 Feb '18
03 Feb '18
# HG changeset patch
# User Tom Hayward <tom(a)tomh.us>
# Date 1465361362 25200
# Tue Jun 07 21:49:22 2016 -0700
# Node ID d1bc2c9177858ff87c86e08447513f53794c2868
# Parent 333a280ca0c4e856258ebf9dfdb7c547fa9ec90c
Support pySerial 3+. Fixes #3167 #3209 #3521 #3671 #3703
diff -r 333a280ca0c4 -r d1bc2c917785 chirp/detect.py
--- a/chirp/detect.py Wed Jun 01 17:30:31 2016 -0700
+++ b/chirp/detect.py Tue Jun 07 21:49:22 2016 -0700
@@ -39,7 +39,7 @@
# ICOM VHF/UHF Clone-type radios @ 9600 baud
try:
- ser.setBaudrate(9600)
+ ser.baudrate = 9600
md = icf.get_model_data(ser)
return _icom_model_data_to_rclass(md)
except errors.RadioError, e:
@@ -47,7 +47,7 @@
# ICOM IC-91/92 Live-mode radios @ 4800/38400 baud
- ser.setBaudrate(4800)
+ ser.baudrate = 4800
try:
ic9x_ll.send_magic(ser)
return _icom_model_data_to_rclass("ic9x")
@@ -58,7 +58,7 @@
for rate in [9600, 4800, 19200]:
try:
- ser.setBaudrate(rate)
+ ser.baudrate = rate
return icomciv.probe_model(ser)
except errors.RadioError:
pass
diff -r 333a280ca0c4 -r d1bc2c917785 chirp/drivers/btech.py
--- a/chirp/drivers/btech.py Wed Jun 01 17:30:31 2016 -0700
+++ b/chirp/drivers/btech.py Tue Jun 07 21:49:22 2016 -0700
@@ -332,7 +332,7 @@
# touching the serial timeout to optimize the flushing
# restored at the end to the default value
- radio.pipe.setTimeout(0.1)
+ radio.pipe.timeout = 0.1
dump = "1"
datacount = 0
@@ -347,7 +347,7 @@
raise errors.RadioError(seriale)
# restore the default serial timeout
- radio.pipe.setTimeout(STIMEOUT)
+ radio.pipe.timeout = STIMEOUT
except Exception:
raise errors.RadioError("Unknown error cleaning the serial buffer")
@@ -477,8 +477,8 @@
def _do_ident(radio, status, upload=False):
"""Put the radio in PROGRAM mode & identify it"""
# set the serial discipline
- radio.pipe.setBaudrate(9600)
- radio.pipe.setParity("N")
+ radio.pipe.baudrate = 9600
+ radio.pipe.parity = "N"
# open the radio into program mode
if _start_clone_mode(radio, status) is False:
@@ -516,7 +516,7 @@
# has the check value in the _id2 var, others simply False
if radio._id2 is not False:
# lower the timeout here as this radios are reseting due to timeout
- radio.pipe.setTimeout(0.05)
+ radio.pipe.timeout = 0.05
# query & receive the extra ID
_send(radio, _make_frame("S", 0x3DF0, 16))
@@ -561,7 +561,7 @@
raise errors.RadioError("Radio didn't ACK the upload")
# restore the default serial timeout
- radio.pipe.setTimeout(STIMEOUT)
+ radio.pipe.timeout = STIMEOUT
# DEBUG
LOG.info("Positive ident, this is a %s %s" % (radio.VENDOR, radio.MODEL))
diff -r 333a280ca0c4 -r d1bc2c917785 chirp/drivers/ft2800.py
--- a/chirp/drivers/ft2800.py Wed Jun 01 17:30:31 2016 -0700
+++ b/chirp/drivers/ft2800.py Tue Jun 07 21:49:22 2016 -0700
@@ -195,7 +195,7 @@
return rf
def sync_in(self):
- self.pipe.setParity("E")
+ self.pipe.parity = "E"
start = time.time()
try:
self._mmap = _download(self)
@@ -208,7 +208,7 @@
def sync_out(self):
self.pipe.timeout = 1
- self.pipe.setParity("E")
+ self.pipe.parity = "E"
start = time.time()
try:
_upload(self)
diff -r 333a280ca0c4 -r d1bc2c917785 chirp/drivers/ic9x_ll.py
--- a/chirp/drivers/ic9x_ll.py Wed Jun 01 17:30:31 2016 -0700
+++ b/chirp/drivers/ic9x_ll.py Tue Jun 07 21:49:22 2016 -0700
@@ -439,31 +439,31 @@
def send_magic(pipe):
"""Send the magic incantation to wake up an ic9x radio"""
- if pipe.getBaudrate() == 38400:
+ if pipe.baudrate == 38400:
resp = _send_magic_38400(pipe)
if resp:
return
LOG.info("Switching from 38400 to 4800")
- pipe.setBaudrate(4800)
+ pipe.baudrate = 4800
resp = _send_magic_4800(pipe)
- pipe.setBaudrate(38400)
+ pipe.baudrate = 38400
if resp:
return
raise errors.RadioError("Radio not responding")
- elif pipe.getBaudrate() == 4800:
+ elif pipe.baudrate == 4800:
resp = _send_magic_4800(pipe)
if resp:
return
LOG.info("Switching from 4800 to 38400")
- pipe.setBaudrate(38400)
+ pipe.baudrate = 38400
resp = _send_magic_38400(pipe)
if resp:
return
- pipe.setBaudrate(4800)
+ pipe.baudrate = 4800
raise errors.RadioError("Radio not responding")
else:
raise errors.InvalidDataError("Radio in unknown state (%i)" %
- pipe.getBaudrate())
+ pipe.baudrate)
def get_memory_frame(pipe, vfo, number):
diff -r 333a280ca0c4 -r d1bc2c917785 chirp/drivers/icf.py
--- a/chirp/drivers/icf.py Wed Jun 01 17:30:31 2016 -0700
+++ b/chirp/drivers/icf.py Tue Jun 07 21:49:22 2016 -0700
@@ -251,7 +251,7 @@
LOG.debug("Response:\n%s" % util.hexprint(resp))
LOG.info("Switching to 38400 baud")
- radio.pipe.setBaudrate(38400)
+ radio.pipe.baudrate = 38400
buf = ("\xFE" * 14) + \
"\xEE\xEF" + \
diff -r 333a280ca0c4 -r d1bc2c917785 chirp/drivers/kenwood_live.py
--- a/chirp/drivers/kenwood_live.py Wed Jun 01 17:30:31 2016 -0700
+++ b/chirp/drivers/kenwood_live.py Tue Jun 07 21:49:22 2016 -0700
@@ -103,7 +103,7 @@
LAST_DELIMITER = delimiter
LOG.info("Trying ID at baud %i with delimiter \"%s\"" %
(i, repr(delimiter)))
- ser.setBaudrate(i)
+ ser.baudrate = i
ser.write(LAST_DELIMITER[0])
ser.read(25)
resp = command(ser, "ID")
diff -r 333a280ca0c4 -r d1bc2c917785 chirp/drivers/thd72.py
--- a/chirp/drivers/thd72.py Wed Jun 01 17:30:31 2016 -0700
+++ b/chirp/drivers/thd72.py Tue Jun 07 21:49:22 2016 -0700
@@ -231,7 +231,7 @@
def _detect_baud(self):
for baud in [9600, 19200, 38400, 57600]:
- self.pipe.setBaudrate(baud)
+ self.pipe.baudrate = baud
try:
self.pipe.write("\r\r")
except:
@@ -422,9 +422,11 @@
raise errors.RadioError("No response from self")
allblocks = range(self._memsize/256)
- self.pipe.setBaudrate(57600)
- self.pipe.getCTS()
- self.pipe.setRTS()
+ self.pipe.baudrate = 57600
+ try:
+ self.pipe.setRTS()
+ except AttributeError:
+ self.pipe.rts = True
self.pipe.read(1)
data = ""
LOG.debug("reading blocks %d..%d" % (blocks[0], blocks[-1]))
@@ -458,9 +460,11 @@
if self.command("0M PROGRAM") != "0M":
raise errors.RadioError("No response from self")
- self.pipe.setBaudrate(57600)
- self.pipe.getCTS()
- self.pipe.setRTS()
+ self.pipe.baudrate = 57600
+ try:
+ self.pipe.setRTS()
+ except AttributeError:
+ self.pipe.rts = True
self.pipe.read(1)
LOG.debug("writing blocks %d..%d" % (blocks[0], blocks[-1]))
total = len(blocks)
diff -r 333a280ca0c4 -r d1bc2c917785 chirp/drivers/tk270.py
--- a/chirp/drivers/tk270.py Wed Jun 01 17:30:31 2016 -0700
+++ b/chirp/drivers/tk270.py Tue Jun 07 21:49:22 2016 -0700
@@ -194,10 +194,9 @@
"""Open the radio into program mode and check if it's the correct model"""
# Set serial discipline
try:
- radio.pipe.setParity("N")
- radio.pipe.setTimeout(TIMEOUT)
- radio.pipe.flushOutput()
- radio.pipe.flushInput()
+ radio.pipe.parity = "N"
+ radio.pipe.timeout = TIMEOUT
+ radio.pipe.flush()
except:
msg = "Serial error: Can't set serial line discipline"
raise errors.RadioError(msg)
diff -r 333a280ca0c4 -r d1bc2c917785 chirp/drivers/tk760.py
--- a/chirp/drivers/tk760.py Wed Jun 01 17:30:31 2016 -0700
+++ b/chirp/drivers/tk760.py Tue Jun 07 21:49:22 2016 -0700
@@ -188,10 +188,9 @@
"""Open the radio into program mode and check if it's the correct model"""
# Set serial discipline
try:
- radio.pipe.setParity("N")
- radio.pipe.setTimeout(TIMEOUT)
- radio.pipe.flushOutput()
- radio.pipe.flushInput()
+ radio.pipe.parity = "N"
+ radio.pipe.timeout = TIMEOUT
+ radio.pipe.flush()
LOG.debug("Serial port open successful")
except:
msg = "Serial error: Can't set serial line discipline"
diff -r 333a280ca0c4 -r d1bc2c917785 chirp/drivers/tk760g.py
--- a/chirp/drivers/tk760g.py Wed Jun 01 17:30:31 2016 -0700
+++ b/chirp/drivers/tk760g.py Tue Jun 07 21:49:22 2016 -0700
@@ -441,8 +441,8 @@
def _open_radio(radio, status):
"""Open the radio into program mode and check if it's the correct model"""
# linux min is 0.13, win min is 0.25; set to bigger to be safe
- radio.pipe.setTimeout(0.25)
- radio.pipe.setParity("E")
+ radio.pipe.timeout = 0.25
+ radio.pipe.parity = "E"
# DEBUG
LOG.debug("Entering program mode.")
@@ -525,17 +525,17 @@
# set the timeout and if windows keep it bigger
if sys.platform in ["win32", "cygwin"]:
# bigger timeout
- radio.pipe.setTimeout(0.55)
+ radio.pipe.timeout = 0.55
else:
# Linux can keep up, MAC?
- radio.pipe.setTimeout(0.05)
+ radio.pipe.timeout = 0.05
# DEBUG
LOG.debug("Starting the download from radio")
for addr in MEM_BLOCKS:
# send request, but before flush the rx buffer
- radio.pipe.flushInput()
+ radio.pipe.flush()
_send(radio, _make_frame("R", addr))
# now we get the data
@@ -574,7 +574,7 @@
radio.status_fn(status)
# the default for the original soft as measured
- radio.pipe.setTimeout(0.5)
+ radio.pipe.timeout = 0.5
# DEBUG
LOG.debug("Starting the upload to the radio")
diff -r 333a280ca0c4 -r d1bc2c917785 chirp/drivers/tk8102.py
--- a/chirp/drivers/tk8102.py Wed Jun 01 17:30:31 2016 -0700
+++ b/chirp/drivers/tk8102.py Tue Jun 07 21:49:22 2016 -0700
@@ -99,7 +99,7 @@
def do_download(radio):
- radio.pipe.setParity("E")
+ radio.pipe.parity = "E"
radio.pipe.timeout = 1
do_ident(radio)
@@ -129,7 +129,7 @@
def do_upload(radio):
- radio.pipe.setParity("E")
+ radio.pipe.parity = "E"
radio.pipe.timeout = 1
do_ident(radio)
diff -r 333a280ca0c4 -r d1bc2c917785 chirp/drivers/tmv71.py
--- a/chirp/drivers/tmv71.py Wed Jun 01 17:30:31 2016 -0700
+++ b/chirp/drivers/tmv71.py Tue Jun 07 21:49:22 2016 -0700
@@ -36,7 +36,7 @@
def _detect_baud(self):
for baud in [9600, 19200, 38400, 57600]:
- self.pipe.setBaudrate(baud)
+ self.pipe.baudrate = baud
self.pipe.write("\r\r")
self.pipe.read(32)
try:
2
4
Is anybody working the Yaesu FT2D? It looks to be in the list of devices wanted and to have hardware, but I see no mention when I looked through the developer archives. And I’ve heard nothing back on the chirp users mailing list.
I’ve not found anybody (but maybe RTsystems and G4FHQ) who can do it reliably [or at all with a Macintosh] using the USB cable, but having a chirp version that can read and write the microSD card file (“BACKUP.dat”) would be a boon. The Yaesu-supplied software is painful to run, and even worse when I tried it under WINE on my macintosh. And I’d really, REALLY like a system that runs on Mac.
I’ve looked at the “Add a Radio” page (http://chirp.danplanet.com/projects/chirp/wiki/DevelopersAdd_a_Radio) and think I might be able to help with the memory dump and data structure identification. But I’d rather not start from scratch if others have already done it!
_________
Don’t be fooled by my email account name. It is NOT an amateur callsign.
4
8
[chirp_devel] [PATCH] [UV-25X2] Add Support for new BTech Color Display Mobile Radios
by Jim Unroe 05 Jul '17
by Jim Unroe 05 Jul '17
05 Jul '17
# HG changeset patch
# User Jim Unroe <rock.unroe(a)gmail.com>
# Date 1489785081 14400
# Node ID 6a37192481c837ea49a60d121dde3de3ec8fc521
# Parent e1113c7da2f3eb00a5b1585ea92a8d164df0d60b
[UV-25X2] Add Support for new BTech Color Display Mobile Radios
This patch modifies the btech.py driver to support additional
mobile radios that have an OLED color display.
Additional radio models supported:
BTech UV-25X4 (quad band)
BTech UV-25X2 (dual band)
BTech UV-50X2 (dual band)
New Model #4269
diff -r e1113c7da2f3 -r 6a37192481c8 chirp/drivers/btech.py
--- a/chirp/drivers/btech.py Wed Mar 08 15:05:23 2017 -0800
+++ b/chirp/drivers/btech.py Fri Mar 17 17:11:21 2017 -0400
@@ -167,6 +167,15 @@
# B-TECH UV-5001 third generation (3G)
UV5001G3_fp = "BTG304"
+# B-TECH UV-25X2
+UV25X2_fp = "UC2012"
+
+# B-TECH UV-25X4
+UV25X4_fp = "UC4014"
+
+# B-TECH UV-50X2
+UV50X2_fp = "UC2M12"
+
# special var to know when we found a BTECH Gen 3
BTECH3 = [UV2501G3_fp, UV2501_220G3_fp, UV5001G3_fp]
@@ -226,6 +235,10 @@
MSTRING = "\x55\x20\x15\x09\x20\x45\x4d\x02"
# for the QYT KT7900D & KT8900D
MSTRING_KT8900D = "\x55\x20\x16\x08\x01\xFF\xDC\x02"
+# for the BTECH UV-25X2 and UV-50X2
+MSTRING_UV25X2 = "\x55\x20\x16\x12\x28\xFF\xDC\x02"
+# for the BTECH UV-25X4
+MSTRING_UV25X4 = "\x55\x20\x16\x11\x18\xFF\xDC\x02"
def _clean_buffer(radio):
@@ -852,10 +865,12 @@
# Extra
mem.extra = RadioSettingGroup("extra", "Extra")
- scramble = RadioSetting("scramble", "Scramble",
- RadioSettingValueBoolean(bool(
- _mem.scramble)))
- mem.extra.append(scramble)
+ if not self.COLOR_LCD or \
+ (self.COLOR_LCD and not self.VENDOR == "BTECH"):
+ scramble = RadioSetting("scramble", "Scramble",
+ RadioSettingValueBoolean(bool(
+ _mem.scramble)))
+ mem.extra.append(scramble)
bcl = RadioSetting("bcl", "Busy channel lockout",
RadioSettingValueBoolean(bool(_mem.bcl)))
@@ -1061,11 +1076,18 @@
_mem.settings.pttlt))
basic.append(pttlt)
- emctp = RadioSetting("settings.emctp", "Alarm mode",
- RadioSettingValueList(
- LIST_EMCTP,
- LIST_EMCTP[_mem.settings.emctp]))
- basic.append(emctp)
+ if self.VENDOR == "BTECH" and self.COLOR_LCD:
+ emctp = RadioSetting("settings.emctp", "Alarm mode",
+ RadioSettingValueList(
+ LIST_EMCTPX,
+ LIST_EMCTPX[_mem.settings.emctp]))
+ basic.append(emctp)
+ else:
+ emctp = RadioSetting("settings.emctp", "Alarm mode",
+ RadioSettingValueList(
+ LIST_EMCTP,
+ LIST_EMCTP[_mem.settings.emctp]))
+ basic.append(emctp)
emcch = RadioSetting("settings.emcch", "Alarm channel",
RadioSettingValueInteger(0, 199,
@@ -1119,10 +1141,17 @@
basic.append(langua)
if self.VENDOR == "BTECH":
- sync = RadioSetting("settings.sync", "A/B channel sync",
- RadioSettingValueBoolean(
- _mem.settings.sync))
- basic.append(sync)
+ if self.COLOR_LCD:
+ sync = RadioSetting("settings.sync", "Channel display sync",
+ RadioSettingValueList(
+ LIST_SYNC,
+ LIST_SYNC[_mem.settings.sync]))
+ basic.append(sync)
+ else:
+ sync = RadioSetting("settings.sync", "A/B channel sync",
+ RadioSettingValueBoolean(
+ _mem.settings.sync))
+ basic.append(sync)
else:
autolk = RadioSetting("settings.sync", "Auto keylock",
RadioSettingValueBoolean(
@@ -1289,6 +1318,24 @@
_mem.settings.dtmfg))
basic.append(dtmfg)
+ if self.VENDOR == "BTECH" and self.COLOR_LCD:
+ mgain = RadioSetting("settings.mgain", "Mic gain",
+ RadioSettingValueInteger(0, 120,
+ _mem.settings.mgain))
+ basic.append(mgain)
+
+ skiptx = RadioSetting("settings.skiptx", "Skip TX",
+ RadioSettingValueList(
+ LIST_SKIPTX,
+ LIST_SKIPTX[_mem.settings.skiptx]))
+ basic.append(skiptx)
+
+ scmode = RadioSetting("settings.scmode", "Scan mode",
+ RadioSettingValueList(
+ LIST_SCMODE,
+ LIST_SCMODE[_mem.settings.scmode]))
+ basic.append(scmode)
+
# Advanced
def _filter(name):
filtered = ""
@@ -1802,17 +1849,19 @@
SPMUTE_LIST[_mem.vfo.d.spmute]))
work.append(vfodspmute)
- vfoascr = RadioSetting("vfo.a.scramble", "VFO A scramble",
- RadioSettingValueBoolean(
- _mem.vfo.a.scramble))
- work.append(vfoascr)
-
- vfobscr = RadioSetting("vfo.b.scramble", "VFO B scramble",
- RadioSettingValueBoolean(
- _mem.vfo.b.scramble))
- work.append(vfobscr)
-
- if self.COLOR_LCD:
+ if not self.COLOR_LCD or \
+ (self.COLOR_LCD and not self.VENDOR == "BTECH"):
+ vfoascr = RadioSetting("vfo.a.scramble", "VFO A scramble",
+ RadioSettingValueBoolean(
+ _mem.vfo.a.scramble))
+ work.append(vfoascr)
+
+ vfobscr = RadioSetting("vfo.b.scramble", "VFO B scramble",
+ RadioSettingValueBoolean(
+ _mem.vfo.b.scramble))
+ work.append(vfobscr)
+
+ if self.COLOR_LCD and not self.VENDOR == "BTECH":
vfocscr = RadioSetting("vfo.c.scramble", "VFO C scramble",
RadioSettingValueBoolean(
_mem.vfo.c.scramble))
@@ -3537,7 +3586,7 @@
LOG.info("Radio ranges: UHF %d to %d" % uhf)
# the additional bands
- if self.MODEL in ["KT7900D", ]:
+ if self.MODEL in ["UV-25X4", "KT7900D"]:
# 200Mhz band
vhf2 = _decode_ranges(ranges.vhf2_low, ranges.vhf2_high)
LOG.info("Radio ranges: VHF(220) %d to %d" % vhf2)
@@ -3554,6 +3603,43 @@
@directory.register
+class UV25X2(BTechColor):
+ """Baofeng Tech UV25X2"""
+ MODEL = "UV-25X2"
+ BANDS = 2
+ _vhf_range = (130000000, 180000000)
+ _uhf_range = (400000000, 521000000)
+ _magic = MSTRING_UV25X2
+ _fileid = [UV25X2_fp, ]
+
+
+(a)directory.register
+class UV25X4(BTechColor):
+ """Baofeng Tech UV25X4"""
+ MODEL = "UV-25X4"
+ BANDS = 4
+ _vhf_range = (130000000, 180000000)
+ _220_range = (200000000, 271000000)
+ _uhf_range = (400000000, 521000000)
+ _350_range = (350000000, 391000000)
+ _magic = MSTRING_UV25X4
+ _fileid = [UV25X4_fp, ]
+
+
+(a)directory.register
+class UV50X2(BTechColor):
+ """Baofeng Tech UV50X2"""
+ MODEL = "UV-50X2"
+ BANDS = 2
+ _vhf_range = (130000000, 180000000)
+ _uhf_range = (400000000, 521000000)
+ _magic = MSTRING_UV25X2
+ _fileid = [UV50X2_fp, ]
+ _power_levels = [chirp_common.PowerLevel("High", watts=50),
+ chirp_common.PowerLevel("Low", watts=10)]
+
+
+(a)directory.register
class KT7900D(BTechColor):
"""QYT KT7900D"""
VENDOR = "QYT"
1
2
I’ve an basic architectural question: my Yaesu FT2D has a subset of memory space wholly devoted to "skip" frequencies: ones that are not scanned during VFO scanning They're formatted just the same as (repeater) memories, but they're always skipped in VFO mode. I've not used 'em, so they weren't high priority when playing with the candidate FT2D driver. Indeed, I “lied” and told the driver to only use memories up to 900; 901-999 are actually defined in the radio as the always-skip memories.
Does chirp natively support an alternate memory of always-skipped frequencies? I feel it’d be better for chirp to be able to read/write memories 901-999, but I’d really hate for somebody to think that they can store [really important] operational items in those spaces.
Declan Rieb WD5EQY
2
1
I’d love a second set of eyes on this. It turns out the FT2DR is almost identical to the FT1D except for for character coding. Thanks to Angus Ainslie (FT1D) and Wade Simmons (FTM3200D) for their work and help.
I’m not a python expert, but there wasn’t much to do in the end, so there’s probably no damage from my processing.
I’m not a mercurial anything. I tried to build a patch, but it doesn’t seem to handle a de-novo file at all (EVERYTHING on the chirp-developers site seems to describe changing an existing file. Ain’t none, ’til now.) So I built a candidate patch description, and am attaching the actual new files. Somebody may need to walk me through building a correct hg patch for a new file; I know I’ll need to attach the image to a formal-submission email anyway, so this may just be an OK format for a first file.
I’m not a Yaesu expert:
- I’ve reset my radio several times and it always leaves some APRS detritus behind. So the test image has Albuqerque-centric APRS logs in it.
- The radio insists that the user enter a callsign before it can CLONE or read or write a microSD card. So the image has my callsign.
- Furthermore, I don’t know much about the useful settings of the radio, so I don’t know what interesting parameters might be bogus in the FT1D format. My spot checks make ‘em look quite OK in chirp!
The chirp tests that I ran work for all other systems (well, I only ADDED one file into the drivers directory, so nothing else SHOULD have broken.) Of course the tests work with mine (since mine is the prototype image for now.)
I’ve looked enough at the microSD card “BACKUP.dat” and the chirp .img file to believe that they’re almost exactly the same format: mostly just memory map. chirp may be adding a sixteen-byte header that includes the chirp model number and other data. chirp doesn’t seem to have any obvious file-format conversion capability that one can automagically call to prepend or remove such headers. My guess is that adding microSD card support will be straightforward but will require modifying the underlying chirp code, and not just fiddling with the driver. I might be able to rig up a unix script or code to do that. (actually I thought I’d HAVE to do that, since it took forever for me to get the correct cable and get my Macintosh to work with it.) I suppose an external script could handle it. But first things first: here’s a
Candidate FT2D driver patch: Add the attached ft2d.py file to chirp/drivers.
# HG changeset patch
# User Declan Rieb <nthreewx(a)gmail.com>
# Date 1498434406 21600
# Sun Jun 25 17:46:46 2017 -0600
# Node ID 781f31ea27002a2e473d4f5783891e6c939aab4c
# Parent c845633cb641f05ac4323d36c913bc1f20d47bf6
[ft2d] New driver for Yaesu FT2DR. #3257 #3325 #3887
Same model as FT1D (and thus a clone of FT1D) except for character handling as in FTM3200D.
Declan Rieb WD5EQY
3
2
Tested changes:
[Windsor Schmidt <windsor.schmidt(a)gmail.com>] [New Model] Add Support for Icom IC-2300H Radio
Patch for review; based on existing code for the IC-2200H.
#959
[Tom Hayward <tom(a)tomh.us>] [id880] Fix typo in charset definition. #281
[Tom Hayward <tom(a)tomh.us>] [thf6a] Support full charset (ASCII). Fixes #141
[Tom Hayward <tom(a)tomh.us>] [id880] Support full charset. Fixes #281
[Tom Hayward <tom(a)tomh.us>] [vx5] Support full charset (ASCII). Fixes #292
[Tom Hayward <tom(a)tomh.us>] [id31a] set used bit when creating new memory, clear when deleting. Fixes #269
[Tom Hayward <tom(a)tomh.us>] Support PyGTK < 2.22 in bank edit. Fixes #231
[Tom Hayward <tom(a)tomh.us>] [d710] [v71] [d72] Fix tone list (not all tones are supported). Fixes #212
[Dan Smith <dsmith(a)danplanet.com>] [vx7] Fix setting memory power levels on 220MHz band
Fixes #214
[Dan Smith <dsmith(a)danplanet.com>] fips: Pennsylvania FIPS code was wrong. #117
[Marco Filippi <iz3gme.marco(a)gmail.com>] Consider lower bound frequency of each valid_band as valid
Fix bug #181
[Tom Hayward <tom(a)tomh.us>] tmd700: allow 8-char names. Fixes #176
[Dan Smith <dsmith(a)danplanet.com>] Fix the "blind deletion" problem, as well as properly direct copy/paste
Fixes #172
[David Griffith <dave(a)661.org>] Bug #155 fix: VX-7 1.25m power levels
[David Griffith <dave(a)661.org>] New INSTALL and README files
Fixes #122
[Tom Hayward <tom(a)tomh.us>] thd72: only use hardware flow on OS X. Fixes #166
[Marco Filippi <iz3gme.marco(a)gmail.com>] [FT817] Tone freq not set correctly
Same as #88 for FT857, to avoid code duplication fix code have been moved from
ft857 to its ancestor class
Fix bug #163
[Tom Hayward <tom(a)tomh.us>] Fix Mac .app so paths with spaces work. Fixes Bug #145
Full log:
Started by an SCM change
Building in workspace /var/lib/jenkins/jobs/chirp-test/workspace
[workspace] $ hg showconfig paths.default
[workspace] $ hg pull --rev default
[workspace] $ hg update --clean --rev default
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
[workspace] $ hg log --rev . --template {node}
[workspace] $ hg log --rev . --template {rev}
[workspace] $ hg log --rev c845633cb641f05ac4323d36c913bc1f20d47bf6
[workspace] $ hg log --template "<changeset node='{node}' author='{author|xmlescape}' rev='{rev}' date='{date}'><msg>{desc|xmlescape}</msg><added>{file_adds|stringify|xmlescape}</added><deleted>{file_dels|stringify|xmlescape}</deleted><files>{files|stringify|xmlescape}</files><parents>{parents}</parents></changeset>\n" --rev default:0 --follow --prune c845633cb641f05ac4323d36c913bc1f20d47bf6
No emails were triggered.
[workspace] $ /bin/sh -xe /tmp/hudson1678507565785007607.sh
[workspace] $ /bin/sh -xe /tmp/hudson7560661680316870774.sh
+ PATH=/usr/bin:/bin:/usr/local/bin ./run_all_tests.sh
test_bit_array (tests.unit.test_bitwise.TestBitType) ... ok
test_bit_array_fail (tests.unit.test_bitwise.TestBitType) ... ok
test_bitfield_u16 (tests.unit.test_bitwise.TestBitfieldTypes) ... ok
test_bitfield_u24 (tests.unit.test_bitwise.TestBitfieldTypes) ... ok
test_bitfield_u8 (tests.unit.test_bitwise.TestBitfieldTypes) ... ok
test_bitfield_ul16 (tests.unit.test_bitwise.TestBitfieldTypes) ... ok
test_bitfield_ul24 (tests.unit.test_bitwise.TestBitfieldTypes) ... ok
test_bbcd (tests.unit.test_bitwise.TestBitwiseBCDTypes) ... ok
test_bbcd_array (tests.unit.test_bitwise.TestBitwiseBCDTypes) ... ok
test_lbcd (tests.unit.test_bitwise.TestBitwiseBCDTypes) ... ok
test_lbcd_array (tests.unit.test_bitwise.TestBitwiseBCDTypes) ... ok
test_int_array (tests.unit.test_bitwise.TestBitwiseBaseIntTypes) ... ok
test_type_u16 (tests.unit.test_bitwise.TestBitwiseBaseIntTypes) ... ok
test_type_u24 (tests.unit.test_bitwise.TestBitwiseBaseIntTypes) ... ok
test_type_u32 (tests.unit.test_bitwise.TestBitwiseBaseIntTypes) ... ok
test_type_u8 (tests.unit.test_bitwise.TestBitwiseBaseIntTypes) ... ok
test_type_ul16 (tests.unit.test_bitwise.TestBitwiseBaseIntTypes) ... ok
test_type_ul24 (tests.unit.test_bitwise.TestBitwiseBaseIntTypes) ... ok
test_type_ul32 (tests.unit.test_bitwise.TestBitwiseBaseIntTypes) ... ok
test_char (tests.unit.test_bitwise.TestBitwiseCharTypes) ... ok
test_string (tests.unit.test_bitwise.TestBitwiseCharTypes) ... ok
test_string_invalid_chars (tests.unit.test_bitwise.TestBitwiseCharTypes) ... ok
test_string_wrong_length (tests.unit.test_bitwise.TestBitwiseCharTypes) ... ok
test_comment_cppstyle (tests.unit.test_bitwise.TestBitwiseComments) ... ok
test_comment_inline_cppstyle (tests.unit.test_bitwise.TestBitwiseComments) ... ok
test_missing_semicolon (tests.unit.test_bitwise.TestBitwiseErrors) ... ok
test_seek (tests.unit.test_bitwise.TestBitwiseSeek) ... ok
test_seekto (tests.unit.test_bitwise.TestBitwiseSeek) ... ok
test_struct_one_element (tests.unit.test_bitwise.TestBitwiseStructTypes) ... ok
test_struct_two_elements (tests.unit.test_bitwise.TestBitwiseStructTypes) ... ok
test_struct_writes (tests.unit.test_bitwise.TestBitwiseStructTypes) ... ok
split_tone_encode_test_cross_dtcs_tone (tests.unit.test_chirp_common.TestSplitTone) ... ok
split_tone_encode_test_cross_none_dtcs (tests.unit.test_chirp_common.TestSplitTone) ... ok
split_tone_encode_test_cross_none_tone (tests.unit.test_chirp_common.TestSplitTone) ... ok
split_tone_encode_test_cross_tone_dtcs (tests.unit.test_chirp_common.TestSplitTone) ... ok
split_tone_encode_test_cross_tone_tone (tests.unit.test_chirp_common.TestSplitTone) ... ok
split_tone_encode_test_dtcs (tests.unit.test_chirp_common.TestSplitTone) ... ok
split_tone_encode_test_none (tests.unit.test_chirp_common.TestSplitTone) ... ok
split_tone_encode_test_tone (tests.unit.test_chirp_common.TestSplitTone) ... ok
split_tone_encode_test_tsql (tests.unit.test_chirp_common.TestSplitTone) ... ok
test_split_tone_decode_cross_dtcs_dtcs (tests.unit.test_chirp_common.TestSplitTone) ... ok
test_split_tone_decode_cross_dtcs_tone (tests.unit.test_chirp_common.TestSplitTone) ... ok
test_split_tone_decode_cross_none_dtcs (tests.unit.test_chirp_common.TestSplitTone) ... ok
test_split_tone_decode_cross_none_tone (tests.unit.test_chirp_common.TestSplitTone) ... ok
test_split_tone_decode_cross_tone_dtcs (tests.unit.test_chirp_common.TestSplitTone) ... ok
test_split_tone_decode_cross_tone_tone (tests.unit.test_chirp_common.TestSplitTone) ... ok
test_split_tone_decode_dtcs (tests.unit.test_chirp_common.TestSplitTone) ... ok
test_split_tone_decode_none (tests.unit.test_chirp_common.TestSplitTone) ... ok
test_split_tone_decode_tone (tests.unit.test_chirp_common.TestSplitTone) ... ok
test_split_tone_decode_tsql (tests.unit.test_chirp_common.TestSplitTone) ... ok
test_fix_rounded_step_250 (tests.unit.test_chirp_common.TestStepFunctions) ... ok
test_fix_rounded_step_500 (tests.unit.test_chirp_common.TestStepFunctions) ... ok
test_fix_rounded_step_750 (tests.unit.test_chirp_common.TestStepFunctions) ... ok
test_is_12_5 (tests.unit.test_chirp_common.TestStepFunctions) ... ok
test_is_2_5 (tests.unit.test_chirp_common.TestStepFunctions) ... ok
test_is_5_0 (tests.unit.test_chirp_common.TestStepFunctions) ... ok
test_is_6_25 (tests.unit.test_chirp_common.TestStepFunctions) ... ok
test_is_fractional_step (tests.unit.test_chirp_common.TestStepFunctions) ... ok
test_required_step (tests.unit.test_chirp_common.TestStepFunctions) ... ok
test_required_step_fail (tests.unit.test_chirp_common.TestStepFunctions) ... ok
test_format_freq (tests.unit.test_chirp_common.TestUtilityFunctions) ... ok
test_parse_freq_bad (tests.unit.test_chirp_common.TestUtilityFunctions) ... ok
test_parse_freq_decimal (tests.unit.test_chirp_common.TestUtilityFunctions) ... ok
test_parse_freq_whitespace (tests.unit.test_chirp_common.TestUtilityFunctions) ... ok
test_parse_freq_whole (tests.unit.test_chirp_common.TestUtilityFunctions) ... ok
test_ensure_has_calls_almost_full (tests.unit.test_import_logic.DstarTests) ... ok
test_ensure_has_calls_empty (tests.unit.test_import_logic.DstarTests) ... ok
test_ensure_has_calls_partial (tests.unit.test_import_logic.DstarTests) ... ok
test_ensure_has_calls_rptcall_full1 (tests.unit.test_import_logic.DstarTests) ... ok
test_ensure_has_calls_rptcall_full2 (tests.unit.test_import_logic.DstarTests) ... ok
test_ensure_has_calls_urcall_full (tests.unit.test_import_logic.DstarTests) ... ok
test_import_bank (tests.unit.test_import_logic.ImportFieldTests) ... ok
test_import_dtcs_diffA_dtcs (tests.unit.test_import_logic.ImportFieldTests) ... ok
test_import_dtcs_diffB_dtcs (tests.unit.test_import_logic.ImportFieldTests) ... ok
test_import_duplex_negative (tests.unit.test_import_logic.ImportFieldTests) ... ok
test_import_duplex_too_big_vhf (tests.unit.test_import_logic.ImportFieldTests) ... ok
test_import_duplex_uhf (tests.unit.test_import_logic.ImportFieldTests) ... ok
test_import_duplex_vhf (tests.unit.test_import_logic.ImportFieldTests) ... ok
test_import_mem (tests.unit.test_import_logic.ImportFieldTests) ... ok
test_import_mem_with_errors (tests.unit.test_import_logic.ImportFieldTests) ... ok
test_import_mem_with_warnings (tests.unit.test_import_logic.ImportFieldTests) ... ok
test_import_mode_invalid (tests.unit.test_import_logic.ImportFieldTests) ... ok
test_import_mode_valid_am (tests.unit.test_import_logic.ImportFieldTests) ... ok
test_import_mode_valid_fm (tests.unit.test_import_logic.ImportFieldTests) ... ok
test_import_name (tests.unit.test_import_logic.ImportFieldTests) ... ok
test_import_power_closest (tests.unit.test_import_logic.ImportFieldTests) ... ok
test_import_power_no_dst (tests.unit.test_import_logic.ImportFieldTests) ... ok
test_import_power_no_src (tests.unit.test_import_logic.ImportFieldTests) ... ok
test_import_power_same (tests.unit.test_import_logic.ImportFieldTests) ... ok
test_import_tone_diffA_tsql (tests.unit.test_import_logic.ImportFieldTests) ... ok
test_import_tone_diffB_tsql (tests.unit.test_import_logic.ImportFieldTests) ... ok
test_mapping (tests.unit.test_mappingmodel.TestBaseBank) ... ok
test_mapping_eq (tests.unit.test_mappingmodel.TestBaseBank) ... ok
test_base_class (tests.unit.test_mappingmodel.TestBaseBankModel) ... ok
test_get_name (tests.unit.test_mappingmodel.TestBaseBankModel) ... ok
test_mapping (tests.unit.test_mappingmodel.TestBaseMapping) ... ok
test_mapping_eq (tests.unit.test_mappingmodel.TestBaseMapping) ... ok
test_base_class (tests.unit.test_mappingmodel.TestBaseMappingModel) ... ok
test_get_name (tests.unit.test_mappingmodel.TestBaseMappingModel) ... ok
test_base_class (tests.unit.test_mappingmodel.TestBaseMappingModelIndexInterface) ... ok
test_add_memory_to_mapping (tests.unit.test_mappingmodel.TestIcomBankModel) ... ok
test_get_mapping_memories (tests.unit.test_mappingmodel.TestIcomBankModel) ... ok
test_get_mappings (tests.unit.test_mappingmodel.TestIcomBankModel) ... ok
test_get_memory_mappings (tests.unit.test_mappingmodel.TestIcomBankModel) ... ok
test_get_num_mappings (tests.unit.test_mappingmodel.TestIcomBankModel) ... ok
test_remove_memory_from_mapping (tests.unit.test_mappingmodel.TestIcomBankModel) ... ok
test_remove_memory_from_mapping_no_bank (tests.unit.test_mappingmodel.TestIcomBankModel) ... ok
test_remove_memory_from_mapping_wrong_bank (tests.unit.test_mappingmodel.TestIcomBankModel) ... ok
test_icom_bank (tests.unit.test_mappingmodel.TestIcomBanks) ... ok
test_mapping (tests.unit.test_mappingmodel.TestIcomBanks) ... ok
test_mapping_eq (tests.unit.test_mappingmodel.TestIcomBanks) ... ok
test_add_memory_to_mapping (tests.unit.test_mappingmodel.TestIcomIndexedBankModel) ... ok
test_get_index_bounds (tests.unit.test_mappingmodel.TestIcomIndexedBankModel) ... ok
test_get_mapping_memories (tests.unit.test_mappingmodel.TestIcomIndexedBankModel) ... ok
test_get_mappings (tests.unit.test_mappingmodel.TestIcomIndexedBankModel) ... ok
test_get_memory_index (tests.unit.test_mappingmodel.TestIcomIndexedBankModel) ... ok
test_get_memory_mappings (tests.unit.test_mappingmodel.TestIcomIndexedBankModel) ... ok
test_get_next_mapping_index (tests.unit.test_mappingmodel.TestIcomIndexedBankModel) ... ok
test_get_num_mappings (tests.unit.test_mappingmodel.TestIcomIndexedBankModel) ... ok
test_remove_memory_from_mapping (tests.unit.test_mappingmodel.TestIcomIndexedBankModel) ... ok
test_remove_memory_from_mapping_no_bank (tests.unit.test_mappingmodel.TestIcomIndexedBankModel) ... ok
test_remove_memory_from_mapping_wrong_bank (tests.unit.test_mappingmodel.TestIcomIndexedBankModel) ... ok
test_set_memory_index (tests.unit.test_mappingmodel.TestIcomIndexedBankModel) ... ok
test_set_memory_index_bad_bank (tests.unit.test_mappingmodel.TestIcomIndexedBankModel) ... ok
test_set_memory_index_bad_index (tests.unit.test_mappingmodel.TestIcomIndexedBankModel) ... ok
test_auto_tone_mode_cross (tests.unit.test_memedit_edits.TestEdits) ... ok
test_auto_tone_mode_dtcs (tests.unit.test_memedit_edits.TestEdits) ... ok
test_auto_tone_mode_dtcs_pol (tests.unit.test_memedit_edits.TestEdits) ... ok
test_auto_tone_mode_dtcs_rx (tests.unit.test_memedit_edits.TestEdits) ... ok
test_auto_tone_mode_tone (tests.unit.test_memedit_edits.TestEdits) ... ok
test_auto_tone_mode_tsql (tests.unit.test_memedit_edits.TestEdits) ... ok
test_init (tests.unit.test_platform.Win32PlatformTest) ... ok
test_serial_ports_bad_portnames (tests.unit.test_platform.Win32PlatformTest) ... ok
test_serial_ports_sorted (tests.unit.test_platform.Win32PlatformTest) ... ok
test_apply_callback (tests.unit.test_settings.TestSettingContainers) ... ok
test_radio_setting (tests.unit.test_settings.TestSettingContainers) ... ok
test_radio_setting_group (tests.unit.test_settings.TestSettingContainers) ... ok
test_radio_setting_multi (tests.unit.test_settings.TestSettingContainers) ... ok
test_changed (tests.unit.test_settings.TestSettingValues) ... ok
test_radio_setting_value_boolean (tests.unit.test_settings.TestSettingValues) ... ok
test_radio_setting_value_float (tests.unit.test_settings.TestSettingValues) ... ok
test_radio_setting_value_integer (tests.unit.test_settings.TestSettingValues) ... ok
test_radio_setting_value_list (tests.unit.test_settings.TestSettingValues) ... ok
test_radio_setting_value_string (tests.unit.test_settings.TestSettingValues) ... ok
test_validate_callback (tests.unit.test_settings.TestSettingValues) ... ok
test_delete_hole_with_all (tests.unit.test_shiftdialog.ShiftDialogTest) ... ok
test_delete_hole_with_all_full (tests.unit.test_shiftdialog.ShiftDialogTest) ... ok
test_delete_hole_with_hole (tests.unit.test_shiftdialog.ShiftDialogTest) ... ok
test_delete_hole_without_hole (tests.unit.test_shiftdialog.ShiftDialogTest) ... ok
test_insert_hole_with_space (tests.unit.test_shiftdialog.ShiftDialogTest) ... ok
test_insert_hole_without_space (tests.unit.test_shiftdialog.ShiftDialogTest) ... ok
----------------------------------------------------------------------
Ran 151 tests in 0.058s
OK
Patch 'tip' is OK
Checking for PEP8 regressions...
./chirp/platform.py:255:80: E501 line too long (82 > 79 characters)
./chirp/ui/mainapp.py:1909:80: E501 line too long (82 > 79 characters)
./chirp/ui/mainapp.py:1965:80: E501 line too long (82 > 79 characters)
real 0m9.071s
user 0m8.896s
sys 0m0.060s
================================================
Tests OK
+ cat /var/lib/jenkins/.chirp/debug.log
[2017-06-26 19:08:59,227] chirp.logger - DEBUG: CHIRP 0.3.0dev on Linux - Ubuntu 16.04.2 LTS (Python 2.7.12)
[2017-06-26 19:08:59,242] chirp.directory - INFO: Registered Kenwood_TH-D7 = THD7Radio
[2017-06-26 19:08:59,242] chirp.directory - INFO: Registered Kenwood_TH-D7G = THD7GRadio
[2017-06-26 19:08:59,243] chirp.directory - INFO: Registered Kenwood_TM-D700 = TMD700Radio
[2017-06-26 19:08:59,243] chirp.directory - INFO: Registered Kenwood_TM-V7 = TMV7Radio
[2017-06-26 19:08:59,243] chirp.directory - INFO: Registered Kenwood_TM-G707 = TMG707Radio
[2017-06-26 19:08:59,243] chirp.directory - INFO: Registered Kenwood_TH-G71 = THG71Radio
[2017-06-26 19:08:59,243] chirp.directory - INFO: Registered Kenwood_TH-F6 = THF6ARadio
[2017-06-26 19:08:59,243] chirp.directory - INFO: Registered Kenwood_TH-F7 = THF7ERadio
[2017-06-26 19:08:59,243] chirp.directory - INFO: Registered Kenwood_TM-D710 = TMD710Radio
[2017-06-26 19:08:59,243] chirp.directory - INFO: Registered Kenwood_TH-D72_live_mode = THD72Radio
[2017-06-26 19:08:59,243] chirp.directory - INFO: Registered Kenwood_TM-V71 = TMV71Radio
[2017-06-26 19:08:59,244] chirp.directory - INFO: Registered Kenwood_TM-D710G = TMD710GRadio
[2017-06-26 19:08:59,244] chirp.directory - INFO: Registered Kenwood_TH-K2 = THK2Radio
[2017-06-26 19:08:59,244] chirp.directory - INFO: Registered Kenwood_TM-271 = TM271Radio
[2017-06-26 19:08:59,244] chirp.directory - INFO: Registered Kenwood_TM-281 = TM281Radio
[2017-06-26 19:08:59,244] chirp.directory - INFO: Registered Kenwood_TM-471 = TM471Radio
[2017-06-26 19:08:59,244] chirp.directory - INFO: Registered Icom_7200 = Icom7200Radio
[2017-06-26 19:08:59,244] chirp.directory - INFO: Registered Icom_IC-7000 = Icom7000Radio
[2017-06-26 19:08:59,244] chirp.directory - INFO: Registered Icom_IC-7100 = Icom7100Radio
[2017-06-26 19:08:59,245] chirp.directory - INFO: Registered Icom_746 = Icom746Radio
[2017-06-26 19:08:59,247] chirp.directory - INFO: Registered Alinco_DR03T = DR03Radio
[2017-06-26 19:08:59,248] chirp.directory - INFO: Registered Alinco_DR06T = DR06Radio
[2017-06-26 19:08:59,248] chirp.directory - INFO: Registered Alinco_DR135T = DR135Radio
[2017-06-26 19:08:59,248] chirp.directory - INFO: Registered Alinco_DR235T = DR235Radio
[2017-06-26 19:08:59,248] chirp.directory - INFO: Registered Alinco_DR435T = DR435Radio
[2017-06-26 19:08:59,248] chirp.directory - INFO: Registered Alinco_DJ596 = DJ596Radio
[2017-06-26 19:08:59,248] chirp.directory - INFO: Registered Jetstream_JT220M = JT220MRadio
[2017-06-26 19:08:59,248] chirp.directory - INFO: Registered Alinco_DJ175 = DJ175Radio
[2017-06-26 19:08:59,248] chirp.directory - INFO: Registered Alinco_DJ-G7EG = AlincoDJG7EG
[2017-06-26 19:08:59,249] chirp.directory - INFO: Registered AnyTone_5888UV = AnyTone5888UVRadio
[2017-06-26 19:08:59,249] chirp.directory - INFO: Registered Intek_HR-2040 = IntekHR2040Radio
[2017-06-26 19:08:59,249] chirp.directory - INFO: Registered Polmar_DB-50M = PolmarDB50MRadio
[2017-06-26 19:08:59,249] chirp.directory - INFO: Registered Powerwerx_DB-750X = PowerwerxDB750XRadio
[2017-06-26 19:08:59,249] chirp.directory - INFO: Registered AnyTone_TERMN-8R = AnyToneTERMN8RRadio
[2017-06-26 19:08:59,249] chirp.directory - INFO: Registered AnyTone_OBLTR-8R = AnyToneOBLTR8RRadio
[2017-06-26 19:08:59,250] chirp.directory - INFO: Registered Baofeng_UV-3R = UV3RRadio
[2017-06-26 19:08:59,251] chirp.directory - INFO: Registered Baofeng_BF-A58 = BFA58
[2017-06-26 19:08:59,251] chirp.directory - INFO: Registered Baofeng_UV-82WP = UV82WP
[2017-06-26 19:08:59,251] chirp.directory - INFO: Registered Baofeng_GT-3WP = GT3WP
[2017-06-26 19:08:59,251] chirp.directory - INFO: Registered Retevis_RT6 = RT6
[2017-06-26 19:08:59,251] chirp.directory - INFO: Registered Baojie_BJ-9900 = BJ9900Radio
[2017-06-26 19:08:59,252] chirp.directory - INFO: Registered Baofeng_UV-5R = BaofengUV5RGeneric
[2017-06-26 19:08:59,252] chirp.directory - INFO: Registered Baofeng_F-11 = BaofengF11Radio
[2017-06-26 19:08:59,252] chirp.directory - INFO: Registered Baofeng_UV-82 = BaofengUV82Radio
[2017-06-26 19:08:59,253] chirp.directory - INFO: Registered Baofeng_UV-6 = BaofengUV6Radio
[2017-06-26 19:08:59,253] chirp.directory - INFO: Registered Intek_KT-980HP = IntekKT980Radio
[2017-06-26 19:08:59,253] chirp.directory - INFO: Registered Baofeng_BF-F8HP = BaofengBFF8HPRadio
[2017-06-26 19:08:59,253] chirp.directory - INFO: Registered Baofeng_UV-82HP = BaofengUV82HPRadio
[2017-06-26 19:08:59,253] chirp.directory - INFO: Registered Baojie_BJ-UV55 = BaojieBJUV55Radio
[2017-06-26 19:08:59,254] chirp.directory - INFO: Registered BTECH_UV-2501 = UV2501
[2017-06-26 19:08:59,254] chirp.directory - INFO: Registered BTECH_UV-2501+220 = UV2501_220
[2017-06-26 19:08:59,254] chirp.directory - INFO: Registered BTECH_UV-5001 = UV5001
[2017-06-26 19:08:59,254] chirp.directory - INFO: Registered WACCOM_MINI-8900 = MINI8900
[2017-06-26 19:08:59,254] chirp.directory - INFO: Registered QYT_KT-UV980 = KTUV980
[2017-06-26 19:08:59,254] chirp.directory - INFO: Registered QYT_KT8900 = KT9800
[2017-06-26 19:08:59,255] chirp.directory - INFO: Registered QYT_KT8900R = KT9800R
[2017-06-26 19:08:59,255] chirp.directory - INFO: Registered LUITON_LT-588UV = LT588UV
[2017-06-26 19:08:59,255] chirp.directory - INFO: Registered BTECH_UV-25X2 = UV25X2
[2017-06-26 19:08:59,255] chirp.directory - INFO: Registered BTECH_UV-25X4 = UV25X4
[2017-06-26 19:08:59,255] chirp.directory - INFO: Registered BTECH_UV-50X2 = UV50X2
[2017-06-26 19:08:59,255] chirp.directory - INFO: Registered QYT_KT7900D = KT7900D
[2017-06-26 19:08:59,255] chirp.directory - INFO: Registered QYT_KT8900D = KT8900D
[2017-06-26 19:08:59,256] chirp.directory - INFO: Registered Feidaxin_FD-268A = FD268ARadio
[2017-06-26 19:08:59,256] chirp.directory - INFO: Registered Feidaxin_FD-268B = FD268BRadio
[2017-06-26 19:08:59,256] chirp.directory - INFO: Registered Feidaxin_FD-288A = FD288ARadio
[2017-06-26 19:08:59,256] chirp.directory - INFO: Registered Feidaxin_FD-288B = FD288BRadio
[2017-06-26 19:08:59,256] chirp.directory - INFO: Registered Feidaxin_FD-150A = FD150ARadio
[2017-06-26 19:08:59,256] chirp.directory - INFO: Registered Feidaxin_FD-160A = FD160ARadio
[2017-06-26 19:08:59,256] chirp.directory - INFO: Registered Feidaxin_FD-450A = FD450ARadio
[2017-06-26 19:08:59,256] chirp.directory - INFO: Registered Feidaxin_FD-460A = FD460ARadio
[2017-06-26 19:08:59,256] chirp.directory - INFO: Registered Feidaxin_FD-460UH = FD460UHRadio
[2017-06-26 19:08:59,257] chirp.directory - INFO: Registered Yaesu_FT-1802M = FT1802Radio
[2017-06-26 19:08:59,258] chirp.directory - INFO: Registered Yaesu_FT-1D_R = FT1Radio
[2017-06-26 19:08:59,258] chirp.directory - INFO: Registered Yaesu_FT-2800M = FT2800Radio
[2017-06-26 19:08:59,258] chirp.directory - INFO: Registered Yaesu_FT-2900R_1900R = FT2900Radio
[2017-06-26 19:08:59,259] chirp.directory - INFO: Registered Yaesu_FT-50 = FT50Radio
[2017-06-26 19:08:59,259] chirp.directory - INFO: Registered Yaesu_FT-60 = FT60Radio
[2017-06-26 19:08:59,260] chirp.directory - INFO: Registered Yaesu_FT-7800_7900 = FT7800Radio
[2017-06-26 19:08:59,260] chirp.directory - INFO: Registered Yaesu_FT-8800 = FT8800Radio
[2017-06-26 19:08:59,260] chirp.directory - INFO: Registered Yaesu_FT-8900 = FT8900Radio
[2017-06-26 19:08:59,260] chirp.directory - INFO: Registered Yaesu_FT-8100 = FT8100Radio
[2017-06-26 19:08:59,261] chirp.directory - INFO: Registered Yaesu_FT-817 = FT817Radio
[2017-06-26 19:08:59,261] chirp.directory - INFO: Registered Yaesu_FT-817ND = FT817NDRadio
[2017-06-26 19:08:59,261] chirp.directory - INFO: Registered Yaesu_FT-817ND_US = FT817NDUSRadio
[2017-06-26 19:08:59,261] chirp.directory - INFO: Registered Yaesu_FT-857_897 = FT857Radio
[2017-06-26 19:08:59,262] chirp.directory - INFO: Registered Yaesu_FT-857_897_US = FT857USRadio
[2017-06-26 19:08:59,262] chirp.directory - INFO: Registered Yaesu_FT-90 = FT90Radio
[2017-06-26 19:08:59,262] chirp.directory - INFO: Registered Yaesu_FTM-3200D_R = FTM3200Radio
[2017-06-26 19:08:59,262] chirp.directory - INFO: Registered Yaesu_FTM-350 = FTM350Radio
[2017-06-26 19:08:59,263] chirp.directory - INFO: Registered Generic_CSV = CSVRadio
[2017-06-26 19:08:59,263] chirp.directory - INFO: Registered Commander_KG-UV = CommanderCSVRadio
[2017-06-26 19:08:59,264] chirp.directory - INFO: Registered RT_Systems_CSV = RTCSVRadio
[2017-06-26 19:08:59,264] chirp.directory - INFO: Registered ARRL_Travel_Plus = TpeRadio
[2017-06-26 19:08:59,273] chirp.directory - INFO: Registered Generic_XML = XMLRadio
[2017-06-26 19:08:59,273] chirp.directory - INFO: Registered BTECH_GMRS-V1 = GMRSV1
[2017-06-26 19:08:59,277] chirp.directory - INFO: Registered Baofeng_BF-888 = H777Radio
[2017-06-26 19:08:59,277] chirp.directory - INFO: Registered HobbyPCB_RS-UV3 = HobbyPCBRSUV3Radio
[2017-06-26 19:08:59,277] chirp.directory - INFO: Registered Icom_IC-208H = IC208Radio
[2017-06-26 19:08:59,278] chirp.directory - INFO: Registered Icom_IC-2100H = IC2100Radio
[2017-06-26 19:08:59,278] chirp.directory - INFO: Registered Icom_IC-2200H = IC2200Radio
[2017-06-26 19:08:59,278] chirp.directory - INFO: Registered Icom_IC-2300H = IC2300Radio
[2017-06-26 19:08:59,278] chirp.directory - INFO: Registered Icom_IC-2720H = IC2720Radio
[2017-06-26 19:08:59,279] chirp.directory - INFO: Registered Icom_IC-2820H = IC2820Radio
[2017-06-26 19:08:59,279] chirp.directory - INFO: Registered Icom_IC-91_92AD = IC9xRadio
[2017-06-26 19:08:59,279] chirp.directory - INFO: Registered Icom_IC-P7 = ICP7Radio
[2017-06-26 19:08:59,280] chirp.directory - INFO: Registered Icom_IC-Q7A = ICQ7Radio
[2017-06-26 19:08:59,280] chirp.directory - INFO: Registered Icom_IC-T70 = ICT70Radio
[2017-06-26 19:08:59,280] chirp.directory - INFO: Registered Icom_IC-T7H = ICT7HRadio
[2017-06-26 19:08:59,280] chirp.directory - INFO: Registered Icom_IC-T8A = ICT8ARadio
[2017-06-26 19:08:59,280] chirp.directory - INFO: Registered Icom_IC-W32A = ICW32ARadio
[2017-06-26 19:08:59,281] chirp.directory - INFO: Registered Icom_IC-W32E = ICW32ERadio
[2017-06-26 19:08:59,281] chirp.directory - INFO: Registered Icom_IC-V82_U82 = ICx8xRadio
[2017-06-26 19:08:59,281] chirp.directory - INFO: Registered Icom_ID-31A = ID31Radio
[2017-06-26 19:08:59,281] chirp.directory - INFO: Registered Icom_ID-51 = ID51Radio
[2017-06-26 19:08:59,282] chirp.directory - INFO: Registered Icom_ID-51_Plus = ID51PLUSRadio
[2017-06-26 19:08:59,282] chirp.directory - INFO: Registered Icom_ID-800H_v2 = ID800v2Radio
[2017-06-26 19:08:59,282] chirp.directory - INFO: Registered Icom_ID-880H = ID880Radio
[2017-06-26 19:08:59,282] chirp.directory - INFO: Registered Icom_ID-80H = ID80Radio
[2017-06-26 19:08:59,283] chirp.directory - INFO: Registered Kenwood_HMK = HMKRadio
[2017-06-26 19:08:59,283] chirp.directory - INFO: Registered Kenwood_ITM = ITMRadio
[2017-06-26 19:08:59,283] chirp.directory - INFO: Registered Wouxun_KG-UV8D = KGUV8DRadio
[2017-06-26 19:08:59,284] chirp.directory - INFO: Registered KYD_NC-630A = NC630aRadio
[2017-06-26 19:08:59,284] chirp.directory - INFO: Registered KYD_IP-620 = IP620Radio
[2017-06-26 19:08:59,285] chirp.directory - INFO: Registered Leixen_VV-898 = LeixenVV898Radio
[2017-06-26 19:08:59,285] chirp.directory - INFO: Registered Jetstream_JT270M = JetstreamJT270MRadio
[2017-06-26 19:08:59,285] chirp.directory - INFO: Registered Jetstream_JT270MH = JetstreamJT270MHRadio
[2017-06-26 19:08:59,285] chirp.directory - INFO: Registered Leixen_VV-898S = LeixenVV898SRadio
[2017-06-26 19:08:59,286] chirp.directory - INFO: Registered LUITON_LT-725UV = LT725UV
[2017-06-26 19:08:59,286] chirp.directory - INFO: Registered Wouxun_KG-UVD1P = KGUVD1PRadio
[2017-06-26 19:08:59,286] chirp.directory - INFO: Registered Wouxun_KG-UV6 = KGUV6DRadio
[2017-06-26 19:08:59,286] chirp.directory - INFO: Registered Wouxun_KG-816 = KG816Radio
[2017-06-26 19:08:59,287] chirp.directory - INFO: Registered Wouxun_KG-818 = KG818Radio
[2017-06-26 19:08:59,287] chirp.directory - INFO: Registered Puxing_PX-777 = Puxing777Radio
[2017-06-26 19:08:59,287] chirp.directory - INFO: Registered Puxing_PX-2R = Puxing2RRadio
[2017-06-26 19:08:59,288] chirp.directory - INFO: Registered Puxing_PX-888K = Puxing_PX888K_Radio
[2017-06-26 19:08:59,288] chirp.directory - INFO: Registered Retevis_RT1 = RT1Radio
[2017-06-26 19:08:59,288] chirp.directory - INFO: Registered Retevis_RT21 = RT21Radio
[2017-06-26 19:08:59,289] chirp.directory - INFO: Registered Retevis_RT22 = RT22Radio
[2017-06-26 19:08:59,289] chirp.directory - INFO: Registered WLN_KD-C1 = KDC1
[2017-06-26 19:08:59,289] chirp.directory - INFO: Registered Zastone_ZT-X6 = ZTX6
[2017-06-26 19:08:59,289] chirp.directory - INFO: Registered LUITON_LT-316 = LT316
[2017-06-26 19:08:59,289] chirp.directory - INFO: Registered TID_TD-M8 = TDM8
[2017-06-26 19:08:59,289] chirp.directory - INFO: Registered Retevis_RT23 = RT23Radio
[2017-06-26 19:08:59,290] chirp.directory - INFO: Registered Rugged_RH5R-V2 = RH5RV2
[2017-06-26 19:08:59,290] chirp.directory - INFO: Registered TDXone_TD-Q8A = TDXoneTDQ8A
[2017-06-26 19:08:59,291] chirp.directory - INFO: Registered TYT_TH-7800_File = TYTTH7800File
[2017-06-26 19:08:59,291] chirp.directory - INFO: Registered TYT_TH-7800 = TYTTH7800Radio
[2017-06-26 19:08:59,291] chirp.directory - INFO: Registered TYT_TH9000_220 = Th9000220Radio
[2017-06-26 19:08:59,291] chirp.directory - INFO: Registered TYT_TH9000_144 = Th9000144Radio
[2017-06-26 19:08:59,292] chirp.directory - INFO: Registered TYT_TH9000_440 = Th9000440Radio
[2017-06-26 19:08:59,292] chirp.directory - INFO: Registered TYT_TH-9800_File = TYTTH9800File
[2017-06-26 19:08:59,292] chirp.directory - INFO: Registered TYT_TH-9800 = TYTTH9800Radio
[2017-06-26 19:08:59,292] chirp.directory - INFO: Registered TYT_TH-UV3R = TYTUV3RRadio
[2017-06-26 19:08:59,292] chirp.directory - INFO: Registered TYT_TH-UV3R-25 = TYTUV3R25Radio
[2017-06-26 19:08:59,293] chirp.directory - INFO: Registered TYT_TH-UVF8D = TYTUVF8DRadio
[2017-06-26 19:08:59,293] chirp.directory - INFO: Registered Kenwood_TH-D72_clone_mode = THD72Radio
[2017-06-26 19:08:59,294] chirp.directory - INFO: Registered TYT_TH-UVF1 = TYTTHUVF1Radio
[2017-06-26 19:08:59,294] chirp.directory - INFO: Registered Kenwood_TK-260 = TK260_Radio
[2017-06-26 19:08:59,294] chirp.directory - INFO: Registered Kenwood_TK-270 = TK270_Radio
[2017-06-26 19:08:59,294] chirp.directory - INFO: Registered Kenwood_TK-272 = TK272_Radio
[2017-06-26 19:08:59,294] chirp.directory - INFO: Registered Kenwood_TK-278 = TK278_Radio
[2017-06-26 19:08:59,294] chirp.directory - INFO: Registered Kenwood_TK-360 = TK360_Radio
[2017-06-26 19:08:59,294] chirp.directory - INFO: Registered Kenwood_TK-370 = TK370_Radio
[2017-06-26 19:08:59,295] chirp.directory - INFO: Registered Kenwood_TK-372 = TK372_Radio
[2017-06-26 19:08:59,295] chirp.directory - INFO: Registered Kenwood_TK-378 = TK378_Radio
[2017-06-26 19:08:59,295] chirp.directory - INFO: Registered Kenwood_TK-760 = TK760_Radio
[2017-06-26 19:08:59,295] chirp.directory - INFO: Registered Kenwood_TK-762 = TK762_Radio
[2017-06-26 19:08:59,295] chirp.directory - INFO: Registered Kenwood_TK-768 = TK768_Radio
[2017-06-26 19:08:59,295] chirp.directory - INFO: Registered Kenwood_TK-860 = TK860_Radio
[2017-06-26 19:08:59,295] chirp.directory - INFO: Registered Kenwood_TK-862 = TK862_Radio
[2017-06-26 19:08:59,296] chirp.directory - INFO: Registered Kenwood_TK-868 = TK868_Radio
[2017-06-26 19:08:59,296] chirp.directory - INFO: Registered Kenwood_TK-868G = TK868G_Radios
[2017-06-26 19:08:59,296] chirp.directory - INFO: Registered Kenwood_TK-862G = TK862G_Radios
[2017-06-26 19:08:59,296] chirp.directory - INFO: Registered Kenwood_TK-860G = TK860G_Radios
[2017-06-26 19:08:59,296] chirp.directory - INFO: Registered Kenwood_TK-768G = TK768G_Radios
[2017-06-26 19:08:59,297] chirp.directory - INFO: Registered Kenwood_TK-762G = TK762G_Radios
[2017-06-26 19:08:59,297] chirp.directory - INFO: Registered Kenwood_TK-760G = TK760G_Radios
[2017-06-26 19:08:59,297] chirp.directory - INFO: Registered Kenwood_TK-388G = TK388G_Radios
[2017-06-26 19:08:59,297] chirp.directory - INFO: Registered Kenwood_TK-378G = TK378G_Radios
[2017-06-26 19:08:59,297] chirp.directory - INFO: Registered Kenwood_TK-372G = TK372G_Radios
[2017-06-26 19:08:59,297] chirp.directory - INFO: Registered Kenwood_TK-370G = TK370G_Radios
[2017-06-26 19:08:59,297] chirp.directory - INFO: Registered Kenwood_TK-360G = TK360G_Radios
[2017-06-26 19:08:59,297] chirp.directory - INFO: Registered Kenwood_TK-278G = TK278G_Radios
[2017-06-26 19:08:59,297] chirp.directory - INFO: Registered Kenwood_TK-272G = TK272G_Radios
[2017-06-26 19:08:59,297] chirp.directory - INFO: Registered Kenwood_TK-270G = TK270G_Radios
[2017-06-26 19:08:59,298] chirp.directory - INFO: Registered Kenwood_TK-260G = TK260G_Radios
[2017-06-26 19:08:59,298] chirp.directory - INFO: Registered Kenwood_TK-7102 = KenwoodTK7102Radio
[2017-06-26 19:08:59,298] chirp.directory - INFO: Registered Kenwood_TK-8102 = KenwoodTK8102Radio
[2017-06-26 19:08:59,298] chirp.directory - INFO: Registered Kenwood_TK-7108 = KenwoodTK7108Radio
[2017-06-26 19:08:59,298] chirp.directory - INFO: Registered Kenwood_TK-8108 = KenwoodTK8108Radio
[2017-06-26 19:08:59,299] chirp.directory - INFO: Registered Kenwood_TS-2000 = TS2000Radio
[2017-06-26 19:08:59,299] chirp.directory - INFO: Registered BTECH_UV-5X3 = UV5X3
[2017-06-26 19:08:59,300] chirp.directory - INFO: Registered Baofeng_UV-6R = UV6R
[2017-06-26 19:08:59,300] chirp.directory - INFO: Registered Baofeng_UV-B5 = BaofengUVB5
[2017-06-26 19:08:59,300] chirp.directory - INFO: Registered BTECH_UV-50X3 = UV50X3
[2017-06-26 19:08:59,301] chirp.directory - INFO: Registered Yaesu_VX-170 = VX170Radio
[2017-06-26 19:08:59,301] chirp.directory - INFO: Registered Yaesu_VX-2 = VX2Radio
[2017-06-26 19:08:59,301] chirp.directory - INFO: Registered Yaesu_VX-3 = VX3Radio
[2017-06-26 19:08:59,302] chirp.directory - INFO: Registered Yaesu_VX-5 = VX5Radio
[2017-06-26 19:08:59,302] chirp.directory - INFO: Registered Yaesu_VX-6 = VX6Radio
[2017-06-26 19:08:59,302] chirp.directory - INFO: Registered Yaesu_VX-7 = VX7Radio
[2017-06-26 19:08:59,303] chirp.directory - INFO: Registered Yaesu_VX-8R = VX8Radio
[2017-06-26 19:08:59,303] chirp.directory - INFO: Registered Yaesu_VX-8DR = VX8DRadio
[2017-06-26 19:08:59,303] chirp.directory - INFO: Registered Yaesu_VX-8GE = VX8GERadio
[2017-06-26 19:08:59,304] chirp.directory - INFO: Registered Vertex_Standard_VXA-700 = VXA700Radio
Email was triggered for: Success
Sending email for trigger: Success
1
0
Well, it worked for me: I can run development chirp natively on my Macintosh macOS Sierra 10.12.5. I did scare myself by removing all of my environment to start from scratch so I could describe it to you… and then it didn’t work. I’ve consolidated several notes and may have elided or duplicated some stuff. I’m sorry if it doesn’t quite work.
Here’s what finally worked (again) … starting from something like scratch in a Terminal window. I happen to have Xcode installed as well; I do not think it’s a prerequisite.
I use homebrew; it doesn’t require root privileges. Install by
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)”
- You can then install all the brew-installed pieces at one time now. Many dependencies get loaded as well.
brew install mercurial libxml2 libxslt pygtk gtk-mac-integration
Two of the brewed pieces need to be linked into python*
echo /usr/local/opt/libxslt/lib/python2.7/site-packages >> /usr/local/lib/python2.7/site-packages/libxslt.pth
echo /usr/local/opt/libxml2/lib/python2.7/site-packages >> /usr/local/lib/python2.7/site-packages/libxslt.pth
- Eventually you will use mercurial to load the chirp source ("hg clone http://d-rats.com/hg/chirp.hg")
- get pyserial. I used "sudo easy-install pyserial". Perhaps better is "pip install pyserial”
The following two python installs may be optional, based upon README in the chirp source. I did them anyway.
- install suds ('pip install suds')
- Install python-support ('pip install support’)
Start up chirp
(cd chirp.hg; ./chirpw)
Woohoo: a window appears!
I still get warnings when I start up chirp. The following three show up before any radio data are displayed:
2017-06-25 19:02:19.088 Python[55559:1689118] *** WARNING: Method userSpaceScaleFactor in class NSView is deprecated on 10.7 and later. It should not be used in new applications. Use convertRectToBacking: instead.
/Users/declan/chirp.hg/chirp/ui/mainapp.py:1971: Warning: invalid cast from 'GtkMenuBar' to 'GtkWindow'
macapp.set_menu_bar(menu_bar)
/Users/declan/chirp.hg/chirp/ui/mainapp.py:1971: GtkWarning: gtk_window_add_accel_group: assertion 'GTK_IS_WINDOW (window)' failed
macapp.set_menu_bar(menu_bar)
A serial driver seems to be needed for many radios. Mine required to use drivers from Prolific (and of course, the vendor happily supply only windoze drivers. And told me explicitly they don’t support Macintosh.) I used http://prolificusa.com/files/PL2303_MacOSX_1.6.1_20160309.zip <http://prolificusa.com/files/PL2303_MacOSX_1.6.1_20160309.zip>
FTDI drivers on Macintosh are described elsewhere
SiLabs drivers at http://www.silabs.com/documents/public/software/Mac_OSX_VCP_Driver.zip <http://www.silabs.com/documents/public/software/Mac_OSX_VCP_Driver.zip>
* These may be in other locations than shown. You may have to do a
find /usr -name site-packages
to locate the pieces for this.
Declan Rieb, WD5EQY
1
0
25 Jun '17
A patch is attached here, and a radio image is attached to the tracker at:
http://chirp.danplanet.com/issues/959#note-15
Thanks,
-Windsor
1
0
I’m back from vacation and trying the FT2D again. I’m stuck on the memory label field. When read from the FT2D using the FT-1D format, the label comes out gibberish. Most other memory fields jibe quite nicely.
I’ve tried reading the source, but got lost in pythonese (translates and rshift and object details I just don’t know yet.)
SO….
when I look at the raw memory image coming from the FT2D, the memory labels (and the memory bank names) are in straight ASCII. (I too have not tried anything in Japanese format.)
But when I get that image into chirp using FT-1D template, the labels come out as mostly-unprintable characters. It looks to me as if translation or decrypting of some sort is happening.
Here’s an example [from my memory 0]
memory image shows ‘APRS US‘, with the standard 0xFF packing
00002d40 00 13 14 43 90 c0 00 00 41 50 52 53 20 55 53 ff |...C....APRS US.|
00002d50 ff ff ff ff ff ff ff ff 00 06 00 0c 00 0d 00 18 |................|
chirp shows ‘:’
BUT, the chirp browser shows the correct ASCII, presumably in python's Unicode string.
0041 0050 0052 0053 0020 0055 0053 x x x x x x x x x
Bank names are also gibberish, although the chirp browser seems to show them to be stored as ASCII bytes rather than python strings, although with the same 0xFF packing.
What happened between chirp browser and chirp? It’d seem to be straightforward to get the ASCII printed! Help please.
Declan Rieb, WD5EQY
4
4
18 Jun '17
# HG changeset patch
# User Jim Unroe <rock.unroe(a)gmail.com>
# Date 1497404221 14400
# Node ID 5af61447fc034ef20d7bf2e1799bd092b641c51e
# Parent fa2ef4dedc56b786c2ff94d70a5a9b2c94785973
[New Model] Add Support for Retevis RT23 Radio
This patch adds basic support for the Retevis RT23 radio.
#4619
diff -r fa2ef4dedc56 -r 5af61447fc03 chirp/drivers/retevis_rt23.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/chirp/drivers/retevis_rt23.py Tue Jun 13 21:37:01 2017 -0400
@@ -0,0 +1,872 @@
+# Copyright 2017 Jim Unroe <rock.unroe(a)gmail.com>
+#
+# 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 2 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 time
+import os
+import struct
+import re
+import logging
+
+from chirp import chirp_common, directory, memmap
+from chirp import bitwise, errors, util
+from chirp.settings import RadioSetting, RadioSettingGroup, \
+ RadioSettingValueInteger, RadioSettingValueList, \
+ RadioSettingValueBoolean, RadioSettingValueString, \
+ RadioSettings
+
+LOG = logging.getLogger(__name__)
+
+MEM_FORMAT = """
+struct memory {
+ lbcd rxfreq[4];
+ lbcd txfreq[4];
+ lbcd rxtone[2];
+ lbcd txtone[2];
+ u8 unknown1;
+ u8 pttid:2, // PTT-ID
+ unknown2:1,
+ signaling:1, // Signaling(ANI)
+ unknown3:1,
+ bcl:1, // Busy Channel Lockout
+ unknown4:2;
+ u8 unknown5:3,
+ highpower:1, // Power Level
+ isnarrow:1, // Bandwidth
+ scan:1, // Scan Add
+ unknown6:2;
+ u8 unknown7;
+};
+
+#seekto 0x0010;
+struct memory channels[128];
+
+#seekto 0x0810;
+struct memory vfo_a;
+struct memory vfo_b;
+
+#seekto 0x0830;
+struct {
+ u8 unknown_0830_1:4,
+ color:2, // Background Color
+ dst:1, // DTMF Side Tone
+ txsel:1; // Priority TX Channel Select
+ u8 scans:2, // Scan Mode
+ unknown_0831:1,
+ autolk:1, // Auto Key Lock
+ save:1, // Battery Save
+ beep:1, // Key Beep
+ voice:2; // Voice Prompt
+ u8 vfomr_fm:1, // FM Radio Display Mode
+ led:2, // Background Light
+ unknown_0832_2:1,
+ dw:1, // FM Radio Dual Watch
+ name:1, // Display Names
+ vfomr_a:2; // Display Mode A
+ u8 opnset:2, // Power On Message
+ unknown_0833_1:3,
+ dwait:1, // Dual Standby
+ vfomr_b:2; // Display Mode B
+ u8 mrcha; // mr a ch num
+ u8 mrchb; // mr b ch num
+ u8 fmch; // fm radio ch num
+ u8 unknown_0837_1:1,
+ ste:1, // Squelch Tail Eliminate
+ roger:1, // Roger Beep
+ unknown_0837_2:1,
+ vox:4; // VOX
+ u8 step:4, // Step
+ unknown_0838_1:4;
+ u8 squelch; // Squelch
+ u8 tot; // Time Out Timer
+ u8 rptmod:1, // Repeater Mode
+ volmod:2, // Volume Mode
+ rptptt:1, // Repeater PTT Switch
+ rptspk:1, // Repeater Speaker
+ relay:3; // Cross Band Repeater Enable
+ u8 unknown_083C:4, // 0x083C
+ rptrl:4; // Repeater TX Delay
+ u8 pf1:4, // Function Key 1
+ pf2:4; // Function Key 2
+ u8 vot; // VOX Delay Time
+} settings;
+
+#seekto 0x0848;
+struct {
+ char line1[7];
+} poweron_msg;
+
+struct limit {
+ bbcd lower[2];
+ bbcd upper[2];
+};
+
+#seekto 0x0850;
+struct {
+ struct limit vhf;
+ struct limit uhf;
+} limits;
+
+#seekto 0x08D0;
+struct {
+ char name[7];
+ u8 unknown2[1];
+} names[128];
+
+#seekto 0x0D20;
+u8 usedflags[16];
+u8 scanflags[16];
+
+#seekto 0x0FA0;
+struct {
+ u8 unknown_0FA0_1:4,
+ dispab:1, // select a/b
+ unknown_0FA0_2:3;
+} settings2;
+"""
+
+CMD_ACK = "\x06"
+BLOCK_SIZE = 0x10
+
+RT23_POWER_LEVELS = [chirp_common.PowerLevel("Low", watts=1.00),
+ chirp_common.PowerLevel("High", watts=2.50)]
+
+
+RT23_DTCS = sorted(chirp_common.DTCS_CODES +
+ [17, 50, 55, 135, 217, 254, 305, 645, 765])
+
+RT23_CHARSET = chirp_common.CHARSET_UPPER_NUMERIC + \
+ ":;<=>?@ !\"#$%&'()*+,-./"
+
+LIST_COLOR = ["Blue", "Orange", "Purple"]
+LIST_LED = ["Off", "On", "Auto"]
+LIST_OPNSET = ["Full", "Voltage", "Message"]
+LIST_PFKEY = [
+ "Radio",
+ "Sub-channel Sent",
+ "Scan",
+ "Alarm",
+ "DTMF",
+ "Squelch Off Momentarily",
+ "Battery Power Indicator",
+ "Tone 1750",
+ "Tone 2100",
+ "Tone 1000",
+ "Tone 1450"]
+LIST_PTTID = ["Off", "BOT", "EOT", "Both"]
+LIST_RPTMOD = ["Single", "Double"]
+LIST_RPTRL = ["0.5S", "1.0S", "1.5S", "2.0S", "2.5S", "3.0S", "3.5S", "4.0S",
+ "4.5S"]
+LIST_SCANS = ["Time Operated", "Carrier Operated", "Search"]
+LIST_SIGNALING = ["No", "DTMF"]
+LIST_TOT = ["OFF"] + ["%s seconds" % x for x in range(30, 300, 30)]
+LIST_TXSEL = ["Edit", "Busy"]
+LIST_STEP = ["2.50K", "5.00K", "6.25K", "10.00K", "12,50K", "20.00K", "25.00K",
+ "50.00K"]
+LIST_VFOMR = ["VFO", "MR(Frequency)", "MR(Channel #/Name)"]
+LIST_VFOMRFM = ["VFO", "Channel"]
+LIST_VOICE = ["Off", "Chinese", "English"]
+LIST_VOLMOD = ["Off", "Sub", "Main"]
+LIST_VOT = ["0.5S", "1.0S", "1.5S", "2.0S", "3.0S"]
+LIST_VOX = ["OFF"] + ["%s" % x for x in range(1, 6)]
+
+
+def _rt23_enter_programming_mode(radio):
+ serial = radio.pipe
+
+ magic = "PROIUAM"
+ exito = False
+ for i in range(0, 5):
+ for j in range(0, len(magic)):
+ time.sleep(0.005)
+ serial.write(magic[j])
+ ack = serial.read(1)
+
+ try:
+ if ack == CMD_ACK:
+ exito = True
+ break
+ except:
+ LOG.debug("Attempt #%s, failed, trying again" % i)
+ pass
+
+ # check if we had EXITO
+ if exito is False:
+ msg = "The radio did not accept program mode after five tries.\n"
+ msg += "Check you interface cable and power cycle your radio."
+ raise errors.RadioError(msg)
+
+ try:
+ serial.write("\x02")
+ ident = serial.read(8)
+ except:
+ raise errors.RadioError("Error communicating with radio")
+
+ if not ident.startswith("P31183"):
+ LOG.debug(util.hexprint(ident))
+ raise errors.RadioError("Radio returned unknown identification string")
+
+ try:
+ serial.write(CMD_ACK)
+ ack = serial.read(1)
+ except:
+ raise errors.RadioError("Error communicating with radio")
+
+ if ack != CMD_ACK:
+ raise errors.RadioError("Radio refused to enter programming mode")
+
+
+def _rt23_exit_programming_mode(radio):
+ serial = radio.pipe
+ try:
+ serial.write("E")
+ except:
+ raise errors.RadioError("Radio refused to exit programming mode")
+
+
+def _rt23_read_block(radio, block_addr, block_size):
+ serial = radio.pipe
+
+ cmd = struct.pack(">cHb", 'R', block_addr, BLOCK_SIZE)
+ expectedresponse = "W" + cmd[1:]
+ LOG.debug("Reading block %04x..." % (block_addr))
+
+ try:
+ serial.write(cmd)
+ response = serial.read(4 + BLOCK_SIZE + 1)
+ if response[:4] != expectedresponse:
+ raise Exception("Error reading block %04x." % (block_addr))
+
+ chunk = response[4:]
+
+ cs = 0
+ for byte in chunk[:-1]:
+ cs += ord(byte)
+ if ord(chunk[-1]) != (cs & 0xFF):
+ raise Exception("Block failed checksum!")
+
+ block_data = chunk[:-1]
+ except:
+ raise errors.RadioError("Failed to read block at %04x" % block_addr)
+
+ return block_data
+
+
+def _rt23_write_block(radio, block_addr, block_size):
+ serial = radio.pipe
+
+ cmd = struct.pack(">cHb", 'W', block_addr, BLOCK_SIZE)
+ data = radio.get_mmap()[block_addr:block_addr + BLOCK_SIZE]
+ cs = 0
+ for byte in data:
+ cs += ord(byte)
+ data += chr(cs & 0xFF)
+
+ LOG.debug("Writing Data:")
+ LOG.debug(util.hexprint(cmd + data))
+
+ try:
+ for j in range(0, len(cmd)):
+ time.sleep(0.002)
+ serial.write(cmd[j])
+ for j in range(0, len(data)):
+ time.sleep(0.002)
+ serial.write(data[j])
+ if serial.read(1) != CMD_ACK:
+ raise Exception("No ACK")
+ except:
+ raise errors.RadioError("Failed to send block "
+ "to radio at %04x" % block_addr)
+
+
+def do_download(radio):
+ LOG.debug("download")
+ _rt23_enter_programming_mode(radio)
+
+ data = ""
+
+ status = chirp_common.Status()
+ status.msg = "Cloning from radio"
+
+ status.cur = 0
+ status.max = radio._memsize
+
+ for addr in range(0, radio._memsize, BLOCK_SIZE):
+ status.cur = addr + BLOCK_SIZE
+ radio.status_fn(status)
+
+ block = _rt23_read_block(radio, addr, BLOCK_SIZE)
+ if addr == 0 and block.startswith("\xFF" * 6):
+ block = "P31183" + "\xFF" * 10
+ data += block
+
+ LOG.debug("Address: %04x" % addr)
+ LOG.debug(util.hexprint(block))
+
+ _rt23_exit_programming_mode(radio)
+
+ return memmap.MemoryMap(data)
+
+
+def do_upload(radio):
+ status = chirp_common.Status()
+ status.msg = "Uploading to radio"
+
+ _rt23_enter_programming_mode(radio)
+
+ status.cur = 0
+ status.max = radio._memsize
+
+ for start_addr, end_addr in radio._ranges:
+ for addr in range(start_addr, end_addr, BLOCK_SIZE):
+ status.cur = addr + BLOCK_SIZE
+ radio.status_fn(status)
+ _rt23_write_block(radio, addr, BLOCK_SIZE)
+
+
+def model_match(cls, data):
+ """Match the opened/downloaded image to the correct version"""
+
+ if len(data) == 0x1000:
+ rid = data[0x0000:0x0006]
+ return rid == "P31183"
+ else:
+ return False
+
+
+def _split(rf, f1, f2):
+ """Returns False if the two freqs are in the same band (no split)
+ or True otherwise"""
+
+ # determine if the two freqs are in the same band
+ for low, high in rf.valid_bands:
+ if f1 >= low and f1 <= high and \
+ f2 >= low and f2 <= high:
+ # if the two freqs are on the same Band this is not a split
+ return False
+
+ # if you get here is because the freq pairs are split
+ return True
+
+
+(a)directory.register
+class RT23Radio(chirp_common.CloneModeRadio):
+ """RETEVIS RT23"""
+ VENDOR = "Retevis"
+ MODEL = "RT23"
+ BAUD_RATE = 9600
+
+ _ranges = [
+ (0x0000, 0x0EC0),
+ ]
+ _memsize = 0x1000
+
+ def get_features(self):
+ rf = chirp_common.RadioFeatures()
+ rf.has_settings = True
+ rf.has_bank = False
+ rf.has_ctone = True
+ rf.has_cross = True
+ rf.has_rx_dtcs = True
+ rf.has_tuning_step = False
+ rf.can_odd_split = True
+ rf.valid_name_length = 7
+ rf.valid_characters = RT23_CHARSET
+ rf.has_name = True
+ rf.valid_skips = ["", "S"]
+ rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"]
+ rf.valid_cross_modes = ["Tone->Tone", "Tone->DTCS", "DTCS->Tone",
+ "->Tone", "->DTCS", "DTCS->", "DTCS->DTCS"]
+ rf.valid_power_levels = RT23_POWER_LEVELS
+ rf.valid_duplexes = ["", "-", "+", "split", "off"]
+ rf.valid_modes = ["FM", "NFM"] # 25 KHz, 12.5 KHz.
+ rf.memory_bounds = (1, 128)
+ rf.valid_bands = [
+ (136000000, 174000000),
+ (400000000, 480000000)]
+
+ return rf
+
+ def process_mmap(self):
+ self._memobj = bitwise.parse(MEM_FORMAT, self._mmap)
+
+ def sync_in(self):
+ """Download from radio"""
+ try:
+ data = do_download(self)
+ except errors.RadioError:
+ # Pass through any real errors we raise
+ raise
+ except:
+ # If anything unexpected happens, make sure we raise
+ # a RadioError and log the problem
+ LOG.exception('Unexpected error during download')
+ raise errors.RadioError('Unexpected error communicating '
+ 'with the radio')
+ self._mmap = data
+ self.process_mmap()
+
+ def sync_out(self):
+ """Upload to radio"""
+ try:
+ do_upload(self)
+ except:
+ # If anything unexpected happens, make sure we raise
+ # a RadioError and log the problem
+ LOG.exception('Unexpected error during upload')
+ raise errors.RadioError('Unexpected error communicating '
+ 'with the radio')
+
+ def get_raw_memory(self, number):
+ return repr(self._memobj.memory[number - 1])
+
+ def decode_tone(self, val):
+ """Parse the tone data to decode from mem, it returns:
+ Mode (''|DTCS|Tone), Value (None|###), Polarity (None,N,R)"""
+ if val.get_raw() == "\xFF\xFF":
+ return '', None, None
+
+ val = int(val)
+ if val >= 12000:
+ a = val - 12000
+ return 'DTCS', a, 'R'
+ elif val >= 8000:
+ a = val - 8000
+ return 'DTCS', a, 'N'
+ else:
+ a = val / 10.0
+ return 'Tone', a, None
+
+ def encode_tone(self, memval, mode, value, pol):
+ """Parse the tone data to encode from UI to mem"""
+ if mode == '':
+ memval[0].set_raw(0xFF)
+ memval[1].set_raw(0xFF)
+ elif mode == 'Tone':
+ memval.set_value(int(value * 10))
+ elif mode == 'DTCS':
+ flag = 0x80 if pol == 'N' else 0xC0
+ memval.set_value(value)
+ memval[1].set_bits(flag)
+ else:
+ raise Exception("Internal error: invalid mode `%s'" % mode)
+
+ def get_memory(self, number):
+ mem = chirp_common.Memory()
+ _mem = self._memobj.channels[number-1]
+ _nam = self._memobj.names[number - 1]
+ mem.number = number
+ bitpos = (1 << ((number - 1) % 8))
+ bytepos = ((number - 1) / 8)
+ _scn = self._memobj.scanflags[bytepos]
+ _usd = self._memobj.usedflags[bytepos]
+ isused = bitpos & int(_usd)
+ isscan = bitpos & int(_scn)
+
+ if not isused:
+ mem.empty = True
+ return mem
+
+ mem.freq = int(_mem.rxfreq) * 10
+
+ # We'll consider any blank (i.e. 0MHz frequency) to be empty
+ if mem.freq == 0:
+ mem.empty = True
+ return mem
+
+ if _mem.rxfreq.get_raw() == "\xFF\xFF\xFF\xFF":
+ mem.empty = True
+ return mem
+
+ if _mem.get_raw() == ("\xFF" * 16):
+ LOG.debug("Initializing empty memory")
+ _mem.set_raw("\x00" * 16)
+
+ # Freq and offset
+ mem.freq = int(_mem.rxfreq) * 10
+ # tx freq can be blank
+ if _mem.get_raw()[4] == "\xFF":
+ # TX freq not set
+ mem.offset = 0
+ mem.duplex = "off"
+ else:
+ # TX freq set
+ offset = (int(_mem.txfreq) * 10) - mem.freq
+ if offset != 0:
+ if _split(self.get_features(), mem.freq, int(_mem.txfreq) * 10):
+ mem.duplex = "split"
+ mem.offset = int(_mem.txfreq) * 10
+ elif offset < 0:
+ mem.offset = abs(offset)
+ mem.duplex = "-"
+ elif offset > 0:
+ mem.offset = offset
+ mem.duplex = "+"
+ else:
+ mem.offset = 0
+
+ for char in _nam.name:
+ if str(char) == "\xFF":
+ char = " "
+ mem.name += str(char)
+ mem.name = mem.name.rstrip()
+
+ mem.mode = _mem.isnarrow and "NFM" or "FM"
+
+ rxtone = txtone = None
+ txtone = self.decode_tone(_mem.txtone)
+ rxtone = self.decode_tone(_mem.rxtone)
+ chirp_common.split_tone_decode(mem, txtone, rxtone)
+
+ mem.power = RT23_POWER_LEVELS[_mem.highpower]
+
+ if not isscan:
+ mem.skip = "S"
+
+ mem.extra = RadioSettingGroup("Extra", "extra")
+
+ rs = RadioSetting("bcl", "BCL",
+ RadioSettingValueBoolean(_mem.bcl))
+ mem.extra.append(rs)
+
+ rs = RadioSetting("pttid", "PTT ID",
+ RadioSettingValueList(
+ LIST_PTTID, LIST_PTTID[_mem.pttid]))
+ mem.extra.append(rs)
+
+ rs = RadioSetting("signaling", "Optional Signaling",
+ RadioSettingValueList(LIST_SIGNALING,
+ LIST_SIGNALING[_mem.signaling]))
+ mem.extra.append(rs)
+
+ return mem
+
+ def set_memory(self, mem):
+ LOG.debug("Setting %i(%s)" % (mem.number, mem.extd_number))
+ _mem = self._memobj.channels[mem.number - 1]
+ _nam = self._memobj.names[mem.number - 1]
+ bitpos = (1 << ((mem.number - 1) % 8))
+ bytepos = ((mem.number - 1) / 8)
+ _scn = self._memobj.scanflags[bytepos]
+ _usd = self._memobj.usedflags[bytepos]
+
+ if mem.empty:
+ _mem.set_raw("\xFF" * 16)
+ _nam.name = ("\xFF" * 7)
+ _usd &= ~bitpos
+ _scn &= ~bitpos
+ return
+ else:
+ _usd |= bitpos
+
+ if _mem.get_raw() == ("\xFF" * 16):
+ LOG.debug("Initializing empty memory")
+ _mem.set_raw("\x00" * 16)
+ _scn |= bitpos
+
+ _mem.rxfreq = mem.freq / 10
+
+ if mem.duplex == "off":
+ for i in range(0, 4):
+ _mem.txfreq[i].set_raw("\xFF")
+ elif mem.duplex == "split":
+ _mem.txfreq = mem.offset / 10
+ elif mem.duplex == "+":
+ _mem.txfreq = (mem.freq + mem.offset) / 10
+ elif mem.duplex == "-":
+ _mem.txfreq = (mem.freq - mem.offset) / 10
+ else:
+ _mem.txfreq = mem.freq / 10
+
+ _namelength = self.get_features().valid_name_length
+ for i in range(_namelength):
+ try:
+ _nam.name[i] = mem.name[i]
+ except IndexError:
+ _nam.name[i] = "\xFF"
+
+ _mem.scan = mem.skip != "S"
+ if mem.skip == "S":
+ _scn &= ~bitpos
+ else:
+ _scn |= bitpos
+ _mem.isnarrow = mem.mode == "NFM"
+
+ ((txmode, txtone, txpol), (rxmode, rxtone, rxpol)) = \
+ chirp_common.split_tone_encode(mem)
+ self.encode_tone(_mem.txtone, txmode, txtone, txpol)
+ self.encode_tone(_mem.rxtone, rxmode, rxtone, rxpol)
+
+ _mem.highpower = mem.power == RT23_POWER_LEVELS[1]
+
+ for setting in mem.extra:
+ setattr(_mem, setting.get_name(), setting.value)
+
+ def get_settings(self):
+ _settings = self._memobj.settings
+ _mem = self._memobj
+ basic = RadioSettingGroup("basic", "Basic Settings")
+ advanced = RadioSettingGroup("advanced", "Advanced Settings")
+ other = RadioSettingGroup("other", "Other Settings")
+ workmode = RadioSettingGroup("workmode", "Workmode Settings")
+ fmradio = RadioSettingGroup("fmradio", "FM Radio Settings")
+ top = RadioSettings(basic, advanced, other, workmode, fmradio)
+
+ save = RadioSetting("save", "Battery Saver",
+ RadioSettingValueBoolean(_settings.save))
+ basic.append(save)
+
+ vox = RadioSetting("vox", "VOX Gain",
+ RadioSettingValueList(
+ LIST_VOX, LIST_VOX[_settings.vox]))
+ basic.append(vox)
+
+ squelch = RadioSetting("squelch", "Squelch Level",
+ RadioSettingValueInteger(
+ 0, 9, _settings.squelch))
+ basic.append(squelch)
+
+ relay = RadioSetting("relay", "Repeater",
+ RadioSettingValueBoolean(_settings.relay))
+ basic.append(relay)
+
+ tot = RadioSetting("tot", "Time-out timer", RadioSettingValueList(
+ LIST_TOT, LIST_TOT[_settings.tot]))
+ basic.append(tot)
+
+ beep = RadioSetting("beep", "Key Beep",
+ RadioSettingValueBoolean(_settings.beep))
+ basic.append(beep)
+
+ color = RadioSetting("color", "Background Color", RadioSettingValueList(
+ LIST_COLOR, LIST_COLOR[_settings.color - 1]))
+ basic.append(color)
+
+ vot = RadioSetting("vot", "VOX Delay Time", RadioSettingValueList(
+ LIST_VOT, LIST_VOT[_settings.vot]))
+ basic.append(vot)
+
+ dwait = RadioSetting("dwait", "Dual Standby",
+ RadioSettingValueBoolean(_settings.dwait))
+ basic.append(dwait)
+
+ led = RadioSetting("led", "Background Light", RadioSettingValueList(
+ LIST_LED, LIST_LED[_settings.led]))
+ basic.append(led)
+
+ voice = RadioSetting("voice", "Voice Prompt", RadioSettingValueList(
+ LIST_VOICE, LIST_VOICE[_settings.voice]))
+ basic.append(voice)
+
+ roger = RadioSetting("roger", "Roger Beep",
+ RadioSettingValueBoolean(_settings.roger))
+ basic.append(roger)
+
+ autolk = RadioSetting("autolk", "Auto Key Lock",
+ RadioSettingValueBoolean(_settings.autolk))
+ basic.append(autolk)
+
+ opnset = RadioSetting("opnset", "Open Mode Set",
+ RadioSettingValueList(
+ LIST_OPNSET, LIST_OPNSET[_settings.opnset]))
+ basic.append(opnset)
+
+ def _filter(name):
+ filtered = ""
+ for char in str(name):
+ if char in chirp_common.CHARSET_ASCII:
+ filtered += char
+ else:
+ filtered += " "
+ return filtered
+
+ _msg = self._memobj.poweron_msg
+ ponmsg = RadioSetting("poweron_msg.line1", "Power-On Message",
+ RadioSettingValueString(
+ 0, 7, _filter(_msg.line1)))
+ basic.append(ponmsg)
+
+
+ scans = RadioSetting("scans", "Scan Mode", RadioSettingValueList(
+ LIST_SCANS, LIST_SCANS[_settings.scans]))
+ basic.append(scans)
+
+ dw = RadioSetting("dw", "FM Radio Dual Watch",
+ RadioSettingValueBoolean(_settings.dw))
+ basic.append(dw)
+
+ name = RadioSetting("name", "Display Names",
+ RadioSettingValueBoolean(_settings.name))
+ basic.append(name)
+
+ rptrl = RadioSetting("rptrl", "Repeater TX Delay",
+ RadioSettingValueList(LIST_RPTRL, LIST_RPTRL[
+ _settings.rptrl]))
+ basic.append(rptrl)
+
+ rptspk = RadioSetting("rptspk", "Repeater Speaker",
+ RadioSettingValueBoolean(_settings.rptspk))
+ basic.append(rptspk)
+
+ rptptt = RadioSetting("rptptt", "Repeater PTT Switch",
+ RadioSettingValueBoolean(_settings.rptptt))
+ basic.append(rptptt)
+
+ rptmod = RadioSetting("rptmod", "Repeater Mode",
+ RadioSettingValueList(
+ LIST_RPTMOD, LIST_RPTMOD[_settings.rptmod]))
+ basic.append(rptmod)
+
+ volmod = RadioSetting("volmod", "Volume Mode",
+ RadioSettingValueList(
+ LIST_VOLMOD, LIST_VOLMOD[_settings.volmod]))
+ basic.append(volmod)
+
+ dst = RadioSetting("dst", "DTMF Side Tone",
+ RadioSettingValueBoolean(_settings.dst))
+ basic.append(dst)
+
+ txsel = RadioSetting("txsel", "Priority TX Channel",
+ RadioSettingValueList(
+ LIST_TXSEL, LIST_TXSEL[_settings.txsel]))
+ basic.append(txsel)
+
+ ste = RadioSetting("ste", "Squelch Tail Eliminate",
+ RadioSettingValueBoolean(_settings.ste))
+ basic.append(ste)
+
+ #advanced
+ if _settings.pf1 > 0x0A:
+ val = 0x00
+ else:
+ val = _settings.pf1
+ pf1 = RadioSetting("pf1", "PF1 Key",
+ RadioSettingValueList(
+ LIST_PFKEY, LIST_PFKEY[val]))
+ advanced.append(pf1)
+
+ if _settings.pf2 > 0x0A:
+ val = 0x00
+ else:
+ val = _settings.pf2
+ pf2 = RadioSetting("pf2", "PF2 Key",
+ RadioSettingValueList(
+ LIST_PFKEY, LIST_PFKEY[val]))
+ advanced.append(pf2)
+
+ # other
+ _limit = str(int(_mem.limits.vhf.lower) / 10)
+ val = RadioSettingValueString(0, 3, _limit)
+ val.set_mutable(False)
+ rs = RadioSetting("limits.vhf.lower", "VHF low", val)
+ other.append(rs)
+
+ _limit = str(int(_mem.limits.vhf.upper) / 10)
+ val = RadioSettingValueString(0, 3, _limit)
+ val.set_mutable(False)
+ rs = RadioSetting("limits.vhf.upper", "VHF high", val)
+ other.append(rs)
+
+ _limit = str(int(_mem.limits.uhf.lower) / 10)
+ val = RadioSettingValueString(0, 3, _limit)
+ val.set_mutable(False)
+ rs = RadioSetting("limits.uhf.lower", "UHF low", val)
+ other.append(rs)
+
+ _limit = str(int(_mem.limits.uhf.upper) / 10)
+ val = RadioSettingValueString(0, 3, _limit)
+ val.set_mutable(False)
+ rs = RadioSetting("limits.uhf.upper", "UHF high", val)
+ other.append(rs)
+
+ #work mode
+ vfomr_a = RadioSetting("vfomr_a", "Display Mode A",
+ RadioSettingValueList(
+ LIST_VFOMR, LIST_VFOMR[_settings.vfomr_a]))
+ workmode.append(vfomr_a)
+
+ vfomr_b = RadioSetting("vfomr_b", "Display Mode B",
+ RadioSettingValueList(
+ LIST_VFOMR, LIST_VFOMR[_settings.vfomr_b]))
+ workmode.append(vfomr_b)
+
+ mrcha = RadioSetting("mrcha", "Channel # A",
+ RadioSettingValueInteger(
+ 1, 128, _settings.mrcha))
+ workmode.append(mrcha)
+
+ mrchb = RadioSetting("mrchb", "Channel # B",
+ RadioSettingValueInteger(
+ 1, 128, _settings.mrchb))
+ workmode.append(mrchb)
+
+ #fm radio
+ vfomr_fm = RadioSetting("vfomr_fm", "FM Radio Display Mode",
+ RadioSettingValueList(
+ LIST_VFOMRFM, LIST_VFOMRFM[
+ _settings.vfomr_fm]))
+ fmradio.append(vfomr_fm)
+
+ fmch = RadioSetting("fmch", "FM Radio Channel #",
+ RadioSettingValueInteger(
+ 1, 25, _settings.fmch))
+ fmradio.append(fmch)
+
+ return top
+
+ def set_settings(self, settings):
+ for element in settings:
+ if not isinstance(element, RadioSetting):
+ self.set_settings(element)
+ continue
+ else:
+ try:
+ if "." in element.get_name():
+ bits = element.get_name().split(".")
+ obj = self._memobj
+ for bit in bits[:-1]:
+ obj = getattr(obj, bit)
+ setting = bits[-1]
+ else:
+ obj = self._memobj.settings
+ setting = element.get_name()
+
+ if element.has_apply_callback():
+ LOG.debug("Using apply callback")
+ element.run_apply_callback()
+ elif setting == "color":
+ setattr(obj, setting, int(element.value) + 1)
+ elif element.value.get_mutable():
+ LOG.debug("Setting %s = %s" % (setting, element.value))
+ setattr(obj, setting, element.value)
+ except Exception, e:
+ LOG.debug(element.get_name())
+ raise
+
+ @classmethod
+ def match_model(cls, filedata, filename):
+ match_size = False
+ match_model = False
+
+ # testing the file data size
+ if len(filedata) in [0x1000, ]:
+ match_size = True
+
+ # testing the model fingerprint
+ match_model = model_match(cls, filedata)
+
+ if match_size and match_model:
+ return True
+ else:
+ return False
4
21