... | ... |
@@ -21,20 +21,19 @@ also handle formatting of CAT commands and their associated parameters, |
21 | 21 |
while 'get' functions handle parsing of data returned from CAT commands |
22 | 22 |
that return status information. |
23 | 23 |
|
24 |
+Email bug reports and comments to: fractal@intravisions.com |
|
25 |
+ |
|
24 | 26 |
Notes |
25 | 27 |
----- |
26 | 28 |
1. The files ft991utility.py and ft991.py should be downloaded from the |
27 |
- github repository and placed in the same folder. At the root level |
|
28 |
- of the fractalxoas/ham repository, click on 'Clone or download'. |
|
29 |
- Experienced github users may choose to clone the repository, otherwise |
|
30 |
- select 'Download ZIP'. |
|
29 |
+ github repository and placed in the same folder. |
|
31 | 30 |
2. To run the utility, open a terminal session in directory containing |
32 | 31 |
the ft991utility.py and ft991.py files. Then simply type the utility |
33 | 32 |
file name after the command line prompt, e.g., |
34 | 33 |
~$ ./ft991utility.py |
35 | 34 |
If necessary, change the permissions on ft991utility.py to allow the file |
36 | 35 |
to be run as an executable. To change the permissions run the command |
37 |
- chmod +x ft991utility.py2. |
|
36 |
+ chmod +x ft991utility.py |
|
38 | 37 |
3. Windows users will need to have the python 2.7 framework installed. |
39 | 38 |
Probably, the easiest way to get the framework is to install the |
40 | 39 |
Windows Subsystem for Linux Ubuntu platform. Note that the utility |
... | ... |
@@ -45,7 +44,7 @@ Notes |
45 | 44 |
name of the utility with no command line arguments, e.g., |
46 | 45 |
./ft991utility.py |
47 | 46 |
5. The utility saves memory settings in a comma-delimited file that |
48 |
- can be imported using a spreadsheet application for ease in viewing |
|
47 |
+ can be imported into a spreadsheet application for ease in viewing |
|
49 | 48 |
and editing. A LibreOffice Calc template 'ft991_memory_settings.ots' |
50 | 49 |
has been provided to facilitate creating a spreadsheet to upload memory |
51 | 50 |
settings to the FT991. |
... | ... |
@@ -58,13 +57,13 @@ Notes |
58 | 57 |
to back up your current memory settings. Unless you change the default |
59 | 58 |
file name, this file should appear in your current working directory as |
60 | 59 |
'ft991mem.csv'. Change this file name to something else such as |
61 |
- 'ft991mem_todaysDate.csv' so that you can restore from this file at a |
|
60 |
+ 'ft991mem_todaysDate.csv so that you can restore from this file at a |
|
62 | 61 |
later date if necessary. |
63 | 62 |
8. By the same token you should immediately back up your menu settings using |
64 | 63 |
the 'bu' command in interactive mode. The default file name is |
65 | 64 |
'ft991menu.cfg'. Likewise change this file name to something else. |
66 | 65 |
9. The example file 'example.csv' shows how a memory settings file should |
67 |
- appear. To load these settings into your FT991, run the 'rm' command in |
|
66 |
+ appear. To load these settings in your FT991, run the 'rm' command in |
|
68 | 67 |
interactive mode. When prompted to enter a file name type 'example.csv'. |
69 | 68 |
For example, |
70 | 69 |
Enter file name or <CR> for default: example.csv |
... | ... |
@@ -75,5 +74,4 @@ Notes |
75 | 74 |
what you are doing. There should rarely be a need to edit this file. |
76 | 75 |
Menu changes should be made on the FT991, itself, and then backed up. |
77 | 76 |
|
78 |
-Email bug reports and comments to: fractal@intravisions.com |
|
79 | 77 |
|
... | ... |
@@ -117,67 +117,26 @@ 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 'set' functions to encapsulate the various FT991 CAT commands. |
|
120 |
+# Define 'get' methods to encapsulate FT991 commands that return status info. |
|
121 | 121 |
|
122 |
-def setMemory(dMem): |
|
122 |
+def getMemory(memloc): |
|
123 | 123 |
""" |
124 |
- Description: Returns a formatted MT command to the calling function. |
|
125 |
- Parameters: dMem - a dictionary objected with the following keys |
|
126 |
- defined: |
|
127 |
- |
|
128 |
- memloc - the memory location to be written |
|
129 |
- rxfreq - the receive frequency of VFO-A in MHz |
|
130 |
- mode - the modulation mode |
|
131 |
- encode - the tone or DCS encoding mode |
|
132 |
- shift - the direction of the repeater shift |
|
133 |
- tag - a label for the memory location |
|
134 |
- |
|
135 |
- Returns: a string containing the formatted command |
|
136 |
- """ |
|
137 |
- sCmd = 'MC%0.3d;' % int(dMem['memloc']) |
|
138 |
- sResult = sendCommand(sCmd) |
|
139 |
- |
|
140 |
- # While the 'MW' and 'MT' commands can be used to turn the Rx |
|
141 |
- # and Tx clarifiers on, the clarifier states can only be turned |
|
142 |
- # off by sending the 'RT0' and 'XT0' commands. This situation is |
|
143 |
- # probably due to a potential bug in the CAT interface. |
|
144 |
- sResult = sendCommand('RC;RT0;XT0;') |
|
145 |
- |
|
146 |
- sCmd = 'MT%0.3d' % int(dMem['memloc']) |
|
147 |
- sCmd += '%d' % int(float(dMem['rxfreq']) * 1E6) |
|
148 |
- sCmd += '%+0.4d' % int(dMem['clarfreq']) |
|
149 |
- sCmd += dRxClar[dMem['rxclar']] |
|
150 |
- sCmd += dTxClar[dMem['txclar']] |
|
151 |
- sCmd += dMode[dMem['mode']] |
|
152 |
- sCmd += '0' |
|
153 |
- sCmd += dEncode[dMem['encode']] |
|
154 |
- sCmd += '00' |
|
155 |
- sCmd += dShift[dMem['shift']] |
|
156 |
- sCmd += '0' |
|
157 |
- sCmd += '%-12s' % dMem['tag'] |
|
158 |
- sCmd += ';' |
|
159 |
- sResult = sendCommand(sCmd) |
|
160 |
- return sResult |
|
161 |
-## end def |
|
162 |
- |
|
163 |
-def getMemory(memLoc): |
|
164 |
- """ |
|
165 |
- Description: |
|
166 |
- Parameters: |
|
167 |
- Returns: |
|
124 |
+ Description: Get memory settings of a specific memory location. |
|
125 |
+ Parameters: memloc - an integer specifying memory location |
|
126 |
+ Returns: a dictionary object containing the memory ettings |
|
168 | 127 |
""" |
169 | 128 |
dMem = {} |
170 | 129 |
|
171 | 130 |
# Set memory location pointer in FT991. This is done |
172 | 131 |
# by sending the memory location select (MC) command. |
173 |
- sCmd = 'MC%0.3d;' % (memLoc) |
|
132 |
+ sCmd = 'MC%0.3d;' % (memloc) |
|
174 | 133 |
sResult = sendCommand(sCmd) |
175 | 134 |
# Skip blank memory locations, which return '?;'. |
176 | 135 |
if sResult == '?;': |
177 | 136 |
return None |
178 | 137 |
|
179 | 138 |
# Send the get memory settings string to the FT991. |
180 |
- sCmd = 'MT%0.3d;' % (memLoc) |
|
139 |
+ sCmd = 'MT%0.3d;' % (memloc) |
|
181 | 140 |
sResult = sendCommand(sCmd) |
182 | 141 |
|
183 | 142 |
# Parse memory settings string returned by the FT991 |
... | ... |
@@ -207,9 +166,9 @@ def getMemory(memLoc): |
207 | 166 |
|
208 | 167 |
def getCTCSS(): |
209 | 168 |
""" |
210 |
- Description: |
|
211 |
- Parameters: |
|
212 |
- Returns: |
|
169 |
+ Description: Get the CTCSS tone setting for the current memory location. |
|
170 |
+ Parameters: none |
|
171 |
+ Returns: string containing the CTCSS tone |
|
213 | 172 |
""" |
214 | 173 |
# Get result CTCSS tone |
215 | 174 |
sResult = sendCommand('CN00;') |
... | ... |
@@ -219,9 +178,9 @@ def getCTCSS(): |
219 | 178 |
|
220 | 179 |
def getDCS(): |
221 | 180 |
""" |
222 |
- Description: |
|
223 |
- Parameters: |
|
224 |
- Returns: |
|
181 |
+ Description: Get the DCS code setting for the current memory location. |
|
182 |
+ Parameters: none |
|
183 |
+ Returns: string containing the DCS code |
|
225 | 184 |
""" |
226 | 185 |
# Get result of CN01 command |
227 | 186 |
sResult = sendCommand('CN01;') |
... | ... |
@@ -229,41 +188,126 @@ def getDCS(): |
229 | 188 |
return dDcs.keys()[dDcs.values().index(dcs)] |
230 | 189 |
## end def |
231 | 190 |
|
191 |
+# Define 'set' functions to encapsulate the various FT991 CAT commands. |
|
192 |
+ |
|
193 |
+def setMemory(dMem): |
|
194 |
+ """ |
|
195 |
+ Description: Sends a formatted MT command. |
|
196 |
+ Parameters: dMem - a dictionary objected with the following keys |
|
197 |
+ defined: |
|
198 |
+ |
|
199 |
+ memloc - the memory location to be written |
|
200 |
+ rxfreq - receive frequency of VFO-A in MHz |
|
201 |
+ clarfreq - clarifier frequency and direction |
|
202 |
+ rxclar - receive clarifier state |
|
203 |
+ txclar - transmit clarifier state |
|
204 |
+ mode - the modulation mode |
|
205 |
+ encode - the tone or DCS encoding mode |
|
206 |
+ shift - the direction of the repeater shift |
|
207 |
+ tag - a label for the memory location |
|
208 |
+ |
|
209 |
+ Returns: a string containing the formatted command |
|
210 |
+ """ |
|
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: |
|
215 |
+ raise Exception('Memory location must be between 1 and ' \ |
|
216 |
+ '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 |
|
228 |
+ |
|
229 |
+ # Validate and append the vfo-a frequency data. |
|
230 |
+ iRxfreq = int(float(dMem['rxfreq']) * 1E6) # vfo-a frequency in Hz |
|
231 |
+ if iRxfreq < 0.030E6 or iRxfreq > 450.0E6: |
|
232 |
+ raise Exception('VFO-A frequency must be between 30 kHz and ' \ |
|
233 |
+ '450 MHz, inclusive.') |
|
234 |
+ sCmd += '%0.9d' % iRxfreq |
|
235 |
+ |
|
236 |
+ # Validate and append the clarifier data. |
|
237 |
+ iClarfreq = int(dMem['clarfreq']) |
|
238 |
+ if abs(iClarfreq) > 9999: |
|
239 |
+ raise Exception('Clarifer frequency must be between -9999 Hz ' \ |
|
240 |
+ 'and +9999 Hz, inclusive.') |
|
241 |
+ sCmd += '%+0.4d' % iClarfreq |
|
242 |
+ |
|
243 |
+ # The following commands will automatically raise an exception if |
|
244 |
+ # incorrect data is supplied. The exception will be a dictionary |
|
245 |
+ # object "key not found" error. |
|
246 |
+ sCmd += dRxClar[dMem['rxclar']] |
|
247 |
+ sCmd += dTxClar[dMem['txclar']] |
|
248 |
+ sCmd += dMode[dMem['mode']] |
|
249 |
+ sCmd += '0' |
|
250 |
+ sCmd += dEncode[dMem['encode']] |
|
251 |
+ sCmd += '00' |
|
252 |
+ sCmd += dShift[dMem['shift']] |
|
253 |
+ sCmd += '0' |
|
254 |
+ sTag = dMem['tag'] |
|
255 |
+ |
|
256 |
+ # Validate and append the memory tag data. |
|
257 |
+ if len(sTag) > 12: |
|
258 |
+ raise Exception('Memory tags must be twelve characters or less.') |
|
259 |
+ sCmd += '%-12s' % sTag |
|
260 |
+ sCmd += ';' # Terminate the completed command. |
|
261 |
+ |
|
262 |
+ # Send the completed command. |
|
263 |
+ sResult = sendCommand(sCmd) |
|
264 |
+ return sResult |
|
265 |
+## end def |
|
266 |
+ |
|
232 | 267 |
def setCTCSS(tone): |
233 | 268 |
""" |
234 |
- Description: returns a formatted CN command that sets the desired |
|
269 |
+ Description: Sends a formatted CN command that sets the desired |
|
235 | 270 |
CTCSS tone. |
236 | 271 |
Parameters: tone - a string containing the CTCSS tone in Hz, e.g., |
237 | 272 |
'100 Hz' |
238 | 273 |
Returns: a string containing the formatted command |
239 | 274 |
""" |
275 |
+ # An exception will automatically be raised if incorrect data is |
|
276 |
+ # supplied - most likely a "key not found" error. |
|
240 | 277 |
sCmd = 'CN00%s;' % dTones[tone] |
241 | 278 |
return sendCommand(sCmd) |
242 | 279 |
## end def |
243 | 280 |
|
244 | 281 |
def setDCS(code): |
245 | 282 |
""" |
246 |
- Description: returns a formatted CN command that sets the desired |
|
283 |
+ Description: Sends a formatted CN command that sets the desired |
|
247 | 284 |
DCS code. |
248 |
- Parameters: code - a string containing the DCS code, e.g., '23' |
|
285 |
+ Parameters: code - a string containing the DCS code, e.g., '23' |
|
249 | 286 |
Returns: a string containing the formatted command |
250 | 287 |
""" |
288 |
+ # An exception will automatically be raised if incorrect data is |
|
289 |
+ # supplied - most likely a "key not found" error. |
|
251 | 290 |
sCmd = 'CN01%s;' % dDcs[code] |
252 | 291 |
return sendCommand(sCmd) |
253 | 292 |
## end def |
254 | 293 |
|
255 | 294 |
def setPower(power): |
256 | 295 |
""" |
257 |
- Description: returns a formatted PC command that sets the desired |
|
296 |
+ Description: Sends a PC command that sets the desired |
|
258 | 297 |
RF transmit power level. |
259 | 298 |
Parameters: power - Watts, an integer between 5 and 100 |
260 | 299 |
Returns: a string containing the formatted command |
261 | 300 |
""" |
262 |
- sCmd = 'PC' |
|
263 |
- sCmd += '%03.d;' % power |
|
301 |
+ power = int(power) |
|
302 |
+ # Validate power data and format command. |
|
303 |
+ if power < 5 or power > 100: |
|
304 |
+ raise Exception('Power must be between 0 and 100 watts, inclusive.') |
|
305 |
+ sCmd += 'PC%03.d;' % power |
|
264 | 306 |
return sendCommand(sCmd) |
265 | 307 |
## end def |
266 | 308 |
|
309 |
+# Helper functions to assist in various tasks. |
|
310 |
+ |
|
267 | 311 |
def parseCsvData(sline): |
268 | 312 |
""" |
269 | 313 |
Description: stores each item in the comma delimited line in a single |
... | ... |
@@ -286,14 +330,43 @@ def parseCsvData(sline): |
286 | 330 |
dChan['tag'] = lchan[6] |
287 | 331 |
dChan['encode'] = lchan[7] |
288 | 332 |
dChan['tone'] = lchan[8] |
289 |
- dChan['dcs'] = str(int(lchan[9])) |
|
333 |
+ dChan['dcs'] = lchan[9] |
|
290 | 334 |
dChan['clarfreq'] = lchan[10] |
291 | 335 |
dChan['rxclar'] = lchan[11] |
292 | 336 |
dChan['txclar'] = lchan[12] |
293 | 337 |
return dChan # return the dictionary object |
294 | 338 |
## end def |
295 | 339 |
|
296 |
-# Define serial communications functions. |
|
340 |
+def sendCommand(sCmd): |
|
341 |
+ """ |
|
342 |
+ Description: Sends a formatted FT911 command to the communication |
|
343 |
+ port connected to the FT991. Prints to stdout the |
|
344 |
+ answer from the FT991 (if any). |
|
345 |
+ Parameters: device - a pointer to the FT991 comm port |
|
346 |
+ sCmd - a string containing the formatted command |
|
347 |
+ Returns: nothing |
|
348 |
+ """ |
|
349 |
+ # Debug mode in conjunction with verbose mode is for verifying |
|
350 |
+ # correct formatting of commands before they are actually sent |
|
351 |
+ # to the FT991. |
|
352 |
+ if verbose: |
|
353 |
+ print sCmd, |
|
354 |
+ # In debug mode do not actually send commands to the FT991. |
|
355 |
+ if debug: |
|
356 |
+ return '' |
|
357 |
+ |
|
358 |
+ # Send the formatted command to the FT991 and get an answer, if any. |
|
359 |
+ # If the command does not generate an answer, no characters will be |
|
360 |
+ # returned by the FT991, resulting in an empty string returned by |
|
361 |
+ # the receiveSerial function. |
|
362 |
+ sendSerial(sCmd) |
|
363 |
+ sResult = receiveSerial(); |
|
364 |
+ if verbose: |
|
365 |
+ print sResult |
|
366 |
+ return sResult |
|
367 |
+## end def |
|
368 |
+ |
|
369 |
+# Low level serial communications functions. |
|
297 | 370 |
|
298 | 371 |
def begin(baud=9600): |
299 | 372 |
""" |
... | ... |
@@ -316,6 +389,7 @@ def begin(baud=9600): |
316 | 389 |
# In debug mode do not actually send commands to the FT991. |
317 | 390 |
if debug: |
318 | 391 |
return |
392 |
+ |
|
319 | 393 |
# Create a FT991 object for serial communication |
320 | 394 |
try: |
321 | 395 |
ptrDevice = serial.Serial(port, baud, |
... | ... |
@@ -332,35 +406,6 @@ def begin(baud=9600): |
332 | 406 |
return ptrDevice |
333 | 407 |
## end def |
334 | 408 |
|
335 |
-def sendCommand(sCmd): |
|
336 |
- """ |
|
337 |
- Description: Sends a formatted FT911 command to the communication |
|
338 |
- port connected to the FT991. Prints to stdout the |
|
339 |
- answer from the FT991 (if any). |
|
340 |
- Parameters: device - a pointer to the FT991 comm port |
|
341 |
- sCmd - a string containing the formatted command |
|
342 |
- Returns: nothing |
|
343 |
- """ |
|
344 |
- # Debug mode in conjunction with verbose mode is for verifying |
|
345 |
- # correct formatting of commands before they are actually sent |
|
346 |
- # to the FT991. |
|
347 |
- if verbose: |
|
348 |
- print sCmd, |
|
349 |
- # In debug mode do not actually send commands to the FT991. |
|
350 |
- if debug: |
|
351 |
- return '' |
|
352 |
- |
|
353 |
- # Send the formatted command to the FT991 and get an answer, if any. |
|
354 |
- # If the command does not generate an answer, no characters will be |
|
355 |
- # returned by the FT991, resulting in an empty string returned by |
|
356 |
- # the receiveSerial function. |
|
357 |
- sendSerial(sCmd) |
|
358 |
- sResult = receiveSerial(); |
|
359 |
- if verbose: |
|
360 |
- print sResult |
|
361 |
- return sResult |
|
362 |
-## end def |
|
363 |
- |
|
364 | 409 |
def receiveSerial(termchar=';'): |
365 | 410 |
""" |
366 | 411 |
Description: Reads output one character at a time from the device |
... | ... |
@@ -413,6 +458,10 @@ def sendSerial(command): |
413 | 458 |
ptrDevice.flushOutput() # Flush serial buffer to prevent overflows |
414 | 459 |
## end def |
415 | 460 |
|
461 |
+# Main routine only gets called when this module is run as a program rather |
|
462 |
+# than imported into another python module. Code testing the functions in |
|
463 |
+# this module should be placed here. |
|
464 |
+ |
|
416 | 465 |
def main(): |
417 | 466 |
""" |
418 | 467 |
Description: Place code for testing this module here. |
... | ... |
@@ -425,17 +474,19 @@ def main(): |
425 | 474 |
verbose = True |
426 | 475 |
debug = False |
427 | 476 |
|
477 |
+ # Instantiate serial connection to FT991 |
|
428 | 478 |
begin() |
429 |
- sendCommand('IF;') |
|
430 |
- sendCommand('MC001;') |
|
431 |
- sendCommand('ZZZ;') |
|
432 |
- |
|
479 |
+ # Commands that send a setting |
|
433 | 480 |
dMem = {'rxfreq': '146.52', 'shift': 'OFF', 'encode': 'OFF', \ |
434 | 481 |
'txclar': 'OFF', 'tag': 'KA7JLO', 'mode': 'FM', 'rxclar': 'OFF', \ |
435 | 482 |
'memloc': '99', 'clarfreq': '0'} |
436 | 483 |
setMemory(dMem) |
437 |
- print getMemory(99) |
|
438 |
- |
|
484 |
+ sendCommand('MC002;') |
|
485 |
+ # Commands that return data |
|
486 |
+ getMemory(99) |
|
487 |
+ sendCommand('IF;') |
|
488 |
+ # Invalid command handling |
|
489 |
+ sendCommand('ZZZ;') |
|
439 | 490 |
## end def |
440 | 491 |
|
441 | 492 |
if __name__ == '__main__': |
... | ... |
@@ -241,52 +241,13 @@ def getFileName(defaultFile): |
241 | 241 |
if commandLineOption != '': |
242 | 242 |
return defaultFile |
243 | 243 |
# Otherwise query the user for a file name |
244 |
- fileName = raw_input("Enter file name or <CR> for default: ") |
|
244 |
+ fileName = raw_input('Enter file name or <CR> for default: ') |
|
245 | 245 |
if fileName == '': |
246 | 246 |
return defaultFile |
247 | 247 |
else: |
248 | 248 |
return fileName |
249 | 249 |
## end def |
250 | 250 |
|
251 |
-def readMenuSettings(): |
|
252 |
- """ |
|
253 |
- Description: Reads all menu settings from the FT991. |
|
254 |
- Parameters: none |
|
255 |
- Returns: a list object containing all the menu settings |
|
256 |
- """ |
|
257 |
- lMenuSettings = [] |
|
258 |
- # Iterate through all menu items, getting each setting and storing |
|
259 |
- # the setting in a file. |
|
260 |
- for inx in range(1, _MAX_NUMBER_OF_MENU_ITEMS): |
|
261 |
- # Format the read menu item CAT command. |
|
262 |
- sCommand = 'EX%0.3d;' % inx |
|
263 |
- # Send the command to the FT991. |
|
264 |
- sResult = ft991.sendCommand(sCommand) |
|
265 |
- # Add the menu setting to a list object. |
|
266 |
- lMenuSettings.append(sResult) |
|
267 |
- return lMenuSettings |
|
268 |
-## end def |
|
269 |
- |
|
270 |
-def writeMenuSettings(lMenuSettings): |
|
271 |
- """ |
|
272 |
- Description: Writes supplied menu settings to the FT991. |
|
273 |
- Parameters: lMenuSettings - a list object containing menu settings |
|
274 |
- Returns: nothing |
|
275 |
- """ |
|
276 |
- for item in lMenuSettings: |
|
277 |
- |
|
278 |
- # Do not write read-only menu settings as this results |
|
279 |
- # in the FT-991 returning an error. The only read-only |
|
280 |
- # setting is the "Radio ID" setting. |
|
281 |
- if item.find('EX087') > -1: |
|
282 |
- continue; |
|
283 |
- # Send the pre-formatted menu setting to the FT991. |
|
284 |
- sResult = ft991.sendCommand(item) |
|
285 |
- if sResult.find('?;') > -1: |
|
286 |
- print 'error restoring menu setting: %s' % item |
|
287 |
- exit(1) |
|
288 |
-## end def |
|
289 |
- |
|
290 | 251 |
def readMemorySettings(): |
291 | 252 |
""" |
292 | 253 |
Description: Reads all defined memory settings from the FT991. The |
... | ... |
@@ -301,7 +262,7 @@ def readMemorySettings(): |
301 | 262 |
contained in the list. |
302 | 263 |
""" |
303 | 264 |
# Define the column headers as the first item in the list. |
304 |
- lMemorySettings = [ 'Memory Ch,Rx Frequency,Tx Frequency,Offset,' \ |
|
265 |
+ lSettings = [ 'Memory Ch,Rx Frequency,Tx Frequency,Offset,' \ |
|
305 | 266 |
'Repeater Shift,Mode,Tag,Encoding,Tone,DCS,' \ |
306 | 267 |
'Clarifier, RxClar, TxClar' ] |
307 | 268 |
|
... | ... |
@@ -327,40 +288,86 @@ def readMemorySettings(): |
327 | 288 |
tone, dcs, dMem['clarfreq'], dMem['rxclar'], \ |
328 | 289 |
dMem['txclar'] ) |
329 | 290 |
# Add the comma-delimited string to the list object. |
330 |
- lMemorySettings.append(sCsvFormat) |
|
291 |
+ lSettings.append(sCsvFormat) |
|
331 | 292 |
if ft991.verbose: |
332 | 293 |
|
333 |
- return lMemorySettings |
|
294 |
+ return lSettings |
|
334 | 295 |
# end def |
335 | 296 |
|
336 |
-def writeMemorySettings(lMemorySettings): |
|
297 |
+def writeMemorySettings(lSettings): |
|
337 | 298 |
""" |
338 | 299 |
Description: Writes the supplied memory settings to the FT991. |
339 |
- Parameters: lMemorySettings - a list object containing the memory |
|
300 |
+ Parameters: lSettings - a list object containing the memory |
|
340 | 301 |
settings in comma delimited format |
341 | 302 |
Returns: nothing |
342 | 303 |
""" |
343 |
- for item in lMemorySettings: |
|
304 |
+ for item in lSettings: |
|
344 | 305 |
# Parse the comma-delimited line and store in a dictionary object. |
345 | 306 |
dItem = ft991.parseCsvData(item) |
346 | 307 |
# The first item in the memory settings list are the column headers; |
347 | 308 |
# so ignore this item. (parseData returns None for this item.) |
348 | 309 |
if dItem == None: |
349 | 310 |
continue |
350 |
- # Set memory channel vfo, mode, and other data. |
|
351 | 311 |
sResult = '' |
352 |
- sResult += ft991.setMemory(dItem) |
|
353 |
- # Set CTCSS tone for memory channel. |
|
354 |
- sResult += ft991.setCTCSS(dItem['tone']) |
|
355 |
- # Set DCS code for memory channel. |
|
356 |
- sResult += ft991.setDCS(dItem['dcs']) |
|
312 |
+ try: |
|
313 |
+ # Set memory channel vfo, mode, and other data. |
|
314 |
+ sResult += ft991.setMemory(dItem) |
|
315 |
+ # Set CTCSS tone for memory channel. |
|
316 |
+ sResult += ft991.setCTCSS(dItem['tone']) |
|
317 |
+ # Set DCS code for memory channel. |
|
318 |
+ sResult += ft991.setDCS(dItem['dcs']) |
|
319 |
+ except Exception, e: |
|
320 |
+ print 'Backup settings file corrupted or incorrectly formatted.\n' \ |
|
321 |
+ 'Please make sure all values are correctly entered.' |
|
322 |
+ print e |
|
323 |
+ exit(1) |
|
324 |
+ |
|
357 | 325 |
# Process any errors returned by the CAT interface. |
358 | 326 |
if sResult.find('?;') > -1: |
359 |
- print 'error restoring memory setting: %s' % sResult |
|
327 |
+ print 'Error restoring memory setting: %s' % sResult |
|
360 | 328 |
if ft991.verbose: |
361 | 329 |
|
362 | 330 |
## end def |
363 | 331 |
|
332 |
+def readMenuSettings(): |
|
333 |
+ """ |
|
334 |
+ Description: Reads all menu settings from the FT991. |
|
335 |
+ Parameters: none |
|
336 |
+ Returns: a list object containing all the menu settings |
|
337 |
+ """ |
|
338 |
+ lSettings = [] |
|
339 |
+ # Iterate through all menu items, getting each setting and storing |
|
340 |
+ # the setting in a file. |
|
341 |
+ for inx in range(1, _MAX_NUMBER_OF_MENU_ITEMS): |
|
342 |
+ # Format the read menu item CAT command. |
|
343 |
+ sCommand = 'EX%0.3d;' % inx |
|
344 |
+ # Send the command to the FT991. |
|
345 |
+ sResult = ft991.sendCommand(sCommand) |
|
346 |
+ # Add the menu setting to a list object. |
|
347 |
+ lSettings.append(sResult) |
|
348 |
+ return lSettings |
|
349 |
+## end def |
|
350 |
+ |
|
351 |
+def writeMenuSettings(lSettings): |
|
352 |
+ """ |
|
353 |
+ Description: Writes supplied menu settings to the FT991. |
|
354 |
+ Parameters: lSettings - a list object containing menu settings |
|
355 |
+ Returns: nothing |
|
356 |
+ """ |
|
357 |
+ for item in lSettings: |
|
358 |
+ |
|
359 |
+ # Do not write read-only menu settings as this results |
|
360 |
+ # in the FT-991 returning an error. The only read-only |
|
361 |
+ # setting is the "Radio ID" setting. |
|
362 |
+ if item.find('EX087') > -1: |
|
363 |
+ continue; |
|
364 |
+ # Send the pre-formatted menu setting to the FT991. |
|
365 |
+ sResult = ft991.sendCommand(item) |
|
366 |
+ if sResult.find('?;') > -1: |
|
367 |
+ print 'error restoring menu setting: %s' % item |
|
368 |
+ exit(1) |
|
369 |
+## end def |
|
370 |
+ |
|
364 | 371 |
def writeToFile(lSettings, fileName): |
365 | 372 |
""" |
366 | 373 |
Description: Writes supplied settings to the specified file. |
... | ... |
@@ -398,8 +405,8 @@ def setIOFile(option, commandLineFile): |
398 | 405 |
well as the command executed by doUserCommand above. |
399 | 406 |
Parameters: option - the command supplied by the command line |
400 | 407 |
argument interpreter getCLarguments. |
401 |
- commandLineFile - the name of the file supplied by the |
|
402 |
- -f command line argument (if supplied). |
|
408 |
+ commandLineFile - the name of the file supplied by the -f |
|
409 |
+ command line argument (if supplied). |
|
403 | 410 |
Returns: nothing |
404 | 411 |
""" |
405 | 412 |
global menuBackupFile, memoryBackupFile, commandLineOption |
... | ... |
@@ -436,7 +443,7 @@ x - exit this program |
436 | 443 |
## end def |
437 | 444 |
|
438 | 445 |
def getCLarguments(): |
439 |
- """ Description: gets command line arguments and configures this program |
|
446 |
+ """ Description: Gets command line arguments and configures this program |
|
440 | 447 |
to run accordingly. See the variable 'usage', below, |
441 | 448 |
for possible arguments that may be used on the command |
442 | 449 |
line. |