# HG changeset patch # User Jim Unroe # Date 1359085465 18000 # Node ID ec472c41b720664b3265ec41912df8c539ea4d0b # Parent 5f4fff6266ab03ebd6720f093541c190a0fee1b8 [uv5r] add work mode vfo a & b frequency setting diff -r 5f4fff6266ab -r ec472c41b720 chirp/settings.py --- a/chirp/settings.py Mon Jan 21 14:59:40 2013 -0800 +++ b/chirp/settings.py Thu Jan 24 22:44:25 2013 -0500 @@ -28,16 +28,20 @@ def __init__(self): self._current = None self._has_changed = False + self._callback = lambda x: x def changed(self): """Returns True if the setting has been changed since init""" return self._has_changed + def set_callback(self, callback): + self._callback = callback + def set_value(self, value): """Sets the current value, triggers changed""" if self._current != None and value != self._current: self._has_changed = True - self._current = value + self._current = self._callback(value) def get_value(self): """Gets the current value""" @@ -81,6 +85,45 @@ """Returns the step increment""" return self._step +class RadioSettingValueFloat(RadioSettingValue): + """A floating-point setting""" + def __init__(self, minval, maxval, current, resolution=0.001, precision=5): + RadioSettingValue.__init__(self) + self._min = minval + self._max = maxval + self._res = resolution + self._pre = precision + self.set_value(current) + + def format(self, value=None): + """Formats the value into a string""" + if value is None: + value = self._current + fmt_string = "%%.%if" % self._pre + print fmt_string + return fmt_string % value + + def set_value(self, value): + try: + value = float(value) + except: + raise InvalidValueError("A floating point value is required") + if value > self._max or value < self._min: + raise InvalidValueError("Value %s not in range %s-%s" % ( + self.format(value), + self.format(self._min), self.format(self._max))) + + # FIXME: honor resolution + + RadioSettingValue.set_value(self, value) + + def get_min(self): + """Returns the minimum allowed value""" + return self._min + + def get_max(self): + """Returns the maximum allowed value""" + class RadioSettingValueBoolean(RadioSettingValue): """A boolean setting""" def __init__(self, current): diff -r 5f4fff6266ab -r ec472c41b720 chirp/uv5r.py --- a/chirp/uv5r.py Mon Jan 21 14:59:40 2013 -0800 +++ b/chirp/uv5r.py Thu Jan 24 22:44:25 2013 -0500 @@ -21,7 +21,8 @@ from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueInteger, RadioSettingValueList, \ RadioSettingValueList, RadioSettingValueBoolean, \ - RadioSettingValueString + RadioSettingValueString, RadioSettingValueFloat, \ + InvalidValueError MEM_FORMAT = """ #seekto 0x0008; @@ -207,6 +208,7 @@ STEDELAY_LIST = ["%s ms" % x for x in range(100, 1100, 100)] STEDELAY_LIST.insert(0, "OFF") SCODE_LIST = ["%s" % x for x in range(1, 16)] +BAND_LIST = ["VHF", "UHF"] SETTING_LISTS = { "step" : STEP_LIST, @@ -226,6 +228,7 @@ "rpste" : RPSTE_LIST, "stedelay" : STEDELAY_LIST, "scode" : SCODE_LIST, + "band" : BAND_LIST, } def _do_status(radio, block): @@ -440,6 +443,7 @@ def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) + print self.get_settings() def sync_in(self): try: @@ -640,7 +644,7 @@ return int(version_tag[idx:idx+3]) raise Exception("Unrecognized firmware version string") - def _get_settings(self): + def get_settings(self): _settings = self._memobj.settings[0] basic = RadioSettingGroup("basic", "Basic Settings") advanced = RadioSettingGroup("advanced", "Advanced Settings") @@ -880,15 +884,45 @@ RadioSettingValueInteger(0, 127, _mrcnb)) workmode.append(rs) - options = ["VHF", "UHF"] rs = RadioSetting("vfoa.band", "VFO A Band", - RadioSettingValueList(options, - options[self._memobj.vfoa.band])) + RadioSettingValueList(BAND_LIST, + BAND_LIST[self._memobj.vfoa.band])) workmode.append(rs) rs = RadioSetting("vfob.band", "VFO B Band", - RadioSettingValueList(options, - options[self._memobj.vfob.band])) + RadioSettingValueList(BAND_LIST, + BAND_LIST[self._memobj.vfob.band])) + workmode.append(rs) + + def convert_bytes_to_freq(bytes): + real_freq = 0 + for byte in bytes: + real_freq = (real_freq * 10) + byte + return real_freq / 100000.0 + + def convert_freq_to_bytes(real_freq): + bytes = [ 0 for x in range(0,8) ] # init list with 8 times 0 + real_freq = int(freq * 100000) # it has to be integer + for i in range(7, -1, -1): # go from 7 to 0 + bytes[i] = real_freq%10 # extract last digit + real_freq /= 10 # throw away last digit + return bytes + + def my_validate(value): + if value < 400 and value > 174: + raise InvalidValueError("Can't be between 174-400") + return value + + val1a = RadioSettingValueFloat(136, 512, + convert_bytes_to_freq(self._memobj.vfoa.freq)) + val1a.set_callback(my_validate) + rs = RadioSetting("vfoa.freq", "VFO A Frequency", val1a) + workmode.append(rs) + + val1b = RadioSettingValueFloat(136, 512, + convert_bytes_to_freq(self._memobj.vfob.freq)) + val1b.set_callback(my_validate) + rs = RadioSetting("vfob.freq", "VFO B Frequency", val1b) workmode.append(rs) options = ["High", "Low"] @@ -945,33 +979,39 @@ return group - def get_settings(self): - try: - return self._get_settings() - except: - import traceback - print "Failed to parse settings:" - traceback.print_exc() - return None - def set_settings(self, settings): + def convert_freq_to_bytes(freq): + bytes = [ 0 for x in range(0,8) ] # init list with 8 times 0 + real_freq = int(freq * 100000) # it has to be integer + for i in range(7, -1, -1): # go from 7 to 0 + bytes[i] = real_freq%10 # extract last digit + real_freq /= 10 # throw away last digit + return bytes + _settings = self._memobj.settings[0] for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue - try: - if "." in element.get_name(): - bits = element.get_name().split(".") - obj = self._memobj - for bit in bits[:-1]: - obj = getattr(obj, bit) - setting = bits[-1] - else: - obj = _settings - setting = element.get_name() - print "Setting %s = %s" % (setting, element.value) - setattr(obj, setting, element.value) - except Exception, e: - print element.get_name() - raise + elif element.get_name() == "vfoa.freq": + self._memobj.vfoa.freq = convert_freq_to_bytes(element.value.get_value()) + elif element.get_name() == "vfob.freq": + self._memobj.vfob.freq = convert_freq_to_bytes(element.value.get_value()) + else: + try: + if "." in element.get_name(): + bits = element.get_name().split(".") + obj = self._memobj + for bit in bits[:-1]: + obj = getattr(obj, bit) + setting = bits[-1] + else: + obj = _settings + setting = element.get_name() + print "Setting %s = %s" % (setting, element.value) + if setting == "footest": + return # This is a fake setting! + setattr(obj, setting, element.value) + except Exception, e: + print element.get_name() + raise diff -r 5f4fff6266ab -r ec472c41b720 chirpui/settingsedit.py --- a/chirpui/settingsedit.py Mon Jan 21 14:59:40 2013 -0800 +++ b/chirpui/settingsedit.py Thu Jan 24 22:44:25 2013 -0500 @@ -63,7 +63,12 @@ if self._top_setting_group is None: return - job = common.RadioJob(None, "set_settings", self._top_setting_group) + def setting_cb(result): + if isinstance(result, Exception): + common.show_error(_("Error in setting value: %s") % result) + + job = common.RadioJob(setting_cb, "set_settings", + self._top_setting_group) job.set_desc("Setting radio settings") self._rthread.submit(job) @@ -73,6 +78,8 @@ adj.configure(value.get_value(), value.get_min(), value.get_max(), value.get_step(), 1, 0) + elif isinstance(value, settings.RadioSettingValueFloat): + widget.set_text(value.format()) elif isinstance(value, settings.RadioSettingValueBoolean): widget.set_active(value.get_value()) elif isinstance(value, settings.RadioSettingValueList): @@ -89,9 +96,11 @@ print "Unsupported widget type %s for %s" % (value.__class__, element.get_name()) - def _save_setting(self, widget, value): + def _do_save_setting(self, widget, value): if isinstance(value, settings.RadioSettingValueInteger): value.set_value(widget.get_adjustment().get_value()) + elif isinstance(value, settings.RadioSettingValueFloat): + value.set_value(widget.get_text()) elif isinstance(value, settings.RadioSettingValueBoolean): value.set_value(widget.get_active()) elif isinstance(value, settings.RadioSettingValueList): @@ -105,6 +114,12 @@ self._save_settings() + def _save_setting(self, widget, value): + try: + self._do_save_setting(widget, value) + except settings.InvalidValueError, e: + common.show_error(_("Invalid setting value: %s") % e) + def _build_ui_group(self, group): def pack(widget, pos): self._table.attach(widget, pos, pos+1, self._index, self._index+1, @@ -139,6 +154,9 @@ widget = gtk.SpinButton() print "Digits: %i" % widget.get_digits() signal = "value-changed" + elif isinstance(value, settings.RadioSettingValueFloat): + widget = gtk.Entry() + signal = "focus-out-event" elif isinstance(value, settings.RadioSettingValueBoolean): widget = gtk.CheckButton(_("Enabled")) signal = "toggled" @@ -160,7 +178,11 @@ arraybox.pack_start(lalign, 1, 1, 1) widget.show() self._load_setting(value, widget) - widget.connect(signal, self._save_setting, value) + if signal == "focus-out-event": + widget.connect(signal, lambda w, e, v: + self._save_setting(w, v), value) + else: + widget.connect(signal, self._save_setting, value) self._index += 1