Created
January 22, 2016 05:56
-
-
Save mlt/d145fa0ef48ccc7a4e04 to your computer and use it in GitHub Desktop.
chirp_rst599
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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