4 | 4 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,43 @@ |
1 |
+Memory Ch,Rx Frequency,Tx Frequency,Offset,Repeater Shift,Mode,Tag,Encoding,Tone,DCS |
|
2 |
+1,145.19,144.59,0.6,-RPT,FM,WA7ABU,TONE ENC,100.0 Hz,23 |
|
3 |
+2,145.29,144.69,0.6,-RPT,FM,WA7ABU,OFF,118.8 Hz,23 |
|
4 |
+3,444.95,449.95,5,+RPT,FM,W7ABU,TONE ENC,100.0 Hz,23 |
|
5 |
+4,145.49,144.89,0.6,-RPT,FM,W7PRA Sa,TONE ENC,136.5 Hz,23 |
|
6 |
+5,444.825,449.825,5,+RPT,FM,W7PRA Ha,DCS,100.0 Hz,23 |
|
7 |
+6,146.61,146.01,0.6,-RPT,FM,KA7ENW,TONE ENC,167.9 Hz,23 |
|
8 |
+7,442.85,447.85,5,+RPT,FM,KA7ENW,TONE ENC,167.9 Hz,23 |
|
9 |
+8,147.06,147.66,0.6,+RPT,FM,W1ARK,TONE ENC,100.0 Hz,23 |
|
10 |
+9,145.33,144.73,0.6,-RPT,FM,W7SRA,TONE ENC,186.2 Hz,23 |
|
11 |
+10,146.72,146.12,0.6,-RPT,FM,W7PXL,TONE ENC,100.0 Hz,23 |
|
12 |
+11,146.68,146.08,0.6,-RPT,FM,W7EUG,TONE ENC,100.0 Hz,23 |
|
13 |
+12,146.78,146.18,0.6,-RPT,FM,K7CVO,TONE ENC,156.7 Hz,23 |
|
14 |
+13,146.82,146.22,0.6,-RPT,FM,WA7TUV,TONE ENC,100.0 Hz,23 |
|
15 |
+14,434.91,439.91,5,+RPT,FM,KF7LDG,TONE ENC,100.0 Hz,23 |
|
16 |
+15,440.425,445.425,5,+RPT,FM,K7LNK,DCS,100.0 Hz,125 |
|
17 |
+16,440.8,445.8,5,+RPT,FM,AB7BS,TONE ENC,100.0 Hz,23 |
|
18 |
+17,441.975,446.975,5,+RPT,FM,W7CQZ,TONE ENC,100.0 Hz,23 |
|
19 |
+18,442.3,447.3,5,+RPT,FM,N8GFO,TONE ENC,162.2 Hz,23 |
|
20 |
+20,146.43,146.43,0,OFF,FM,Prep Net,OFF,100.0 Hz,23 |
|
21 |
+21,146.42,146.42,0,OFF,FM,VHF Prep,OFF,100.0 Hz,23 |
|
22 |
+22,146.55,146.55,0,OFF,FM,VHF Surv,OFF,100.0 Hz,23 |
|
23 |
+23,446.03,446.03,0,OFF,FM,UHF Prep,OFF,100.0 Hz,23 |
|
24 |
+24,146.43,146.43,0.6,OFF,FM,V Sim 1,OFF,100.0 Hz,23 |
|
25 |
+25,146.475,146.475,0.6,OFF,FM,V Sim 2,OFF,100.0 Hz,23 |
|
26 |
+26,146.58,146.58,0.6,OFF,FM,V Sim 3,OFF,100.0 Hz,23 |
|
27 |
+27,147.465,147.465,0.6,OFF,FM,V Sim 4,OFF,100.0 Hz,23 |
|
28 |
+28,445.9625,445.9625,5,OFF,FM,U Sim1,OFF,100.0 Hz,23 |
|
29 |
+29,445.975,445.975,5,OFF,FM,U Sim 2,OFF,100.0 Hz,23 |
|
30 |
+30,446.0375,446.0375,5,OFF,FM,U Sim 3,OFF,100.0 Hz,23 |
|
31 |
+31,446.075,446.075,5,OFF,FM,U Sim 4,OFF,100.0 Hz,23 |
|
32 |
+40,162.475,162.475,0,OFF,FM,WX3PA4,OFF,100.0 Hz,23 |
|
33 |
+41,162.5,162.5,0,OFF,FM,WX6PA5,OFF,100.0 Hz,23 |
|
34 |
+42,122.725,122.725,0,OFF,AM,ALB CTAF,OFF,100.0 Hz,23 |
|
35 |
+43,123.075,123.075,0,OFF,AM,CVO CTAF,OFF,100.0 Hz,23 |
|
36 |
+44,156.08,156.08,0.6,OFF,FM,PD,OFF,100.0 Hz,23 |
|
37 |
+45,156.815,156.815,0,OFF,FM,ALB PD,OFF,100.0 Hz,23 |
|
38 |
+46,155.01,155.01,0,OFF,FM,PD Sec,OFF,100.0 Hz,23 |
|
39 |
+47,151.13,151.13,0,OFF,FM,LCSO Knx,OFF,100.0 Hz,23 |
|
40 |
+48,154.71,154.71,0,OFF,FM,LCSO Sct,OFF,100.0 Hz,23 |
|
41 |
+49,156.7,156.7,0,OFF,FM,LCSO ST,OFF,100.0 Hz,23 |
|
42 |
+50,155.805,155.805,0,OFF,FM,LCSO SAR,OFF,100.0 Hz,23 |
|
43 |
+51,155.34,155.34,0,OFF,FM,ALB GEN,OFF,100.0 Hz,23 |
0 | 44 |
new file mode 100755 |
... | ... |
@@ -0,0 +1,247 @@ |
1 |
+#!/usr/bin/python -u |
|
2 |
+# The -u option turns off block buffering of python output. This assures |
|
3 |
+# that output streams to stdout when output happens. |
|
4 |
+# |
|
5 |
+# Description: This module contains tables for tranlating common transceiver |
|
6 |
+# settings to FT991 CAT parameters. Low level serial |
|
7 |
+# communication functions are handled by this module. In |
|
8 |
+# particular this module handles: |
|
9 |
+# 1. Setting a serial connection object |
|
10 |
+# 2. Sending character strings to the serial port |
|
11 |
+# 3. Reading characters from the serial port |
|
12 |
+# 4. Formatting of FT991 commands |
|
13 |
+# |
|
14 |
+# This script has been tested with the following |
|
15 |
+# |
|
16 |
+# Python 2.7.15rc1 (default, Nov 12 2018, 14:31:15) |
|
17 |
+# [GCC 7.3.0] on linux2 |
|
18 |
+#2345678901234567890123456789012345678901234567890123456789012345678901234567890 |
|
19 |
+ |
|
20 |
+import sys, serial, time |
|
21 |
+ |
|
22 |
+# Determine OS type and set device port accordingly. |
|
23 |
+OS_type = sys.platform |
|
24 |
+if 'WIN' in OS_type.upper(): |
|
25 |
+ _SERIAL_PORT = 'COM5' |
|
26 |
+else: |
|
27 |
+ _SERIAL_PORT = '/dev/ttyUSB0' |
|
28 |
+ |
|
29 |
+# General constant defines |
|
30 |
+_BAUD_RATE = 9600 |
|
31 |
+_INTERFACE_TIMEOUT = 0.1 # seconds |
|
32 |
+_SERIAL_READ_TIMEOUT = 0.1 # seconds |
|
33 |
+_SERIAL_READ_BUFFER_LENGTH = 1024 # characters |
|
34 |
+ |
|
35 |
+verbose = False |
|
36 |
+debug = False |
|
37 |
+ |
|
38 |
+# Define lookup tables for common transceiver settings. Common settings |
|
39 |
+# such as modulation mode, repeater offset direction, DCS/CTCSS mode, |
|
40 |
+# CTCSS tone, and DCS code are translated to the repective FT991 parameter |
|
41 |
+# value. |
|
42 |
+ |
|
43 |
+dMode = {'LSB':'1', 'USB':'2', 'CW':'3', 'FM':'4', 'AM':'5', 'RTTY-LSB':'6', |
|
44 |
+ 'CW-R':'7', 'DATA-LSB':'8', 'RTTY-USB':'9', 'DATA-FM':'A', |
|
45 |
+ 'FM-N':'B', 'DATA-USB':'C', 'AM-N':'D', 'C4FM':'E'} |
|
46 |
+ |
|
47 |
+dShift = {'OFF':'0', '+RPT':'1', '-RPT':'2'} |
|
48 |
+ |
|
49 |
+dPower = { 'LOW':'005', 'MID':'020', 'HIGH':'050' } |
|
50 |
+ |
|
51 |
+dEncode = {'OFF':'0', 'ENC/DEC':'1', 'TONE ENC':'2', 'DCS ENC/DEC':'4', |
|
52 |
+ 'DCS':'3'} |
|
53 |
+ |
|
54 |
+dTones = {'67.0 Hz':'000', '69.3 Hz':'001', '71.9 Hz':'002', '74.4 Hz':'003', |
|
55 |
+ '77.0 Hz':'004', '79.7 Hz':'005', '82.5 Hz':'006', '85.4 Hz':'007', |
|
56 |
+ '88.5 Hz':'008', '91.5 Hz':'009', '94.8 Hz':'010', '97.4 Hz':'011', |
|
57 |
+ '100.0 Hz':'012', '103.5 Hz':'013', '107.2 Hz':'014', '110.9 Hz':'015', |
|
58 |
+ '114.8 Hz':'016', '118.8 Hz':'017', '123.0 Hz':'018', '127.3 Hz':'019', |
|
59 |
+ '131.8 Hz':'020', '136.5 Hz':'021', '141.3 Hz':'022', '146.2 Hz':'023', |
|
60 |
+ '151.4 Hz':'024', '156.7 Hz':'025', '159.8 Hz':'026', '162.2 Hz':'027', |
|
61 |
+ '165.5 Hz':'028', '167.9 Hz':'029', '171.3 Hz':'030', '173.8 Hz':'031', |
|
62 |
+ '177.3 Hz':'032', '179.9 Hz':'033', '183.5 Hz':'034', '186.2 Hz':'035', |
|
63 |
+ '189.9 Hz':'036', '192.8 Hz':'037', '196.6 Hz':'038', '199.5 Hz':'039', |
|
64 |
+ '203.5 Hz':'040', '206.5 Hz':'041', '210.7 Hz':'042', '218.1 Hz':'043', |
|
65 |
+ '225.7 Hz':'044', '229.1 Hz':'045', '233.6 Hz':'046', '241.8 Hz':'047', |
|
66 |
+ '250.3 Hz':'048', '254.1 Hz':'049'} |
|
67 |
+ |
|
68 |
+dDcs = {'23':'000', '25':'001', '26':'002', '31':'003', '32':'004', |
|
69 |
+ '36':'005', '43':'006', '47':'007', '51':'008', '53':'009', |
|
70 |
+ '54':'010', '65':'011', '71':'012', '72':'013', '73':'014', |
|
71 |
+ '74':'015', '114':'016', '115':'017', '116':'018', '122':'019', |
|
72 |
+ '125':'020', '131':'021', '132':'022', '134':'023', '143':'024', |
|
73 |
+ '145':'025', '152':'026', '155':'027', '156':'028', '162':'029', |
|
74 |
+ '165':'030', '172':'031', '174':'032', '205':'033', '212':'034', |
|
75 |
+ '223':'035', '225':'036', '226':'037', '243':'038', '244':'039', |
|
76 |
+ '245':'040', '246':'041', '251':'042', '252':'043', '255':'044', |
|
77 |
+ '261':'045', '263':'046', '265':'047', '266':'048', '271':'049', |
|
78 |
+ '274':'050', '306':'051', '311':'052', '315':'053', '325':'054', |
|
79 |
+ '331':'055', '332':'056', '343':'057', '346':'058', '351':'059', |
|
80 |
+ '356':'060', '364':'061', '365':'062', '371':'063', '411':'064', |
|
81 |
+ '412':'065', '413':'066', '423':'067', '431':'068', '432':'069', |
|
82 |
+ '445':'070', '446':'071', '452':'072', '454':'073', '455':'074', |
|
83 |
+ '462':'075', '464':'076', '465':'077', '466':'078', '503':'079', |
|
84 |
+ '506':'080', '516':'081', '523':'082', '526':'083', '532':'084', |
|
85 |
+ '546':'085', '565':'086', '606':'087', '612':'088', '624':'089', |
|
86 |
+ '627':'090', '631':'091', '632':'092', '654':'093', '662':'094', |
|
87 |
+ '664':'095', '703':'096', '712':'097', '723':'098', '731':'099', |
|
88 |
+ '732':'100', '734':'101', '743':'102', '754':'103'} |
|
89 |
+ |
|
90 |
+# Define functions for implementing the various FT991 CAT commands |
|
91 |
+ |
|
92 |
+def getMTcommand(dChan): |
|
93 |
+ """ |
|
94 |
+ Description: returns a formatted MT command to the calling function. |
|
95 |
+ Parameters: dChan - a dictionary objected with the following keys defined |
|
96 |
+ chnum - the memory location to be written |
|
97 |
+ rxfreq - the receive frequency of VFO-A in MHz |
|
98 |
+ mode - the modulation mode |
|
99 |
+ encode - the tone or DCS encoding mode |
|
100 |
+ shift - the direction of the repeater shift |
|
101 |
+ tag - a label for the memory location |
|
102 |
+ Returns: a string containing the formatted command |
|
103 |
+ """ |
|
104 |
+ sCmd = 'MT' |
|
105 |
+ sCmd += '%0.3d' % int(dChan['chnum']) |
|
106 |
+ sCmd += '%d' % int(float(dChan['rxfreq']) * 1E6) |
|
107 |
+ sCmd += '+000000' |
|
108 |
+ sCmd += dMode[dChan['mode']] |
|
109 |
+ sCmd += '0' |
|
110 |
+ sCmd += dEncode[dChan['encode']] |
|
111 |
+ sCmd += '00' |
|
112 |
+ sCmd += dShift[dChan['shift']] |
|
113 |
+ sCmd += '0' |
|
114 |
+ sCmd += '%-12s' % dChan['tag'] |
|
115 |
+ sCmd += ';' |
|
116 |
+ if verbose: |
|
117 |
+ print sCmd, |
|
118 |
+ return sCmd |
|
119 |
+ |
|
120 |
+def getCTCSScommand(dChan): |
|
121 |
+ """ |
|
122 |
+ Description: returns a formatted CN command that sets the desired |
|
123 |
+ CTCSS tone. |
|
124 |
+ Parameters: dChan - a dictionary object with the following key defined |
|
125 |
+ tone - the CTCSS tone in Hz, e.g., |
|
126 |
+ dChan = {'tone':'100 Hz'} |
|
127 |
+ Returns: a string containing the formatted command |
|
128 |
+ """ |
|
129 |
+ sCmd = 'CN0' |
|
130 |
+ sCmd += '0%s;' % dTones[dChan['tone']] |
|
131 |
+ if verbose: |
|
132 |
+ print sCmd, |
|
133 |
+ return sCmd |
|
134 |
+ |
|
135 |
+def getDCScommand(dChan): |
|
136 |
+ """ |
|
137 |
+ Description: returns a formatted CN command that sets the desired |
|
138 |
+ DCS code. |
|
139 |
+ Parameters: dChan - a dictionary object with the following key defined |
|
140 |
+ dcs - the DCS code, e.g., dChan = {'dcs':'23'} |
|
141 |
+ Returns: a string containing the formatted command |
|
142 |
+ """ |
|
143 |
+ sCmd = 'CN0' |
|
144 |
+ sCmd += '1%s;' % dDcs[dChan['dcs']] |
|
145 |
+ if verbose: |
|
146 |
+ print sCmd, |
|
147 |
+ return sCmd |
|
148 |
+ |
|
149 |
+def getPCcommand(dChan): |
|
150 |
+ """ |
|
151 |
+ Description: returns a formatted PC command that sets the desired |
|
152 |
+ RF transmit power level. |
|
153 |
+ Parameters: dChan - a dictionary object with the following key defined |
|
154 |
+ power - the power level in Watts |
|
155 |
+ e.g., dChan = {'power':'020'} |
|
156 |
+ Returns: a string containing the formatted command |
|
157 |
+ """ |
|
158 |
+ sCmd = 'PC' |
|
159 |
+ sCmd += '%s;' % dPower[dChan['power']] |
|
160 |
+ if verbose: |
|
161 |
+ print sCmd, |
|
162 |
+ return sCmd |
|
163 |
+ |
|
164 |
+def receiveSerial(device, termchar=';'): |
|
165 |
+ """ |
|
166 |
+ Description: reads output one character at a time from the device |
|
167 |
+ until a terminating character is received. Returns a |
|
168 |
+ string containing the characters read from the serial |
|
169 |
+ port. |
|
170 |
+ Parameters: device - a serial object connected to the device port |
|
171 |
+ termchar - character terminating the answer string |
|
172 |
+ Returns: string |
|
173 |
+ """ |
|
174 |
+ answer = '' # initialize answer string to empty string |
|
175 |
+ charCount = 0 # reset read character count to zero |
|
176 |
+ |
|
177 |
+ while True: |
|
178 |
+ startTime = time.time() # Start read character timer |
|
179 |
+ c ='' |
|
180 |
+ while True: |
|
181 |
+ # Check for a character available in the serial read buffer. |
|
182 |
+ if device.in_waiting: |
|
183 |
+ c = device.read() |
|
184 |
+ break |
|
185 |
+ # Timeout if a character does not become available. |
|
186 |
+ if time.time() - startTime > _SERIAL_READ_TIMEOUT: |
|
187 |
+ break # Character waiting timer has timed out. |
|
188 |
+ # Return empty string if a character has not become available. |
|
189 |
+ if c == '': |
|
190 |
+ break; |
|
191 |
+ answer += c # Form a string from the received characters. |
|
192 |
+ charCount += 1 # Increment character count. |
|
193 |
+ # If a semicolon has arrived then the FT991 has completed |
|
194 |
+ # sending output to the serial port so stop reading characters. |
|
195 |
+ # Also stop if max characters received. |
|
196 |
+ if c == termchar: |
|
197 |
+ break |
|
198 |
+ if charCount > _SERIAL_READ_BUFFER_LENGTH: |
|
199 |
+ raise Exception('serial read buffer overflow') |
|
200 |
+ device.flushInput() # Flush serial buffer to prevent overflows. |
|
201 |
+ return answer |
|
202 |
+## end def |
|
203 |
+ |
|
204 |
+def sendSerial(device, command): |
|
205 |
+ """ |
|
206 |
+ Description: writes a string to the device. |
|
207 |
+ Parameters: device - a serial object connected to the device port |
|
208 |
+ command - string containing the FT991 command |
|
209 |
+ Returns: nothing |
|
210 |
+ """ |
|
211 |
+ # In debug we only want to see the output of the command formatter, |
|
212 |
+ # not actually send commands to the FT991. Debug mode should be |
|
213 |
+ # used in conjunction with verbose mode. |
|
214 |
+ if not debug: |
|
215 |
+ device.write(command) # Send command string to FT991 |
|
216 |
+ device.flushOutput() # Flush serial buffer to prevent overflows |
|
217 |
+ |
|
218 |
+def begin(): |
|
219 |
+ """ |
|
220 |
+ Description: initiates a serial connection the the FT991. Should always |
|
221 |
+ be called before sending commands to or receiving data |
|
222 |
+ from the FT991. Only needs to be called once. |
|
223 |
+ Parameters: none |
|
224 |
+ Returns: a pointer to the FT991 serial connection |
|
225 |
+ """ # Create a FT991 object for serial communication |
|
226 |
+ pDevice = serial.Serial(_SERIAL_PORT, _BAUD_RATE, |
|
227 |
+ timeout=_INTERFACE_TIMEOUT) |
|
228 |
+ time.sleep(.1) # give the connection a moment to settle |
|
229 |
+ return pDevice |
|
230 |
+ |
|
231 |
+ |
|
232 |
+def main(): |
|
233 |
+ """ |
|
234 |
+ Description: functions and function calls that test the functions |
|
235 |
+ in this module should be placed here. |
|
236 |
+ Parameters: none |
|
237 |
+ Returns: nothing |
|
238 |
+ """ # Test this module. |
|
239 |
+ verbose = True |
|
240 |
+ ft991 = begin() |
|
241 |
+ sendSerial(ft991,'if;') |
|
242 |
+ answer= receiveSerial(ft991) |
|
243 |
+ print answer |
|
244 |
+## end def |
|
245 |
+ |
|
246 |
+if __name__ == '__main__': |
|
247 |
+ main() |
2 | 250 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,19 @@ |
1 |
+1. Create a folder for the writemmory files. |
|
2 |
+2. Copy the files writememory.py and ft991.py to the folder. |
|
3 |
+3. Use the following commands to make the file executable |
|
4 |
+ chmod +x writememory.py |
|
5 |
+4. An example of a comma delimited spreadsheet has been provided. |
|
6 |
+ To use the example without actually programming your FT991 run |
|
7 |
+ the following command |
|
8 |
+ ./writememory.py -d -v -f example.csv |
|
9 |
+5. Using the -d debug option prevents commands from actually being |
|
10 |
+ written to the FT991. Using the -v verbose option allows you to |
|
11 |
+ see the commands that are sent to the FT991. The -f file option |
|
12 |
+ allows you to use a custom file name for the settings file. |
|
13 |
+6. A LibreOffice spreadsheet template "ft991_memory_settings.ots" has |
|
14 |
+ been provided to help you create comma delimited settings files. |
|
15 |
+ Various cells have dropdown list boxes for modes, tones, dcs codes, etc. |
|
16 |
+ You should use these list boxes for setting those items. Save the |
|
17 |
+ spreadsheet in comma delimited format (.csv). |
|
18 |
+7. Incorrectly entered modes, codes, tones, etc, will cause to program |
|
19 |
+ to crash, most likely with a dictionary object, key error. |
0 | 20 |
new file mode 100755 |
... | ... |
@@ -0,0 +1,159 @@ |
1 |
+#!/usr/bin/python -u |
|
2 |
+# The -u option turns off block buffering of python output. This assures |
|
3 |
+# that output streams to stdout when output happens. |
|
4 |
+# |
|
5 |
+# Description: This program reads a comma delimited spreadsheet file |
|
6 |
+# containing common transceiver settings. The settings |
|
7 |
+# are stored in the transceivers memory. |
|
8 |
+# |
|
9 |
+# This script has been tested with the following |
|
10 |
+# |
|
11 |
+# Python 2.7.15rc1 (default, Nov 12 2018, 14:31:15) |
|
12 |
+# [GCC 7.3.0] on linux2 |
|
13 |
+#2345678901234567890123456789012345678901234567890123456789012345678901234567890 |
|
14 |
+ |
|
15 |
+# Import python library modules. The serial module should be included in |
|
16 |
+# recent linux distributions. If not, it may need to be installed. |
|
17 |
+import sys, serial, time |
|
18 |
+# Import FT991 serial communication functions and command library. This |
|
19 |
+# is a custom module that should be in the same folder as this script. |
|
20 |
+import ft991 |
|
21 |
+ |
|
22 |
+# Define default memory settings file |
|
23 |
+_SETTINGS_FILE = './ft991mem.csv' |
|
24 |
+ |
|
25 |
+# Define global variables |
|
26 |
+settingsFile = _SETTINGS_FILE |
|
27 |
+ |
|
28 |
+def readSettingsFile(fileName): |
|
29 |
+ """ |
|
30 |
+ Description: reads the comma delimited memory settings file and parses |
|
31 |
+ each line of that file into a dictionary object which stores |
|
32 |
+ the settings for that memory location. Each dictionary |
|
33 |
+ object in turn gets stored in a single list object. |
|
34 |
+ Parameters: name of memory settings file |
|
35 |
+ Returns: a list object |
|
36 |
+ """ |
|
37 |
+ lChan = [] |
|
38 |
+ fchs = open(fileName, 'r') # open the file for reading |
|
39 |
+ # read a line from the file |
|
40 |
+ for line in fchs: |
|
41 |
+ # remove non-printable characters |
|
42 |
+ rline = line.strip() |
|
43 |
+ # parse the comma delimited line and store in a dictionary object |
|
44 |
+ dChanData = parseData(rline) |
|
45 |
+ # store the parsed line in a list object |
|
46 |
+ if dChanData != None: |
|
47 |
+ lChan.append(dChanData) |
|
48 |
+ fchs.close() |
|
49 |
+ return lChan |
|
50 |
+ |
|
51 |
+def parseData(sline): |
|
52 |
+ """ |
|
53 |
+ Description: stores each item in the comma delimited line in a single |
|
54 |
+ dictionary object using a key appropriate for that item. |
|
55 |
+ Parameters: a string containing the comma delimited items to be parsed. |
|
56 |
+ Returns: a dictionary object containing the parsed line. |
|
57 |
+ """ |
|
58 |
+ dChan = {} # define an empty dictionary object |
|
59 |
+ lchan = sline.split(',') # split the line at the commas |
|
60 |
+ # If the first line is a header line, ignore it. |
|
61 |
+ if not lchan[0].isdigit(): |
|
62 |
+ return None |
|
63 |
+ # Store the parsed items with the appropriate key in the dictionary object. |
|
64 |
+ dChan['chnum'] = lchan[0] |
|
65 |
+ dChan['rxfreq'] = lchan[1] |
|
66 |
+ dChan['txfreq'] = lchan[2] |
|
67 |
+ dChan['offset'] = lchan[3] |
|
68 |
+ dChan['shift'] = lchan[4] |
|
69 |
+ dChan['mode'] = lchan[5] |
|
70 |
+ dChan['tag'] = lchan[6] |
|
71 |
+ dChan['encode'] = lchan[7] |
|
72 |
+ dChan['tone'] = lchan[8] |
|
73 |
+ dChan['dcs'] = str(int(lchan[9])) |
|
74 |
+ return dChan # return the dictionary object |
|
75 |
+ |
|
76 |
+ |
|
77 |
+def sendCommand(device, sCmd): |
|
78 |
+ """ |
|
79 |
+ Description: sends a formatted FT911 command to the communication port |
|
80 |
+ connected to the FT991. Prints to stdout the answer from |
|
81 |
+ the FT991 (if any). |
|
82 |
+ Parameters: device - a pointer to the FT991 comm port |
|
83 |
+ sCmd - a string containing the formatted command |
|
84 |
+ Returns: nothing |
|
85 |
+ """ |
|
86 |
+ ft991.sendSerial(device, sCmd) |
|
87 |
+ sAnswer = ft991.receiveSerial(device); |
|
88 |
+ if sAnswer != '': |
|
89 |
+ print sAnswer |
|
90 |
+ |
|
91 |
+def getCLarguments(): |
|
92 |
+ """Get command line arguments. There are four possible arguments |
|
93 |
+ -v turns on verbose mode |
|
94 |
+ -d turns on debug mode |
|
95 |
+ -f name of comman delimited memory settings file |
|
96 |
+ Returns: nothing |
|
97 |
+ """ |
|
98 |
+ #global ft991.verbose, ft991.debug, settingsFile |
|
99 |
+ global settingsFile |
|
100 |
+ |
|
101 |
+ index = 1 |
|
102 |
+ while index < len(sys.argv): |
|
103 |
+ if sys.argv[index] == '-f': |
|
104 |
+ if len(sys.argv) < index + 2: |
|
105 |
+ print "-f option requires file name" |
|
106 |
+ exit(1); |
|
107 |
+ settingsFile = sys.argv[index + 1] |
|
108 |
+ index += 1 |
|
109 |
+ elif sys.argv[index] == '-v': |
|
110 |
+ ft991.verbose = True |
|
111 |
+ elif sys.argv[index] == '-d': |
|
112 |
+ ft991.debug = True |
|
113 |
+ else: |
|
114 |
+ cmd_name = sys.argv[0].split('/') |
|
115 |
+ print "Usage: %s [-v] [-f file]\n" \ |
|
116 |
+ " -f: settings file\n" \ |
|
117 |
+ " -v: verbose mode\n" \ |
|
118 |
+ " -d: debug mode" % cmd_name[-1] |
|
119 |
+ exit(-1) |
|
120 |
+ index += 1 |
|
121 |
+##end def |
|
122 |
+ |
|
123 |
+def main(): |
|
124 |
+ """ |
|
125 |
+ Description: Reads the settings file, creating a list object which |
|
126 |
+ contains dictionary objects as its elements. The dictionary |
|
127 |
+ objects contain the settings for each memory location to be |
|
128 |
+ programmed. |
|
129 |
+ Parameters: none |
|
130 |
+ Returns: nothing |
|
131 |
+ """ |
|
132 |
+ |
|
133 |
+ # Get command line arguments, if any. Otherwise use defaults. |
|
134 |
+ getCLarguments() |
|
135 |
+ |
|
136 |
+ # Create a FT991 object for serial communication. |
|
137 |
+ pft991 = ft991.begin() |
|
138 |
+ time.sleep(.1) # give the connection a moment to settle |
|
139 |
+ |
|
140 |
+ # Read and parse the settings file. |
|
141 |
+ dChan = readSettingsFile(settingsFile) |
|
142 |
+ # Get and send the commands to the FT991 for writing the memory locations. |
|
143 |
+ for item in dChan: |
|
144 |
+ if ft991.verbose: |
|
145 |
+ print '%s: ' % item['chnum'], |
|
146 |
+ |
|
147 |
+ # Format and send memory channel vfo and mode data. |
|
148 |
+ sendCommand(pft991, ft991.getMTcommand(item)) |
|
149 |
+ # Format and send CTCSS tone for memory channel. |
|
150 |
+ sendCommand(pft991, ft991.getCTCSScommand(item)) |
|
151 |
+ # Format and send DCS code for memory channel. |
|
152 |
+ sendCommand(pft991, ft991.getDCScommand(item)) |
|
153 |
+ |
|
154 |
+ if ft991.verbose: |
|
155 |
|
|
156 |
+## end def |
|
157 |
+ |
|
158 |
+if __name__ == '__main__': |
|
159 |
+ main() |