Skip to content

Instantly share code, notes, and snippets.

@mlt
Created January 22, 2016 05:56
Show Gist options
  • Save mlt/d145fa0ef48ccc7a4e04 to your computer and use it in GitHub Desktop.
Save mlt/d145fa0ef48ccc7a4e04 to your computer and use it in GitHub Desktop.
chirp_rst599
# Copyright 2015 Mikhail Titov <mlt@gmx.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 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 struct
import time
import os
import logging
from chirp import chirp_common, errors, util, directory, memmap
from chirp import bitwise
from chirp.settings import RadioSetting, RadioSettingGroup, \
RadioSettingValueInteger, RadioSettingValueList, \
RadioSettingValueBoolean, RadioSettingValueString, \
RadioSettingValueFloat, InvalidValueError, RadioSettings
from textwrap import dedent
LOG = logging.getLogger(__name__)
##seekto 0x19a1; logo
#seekto 0x0016;
MEM_FORMAT = """
struct {
lbcd rxfreq[4];
lbcd txfreq[4];
ul16 rxtone;
ul16 txtone;
u8 _3_unknown_1:3,
bcl:2,
_3_unknown_2:3;
u8 scan:1,
power:2,
wide:1,
splitdup:1,
_2_unknown_2:3;
u8 signal:3,
_1_unk:1,
signal_no:4;
u8 _0_unknown_1:3,
iswidex:1,
_0_unknown_2:4;
char name[6];
} memory[241];
struct channel {
lbcd freq[4];
ul16 rxtone;
ul16 txtone;
u8 _2_unk:2,
bcl:2,
_4_unk:4;
u8 _unk1:1,
power:2,
wide:1,
unk2:4;
u8 _unk6[6];
u8 mode;
u8 _unk4[4];
u8 _unk:7,
vox:1;
u8 _unk10[10];
};
#seekto 0x14e0;
struct {
struct channel a;
struct channel b;
u16 save_year;
u8 save_month;
u8 save_day;
u16 bcd_time;
u8 LiSheng[10];
u8 toa;
u8 tot;
u8 _unk3[3];
u8 wtled;
u8 txled;
u8 rxled;
u8 _unk3[3];
u8 key_beep;
u8 save;
u8 _unk3[3];
u8 _unk3[3];
u8 squelch;
u8 vox_gain;
u16 vox_delay;
u8 _unk2[2];
u8 alarm_ring;
u8 _unk1;
u8 priority;
u8 name_display;
u8 oneline;
u8 abswitch;
u8 burst;
u8 _unk4[4];
u8 _unk:4,
_unk:3,
whisper:1;
u8 password_set;
char password[6];
u8 _unk4[4];
u8 _unk7[16];
u8 _unk7[16];
u8 _unk6[6];
u8 fm_step;
u32 fm_freq;
u32 fm_low;
u32 fm_high;
u32 fm_preset[20];
} settings;
#seek 0x1667;
struct {
u8 no;
u8 code[16];
u8 length;
char name[6];
u8 _unk;
} pttid[30];
#seekto 0x1979;
struct {
u32 vhf_tx_min;
u32 vhf_tx_max;
u32 vhf_rx_min;
u32 vhf_rx_max;
u32 uhf_tx_min;
u32 uhf_tx_max;
u32 uhf_rx_min;
u32 uhf_rx_max;
u32 _unk_u32;
u32 _unk_u32;
} band_limits;
u8 logo;
struct {
u8 line_no;
u8 font;
u8 align;
char line[16];
} poweron_msg[4];
#seekto 0x4100;
struct {
u32 start;
u32 to;
u8 dir;
u32 offset;
} ars[16];
#seekto 0x41d8;
struct {
u8 _unk9[9];
char name[6];
} tone2[16];
#seekto 0x4317;
struct {
u8 _unk8[8];
char name[6];
} tone5[16];
"""
AB_LIST = ["A", "B"]
ALMOD_LIST = ["Site", "Tone", "Code"]
BANDWIDTH_LIST = ["Wide", "Narrow"]
COLOR_LIST = ["Red", "Green", "Blue", "Yellow", "Purple", "Cyan", "White"]
DTMFSPEED_LIST = ["%s ms" % x for x in range(50, 2010, 10)]
DTMFST_LIST = ["OFF", "DT-ST", "ANI-ST", "DT+ANI"]
MODE_LIST = ["Frequency", "Name", "Channel"]
PONMSG_LIST = ["Full", "Message"]
PTTID_LIST = ["Off", "BOT", "EOT", "Both"]
PTTIDCODE_LIST = ["%s" % x for x in range(1, 16)]
RTONE_LIST = ["1000 Hz", "1450 Hz", "1750 Hz", "2100Hz"]
RESUME_LIST = ["TO", "CO", "SE"]
ROGERRX_LIST = ["Off"] + AB_LIST
RPSTE_LIST = ["OFF"] + ["%s" % x for x in range(1, 11)]
SAVE_LIST = ["Off", "1:1", "1:2", "1:3", "1:4"]
SCODE_LIST = ["%s" % x for x in range(1, 16)]
SHIFTD_LIST = ["Off", "+", "-"]
STEDELAY_LIST = ["OFF"] + ["%s ms" % x for x in range(100, 1100, 100)]
STEPS = [2.5, 5.0, 6.25, 10.0, 12.5, 25.0]
STEP_LIST = [str(x) for x in STEPS]
STEPS = [2.5, 5.0, 6.25, 10.0, 12.5, 20.0, 25.0, 50.0]
STEP291_LIST = [str(x) for x in STEPS]
TDRAB_LIST = ["Off"] + AB_LIST
TDRCH_LIST = ["CH%s" % x for x in range(1, 129)]
TIMEOUT_LIST = ["%s sec" % x for x in range(15, 615, 15)]
TXPOWER3_LIST = ["Low", "High", "Mid"]
VOICE_LIST = ["Off", "English", "Chinese"]
VOX_LIST = ["OFF"] + ["%s" % x for x in range(1, 11)]
WORKMODE_LIST = ["Frequency", "Channel"]
SETTING_LISTS = {
"almod": ALMOD_LIST,
# "aniid": PTTID_LIST,
"displayab": AB_LIST,
"dtmfst": DTMFST_LIST,
"dtmfspeed": DTMFSPEED_LIST,
"mdfa": MODE_LIST,
"mdfb": MODE_LIST,
"ponmsg": PONMSG_LIST,
# "pttid": PTTID_LIST,
"rtone": RTONE_LIST,
"rogerrx": ROGERRX_LIST,
"rpste": RPSTE_LIST,
"rxled": COLOR_LIST,
"save": SAVE_LIST,
"scode": PTTIDCODE_LIST,
"screv": RESUME_LIST,
"sftd": SHIFTD_LIST,
"stedelay": STEDELAY_LIST,
"step": STEP_LIST,
"step291": STEP291_LIST,
"tdrab": TDRAB_LIST,
"tdrch": TDRCH_LIST,
"timeout": TIMEOUT_LIST,
"txled": COLOR_LIST,
"power": TXPOWER3_LIST,
"voice": VOICE_LIST,
"vox": VOX_LIST,
"widenarr": BANDWIDTH_LIST,
"workmode": WORKMODE_LIST,
"wtled": COLOR_LIST
}
def _do_status(radio, block):
status = chirp_common.Status()
status.msg = "Cloning"
status.cur = block
status.max = radio.get_memsize()
radio.status_fn(status)
def _upper_band_from_data(data):
return data[0x03:0x04]
def _upper_band_from_image(radio):
return _upper_band_from_data(radio.get_mmap())
def _firmware_version_from_data(data, version_start, version_stop):
version_tag = data[version_start:version_stop]
return version_tag
def _firmware_version_from_image(radio):
version = _firmware_version_from_data(radio.get_mmap(),
radio._fw_ver_file_start,
radio._fw_ver_file_stop)
LOG.debug("_firmware_version_from_image: " + util.hexprint(version))
return version
def _special_block_from_data(data, special_block_start, special_block_stop):
special_block_tag = data[special_block_start:special_block_stop]
return special_block_tag
def _special_block_from_image(radio):
special_block = _special_block_from_data(radio.get_mmap(), 0x0CFA, 0x0D01)
LOG.debug("_special_block_from_image: " + util.hexprint(special_block))
return special_block
def _ident_radio(radio):
error = None
try:
data = _do_ident(radio)
return data
except errors.RadioError, e:
LOG.error(e)
error = e
time.sleep(2)
if error:
raise error
raise errors.RadioError("Radio did not respond")
def _do_ident(radio):
serial = radio.pipe
serial.setTimeout(1)
LOG.info("Sending Magic")
serial.write("\x06YASHE\xff\xff")
data = serial.read(8)
if data != "TDXSD01\xff":
raise errors.RadioError("Wrong reply")
LOG.info("Confirming")
serial.write("\x02")
ack = serial.read(1)
if ack != "\x06":
if ack:
LOG.debug(repr(ack))
raise errors.RadioError("Radio did not respond")
LOG.info("Sending more Magic")
serial.write("\x00\x91\x52\x16\xb7\x59\xfa\x9c\x3d\xde\x80\x21\xc2\x64\x05\x86") # TODO needs documentation badly. Changes often
ack = serial.read(1)
if ack != "\x06":
if ack:
LOG.debug(repr(ack))
raise errors.RadioError("Radio did not respond")
return data
def _read_block(radio, start, size):
msg = struct.pack(">BHB", ord("R"), start, size)
radio.pipe.write(msg)
answer = radio.pipe.read(4)
if len(answer) != 4:
raise errors.RadioError("Radio refused to send block 0x%04x" % start)
cmd, addr, length = struct.unpack(">BHB", answer)
if cmd != ord("W") or addr != start or length != size:
LOG.error("Invalid answer for block 0x%04x:" % start)
LOG.debug("CMD: %s ADDR: %04x SIZE: %02x" % (cmd, addr, length))
raise errors.RadioError("Unknown response from radio")
chunk = radio.pipe.read(size)
if not chunk:
raise errors.RadioError("Radio did not send block 0x%04x" % start)
elif len(chunk) != size:
LOG.error("Chunk length was 0x%04i" % len(chunk))
raise errors.RadioError("Radio sent incomplete block 0x%04x" % start)
return chunk
def _get_radio_firmware_version(radio):
if radio.MODEL == "BJ-UV55":
block = _read_block(radio, 0x1FF0, 0x40)
version = block[0:6]
else:
block1 = _read_block(radio, 0x1EC0, 0x40)
block2 = _read_block(radio, 0x1F00, 0x40)
block = block1 + block2
version = block[48:62]
return version
def _get_radio_special_block(radio):
block = _read_block(radio, 0xCF0, 0x40)
special_block = block[2:9]
return special_block
def _do_download(radio):
_ident_radio(radio)
# we could request all but we are cutting corners and saving time
# beware when uploading! Don't upload zeros where they don't belong!
mmap = memmap.MemoryMap("\x00"*radio._memsize)
# original file starts at 0x1626 till 0x196e _or so_ ~ 0x0350 bytes
LOG.debug("downloading memory channels...")
mask = _read_block(radio, 0x4000, 32)
mmap[0x4000] = mask
chan = 0
for x in mask[:31]:
x = struct.unpack("B", x)[0]
for bit in range(0, 8):
present = x & 1 > 0
x >>= 1
if present:
at = chan * 0x16
mmap[at] = _read_block(radio, at, 0x16)
_do_status(radio, at)
chan += 1
# radio_version = _get_radio_firmware_version(radio)
# LOG.info("Radio Version is %s" % repr(radio_version))
# if not any(type in radio_version for type in radio._basetype):
# raise errors.RadioError("Incorrect 'Model' selected.")
# Main block
# LOG.debug("downloading main block...")
# for i in range(0x16, 0x14b6, 0x16): # 4520
# data += _read_block(radio, i, 0x16)
# _do_status(radio, i)
# _do_status(radio, radio.get_memsize())
# mmap[0x16] = data
LOG.debug("done.")
LOG.debug("downloading aux block...")
# Auxiliary block starts at 0x1ECO (?)
for i in range(0x14e0, 0x19f0, 0x10):
mmap[i] = _read_block(radio, i, 0x10)
_do_status(radio, i)
for i in range(0x4100, 0x4520, 0x10):
mmap[i] = _read_block(radio, i, 0x10)
_do_status(radio, i)
_do_status(radio, radio.get_memsize())
LOG.debug("done.")
radio.pipe.write("\x45")
return mmap#memmap.MemoryMap(data)
def _send_block(radio, addr, data):
msg = struct.pack(">BHB", ord("X"), addr, len(data))
radio.pipe.write(msg + data)
time.sleep(0.05)
ack = radio.pipe.read(1)
if ack != "\x06":
raise errors.RadioError("Radio refused to accept block 0x%04x" % addr)
def _do_upload(radio):
pass
ident = _ident_radio(radio)
radio_upper_band = ident[3:4]
image_upper_band = _upper_band_from_image(radio)
if image_upper_band == vhf_220_radio or radio_upper_band == vhf_220_radio:
if image_upper_band != radio_upper_band:
raise errors.RadioError("Image not supported by radio")
image_version = _firmware_version_from_image(radio)
radio_version = _get_radio_firmware_version(radio)
LOG.info("Image Version is %s" % repr(image_version))
LOG.info("Radio Version is %s" % repr(radio_version))
if image_version != radio_version:
msg = ("The upload was stopped because the firmware "
"version of the image (%s) does not match that "
"of the radio (%s).")
raise errors.RadioError(msg % (image_version, radio_version))
image_special_block = _special_block_from_image(radio)
radio_special_block = _get_radio_special_block(radio)
LOG.debug("Image Special Block is " + util.hexprint(image_special_block))
LOG.debug("Radio Special Block is " + util.hexprint(radio_special_block))
if image_special_block != radio_special_block:
raise errors.RadioError("Image not supported by radio: `%s'" %
radio_special_block)
# Main block
for i in range(0x08, 0x1808, 0x10):
_send_block(radio, i - 0x08, radio.get_mmap()[i:i + 0x10])
_do_status(radio, i)
_do_status(radio, radio.get_memsize())
if len(radio.get_mmap().get_packed()) == 0x1808:
LOG.info("Old image, not writing aux block")
return # Old image, no aux block
if image_version != radio_version:
msg = ("Upload finished, but the 'Other Settings' "
"could not be sent because the firmware "
"version of the image (%s) does not match "
"that of the radio (%s).")
raise errors.RadioError(msg % (image_version, radio_version))
# Auxiliary block at radio address 0x1EC0, our offset 0x1808
for i in range(0x1EC0, 0x2000, 0x10):
addr = 0x1808 + (i - 0x1EC0)
_send_block(radio, i, radio.get_mmap()[addr:addr + 0x10])
UV5R_POWER_LEVELS3 = [
chirp_common.PowerLevel("Low", watts=1.00),
chirp_common.PowerLevel("High", watts=8.00),
chirp_common.PowerLevel("Med", watts=4.00),
]
UV5R_DTCS = sorted(chirp_common.DTCS_CODES + [645])
UV5R_CHARSET = chirp_common.CHARSET_UPPER_NUMERIC + \
"!@#$%^&*()+-=[]:\";'<>?,./"
@directory.register
class SainsonicRST599Radio(chirp_common.CloneModeRadio):
"""Sainsonic RST599"""
VENDOR = "Sainsonic"
MODEL = "RST599"
BAUD_RATE = 9600
# FILE_EXTENSION = "Ysf"
# _model = ""
_memsize = 0x4520 #19815
# _basetype = BASETYPE_UV5R
# _idents = [UV5R_MODEL_291,
# UV5R_MODEL_ORIG
# ]
_vhf_range = (136000000, 174000000)
_uhf_range = (400000000, 520000000)
# offset of fw version in image file
# _fw_ver_file_start = 0x1838
# _fw_ver_file_stop = 0x1846
# def __getattr__(self, attr):
# LOG.warn("missing: %s" % attr)
# def __init__(self, pipe):
# self.errors = []
# self._mmap = None
# if isinstance(pipe, str):
# self.pipe = None
# self.load_mmap(pipe)
# else:
# chirp_common.FileBackedRadio.__init__(self, pipe)
def get_features(self):
rf = chirp_common.RadioFeatures()
rf.has_settings = True
rf.has_bank = False
rf.has_cross = True
rf.has_rx_dtcs = True
rf.has_tuning_step = False
rf.can_odd_split = True
rf.valid_name_length = 6
rf.valid_characters = UV5R_CHARSET
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 = UV5R_POWER_LEVELS3
rf.valid_duplexes = ["", "-", "+", "split", "off"]
rf.valid_modes = ["FM", "NFM"]
normal_bands = [self._vhf_range, self._uhf_range]
# if self._mmap is None:
# rf.valid_bands = [normal_bands[0], rax_bands[1], normal_bands[1]]
# elif not self._is_orig() and self._my_upper_band() == vhf_220_radio:
# rf.valid_bands = rax_bands
# else:
# rf.valid_bands = normal_bands
rf.valid_bands = normal_bands
rf.memory_bounds = (1, 240)
return rf
@classmethod
def match_model(cls, filedata, filename):
"Consider including TDXSD01 or something"
match_size = False
match_model = False
if len(filedata) == cls._memsize and filedata[0x1526:0x152d] == "LiSheng":
return True
return False
def process_mmap(self):
self._memobj = bitwise.parse(MEM_FORMAT, self._mmap)
def sync_in(self):
try:
self._mmap = _do_download(self)
except errors.RadioError:
raise
except Exception, e:
raise errors.RadioError("Failed to communicate with radio: %s" % e)
self.process_mmap()
def sync_out(self):
try:
_do_upload(self)
except errors.RadioError:
raise
except Exception, e:
raise errors.RadioError("Failed to communicate with radio: %s" % e)
def get_raw_memory(self, number):
return repr(self._memobj.memory[number])
def _is_txinh(self, _mem):
raw_tx = ""
for i in range(0, 4):
raw_tx += _mem.txfreq[i].get_raw()
return raw_tx == "\xFF\xFF\xFF\xFF"
def _get_mem(self, number):
return self._memobj.memory[number]
def get_memory(self, number):
_mem = self._get_mem(number)
mem = chirp_common.Memory()
mem.number = number
group, bit = divmod(number, 8)
mask = ord(self.get_mmap()[0x4000 + group])
mask >>= bit
if mask & 1 == 0:
mem.empty = True
return mem
mem.freq = int(_mem.rxfreq) * 10
if self._is_txinh(_mem):
mem.duplex = "off"
mem.offset = 0
elif int(_mem.rxfreq) == int(_mem.txfreq):
mem.duplex = ""
mem.offset = 0
elif abs(int(_mem.rxfreq) * 10 - int(_mem.txfreq) * 10) > 70000000:
mem.duplex = "split"
mem.offset = int(_mem.txfreq) * 10
else:
mem.duplex = int(_mem.rxfreq) > int(_mem.txfreq) and "-" or "+"
mem.offset = abs(int(_mem.rxfreq) - int(_mem.txfreq)) * 10
mem.name = str(_mem.name).rstrip("\x00")
dtcs_pol = ["N", "N"]
if _mem.txtone in [0, 0xFFFF]:
txmode = ""
elif _mem.txtone <= 0x09ED:
txmode = "Tone"
mem.rtone = int(_mem.txtone) / 10.0
elif _mem.txtone > 0x09ED:
txmode = "DTCS"
if _mem.txtone > 0xA814:
index = _mem.txtone - 0xA814
dtcs_pol[0] = "R"
else:
index = _mem.txtone - 0x2814
mem.dtcs = UV5R_DTCS[index]
else:
LOG.warn("Bug: txtone is %04x" % _mem.txtone)
if _mem.rxtone in [0, 0xFFFF]:
rxmode = ""
elif _mem.rxtone <= 0x09ED:
rxmode = "Tone"
mem.ctone = int(_mem.rxtone) / 10.0
elif _mem.rxtone > 0x09ED:
rxmode = "DTCS"
if _mem.rxtone >= 0xA814:
index = _mem.rxtone - 0xA814
dtcs_pol[1] = "R"
else:
index = _mem.rxtone - 0x2814
mem.rx_dtcs = UV5R_DTCS[index]
else:
LOG.warn("Bug: rxtone is %04x" % _mem.rxtone)
if txmode == "Tone" and not rxmode:
mem.tmode = "Tone"
elif txmode == rxmode and txmode == "Tone" and mem.rtone == mem.ctone:
mem.tmode = "TSQL"
elif txmode == rxmode and txmode == "DTCS" and mem.dtcs == mem.rx_dtcs:
mem.tmode = "DTCS"
elif rxmode or txmode:
mem.tmode = "Cross"
mem.cross_mode = "%s->%s" % (txmode, rxmode)
mem.dtcs_polarity = "".join(dtcs_pol)
if not _mem.scan:
mem.skip = "S"
levels = UV5R_POWER_LEVELS3
mem.power = levels[_mem.power]
mem.mode = _mem.wide and "FM" or "NFM"
mem.extra = RadioSettingGroup("Extra", "extra")
bcl = ["OFF", "DQT", "CAT"]
rs = RadioSetting("bcl", "BCL",
RadioSettingValueList(bcl, bcl[_mem.bcl]))
mem.extra.append(rs)
signal = ["OFF", "DTMF", "2-TONE", "5-TONE"]
rs = RadioSetting("signal", "Signaling system",
RadioSettingValueList(signal, signal[_mem.signal]))
mem.extra.append(rs)
# rs = RadioSetting("signal_no", "Signal #",
# RadioSettingValueInteger(0 if _mem.signal == 0 else 1, 30 if _mem.signal == 1 else 16, 4, 1))
# mem.extra.append(rs)
# rs = RadioSetting("pttid", "PTT ID",
# RadioSettingValueList(PTTID_LIST,
# PTTID_LIST[_mem.pttid]))
# mem.extra.append(rs)
# rs = RadioSetting("scode", "PTT ID Code",
# RadioSettingValueList(PTTIDCODE_LIST,
# PTTIDCODE_LIST[_mem.scode]))
# mem.extra.append(rs)
return mem
def _set_mem(self, number):
return self._memobj.memory[number]
def set_memory(self, mem):
_mem = self._get_mem(mem.number)
# _nam = self._get_nam(mem.number)
if mem.empty:
_mem.set_raw("\xff" * 22)
return
_mem.set_raw("\x00" * 22)
_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"
rxmode = txmode = ""
if mem.tmode == "Tone":
_mem.txtone = int(mem.rtone * 10)
_mem.rxtone = 0
elif mem.tmode == "TSQL":
_mem.txtone = int(mem.ctone * 10)
_mem.rxtone = int(mem.ctone * 10)
elif mem.tmode == "DTCS":
rxmode = txmode = "DTCS"
_mem.txtone = UV5R_DTCS.index(mem.dtcs) + 1
_mem.rxtone = UV5R_DTCS.index(mem.dtcs) + 1
elif mem.tmode == "Cross":
txmode, rxmode = mem.cross_mode.split("->", 1)
if txmode == "Tone":
_mem.txtone = int(mem.rtone * 10)
elif txmode == "DTCS":
_mem.txtone = UV5R_DTCS.index(mem.dtcs) + 1
else:
_mem.txtone = 0
if rxmode == "Tone":
_mem.rxtone = int(mem.ctone * 10)
elif rxmode == "DTCS":
_mem.rxtone = UV5R_DTCS.index(mem.rx_dtcs) + 1
else:
_mem.rxtone = 0
else:
_mem.rxtone = 0
_mem.txtone = 0
if txmode == "DTCS" and mem.dtcs_polarity[0] == "R":
_mem.txtone += 0x69
if rxmode == "DTCS" and mem.dtcs_polarity[1] == "R":
_mem.rxtone += 0x69
_mem.scan = mem.skip != "S"
_mem.wide = mem.mode == "FM"
if mem.power:
levels = [str(l) for l in UV5R_POWER_LEVELS3]
_mem.power = levels.index(str(mem.power))
else:
_mem.power = 0
for setting in mem.extra:
setattr(_mem, setting.get_name(), setting.value)
def _is_orig(self):
version_tag = _firmware_version_from_image(self)
LOG.debug("@_is_orig, version_tag: %s", util.hexprint(version_tag))
try:
if 'BFB' in version_tag:
idx = version_tag.index("BFB") + 3
version = int(version_tag[idx:idx + 3])
return version < 291
return False
except:
pass
raise errors.RadioError("Unable to parse version string %s" %
version_tag)
def _my_version(self):
version_tag = _firmware_version_from_image(self)
if 'BFB' in version_tag:
idx = version_tag.index("BFB") + 3
return int(version_tag[idx:idx + 3])
raise Exception("Unrecognized firmware version string")
def _my_upper_band(self):
band_tag = _upper_band_from_image(self)
return band_tag
def _get_settings(self):
# _ani = self._memobj.ani
_settings = self._memobj.settings
_bands = self._memobj.band_limits
_ars = self._memobj.ars
# _squelch = self._memobj.squelch_new
# _vfoa = self._memobj.vfoa
# _vfob = self._memobj.vfob
# _wmchannel = self._memobj.wmchannel
basic = RadioSettingGroup("basic", "Basic Settings")
advanced = RadioSettingGroup("advanced", "Advanced Settings")
fm_preset = RadioSettingGroup("presets", "FM presets")
ars = RadioSettingGroup("ars", "AutoOffset")
bands = RadioSettingGroup("bands", "Band limits")
channel_a = RadioSettingGroup("channel_a", "Channel A")
channel_b = RadioSettingGroup("channel_b", "Channel B")
group = RadioSettings(channel_a, channel_b, basic, advanced, fm_preset, ars, bands)
rs = RadioSetting("afreq", "Freq A",
RadioSettingValueString(0, 100, "%.4f" % (int(_settings.a.freq)/1.e5)))
channel_a.append(rs)
rs = RadioSetting("bfreq", "Freq B",
RadioSettingValueString(0, 100, "%.4f" % (int(_settings.b.freq)/1.e5)))
channel_b.append(rs)
rs = RadioSetting("avox", "Talk around/Vox",
RadioSettingValueBoolean(_settings.a.vox))
channel_a.append(rs)
rs = RadioSetting("bvox", "Talk around/Vox",
RadioSettingValueBoolean(_settings.b.vox))
channel_b.append(rs)
levels = TXPOWER3_LIST
rs = RadioSetting("apower", "TX Power",
RadioSettingValueList(levels, levels[_settings.a.power]))
channel_a.append(rs)
rs = RadioSetting("bpower", "TX Power",
RadioSettingValueList(levels, levels[_settings.b.power]))
channel_b.append(rs)
rs = RadioSetting("awide", "Wide",
RadioSettingValueBoolean(_settings.a.wide))
channel_a.append(rs)
rs = RadioSetting("bwide", "Wide",
RadioSettingValueBoolean(_settings.b.wide))
channel_b.append(rs)
bcl = ["OFF", "DQT", "CAT"]
rs = RadioSetting("abcl", "BCL",
RadioSettingValueList(bcl, bcl[_settings.a.bcl]))
channel_a.append(rs)
rs = RadioSetting("bbcl", "BCL",
RadioSettingValueList(bcl, bcl[_settings.b.bcl]))
channel_b.append(rs)
rs = RadioSetting("mdfa", "Display Mode",
RadioSettingValueList(
MODE_LIST, MODE_LIST[_settings.a.mode]))
channel_a.append(rs)
rs = RadioSetting("mdfb", "Display Mode",
RadioSettingValueList(
MODE_LIST, MODE_LIST[_settings.b.mode]))
channel_b.append(rs)
rs = RadioSetting("squelch", "Carrier Squelch Level",
RadioSettingValueInteger(0, 9, _settings.squelch))
basic.append(rs)
tot = ["OFF", "30s", "60s"]
rs = RadioSetting("tot", "TOT, s",
RadioSettingValueList(tot, tot[_settings.tot]))
basic.append(rs)
rs = RadioSetting("toa", "TOA, s",
RadioSettingValueInteger(0, 10, _settings.toa))
basic.append(rs)
rs = RadioSetting("vox_gain", "VOX gain",
RadioSettingValueInteger(0, 9, _settings.vox_gain))
basic.append(rs)
rs = RadioSetting("vox_delay", "VOX delay, ms",
RadioSettingValueInteger(0, 5000, _settings.vox_delay, 100))
basic.append(rs)
rs = RadioSetting("oneline", "Single line",
RadioSettingValueBoolean(_settings.oneline))
basic.append(rs)
ABSWITCH = ["Auto", "On", "Off"]
rs = RadioSetting("abswitch", "A/B switch (DoubleWatch)",
RadioSettingValueList(ABSWITCH, ABSWITCH[_settings.abswitch]))
basic.append(rs)
rs = RadioSetting("save", "Battery Saver",
RadioSettingValueList(
SAVE_LIST, SAVE_LIST[_settings.save]))
basic.append(rs)
# rs = RadioSetting("tdrab", "Dual Watch TX Priority",
# RadioSettingValueList(
# TDRAB_LIST, TDRAB_LIST[_settings.tdrab]))
# advanced.append(rs)
rs = RadioSetting("whisper", "Whisper",
RadioSettingValueBoolean(_settings.whisper))
basic.append(rs)
rs = RadioSetting("burst", "1750 Hz burst, s",
RadioSettingValueInteger(0, 5, _settings.burst))
basic.append(rs)
def _filter(name):
filtered = ""
for char in str(name):
if char in chirp_common.CHARSET_ASCII:
filtered += char
else:
filtered += " "
return filtered
rs = RadioSetting("password", "Password",
RadioSettingValueString(0, 6, _filter(_settings.password)))
basic.append(rs)
rs = RadioSetting("vhf_tx_min", "VHF Tx Min",
RadioSettingValueFloat(30, 300, _bands.vhf_tx_min/1.e6))
bands.append(rs)
rs = RadioSetting("vhf_tx_max", "VHF Tx Max",
RadioSettingValueFloat(30, 300, _bands.vhf_tx_max/1.e6))
bands.append(rs)
rs = RadioSetting("vhf_rx_min", "VHF Rx Min",
RadioSettingValueFloat(30, 300, _bands.vhf_rx_min/1.e6))
bands.append(rs)
rs = RadioSetting("vhf_rx_max", "VHF Rx Max",
RadioSettingValueFloat(30, 300, _bands.vhf_rx_max/1.e6))
bands.append(rs)
rs = RadioSetting("uhf_tx_min", "UHF Tx Min",
RadioSettingValueFloat(30, 1000, _bands.uhf_tx_min/1.e6))
bands.append(rs)
rs = RadioSetting("uf_tx_max", "UHF Tx Max",
RadioSettingValueFloat(300, 1000, _bands.uhf_tx_max/1.e6))
bands.append(rs)
rs = RadioSetting("uhf_rx_min", "UHF Rx Min",
RadioSettingValueFloat(300, 1000, _bands.uhf_rx_min/1.e6))
bands.append(rs)
rs = RadioSetting("uhf_rx_max", "UHF Rx Max",
RadioSettingValueFloat(300, 1000, _bands.uhf_rx_max/1.e6))
bands.append(rs)
# idle = ["Red", "Green", "Blue", "Yellow", "Purple", "Cyan", "White"]
# rs = RadioSetting("color_idle", "Idle color",
# RadioSettingValueList(idle, idle[_settings.color_idle]))
# basic.append(rs)
fm_step = ["0.05", ".1", ".5", "1"]
rs = RadioSetting("fm_step", "FM step",
RadioSettingValueList(fm_step, fm_step[_settings.fm_step]))
basic.append(rs)
rs = RadioSetting("fm_low", "FM low",
RadioSettingValueFloat(87, 108, _settings.fm_low/1.e6))
basic.append(rs)
rs = RadioSetting("fm_high", "FM high",
RadioSettingValueFloat(87, 108, _settings.fm_high/1.e6))
basic.append(rs)
rs = RadioSetting("wtled", "Standby LED Color",
RadioSettingValueList(
COLOR_LIST, COLOR_LIST[_settings.wtled]))
basic.append(rs)
rs = RadioSetting("rxled", "RX LED Color",
RadioSettingValueList(
COLOR_LIST, COLOR_LIST[_settings.rxled]))
basic.append(rs)
rs = RadioSetting("txled", "TX LED Color",
RadioSettingValueList(
COLOR_LIST, COLOR_LIST[_settings.txled]))
basic.append(rs)
rs = RadioSetting("priority", "Proprity channel",
RadioSettingValueInteger(1, 240, _settings.priority))
basic.append(rs)
rs = RadioSetting("name_display", "Name display",
RadioSettingValueBoolean(_settings.name_display))
basic.append(rs)
rs = RadioSetting("key_beep", "Key beep",
RadioSettingValueBoolean(_settings.key_beep))
basic.append(rs)
rings = ["OFF", "Ring 1", "Ring 2", "Ring 3"]
rs = RadioSetting("alarm_ring", "Alarm ring",
RadioSettingValueList(rings, rings[_settings.alarm_ring]))
basic.append(rs)
for i in range(0,20):
freq = _settings.fm_preset[i]
if freq == 0:
used = False
freq = 87.
else:
used = True
freq = freq/1.e6
rs = RadioSetting("fm_%d" % i, "FM %d" % (i+1),
RadioSettingValueBoolean(used),
RadioSettingValueFloat(87, 108, freq, 0.1, 1))
fm_preset.append(rs)
for i in range(0,16):
e = _ars[i]
if e.start == 0:
used = False
start = 144.
to = 144.
offset = 0.
else:
used = True
start = e.start/1.e6
to = e.to/1.e6
offset = e.offset/1.e6
offsets = ["Disabled", "+", "-"]
rs = RadioSetting("ars_%d" % i, "AutoOffset %d" % (i+1),
RadioSettingValueList(offsets, offsets[e.dir * used]),
RadioSettingValueFloat(144, 520, start, 0.1, 1),
RadioSettingValueFloat(144, 520, to, 0.1, 1),
RadioSettingValueFloat(0, 10, offset, 0.1, 1)
)
ars.append(rs)
welcome = RadioSettingGroup("welcome", "Welcome")
group.append(welcome)
_msg = self._memobj.poweron_msg
logo = ["OFF", "Welcome (Chineese)", "Welcome (English)", "Custom (below)"]
rs = RadioSetting("logo", "Logo",
RadioSettingValueList(logo, logo[self._memobj.logo]))
welcome.append(rs)
rs = RadioSetting("poweron_msg.line1", "Power-On Message 1",
RadioSettingValueString(
0, 16, _filter(_msg[0].line)))
welcome.append(rs)
rs = RadioSetting("poweron_msg.line2", "Power-On Message 2",
RadioSettingValueString(
0, 16, _filter(_msg[1].line)))
welcome.append(rs)
rs = RadioSetting("poweron_msg.line3", "Power-On Message 3",
RadioSettingValueString(
0, 16, _filter(_msg[2].line)))
welcome.append(rs)
rs = RadioSetting("poweron_msg.line4", "Power-On Message 4",
RadioSettingValueString(
0, 16, _filter(_msg[3].line)))
welcome.append(rs)
# rs = RadioSetting("vox", "VOX Sensitivity",
# RadioSettingValueList(
# VOX_LIST, VOX_LIST[_settings.vox]))
# advanced.append(rs)
# if self.MODEL == "UV-6":
# # NOTE: The UV-6 calls this byte voxenable, but the UV-5R calls it
# # autolk. Since this is a minor difference, it will be referred to
# # by the wrong name for the UV-6.
# rs = RadioSetting("autolk", "Vox",
# RadioSettingValueBoolean(_settings.autolk))
# advanced.append(rs)
# if self.MODEL != "UV-6":
# rs = RadioSetting("abr", "Backlight Timeout",
# RadioSettingValueInteger(0, 24, _settings.abr))
# basic.append(rs)
# if self.MODEL == "UV-6":
# rs = RadioSetting("tdrch", "Dual Watch Channel",
# RadioSettingValueList(
# TDRCH_LIST, TDRCH_LIST[_settings.tdrch]))
# advanced.append(rs)
# rs = RadioSetting("tdrab", "Dual Watch TX Priority",
# RadioSettingValueBoolean(_settings.tdrab))
# advanced.append(rs)
# else:
# rs = RadioSetting("tdrab", "Dual Watch TX Priority",
# RadioSettingValueList(
# TDRAB_LIST, TDRAB_LIST[_settings.tdrab]))
# advanced.append(rs)
# if self.MODEL == "UV-6":
# rs = RadioSetting("alarm", "Alarm Sound",
# RadioSettingValueBoolean(_settings.alarm))
# advanced.append(rs)
# if _settings.almod > 0x02:
# val = 0x01
# else:
# val = _settings.almod
# rs = RadioSetting("almod", "Alarm Mode",
# RadioSettingValueList(
# ALMOD_LIST, ALMOD_LIST[val]))
# advanced.append(rs)
# rs = RadioSetting("beep", "Beep",
# RadioSettingValueBoolean(_settings.beep))
# basic.append(rs)
# rs = RadioSetting("timeout", "Timeout Timer",
# RadioSettingValueList(
# TIMEOUT_LIST, TIMEOUT_LIST[_settings.timeout]))
# basic.append(rs)
# if self._is_orig() and self._my_version() < 251:
# rs = RadioSetting("voice", "Voice",
# RadioSettingValueBoolean(_settings.voice))
# advanced.append(rs)
# else:
# rs = RadioSetting("voice", "Voice",
# RadioSettingValueList(
# VOICE_LIST, VOICE_LIST[_settings.voice]))
# advanced.append(rs)
# rs = RadioSetting("screv", "Scan Resume",
# RadioSettingValueList(
# RESUME_LIST, RESUME_LIST[_settings.screv]))
# advanced.append(rs)
# if self.MODEL != "UV-6":
# rs = RadioSetting("mdfa", "Display Mode (A)",
# RadioSettingValueList(
# MODE_LIST, MODE_LIST[_settings.mdfa]))
# basic.append(rs)
# rs = RadioSetting("mdfb", "Display Mode (B)",
# RadioSettingValueList(
# MODE_LIST, MODE_LIST[_settings.mdfb]))
# basic.append(rs)
# rs = RadioSetting("bcl", "Busy Channel Lockout",
# RadioSettingValueBoolean(_settings.bcl))
# advanced.append(rs)
# if self.MODEL != "UV-6":
# rs = RadioSetting("autolk", "Automatic Key Lock",
# RadioSettingValueBoolean(_settings.autolk))
# advanced.append(rs)
# rs = RadioSetting("fmradio", "Broadcast FM Radio",
# RadioSettingValueBoolean(_settings.fmradio))
# advanced.append(rs)
# if self.MODEL != "UV-6":
# rs = RadioSetting("wtled", "Standby LED Color",
# RadioSettingValueList(
# COLOR_LIST, COLOR_LIST[_settings.wtled]))
# basic.append(rs)
# rs = RadioSetting("rxled", "RX LED Color",
# RadioSettingValueList(
# COLOR_LIST, COLOR_LIST[_settings.rxled]))
# basic.append(rs)
# rs = RadioSetting("txled", "TX LED Color",
# RadioSettingValueList(
# COLOR_LIST, COLOR_LIST[_settings.txled]))
# basic.append(rs)
# if self.MODEL == "UV-82":
# rs = RadioSetting("roger", "Roger Beep (TX)",
# RadioSettingValueBoolean(_settings.roger))
# basic.append(rs)
# rs = RadioSetting("rogerrx", "Roger Beep (RX)",
# RadioSettingValueList(
# ROGERRX_LIST,
# ROGERRX_LIST[_settings.rogerrx]))
# basic.append(rs)
# else:
# rs = RadioSetting("roger", "Roger Beep",
# RadioSettingValueBoolean(_settings.roger))
# basic.append(rs)
# rs = RadioSetting("ste", "Squelch Tail Eliminate (HT to HT)",
# RadioSettingValueBoolean(_settings.ste))
# advanced.append(rs)
# rs = RadioSetting("rpste", "Squelch Tail Eliminate (repeater)",
# RadioSettingValueList(
# RPSTE_LIST, RPSTE_LIST[_settings.rpste]))
# advanced.append(rs)
# rs = RadioSetting("rptrl", "STE Repeater Delay",
# RadioSettingValueList(
# STEDELAY_LIST, STEDELAY_LIST[_settings.rptrl]))
# advanced.append(rs)
# if self.MODEL != "UV-6":
# rs = RadioSetting("reset", "RESET Menu",
# RadioSettingValueBoolean(_settings.reset))
# advanced.append(rs)
# rs = RadioSetting("menu", "All Menus",
# RadioSettingValueBoolean(_settings.menu))
# advanced.append(rs)
# if self.MODEL == "F-11":
# # this is an F-11 only feature
# rs = RadioSetting("vfomrlock", "VFO/MR Button",
# RadioSettingValueBoolean(_settings.vfomrlock))
# advanced.append(rs)
# if self.MODEL == "UV-82":
# # this is a UV-82C only feature
# rs = RadioSetting("vfomrlock", "VFO/MR Switching (UV-82C only)",
# RadioSettingValueBoolean(_settings.vfomrlock))
# advanced.append(rs)
# if self.MODEL == "UV-82HP":
# # this is a UV-82HP only feature
# rs = RadioSetting("vfomrlock", "VFO/MR Switching",
# RadioSettingValueBoolean(_settings.vfomrlock))
# advanced.append(rs)
# if self.MODEL == "UV-82":
# # this is an UV-82C only feature
# rs = RadioSetting("singleptt", "Single PTT (UV-82C only)",
# RadioSettingValueBoolean(_settings.singleptt))
# advanced.append(rs)
# if self.MODEL == "UV-82HP":
# # this is an UV-82HP only feature
# rs = RadioSetting("singleptt", "Single PTT",
# RadioSettingValueBoolean(_settings.singleptt))
# advanced.append(rs)
# if self.MODEL == "UV-82HP":
# # this is an UV-82HP only feature
# rs = RadioSetting("tdrch", "Tone Burst Frequency",
# RadioSettingValueList(
# RTONE_LIST, RTONE_LIST[_settings.tdrch]))
# advanced.append(rs)
# if len(self._mmap.get_packed()) == 0x1808:
# # Old image, without aux block
# return group
# other = RadioSettingGroup("other", "Other Settings")
# group.append(other)
# _msg = self._memobj.firmware_msg
# val = RadioSettingValueString(0, 7, _filter(_msg.line1))
# val.set_mutable(False)
# rs = RadioSetting("firmware_msg.line1", "Firmware Message 1", val)
# other.append(rs)
# val = RadioSettingValueString(0, 7, _filter(_msg.line2))
# val.set_mutable(False)
# rs = RadioSetting("firmware_msg.line2", "Firmware Message 2", val)
# other.append(rs)
# if self.MODEL != "UV-6":
# _msg = self._memobj.sixpoweron_msg
# rs = RadioSetting("sixpoweron_msg.line1", "6+Power-On Message 1",
# RadioSettingValueString(
# 0, 7, _filter(_msg.line1)))
# other.append(rs)
# rs = RadioSetting("sixpoweron_msg.line2", "6+Power-On Message 2",
# RadioSettingValueString(
# 0, 7, _filter(_msg.line2)))
# other.append(rs)
# _msg = self._memobj.poweron_msg
# rs = RadioSetting("poweron_msg.line1", "Power-On Message 1",
# RadioSettingValueString(
# 0, 7, _filter(_msg.line1)))
# other.append(rs)
# rs = RadioSetting("poweron_msg.line2", "Power-On Message 2",
# RadioSettingValueString(
# 0, 7, _filter(_msg.line2)))
# other.append(rs)
# rs = RadioSetting("ponmsg", "Power-On Message",
# RadioSettingValueList(
# PONMSG_LIST, PONMSG_LIST[_settings.ponmsg]))
# other.append(rs)
# if self._is_orig():
# limit = "limits_old"
# else:
# limit = "limits_new"
# vhf_limit = getattr(self._memobj, limit).vhf
# rs = RadioSetting("%s.vhf.lower" % limit, "VHF Lower Limit (MHz)",
# RadioSettingValueInteger(1, 1000,
# vhf_limit.lower))
# other.append(rs)
# rs = RadioSetting("%s.vhf.upper" % limit, "VHF Upper Limit (MHz)",
# RadioSettingValueInteger(1, 1000,
# vhf_limit.upper))
# other.append(rs)
# rs = RadioSetting("%s.vhf.enable" % limit, "VHF TX Enabled",
# RadioSettingValueBoolean(vhf_limit.enable))
# other.append(rs)
# uhf_limit = getattr(self._memobj, limit).uhf
# rs = RadioSetting("%s.uhf.lower" % limit, "UHF Lower Limit (MHz)",
# RadioSettingValueInteger(1, 1000,
# uhf_limit.lower))
# other.append(rs)
# rs = RadioSetting("%s.uhf.upper" % limit, "UHF Upper Limit (MHz)",
# RadioSettingValueInteger(1, 1000,
# uhf_limit.upper))
# other.append(rs)
# rs = RadioSetting("%s.uhf.enable" % limit, "UHF TX Enabled",
# RadioSettingValueBoolean(uhf_limit.enable))
# other.append(rs)
# if self.MODEL != "UV-6":
# workmode = RadioSettingGroup("workmode", "Work Mode Settings")
# group.append(workmode)
# rs = RadioSetting("displayab", "Display",
# RadioSettingValueList(
# AB_LIST, AB_LIST[_settings.displayab]))
# workmode.append(rs)
# rs = RadioSetting("workmode", "VFO/MR Mode",
# RadioSettingValueList(
# WORKMODE_LIST,
# WORKMODE_LIST[_settings.workmode]))
# workmode.append(rs)
# rs = RadioSetting("keylock", "Keypad Lock",
# RadioSettingValueBoolean(_settings.keylock))
# workmode.append(rs)
# rs = RadioSetting("wmchannel.mrcha", "MR A Channel",
# RadioSettingValueInteger(0, 127,
# _wmchannel.mrcha))
# workmode.append(rs)
# rs = RadioSetting("wmchannel.mrchb", "MR B Channel",
# RadioSettingValueInteger(0, 127,
# _wmchannel.mrchb))
# workmode.append(rs)
# def convert_bytes_to_freq(bytes):
# real_freq = 0
# for byte in bytes:
# real_freq = (real_freq * 10) + byte
# return chirp_common.format_freq(real_freq * 10)
# def my_validate(value):
# value = chirp_common.parse_freq(value)
# if 17400000 <= value and value < 40000000:
# msg = ("Can't be between 174.00000-400.00000")
# raise InvalidValueError(msg)
# return chirp_common.format_freq(value)
# def apply_freq(setting, obj):
# value = chirp_common.parse_freq(str(setting.value)) / 10
# obj.band = value >= 40000000
# for i in range(7, -1, -1):
# obj.freq[i] = value % 10
# value /= 10
# val1a = RadioSettingValueString(0, 10,
# convert_bytes_to_freq(_vfoa.freq))
# val1a.set_validate_callback(my_validate)
# rs = RadioSetting("vfoa.freq", "VFO A Frequency", val1a)
# rs.set_apply_callback(apply_freq, _vfoa)
# workmode.append(rs)
# val1b = RadioSettingValueString(0, 10,
# convert_bytes_to_freq(_vfob.freq))
# val1b.set_validate_callback(my_validate)
# rs = RadioSetting("vfob.freq", "VFO B Frequency", val1b)
# rs.set_apply_callback(apply_freq, _vfob)
# workmode.append(rs)
# rs = RadioSetting("vfoa.sftd", "VFO A Shift",
# RadioSettingValueList(
# SHIFTD_LIST, SHIFTD_LIST[_vfoa.sftd]))
# workmode.append(rs)
# rs = RadioSetting("vfob.sftd", "VFO B Shift",
# RadioSettingValueList(
# SHIFTD_LIST, SHIFTD_LIST[_vfob.sftd]))
# workmode.append(rs)
# def convert_bytes_to_offset(bytes):
# real_offset = 0
# for byte in bytes:
# real_offset = (real_offset * 10) + byte
# return chirp_common.format_freq(real_offset * 10000)
# def apply_offset(setting, obj):
# value = chirp_common.parse_freq(str(setting.value)) / 10000
# for i in range(3, -1, -1):
# obj.offset[i] = value % 10
# value /= 10
# val1a = RadioSettingValueString(
# 0, 10, convert_bytes_to_offset(_vfoa.offset))
# rs = RadioSetting("vfoa.offset",
# "VFO A Offset (0.00-69.95)", val1a)
# rs.set_apply_callback(apply_offset, _vfoa)
# workmode.append(rs)
# val1b = RadioSettingValueString(
# 0, 10, convert_bytes_to_offset(_vfob.offset))
# rs = RadioSetting("vfob.offset",
# "VFO B Offset (0.00-69.95)", val1b)
# rs.set_apply_callback(apply_offset, _vfob)
# workmode.append(rs)
# rs = RadioSetting("vfoa.widenarr", "VFO A Bandwidth",
# RadioSettingValueList(
# BANDWIDTH_LIST,
# BANDWIDTH_LIST[_vfoa.widenarr]))
# workmode.append(rs)
# rs = RadioSetting("vfob.widenarr", "VFO B Bandwidth",
# RadioSettingValueList(
# BANDWIDTH_LIST,
# BANDWIDTH_LIST[_vfob.widenarr]))
# workmode.append(rs)
# rs = RadioSetting("vfoa.scode", "VFO A PTT-ID",
# RadioSettingValueList(
# PTTIDCODE_LIST, PTTIDCODE_LIST[_vfoa.scode]))
# workmode.append(rs)
# rs = RadioSetting("vfob.scode", "VFO B PTT-ID",
# RadioSettingValueList(
# PTTIDCODE_LIST, PTTIDCODE_LIST[_vfob.scode]))
# workmode.append(rs)
# if not self._is_orig():
# rs = RadioSetting("vfoa.step", "VFO A Tuning Step",
# RadioSettingValueList(
# STEP291_LIST, STEP291_LIST[_vfoa.step]))
# workmode.append(rs)
# rs = RadioSetting("vfob.step", "VFO B Tuning Step",
# RadioSettingValueList(
# STEP291_LIST, STEP291_LIST[_vfob.step]))
# workmode.append(rs)
# else:
# rs = RadioSetting("vfoa.step", "VFO A Tuning Step",
# RadioSettingValueList(
# STEP_LIST, STEP_LIST[_vfoa.step]))
# workmode.append(rs)
# rs = RadioSetting("vfob.step", "VFO B Tuning Step",
# RadioSettingValueList(
# STEP_LIST, STEP_LIST[_vfob.step]))
# workmode.append(rs)
# fm_preset = RadioSettingGroup("fm_preset", "FM Radio Preset")
# group.append(fm_preset)
# if self._memobj.fm_presets <= 116.1 * 10 - 650:
# preset = self._memobj.fm_presets / 10.0 + 65
# else:
# preset = 76.0
# rs = RadioSetting("fm_presets", "FM Preset(MHz)",
# RadioSettingValueFloat(65, 116.1, preset, 0.1, 1))
# fm_preset.append(rs)
dtmf = RadioSettingGroup("dtmf", "DTMF Settings")
group.append(dtmf)
dtmfchars = "0123456789*#ABCD"
for i in range(0, 30):
_codeobj = self._memobj.pttid[i].code
_code = "".join([dtmfchars[x] for x in _codeobj if int(x) < 0x1F])
val = RadioSettingValueString(0, 16, _code, False)
val.set_charset(dtmfchars)
rs = RadioSetting("pttid/%i.code" % i,
"PTT ID Code %i" % (i + 1), val)
def apply_code(setting, obj):
code = []
for j in range(0, 5):
try:
code.append(dtmfchars.index(str(setting.value)[j]))
except IndexError:
code.append(0xFF)
obj.code = code
rs.set_apply_callback(apply_code, self._memobj.pttid[i])
dtmf.append(rs)
# _codeobj = self._memobj.ani.code
# _code = "".join([dtmfchars[x] for x in _codeobj if int(x) < 0x1F])
# val = RadioSettingValueString(0, 5, _code, False)
# val.set_charset(dtmfchars)
# rs = RadioSetting("ani.code", "ANI Code", val)
# def apply_code(setting, obj):
# code = []
# for j in range(0, 5):
# try:
# code.append(dtmfchars.index(str(setting.value)[j]))
# except IndexError:
# code.append(0xFF)
# obj.code = code
# rs.set_apply_callback(apply_code, _ani)
# dtmf.append(rs)
# rs = RadioSetting("ani.aniid", "ANI ID",
# RadioSettingValueList(PTTID_LIST,
# PTTID_LIST[_ani.aniid]))
# dtmf.append(rs)
# _codeobj = self._memobj.ani.alarmcode
# _code = "".join([dtmfchars[x] for x in _codeobj if int(x) < 0x1F])
# val = RadioSettingValueString(0, 3, _code, False)
# val.set_charset(dtmfchars)
# rs = RadioSetting("ani.alarmcode", "Alarm Code", val)
# def apply_code(setting, obj):
# alarmcode = []
# for j in range(0, 3):
# try:
# alarmcode.append(dtmfchars.index(str(setting.value)[j]))
# except IndexError:
# alarmcode.append(0xFF)
# obj.alarmcode = alarmcode
# rs.set_apply_callback(apply_code, _ani)
# dtmf.append(rs)
# rs = RadioSetting("dtmfst", "DTMF Sidetone",
# RadioSettingValueList(DTMFST_LIST,
# DTMFST_LIST[_settings.dtmfst]))
# dtmf.append(rs)
# if _ani.dtmfon > 0xC3:
# val = 0x00
# else:
# val = _ani.dtmfon
# rs = RadioSetting("ani.dtmfon", "DTMF Speed (on)",
# RadioSettingValueList(DTMFSPEED_LIST,
# DTMFSPEED_LIST[val]))
# dtmf.append(rs)
# if _ani.dtmfoff > 0xC3:
# val = 0x00
# else:
# val = _ani.dtmfoff
# rs = RadioSetting("ani.dtmfoff", "DTMF Speed (off)",
# RadioSettingValueList(DTMFSPEED_LIST,
# DTMFSPEED_LIST[val]))
# dtmf.append(rs)
# rs = RadioSetting("pttlt", "PTT ID Delay",
# RadioSettingValueInteger(0, 30, _settings.pttlt))
# dtmf.append(rs)
# if not self._is_orig():
# service = RadioSettingGroup("service", "Service Settings")
# group.append(service)
# for band in ["vhf", "uhf"]:
# for index in range(0, 10):
# key = "squelch_new.%s.sql%i" % (band, index)
# if band == "vhf":
# _obj = self._memobj.squelch_new.vhf
# elif band == "uhf":
# _obj = self._memobj.squelch_new.uhf
# name = "%s Squelch %i" % (band.upper(), index)
# rs = RadioSetting(key, name,
# RadioSettingValueInteger(
# 0, 123,
# getattr(_obj, "sql%i" % (index))))
# service.append(rs)
return group
def get_settings(self):
try:
return self._get_settings()
except:
import traceback
LOG.error("Failed to parse settings: %s", traceback.format_exc())
return None
def set_settings(self, settings):
_settings = self._memobj.settings
for element in settings:
if not isinstance(element, RadioSetting):
if element.get_name() == "fm_preset":
self._set_fm_preset(element)
else:
self.set_settings(element)
continue
else:
try:
name = element.get_name()
if "." in name:
bits = name.split(".")
obj = self._memobj
for bit in bits[:-1]:
if "/" in bit:
bit, index = bit.split("/", 1)
index = int(index)
obj = getattr(obj, bit)[index]
else:
obj = getattr(obj, bit)
setting = bits[-1]
else:
obj = _settings
setting = element.get_name()
if element.has_apply_callback():
LOG.debug("Using apply callback")
element.run_apply_callback()
else:
LOG.debug("Setting %s = %s" % (setting, element.value))
setattr(obj, setting, element.value)
except Exception, e:
LOG.debug(element.get_name())
raise
def _set_fm_preset(self, settings):
for element in settings:
try:
val = element.value
value = int(val.get_value() * 10 - 650)
LOG.debug("Setting fm_presets = %s" % (value))
self._memobj.fm_presets = value
except Exception, e:
LOG.debug(element.get_name())
raise
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment