Source code for pyfldigi.client.main

'''
'''

import time


[docs]class Main(object): '''All the commands under 'fldigi.main' in the XML-RPC spec for fldigi. .. note:: An instance of this class automatically gets created under :py:class:`pyfldigi.client.client.Client` when it is constructed. ''' def __init__(self, clientObj): self.clientObj = clientObj self.client = clientObj.client self.mutex = clientObj.mutex @property def status1(self): '''Returns the contents of the first status field (typically s/n) :returns: First status field :rtype: str :Example: >>> import pyfldigi >>> fldigi = pyfldigi.Client() >>> fldigi.main.status1 '' ''' return self.client.main.get_status1() @property def status2(self): '''Returns the contents of the second status field :returns: Second status field :rtype: str :Example: >>> import pyfldigi >>> fldigi = pyfldigi.Client() >>> fldigi.main.status2 '' ''' return self.client.main.get_status2() @property def wf_sideband(self): '''The current waterfall sideband (either USB or LSB) :getter: Returns the current waterfall sideband (either USB or LSB) :setter: Sets the waterfall sideband to USB or LSB. :todo: The setter doesn't seem to work, at least in some contexts or modes. :type: str :Example: >>> import pyfldigi >>> fldigi = pyfldigi.Client() >>> fldigi.main.wf_sideband # read to demonstrate its initial value 'USB' >>> fldigi.main.wf_sideband = 'LSB' # set to Lower sideband >>> fldigi.main.wf_sideband # read back to demonstrate that it changed 'LSB' ''' return self.client.main.get_wf_sideband() @wf_sideband.setter def set_wf_sideband(self, sideband): '''Sets the waterfall sideband to USB or LSB NOTE: sphinx ignores docstrings from setters, the documentation is above under the @property''' if str(sideband) not in ['USB', 'LSB']: raise ValueError('sideband must be USB or LSB') self.client.main.set_wf_sideband(str(sideband)) @property def afc(self): '''The AFC (auto frequency control) state :getter: Returns the AFC [auto frequency control] state :setter: Sets the AFC [auto frequency control] state. :type: bool :Example: >>> import pyfldigi >>> fldigi = pyfldigi.Client() >>> fldigi.main.afc # read to demonstrate its initial value True >>> fldigi.main.afc = False # disable >>> fldigi.main.afc # read back to demonstrate that it changed False ''' return bool(self.client.main.get_afc()) @afc.setter def afc(self, afc): '''Sets the AFC (auto frequency control) state. NOTE: sphinx ignores docstrings from setters, the documentation is above under the @property''' if not isinstance(afc, bool): raise TypeError('afc must be a bool') self.client.main.set_afc(bool(afc)) @property def squelch(self): '''The squelch state (True or False) :getter: Returns the squelch state. :setter: Sets the squelch state. :type: bool :Example: >>> import pyfldigi >>> fldigi = pyfldigi.Client() >>> fldigi.main.squelch # read to demonstrate its initial value True >>> fldigi.main.squelch = False # disable >>> fldigi.main.squelch # read back to demonstrate that it changed False ''' return bool(self.client.main.get_squelch()) @squelch.setter def squelch(self, squelch): '''Sets the squelch state. NOTE: sphinx ignores docstrings from setters, the documentation is above under the @property''' if not isinstance(squelch, bool): raise TypeError('squelch state must be a bool') self.client.main.set_squelch(bool(squelch)) @property def squelch_level(self): '''The squelch level. Range is 0.0 - 100.0 :getter: Returns the squelch level :setter: Sets the squelch state. :type: float :Example: >>> import pyfldigi >>> fldigi = pyfldigi.Client() >>> fldigi.main.squelch_level # read to demonstrate its initial value 5.0 >>> fldigi.main.squelch_level = 4 # set to 4. will be casted to float. >>> fldigi.main.squelch_level # read back to demonstrate that it changed 4.0 ''' return self.client.main.get_squelch_level() @squelch_level.setter def squelch_level(self, level): '''Sets the squelch level. NOTE: sphinx ignores docstrings from setters, the documentation is above under the @property''' if not 0 <= level <= 100: raise ValueError('squelch level must be between 0 and 100') self.client.main.set_squelch_level(float(level)) @property def reverse(self): '''The Reverse Sideband state (whether or not the mark and space are reversed) :getter: Returns the Reverse Sideband state :setter: Sets the Reverse Sideband state. :type: bool :Example: >>> import pyfldigi >>> fldigi = pyfldigi.Client() >>> fldigi.main.reverse # read to demonstrate its initial value True >>> fldigi.main.reverse = False # disable >>> fldigi.main.reverse # read back to demonstrate that it changed False ''' return bool(self.client.main.get_reverse()) @reverse.setter def reverse(self, state): '''Sets the Reverse Sideband state. NOTE: sphinx ignores docstrings from setters, the documentation is above under the @property''' self.client.main.set_reverse(bool(state)) @property def txlock(self): '''The Transmit [frequency] Lock state. When unlocked the transmit and receive frequencies can be uncoupled. :getter: Returns the Transmit [frequency] Lock state :setter: Sets the Transmit [frequency] Lock state. :type: bool :Example: >>> import pyfldigi >>> fldigi = pyfldigi.Client() >>> fldigi.main.txlock # read to demonstrate its initial value True >>> fldigi.main.txlock = False # disable >>> fldigi.main.txlock # read back to demonstrate that it changed False ''' return bool(self.client.main.get_lock()) @txlock.setter def txlock(self, value=True): '''Sets the Transmit [frequency] Lock state. NOTE: sphinx ignores docstrings from setters, the documentation is above under the @property''' self.client.main.set_lock(bool(value)) @property def rsid(self): '''The RSID state. Reed-Solomon Identification (RSID) is used in several digital mode programs. RSID allows the automatic identification of any digital transmission which has been assigned a unique code identifier. On reception of a RS ID, two events occur: the mode used is detected and the central frequency of the RSID, which is also the central frequency of the identified mode, is determined with a precision of 2.7 Hz. This is sufficient to allow all current modes to begin accurate decoding. This is an excellent way to insure that signals like MFSK are properly tuned and decoded. The RSID signal is transmitted in 1.4 sec and has a bandwidth of 172 Hz. Detection of the RSID signal is possible down to a Signal to Noise ratio of about -16 dB, so with a sensitivity equal or better than the majority of the digital modes (RTTY, PSK31...), except several modes as PSK10, PSKAM10, THROB, THROBX or JT65. .. Note:: Consequently, it is possible to detect RSID and not be able to decode the ensuing data signal due to it being too weak a signal. fldigi allows the RSID signal to be sent at the beginning and the end of each transmission. The leading RSID is the normal position. During reception fldigi can decode RSID signals within the entire audio spectrum. It can also be configured to limit the reception to a narrow bandwidth centered on the current audio subcarrier. Detection occurs as a background process and does not interfer with the normal signal decoding. False detection is possible, but statistically rare due to the use of a very strong autocorrelation function associated with the RSID codes. .. note:: For more info, please see: http://www.w1hkj.com/RSID_description.html :getter: Returns the RSID state. :setter: Sets the RSID state. :type: bool :Example: >>> import pyfldigi >>> fldigi = pyfldigi.Client() >>> fldigi.main.rsid # read to demonstrate its initial value True >>> fldigi.main.rsid = False # disable >>> fldigi.main.rsid # read back to demonstrate that it changed False ''' return bool(self.client.main.get_rsid()) @rsid.setter def rsid(self, value): '''Sets the RSID state. NOTE: sphinx ignores docstrings from setters, the documentation is above under the @property''' self.client.main.set_rsid(bool(value))
[docs] def get_trx_state(self, suppress_errors=False): '''Returns transmit/tune/receive status returns: ['TX', 'RX', 'TUNE'] ?? ''' for tries in range(0, 3): # retry up to 3 times. self.mutex.acquire() try: state = str(self.client.main.get_trx_status()).upper() except Exception as e: state = 'ERROR' finally: self.mutex.release() if state in ['TX', 'RX', 'TUNE']: break time.sleep(0.005) return state
[docs] def rx(self): '''Puts fldigi into receive mode. .. note:: This is the default mode that FLDIGI starts in. This command is only needed when you've put it into some other mode. :Example: >>> import pyfldigi >>> fldigi = pyfldigi.Client() >>> fldigi.main.tx() # Put flgidigi into transmit mode >>> fldigi.delay(1000) # wait a bit >>> fldigi.main.rx() # Put flgidigi into receive mode ''' self.client.main.rx()
[docs] def tx(self): '''Puts fldigi into transmit mode. This will key the PTT or VOX via CAT control. .. note:: If you're looking to transmit a block of text, please use :py:method:`pyfldigi.client.main.send` :Example: >>> import pyfldigi >>> fldigi = pyfldigi.Client() >>> fldigi.main.tx() # Put flgidigi into transmit mode >>> fldigi.delay(1000) # wait a bit >>> fldigi.main.rx() # Put flgidigi into receive mode ''' self.client.main.tx()
[docs] def tune(self): '''Puts fldigi into tune mode. I'm assuming that this allows antenna tuning via CAT/RIG control. :Example: >>> import pyfldigi >>> fldigi = pyfldigi.Client() >>> fldigi.main.tune() # Put flgidigi into tune mode ''' self.client.main.tune()
[docs] def abort(self): '''Aborts a transmit or tune :Example: >>> import pyfldigi >>> fldigi = pyfldigi.Client() >>> fldigi.main.tx() # Put flgidigi into transmit mode >>> fldigi.delay(10) # wait a bit >>> fldigi.main.abort() # abort the transmit ''' self.client.main.abort()
[docs] def run_macro(self, macroNum): '''Runs a macro :param macroNum: The macro # to run. Must be a valid #. :type macroNum: int ''' return self.client.main.run_macro(int(macroNum))
[docs] def get_max_macro_id(self): '''Returns the maximum macro ID number :returns: The maximum macro ID number :rtype: int ''' return self.client.main.get_max_macro_id()
[docs] def send(self, data, block=True, timeout=10): '''This is the preferred way of sending a block of text. :param data: The text or data to encode and transmit :type data: str or bytes :param block: if True, the function blocks until all data has been transmitted. If False, this method returns immediately while the radio transmits. :type block: bool :param timeout: The # of seconds to wait before returning a TimeoutError :type timeout: float or int .. warning:: FLDIGI does NOT turn the transmit off after the text is done transmitting. :example: >>> import pyfldigi >>> c = pyfldigi.Client() >>> # Make sure to set up the modem and rig settings here!!! >>> c.main.send('Lorem ipsum dolor sit amet') ''' state = self.clientObj.main.get_trx_state() print('send(): state={}'.format(state)) if state == 'TX': # already chooching tx_start = time.time() self.clientObj.text.add_tx(data) elif state == 'RX': self.clientObj.text.clear_tx() self.clientObj.txmonitor.history.txdata_history = [] # clear tx_start = time.time() self.clientObj.main.tx() self.clientObj.text.add_tx(data) # wait until the first character has been transmitted, even if non blocking while(1): if len(self.clientObj.txmonitor.history.txdata_history) >= 1: break if time.time() - tx_start >= timeout: raise TimeoutError('Timeout while transmitting, waiting for first byte to go out') else: raise Exception('cannot transmit if FLDIGI state is \'{}\''.format(state)) if block is True: while(1): if self.clientObj.txmonitor.transmitting is False: print('Returning from blocking call to send()...') break if time.time() - tx_start >= timeout: raise TimeoutError('Timeout while transmitting, waiting for text to be transmitted')