Browse code

set methods now upon errors raise exceptions

Gandolf authored on 11/28/2019 21:39:18
Showing 2 changed files
... ...
@@ -117,7 +117,9 @@ dDcs = { '23':'000', '25':'001', '26':'002', '31':'003', '32':'004',
117 117
 dRxClar = { 'OFF':'0', 'ON':'1' }
118 118
 dTxClar = { 'OFF':'0', 'ON':'1' }
119 119
 
120
-# Define 'get' methods to encapsulate FT991 commands that return status info.
120
+#############################################################################
121
+# Define 'get' methods to encapsulate FT991 commands returning status info. #
122
+#############################################################################
121 123
 
122 124
 def getMemory(memloc):
123 125
     """
... ...
@@ -127,17 +129,11 @@ def getMemory(memloc):
127 129
     """
128 130
     dMem = {}
129 131
 
130
-    # Set memory location pointer in FT991.  This is done
131
-    # by sending the memory location select (MC) command.
132
-    sCmd = 'MC%0.3d;' % (memloc)
133
-    sResult = sendCommand(sCmd)
134
-    # Skip blank memory locations, which return '?;'.
135
-    if sResult == '?;':
136
-        return None
137
-
138 132
     # Send the get memory settings string to the FT991.
139 133
     sCmd = 'MT%0.3d;' % (memloc)
140 134
     sResult = sendCommand(sCmd)
135
+    if sResult == '?;':
136
+        return None
141 137
 
142 138
     # Parse memory settings string returned by the FT991
143 139
     memloc = sResult[2:5]
... ...
@@ -188,7 +184,37 @@ def getDCS():
188 184
     return dDcs.keys()[dDcs.values().index(dcs)]
189 185
 ## end def
190 186
 
191
-# Define 'set' functions to encapsulate the various FT991 CAT commands.
187
+def getRxClarifier():
188
+    """
189
+    Description:  Gets the state of the Rx clarifier.
190
+    Parameters: none
191
+    Returns: string containing the state of the clarifier
192
+    """
193
+    # An exception will automatically be raised if incorrect data is
194
+    # supplied - most likely a "key not found" error.
195
+    sCmd = 'RT;'
196
+    sResult = sendCommand(sCmd)
197
+    state = sResult[2]
198
+    return dRxClar.keys()[dRxClar.values().index(state)]
199
+## end def
200
+
201
+def getTxClarifier():
202
+    """
203
+    Description:  Gets the state of the Tx clarifier.
204
+    Parameters: none
205
+    Returns: string containing the state of the clarifier
206
+    """
207
+    # An exception will automatically be raised if incorrect data is
208
+    # supplied - most likely a "key not found" error.
209
+    sCmd = 'XT;'
210
+    sResult = sendCommand(sCmd)
211
+    state = sResult[2]
212
+    return dTxClar.keys()[dTxClar.values().index(state)]
213
+## end def
214
+
215
+#########################################################################
216
+# Define 'set' functions to encapsulate the various FT991 CAT commands. #
217
+#########################################################################
192 218
 
193 219
 def setMemory(dMem):
194 220
     """
... ...
@@ -206,25 +232,17 @@ def setMemory(dMem):
206 232
                        shift - the direction of the repeater shift
207 233
                        tag - a label for the memory location
208 234
 
209
-    Returns: a string containing the formatted command
235
+    Returns: nothing
210 236
     """
211
-    # Format the set memory location (MC) command.
212
-    iMemloc = int(dMem['memloc'])
213
-    # Validate memory location data and send the command.
214
-    if iMemloc < 1 or iMemloc > 118:
237
+    # Format the set memory with tag command (MT).
238
+    sCmd = 'MT'
239
+
240
+    # Validate and append memory location data.
241
+    iLocation = int(dMem['memloc'])
242
+    if iLocation < 1 or iLocation > 118:
215 243
         raise Exception('Memory location must be between 1 and ' \
216 244
                         '118, inclusive.')
217
-    sCmd = 'MC%0.3d;' % iMemloc
218
-    sResult = sendCommand(sCmd)
219
-
220
-    # While the 'MW' and 'MT' commands can be used to turn the Rx
221
-    # and Tx clarifiers on, the clarifier states can only be turned
222
-    # off by sending the 'RT0' and 'XT0' commands.  This situation is
223
-    # probably due to a bug in the CAT interface.
224
-    sResult = sendCommand('RC;RT0;XT0;')
225
-
226
-    # Format the set memory with tag command (MT).
227
-    sCmd = 'MT%0.3d' % iMemloc
245
+    sCmd += '%0.3d' % iLocation
228 246
 
229 247
     # Validate and append the vfo-a frequency data.
230 248
     iRxfreq = int(float(dMem['rxfreq']) * 1E6) # vfo-a frequency in Hz
... ...
@@ -261,7 +279,8 @@ def setMemory(dMem):
261 279
 
262 280
     # Send the completed command.
263 281
     sResult = sendCommand(sCmd)
264
-    return sResult
282
+    if sResult == '?;':
283
+        raise Exception('setMemory error')
265 284
 ## end def
266 285
 
267 286
 def setCTCSS(tone):
... ...
@@ -270,12 +289,15 @@ def setCTCSS(tone):
270 289
                   CTCSS tone.
271 290
     Parameters:   tone - a string containing the CTCSS tone in Hz, e.g.,
272 291
                          '100 Hz'
273
-    Returns: a string containing the formatted command
292
+    Returns: nothing
274 293
     """
275 294
     # An exception will automatically be raised if incorrect data is
276 295
     # supplied - most likely a "key not found" error.
277 296
     sCmd = 'CN00%s;' % dTones[tone]
278
-    return sendCommand(sCmd)
297
+    # Send the completed command.
298
+    sResult = sendCommand(sCmd)
299
+    if sResult == '?;':
300
+        raise Exception('setCTCSS error')
279 301
 ## end def
280 302
 
281 303
 def setDCS(code):
... ...
@@ -283,12 +305,15 @@ def setDCS(code):
283 305
     Description:  Sends a formatted CN command that sets the desired
284 306
                   DCS code.
285 307
     Parameters: code - a string containing the DCS code, e.g., '23'
286
-    Returns: a string containing the formatted command
308
+    Returns: nothing
287 309
     """
288 310
     # An exception will automatically be raised if incorrect data is
289 311
     # supplied - most likely a "key not found" error.
290 312
     sCmd = 'CN01%s;' % dDcs[code]
291
-    return sendCommand(sCmd)
313
+    # Send the completed command.
314
+    sResult = sendCommand(sCmd)
315
+    if sResult == '?;':
316
+        raise Exception('setDCS error')
292 317
 ## end def
293 318
 
294 319
 def setPower(power):
... ...
@@ -296,17 +321,73 @@ def setPower(power):
296 321
     Description:  Sends a PC command that sets the desired
297 322
                   RF transmit power level.
298 323
     Parameters:   power - Watts, an integer between 5 and 100
299
-    Returns: a string containing the formatted command
324
+    Returns: nothing
300 325
     """
301 326
     power = int(power)
302 327
     # Validate power data and format command.
303 328
     if power < 5 or power > 100:
304 329
         raise Exception('Power must be between 0 and 100 watts, inclusive.')
305 330
     sCmd += 'PC%03.d;' % power
306
-    return sendCommand(sCmd)
331
+    # Send the completed command.
332
+    sResult = sendCommand(sCmd)
333
+    if sResult == '?;':
334
+        raise Exception('setPower error')
335
+
307 336
 ## end def
308 337
 
309
-# Helper functions to assist in various tasks.
338
+def setRxClarifier(state='OFF'):
339
+    """
340
+    Description:  Sends a formatted RT command that turns the Rx clarifier
341
+                  on or off.
342
+    Parameters: state - string 'OFF' or 'ON'
343
+    Returns: nothing
344
+    """
345
+    # An exception will automatically be raised if incorrect data is
346
+    # supplied - most likely a "key not found" error.
347
+    sCmd = 'RT%s;' % dRxClar[state]
348
+    # Send the completed command.
349
+    sResult = sendCommand(sCmd)
350
+    if sResult == '?;':
351
+        raise Exception('setRxClarifier error')
352
+## end def
353
+
354
+def setTxClarifier(state='OFF'):
355
+    """
356
+    Description:  Sends a formatted XT command that turns the Rx clarifier
357
+                  on or off.
358
+    Parameters: state - string 'OFF' or 'ON'
359
+    Returns: nothing
360
+    """
361
+    # An exception will automatically be raised if incorrect data is
362
+    # supplied - most likely a "key not found" error.
363
+    sCmd = 'XT%s;' % dTxClar[state]
364
+    # Send the completed command.
365
+    sResult = sendCommand(sCmd)
366
+    if sResult == '?;':
367
+        raise Exception('setTxClarifier error')
368
+## end def
369
+
370
+def setMemoryLocation(iLocation):
371
+    """
372
+    Description:  Sends a formatted MC command that sets the current
373
+                  memory location.
374
+    Parameters: location - integer specifying memory location
375
+    Returns: nothing
376
+    """
377
+    # Validate memory location data and send the command.
378
+    if iLocation < 1 or iLocation > 118:
379
+        raise Exception('Memory location must be an integer between 1 and ' \
380
+                        '118, inclusive.')
381
+    sCmd = 'MC%0.3d;' % iLocation
382
+    # Send the completed command.
383
+    sResult = sendCommand(sCmd)
384
+    if sResult == '?;':
385
+        raise Exception('setMemoryLocation error')
386
+## end def
387
+
388
+############################################################################
389
+# Helper functions to assist in various tasks.                             #
390
+############################################################################
310 391
 
311 392
 def parseCsvData(sline):
312 393
     """
... ...
@@ -476,14 +557,41 @@ def main():
476 557
 
477 558
     # Instantiate serial connection to FT991
478 559
     begin()
479
-    # Commands that send a setting
480
-    dMem = {'rxfreq': '146.52', 'shift': 'OFF', 'encode': 'OFF', \
481
-        'txclar': 'OFF', 'tag': 'KA7JLO', 'mode': 'FM', 'rxclar': 'OFF', \
482
-        'memloc': '99', 'clarfreq': '0'}
560
+    # Set and receive a memory channel
561
+    dMem = {'memloc': '98', 'rxfreq': '146.52', 'shift': 'OFF', \
562
+            'mode': 'FM', 'encode': 'TONE ENC', 'tag': 'KA7JLO', \
563
+            'clarfreq': '1234', 'rxclar': 'ON', 'txclar': 'ON' \
564
+           }
483 565
     setMemory(dMem)
484
-    sendCommand('MC002;')
485
-    # Commands that return data
566
+    setMemoryLocation(int(dMem['memloc']))
567
+    setRxClarifier(dMem['rxclar'])
568
+    setTxClarifier(dMem['txclar'])
569
+    setCTCSS('127.3 Hz')
570
+    setDCS('115')
571
+    print
572
+    getMemory(98)
573
+    print
574
+    # Set and receive a memory channel
575
+    dMem = {'memloc': '99', 'rxfreq': '146.52', 'shift': 'OFF', \
576
+            'mode': 'FM', 'encode': 'OFF', 'tag': 'KA7JLO', \
577
+            'clarfreq': '0', 'rxclar': 'OFF', 'txclar': 'OFF' \
578
+           }
579
+    setMemory(dMem)
580
+    setMemoryLocation(int(dMem['memloc']))
581
+    setRxClarifier(dMem['rxclar'])
582
+    setTxClarifier(dMem['txclar'])
583
+    setCTCSS('141.3 Hz')
584
+    setDCS('445')
585
+    print
486 586
     getMemory(99)
587
+    print
588
+
589
+    # Test set commands
590
+    #setMemoryLocation(2)
591
+    # Test get commands
592
+    #   commands...
593
+    # Test CAT commands via direct pass-through
594
+    # Commands that return data
487 595
     sendCommand('IF;')
488 596
     # Invalid command handling
489 597
     sendCommand('ZZZ;')
... ...
@@ -266,16 +266,19 @@ def readMemorySettings():
266 266
                         'Repeater Shift,Mode,Tag,Encoding,Tone,DCS,' \
267 267
                         'Clarifier, RxClar, TxClar' ]
268 268
 
269
-    for memoryLocation in range(1, _MAX_NUMBER_OF_MEMORY_ITEMS):
269
+    for iLocation in range(1, _MAX_NUMBER_OF_MEMORY_ITEMS):
270
+
270 271
         # For each memory location get the memory contents.  Note that
271 272
         # several CAT commands are required to get the entire contents
272 273
         # of a memory location.  Specifically, additional commands are
273 274
         # required to get DCS code and CTCSS tone.
274
-        dMem = ft991.getMemory(memoryLocation)
275
+        dMem = ft991.getMemory(iLocation)
275 276
         # If a memory location is empty (has not been programmed or has
276 277
         # been erased), do not created a list entry for that location.
277 278
         if dMem == None:
278 279
             continue
280
+        # Set current memory location to the channel being set.
281
+        sResult = ft991.setMemoryLocation(iLocation)
279 282
         # Get DCS and CTCSS.
280 283
         tone = ft991.getCTCSS()
281 284
         dcs = ft991.getDCS()
... ...
@@ -289,8 +292,6 @@ def readMemorySettings():
289 292
                  dMem['txclar'] )
290 293
         # Add the comma-delimited string to the list object.
291 294
         lSettings.append(sCsvFormat)
292
-        if ft991.verbose:
293
-            print
294 295
     return lSettings
295 296
 # end def
296 297
 
... ...
@@ -308,25 +309,28 @@ def writeMemorySettings(lSettings):
308 309
         # so ignore this item.  (parseData returns None for this item.)
309 310
         if dItem == None:
310 311
             continue
311
-        sResult = ''
312 312
         try:
313
-            # Set memory channel vfo, mode, and other data.
314
-            sResult += ft991.setMemory(dItem)
313
+            # Set the parameters for the memory location.
314
+            ft991.setMemory(dItem)
315
+            # Set current channel to memory location being set.
316
+            ft991.setMemoryLocation(int(dItem['memloc']))
315 317
             # Set CTCSS tone for memory channel.
316
-            sResult += ft991.setCTCSS(dItem['tone'])
318
+            ft991.setCTCSS(dItem['tone'])
317 319
             # Set DCS code for memory channel. 
318
-            sResult += ft991.setDCS(dItem['dcs'])
320
+            ft991.setDCS(dItem['dcs'])
321
+            # Set clarifier mode.  Note that
322
+            # while the 'MW' and 'MT' commands can be used to turn the Rx
323
+            # and Tx clarifiers on, the clarifier states can only be turned
324
+            # off by sending the 'RT0' and 'XT0' commands.  This situation
325
+            # is probably due to a bug in the CAT interface.
326
+            ft991.setRxClarifier(dItem['rxclar'])
327
+            ft991.setTxClarifier(dItem['txclar'])            
319 328
         except Exception, e:
320
-            print 'Backup settings file corrupted or incorrectly formatted.\n' \
321
-                  'Please make sure all values are correctly entered.'
329
+            print 'Memory settings restore operation failed. Most likely\n' \
330
+                  'this is due to the backup settings file corrupted or\n' \
331
+                  'incorrectly formatted. Look for the following error: \n'
322 332
             print e
323 333
             exit(1)
324
-
325
-        # Process any errors returned by the CAT interface.
326
-        if sResult.find('?;') > -1:
327
-            print 'Error restoring memory setting: %s' % sResult
328
-        if ft991.verbose:
329
-            print
330 334
 ## end def
331 335
 
332 336
 def readMenuSettings():