#!/usr/bin/env python # # Copyright 2017 Alexander Fasching # # 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 3 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 . # from __future__ import print_function, division import sys import argparse import socket import time import Tkinter from Tkinter import * DEBUG=True delay_secs = 0.05 # 50 msec delay timeout = 0.0 usb_if_offset = 0 #-3000 # 0 #-2250 lsb_if_offset = 0 #3000 # -1000 #0 rs = 0 gs = 0 #class TmpSettings: # def __init__(self): # self.RIG_TO_GQRX = IntVar(1) # self.GQRX_TO_RIG = IntVar(1) def freq_to_string(freq): freq_str = str(freq).rjust(9) return freq_str[0:3] + "." + freq_str[3:6] + "." + freq_str[6:9] #MHz = int(freq/1000000) #kHz = int(freq/1000)-(MHz*1000) #Hz = freq - ((MHz*1000000)+(kHz*1000)) #return str(MHz) + "." + str(kHz) + "." + str(Hz) class MainWindow: def __init__(self, root, rig_name="uBITX"): self.__root = root self.__root.title("Gqrx Panadapter - " + rig_name) self.rig_to_gqrx = IntVar() self.gqrx_to_rig = IntVar() self.rig_freq = StringVar() self.gqrx_freq = StringVar() self.rig_mode = StringVar() self.__rig_frame = Frame(self.__root, relief=GROOVE, bd=3) self.__rig_frame.grid(row=0, column=0) self.__rig_freq_lbl = Label(self.__rig_frame, text="Rig Freq: ") self.__rig_freq_lbl.grid(row=0, column=0, padx=5) self.__rig_freq_val = Label(self.__rig_frame, textvariable=self.rig_freq) self.__rig_freq_val.grid(row=0, column=1, padx=5) self.__rig_mode_lbl = Label(self.__rig_frame, text="Mode: ") self.__rig_mode_lbl.grid(row=0, column=2, padx=5) self.__rig_mode_val = Label(self.__rig_frame, textvariable=self.rig_mode) self.__rig_mode_val.grid(row=0, column=3, padx=5) self.__r2g_ctrl = Checkbutton(self.__rig_frame, text="Rig-to-Gqrx", variable=self.rig_to_gqrx) self.__r2g_ctrl.grid(row=0, column=4, padx=5) self.rig_to_gqrx.set(1) self.__gqrx_frame = Frame(self.__root, relief=GROOVE, bd=3) self.__gqrx_frame.grid(row=0, column=1) self.__gqrx_freq_lbl = Label(self.__gqrx_frame, text="Gqrx Freq: ") self.__gqrx_freq_lbl.grid(row=0, column=0, padx=5) self.__gqrx_freq_val = Label(self.__gqrx_frame, textvariable=self.gqrx_freq) self.__gqrx_freq_val.grid(row=0, column=1, padx=5) self.__g2r_ctrl = Checkbutton(self.__gqrx_frame, text="Gqrx-to-Rig", variable=self.gqrx_to_rig) self.__g2r_ctrl.grid(row=0, column=2, padx=5) self.gqrx_to_rig.set(1) #self.__hw_freq = Entry(self.__gqrx_frame, text=H def calc_lnb_lo(freq, ifreq, isusb=True): if DEBUG: print('Freq: ' + str(freq)) print('IF Freq: ' + str(ifreq)) if isusb: if DEBUG: print('USB IF: ' + str(ifreq + usb_if_offset)) #return - freq - (ifreq - usb_if_offset) #return freq + usb_if_offset - (ifreq + (129600*2)) # need to make this configurable; would be great to get it from Gqrx return freq - (ifreq + 129600*2 + usb_if_offset) else: if DEBUG: print('LSB IF: ' + str(ifreq + lsb_if_offset)) #return - freq - (ifreq + lsb_if_offset) #return freq + lsb_if_offset - (ifreq + (129600*2)) # need to make this configurable; would be great to get it from Gqrx return freq - (ifreq + 129600*2 + lsb_if_offset) def get_rig_freq(rs): rs.send(b'm\n') is_usb = True if rs.recv(1024).splitlines()[0] == "USB" else False rs.send(b'f\n') return (int(rs.recv(1024)), is_usb) def set_rig_freq(rs, freq): if DEBUG: print('Set Rig freq: {}'.format(freq).encode()) rs.send(b'F ' + str(freq) + '\n') rs.recv(1024) def get_gqrx_freq(gs): gs.send(b'f\n') return int(gs.recv(1024)) #* -1 def set_gqrx_freq(gs, freq): if DEBUG: print('Set GQRX Freq: {}'.format(freq).encode()) gs.send('F {}'.format(freq).encode()) gs.recv(1024) def set_gqrx_lnb_lo(gs, freq, ifreq, isusb): lnb = calc_lnb_lo(freq, ifreq, isusb) if DEBUG: print('Set LNB Freq: {}'.format(lnb).encode()) gs.send('LNB_LO {}'.format(lnb).encode()) gs.recv(1024) def reset_gqrx(gs, ifreq): set_gqrx_lnb_lo(gs, 0, 0, True) set_gqrx_freq(gs, 28800000) set_gqrx_freq(gs, ifreq) def main(): parser = argparse.ArgumentParser() parser.add_argument('-ga', '--gqrx-address', type=str, default='localhost', metavar='A', help='address that Gqrx is listening on') parser.add_argument('-gp', '--gqrx-port', type=int, default=7356, metavar='P', help='remote control port configured in Gqrx') parser.add_argument('-ra', '--rigctld-address', type=str, default='localhost', metavar='A', help='address that rigctld is listening on') parser.add_argument('-rp', '--rigctld-port', type=int, default=4532, metavar='P', help='listening port of rigctld') parser.add_argument('-i', '--interval', type=int, default=1000, metavar='T', help='update interval in milliseconds') parser.add_argument('-f', '--ifreq', type=float, default=68.33, metavar='F', help='intermediate frequency in MHz') args = parser.parse_args() try: rs = socket.socket(socket.AF_INET, socket.SOCK_STREAM) rs.connect((args.rigctld_address, args.rigctld_port)) except Exception as e: print('Connection to rigctld failed:', e, file=sys.stderr) return 1 try: gs = socket.socket(socket.AF_INET, socket.SOCK_STREAM) gs.connect((args.gqrx_address, args.gqrx_port)) except Exception as e: print('Connection to Gqrx failed:', e, file=sys.stderr) return 1 try: if_freq = int(args.ifreq * 1e6) #reset_gqrx(gs, if_freq) old_is_usb = False old_rig_freq = -1 # force initial update old_gqrx_freq = -1 # force initial update (rig_freq, is_usb) = get_rig_freq(rs) gqrx_freq = get_gqrx_freq(gs) tk = Tk() window = MainWindow(tk) while True: allow_rig_to_gqrx = window.rig_to_gqrx.get() allow_gqrx_to_rig = window.gqrx_to_rig.get() (rig_freq, is_usb) = get_rig_freq(rs) gqrx_freq = get_gqrx_freq(gs) #----------------------------------------------------------------- # Update the GUI, if the freqs/modes have changed. #----------------------------------------------------------------- if rig_freq != old_rig_freq or is_usb != old_is_usb: window.rig_freq.set(freq_to_string(rig_freq)) if is_usb: window.rig_mode.set("USB") else: window.rig_mode.set("LSB") if gqrx_freq != old_gqrx_freq: window.gqrx_freq.set(freq_to_string(gqrx_freq)) #----------------------------------------------------------------- # Update the Rig and/or Gqrx, as applicable #----------------------------------------------------------------- # Regardless of anything else, if the rig freq changes, the # LNB LO frequency must be updated (even if allow_rig_to_gqrx is # false). if rig_freq != old_rig_freq or is_usb != old_is_usb: #if abs(rig_freq - old_rig_freq) > 500000: # reset_gqrx(gs, if_freq) if DEBUG: print("\nRig freq changed -- update LNB LO\n") set_gqrx_lnb_lo(gs, rig_freq, if_freq, is_usb) set_gqrx_freq(gs, gqrx_freq) #time.sleep(delay_secs) if allow_rig_to_gqrx and (rig_freq != old_rig_freq or is_usb != old_is_usb): if DEBUG: print("\nRig freq to Gqrx freq\n") set_gqrx_lnb_lo(gs, rig_freq, if_freq, is_usb) set_gqrx_freq(gs, rig_freq) #time.sleep(delay_secs) elif allow_gqrx_to_rig and gqrx_freq != old_gqrx_freq: if DEBUG: print("\nGqrx freq to Rig freq\n") # First set the rig frequency,then wait to ensure it takes. set_rig_freq(rs, gqrx_freq) #time.sleep(delay_secs) # Now grab the rig frequency and use it to re-set the Gqrx # frequency. This is due to the fact that tuning steps on # the rig may prevent the actual Gqrx frequency from being # set, so Gqrx will use whatever the rig accepted. (rig_freq, is_usb) = get_rig_freq(rs) set_gqrx_lnb_lo(gs, rig_freq, if_freq, is_usb) set_gqrx_freq(gs, rig_freq) #time.sleep(delay_secs) tk.update_idletasks() tk.update() time.sleep(args.interval / 1000.0) old_is_usb = is_usb old_rig_freq = rig_freq old_gqrx_freq = gqrx_freq except KeyboardInterrupt: pass except Exception as e: print('Unexpected error:', e, file=sys.stderr) return 1 rs.close() gs.close() if __name__ == '__main__': sys.exit(main() or 0)