Project

General

Profile

New Model #9131 » vxf20ab.py

Mathieu Therrien, 06/14/2021 02:02 PM

 
1
#!/usr/bin/env python3
2
'''
3
[rx_status, rx_frequence, tx_status, tx_frequence, rx_dcs, tx_dcs]
4
	 status bits :
5
		0: Rig ON(0)/OFF(1)
6
		1: DCS ON(0)/OFF(1)
7
		2: ARTS ON(0)/OFF(1)
8
rxs rx frequence  txs tx frequence  rx dcx   tx dcs
9
111 0111110100000 110 0111110100000 11111111 11111111
10
111 0111110100000 110 0111110100000 11111111 11111111
11
111 0111110100000 110 0111110100000 11111111 11111111
12
111 0111110100000 110 0111110100000 11111111 11111111
13
111 0111110100000 110 0111110100000 11111111 11111111
14
111 0111110100000 110 0111110100000 11111111 11111111
15
111 0111110100000 110 0111110100000 11111111 11111111
16
111 0111110100000 110 0111110100000 11111111 11111111
17
111 0111110100000 110 0111110100000 11111111 11111111
18
111 0111110100000 110 0111110100000 11111111 11111111
19
111 0111110100000 110 0111110100000 11111111 11111111
20
111 0111110100000 110 0111110100000 11111111 11111111
21
111 0111110100000 110 0111110100000 11111111 11111111
22
111 0111110100000 110 0111110100000 11111111 11111111
23

    
24
Weather channels
25
1111111111111111
26
1111111111111111
27
1111111111111111
28
1111111111111111
29
1111111111111111
30
1111111111111111
31
1111111111111111
32
1111111111111111
33
1111111111111111
34
1111111111111111
35

    
36
* Voici une representation de la matrice initiale.
37
 * Le premier octet est toujours 0x01 et l'avant dernier est 0x0. Les dernier est un checksum.
38
 * 00000001 11101111 10100000 11001111 10100000 11111111
39
 * 11111111 11101111 10100000 11001111 10100000 11111111
40
 * 11111111 11101111 10100000 11001111 10100000 11111111
41
 * 11111111 11101111 10100000 11001111 10100000 11111111
42
 * 11111111 11101111 10100000 11001111 10100000 11111111
43
 * 11111111 11101111 10100000 11001111 10100000 11111111
44
 * 11111111 11101111 10100000 11001111 10100000 11111111
45
 * 11111111 11101111 10100000 11001111 10100000 11111111
46
 * 11111111 11101111 10100000 11001111 10100000 11111111
47
 * 11111111 11101111 10100000 11001111 10100000 11111111
48
 * 11111111 11101111 10100000 11001111 10100000 11111111
49
 * 11111111 11101111 10100000 11001111 10100000 11111111
50
 * 11111111 11101111 10100000 11001111 10100000 11111111
51
 * 11111111 11101111 10100000 11001111 10100000 11111111
52
 * 11111111 11111111 11111111 11111111 11111111 11111111
53
 * 11111111 11111111 11111111 11111111 11111111 11111111
54
 * 11111111 11111111 11111111 11111111 11111111 11111111
55
 * 11111111 11111111 11111111 00000000 11111111
56
 *
57
 
58
* Exemple d'un fichier CSV valide
59
 Channel,RX on,RX DCS on,RX ARTS on,RX Frequency,RX DCS,TX on,TX DCS on,TX ARTS on,TX Frequency,TX DCS
60
1,True,True,True,462.5625,23,True,True,True,462.5625,23
61
2,True,True,True,462.5875,23,True,True,True,462.5875,23
62
3,True,True,True,462.6125,23,True,True,True,462.6125,23
63
4,True,True,True,462.6375,23,True,True,True,462.6375,23
64
5,True,True,True,462.6625,23,True,True,True,462.6625,23
65
6,True,True,True,462.6875,23,True,True,True,462.6875,23
66
7,True,True,True,462.7125,23,True,True,True,462.7125,23
67
8,True,True,True,467.5625,23,True,True,True,467.5625,23
68
9,True,True,True,467.5875,23,True,True,True,467.5875,23
69
10,True,True,True,467.6125,23,True,True,True,467.6125,23
70
11,True,True,True,467.6375,23,True,True,True,467.6375,23
71
12,True,True,True,467.6625,23,True,True,True,467.6625,23
72
13,True,True,True,467.6875,23,True,True,True,467.6875,23
73
14,True,True,True,467.7125,23,True,True,True,467.7125,23
74
Weather Frequency
75
162.4
76
162.425
77
162.45
78
162.475
79
162.5
80
162.525
81
162.55
82
""
83
""
84
""
85

    
86
'''
87

    
88
import serial
89
import csv
90

    
91
class vxf20(object):
92
    def __init__(self):
93
        self.channels = dict()
94
        self.ch_weather = list()
95
    
96
    def decode_pgmbytes(self, pgmbytes):
97
        for ch in range(0, 14):
98
            i = ch * 6 + 1
99
            channel = dict()
100
            rx = dict()
101
            tx = dict()
102
            rx['status'] = self.get_status(pgmbytes[i] >> 5)
103
            rx['frequency'] = self.get_frequency( (pgmbytes[i] & 0x1f) << 8 | pgmbytes[i+1] )
104

    
105
            tx['status'] = self.get_status(pgmbytes[i+2] >> 5)
106
            tx['frequency'] = self.get_frequency( (pgmbytes[i+2] & 0x1f) << 8 | pgmbytes[i+3] )
107

    
108
            rx['dcs'] = self.get_dcs(pgmbytes[i+4])
109
            tx['dcs'] = self.get_dcs(pgmbytes[i+5])
110
            
111
            channel['rx'] = rx
112
            channel['tx'] = tx
113
            self.channels[ch + 1] = channel
114

    
115
        for wch in range(0, 10):
116
            i = wch * 2 + 85
117
            ch_weather = self.get_weather_frequency(pgmbytes[i] << 8 | pgmbytes[i+1])
118
            self.ch_weather.append(ch_weather)
119
        
120
    def encode_pgmbytes(self):
121
        pgmlist = [1]
122
        for ch in self.channels:
123
            rx = (self.set_status(self.channels[ch]['rx']['status']) << 5+8) | self.set_frequency(self.channels[ch]['rx']['frequency'])
124
            rxHIGH = (rx & 0xff00) >> 8
125
            rxLOW = rx & 0xff
126

    
127
            tx = (self.set_status(self.channels[ch]['tx']['status']) << 5+8) | self.set_frequency(self.channels[ch]['tx']['frequency'])
128
            txHIGH = (tx & 0xff00) >> 8
129
            txLOW = tx & 0xff
130

    
131
            rxDCS = self.set_dcs(self.channels[ch]['rx']['dcs'])
132
            txDCS = self.set_dcs(self.channels[ch]['rx']['dcs'])
133
            pgmlist += [rxHIGH, rxLOW, txHIGH, txLOW, rxDCS, txDCS]
134
            
135
        for wch in self.ch_weather:
136
            fr = self.set_weather_frequency(wch)
137
            frHIGH = (fr & 0xff00) >> 8
138
            frLOW = fr & 0xff
139
            pgmlist += [frHIGH, frLOW]
140

    
141
        
142
        pgmlist += [0x00, self.set_checksum(bytes(pgmlist))]
143
        pgmbytes = bytes(pgmlist)
144
        print(pgmbytes)
145
        
146
        return pgmbytes
147

    
148
    def read(self, com = '/dev/ttyUSB0'):
149
        with serial.Serial(com, 2400, timeout=5) as rig:
150
            print('Press PTT...')
151
            pgmbytes = rig.read(107)
152
        
153
        print(pgmbytes)
154
        self.decode_pgmbytes(pgmbytes)
155
        
156
    def write(self, com = '/dev/ttyUSB0'):
157
        pgmbytes = self.encode_pgmbytes()
158
        
159
        with serial.Serial(com, 2400, timeout=5) as rig:
160
            rig.write(pgmbytes)
161
            checkback = rig.read(107)
162
            
163
            pgmlist = list(pgmbytes)
164
            #pgmlist += [0xff]
165
            if bytes(pgmlist) == checkback:
166
                #rig.write(bytes([0x06]))
167
                print('done')
168

    
169
    def get_frequency(self, fr):
170
        return (125 * fr + 4000000) / 10000
171

    
172
    def set_frequency(self, fr):
173
        return int((10000 * fr - 4000000) / 125)
174

    
175
    def get_weather_frequency(self, wfr):
176
        if wfr < 0xffff:
177
            return (6.25 * wfr + 130025) / 1000
178
        else:
179
            return None
180

    
181
    def set_weather_frequency(self, wfr):
182
        if wfr is None:
183
            return 0xffff
184
        else:
185
            return int((1000 * wfr - 130025) / 6.25)
186

    
187
    def get_status(self, status):
188
        s = dict()
189
        s['rig'] = bool(~status & 0b100)
190
        s['dcs'] = bool(~status & 0b010)
191
        s['arts'] = bool(~status & 0b001)
192
        return s
193

    
194
    def set_status(self, status):
195
        rig = int((not status['rig']) << 2)
196
        dcs = int((not status['dcs']) << 1)
197
        arts = int(not status['arts'])
198
        return (rig | dcs | arts)
199

    
200
    def get_dcs(self, dcs):
201
        if dcs == 0:
202
            return 23
203
        elif dcs == 1:
204
            return 25
205
        elif dcs == 2:
206
            return 26
207
        elif dcs == 3:
208
            return 31
209
        elif dcs == 4:
210
            return 32
211
        elif dcs == 5:
212
            return 36
213
        elif dcs == 6:
214
            return 43
215
        elif dcs == 7:
216
            return 47
217
        elif dcs == 8:
218
            return 51
219
        elif dcs == 9:
220
            return 53
221
        elif dcs == 10:
222
            return 54
223
        elif dcs == 11:
224
            return 65
225
        elif dcs == 12:
226
            return 71
227
        elif dcs ==13:
228
            return 72
229
        elif dcs == 14:
230
            return 73
231
        elif dcs == 15:
232
            return 74
233
        elif dcs == 16:
234
            return 114
235
        elif dcs == 17:
236
            return 115
237
        elif dcs == 18:
238
            return 116
239
        elif dcs == 19:
240
            return 122
241
        elif dcs == 20:
242
            return 125
243
        elif dcs == 21:
244
            return 131
245
        elif dcs == 22:
246
            return 132
247
        elif dcs == 23:
248
            return 134
249
        elif dcs == 24:
250
            return 143
251
        elif dcs == 25:
252
            return 145
253
        elif dcs == 26:
254
            return 152
255
        elif dcs == 27:
256
            return 155
257
        elif dcs == 28:
258
            return 156
259
        elif dcs == 29:
260
            return 162
261
        elif dcs == 30:
262
            return 165
263
        elif dcs == 31:
264
            return 172
265
        elif dcs == 32:
266
            return 174
267
        elif dcs == 33:
268
            return 205
269
        elif dcs == 34:
270
            return 212
271
        elif dcs == 35:
272
            return 223
273
        elif dcs == 36:
274
            return 225
275
        elif dcs == 37:
276
            return 226
277
        elif dcs == 38:
278
            return 243
279
        elif dcs == 39:
280
            return 244
281
        elif dcs == 40:
282
            return 245
283
        elif dcs == 41:
284
            return 246
285
        elif dcs == 42:
286
            return 251
287
        elif dcs == 43:
288
            return 252
289
        elif dcs == 44:
290
            return 255
291
        elif dcs == 45:
292
            return 261
293
        elif dcs == 46:
294
            return 263
295
        elif dcs == 47:
296
            return 265
297
        elif dcs == 48:
298
            return 266
299
        elif dcs == 49:
300
            return 271
301
        elif dcs == 50:
302
            return 274
303
        elif dcs == 51:
304
            return 306
305
        elif dcs == 52:
306
            return 311
307
        elif dcs == 53:
308
            return 315
309
        elif dcs == 54:
310
            return 325
311
        elif dcs == 55:
312
            return 331
313
        elif dcs == 56:
314
            return 332
315
        elif dcs == 57:
316
            return 343
317
        elif dcs == 58:
318
            return 346
319
        elif dcs == 59:
320
            return 351
321
        elif dcs == 60:
322
            return 356
323
        elif dcs == 61:
324
            return 364
325
        elif dcs == 62:
326
            return 365
327
        elif dcs == 63:
328
            return 371
329
        elif dcs == 64:
330
            return 411
331
        elif dcs == 65:
332
            return 412
333
        elif dcs == 66:
334
            return 413
335
        elif dcs == 67:
336
            return 423
337
        elif dcs == 68:
338
            return 431
339
        elif dcs == 69:
340
            return 432
341
        elif dcs == 70:
342
            return 445
343
        elif dcs == 71:
344
            return 446
345
        elif dcs == 72:
346
            return 452
347
        elif dcs == 73:
348
            return 454
349
        elif dcs == 74:
350
            return 455
351
        elif dcs == 75:
352
            return 462
353
        elif dcs == 76:
354
            return 464
355
        elif dcs == 77:
356
            return 465
357
        elif dcs == 78:
358
            return 466
359
        elif dcs == 79:
360
            return 503
361
        elif dcs == 80:
362
            return 506
363
        elif dcs == 81:
364
            return 513
365
        elif dcs == 82:
366
            return 523
367
        elif dcs == 83:
368
            return 526
369
        elif dcs == 84:
370
            return 532
371
        elif dcs == 85:
372
            return 546
373
        elif dcs == 86:
374
            return 565
375
        elif dcs == 87:
376
            return 606
377
        elif dcs == 88:
378
            return 612
379
        elif dcs == 89:
380
            return 624
381
        elif dcs == 90:
382
            return 627
383
        elif dcs == 91:
384
            return 631
385
        elif dcs == 92:
386
            return 632
387
        elif dcs == 93:
388
            return 654
389
        elif dcs == 94:
390
            return 662
391
        elif dcs == 95:
392
            return 664
393
        elif dcs == 96:
394
            return 703
395
        elif dcs == 97:
396
            return 712
397
        elif dcs == 98:
398
            return 723
399
        elif dcs == 99:
400
            return 731
401
        elif dcs == 100:
402
            return 732
403
        elif dcs == 101:
404
            return 734
405
        elif dcs == 102:
406
            return 743
407
        elif dcs == 103:
408
            return 754
409
        else:
410
            return 0
411

    
412
    def set_dcs(self, dcs):
413
        if dcs == 23:
414
            return 0
415
        elif dcs == 25:
416
            return 1;
417
        elif dcs == 26:
418
            return 2;
419
        elif dcs == 31:
420
            return 3;
421
        elif dcs == 32:
422
            return 4;
423
        elif dcs == 36:
424
            return 5;
425
        elif dcs == 43:
426
            return 6;
427
        elif dcs == 47:
428
            return 7;
429
        elif dcs == 51:
430
            return 8;
431
        elif dcs == 53:
432
            return 9;
433
        elif dcs == 54:
434
            return 10;
435
        elif dcs == 65:
436
            return 11;
437
        elif dcs == 71:
438
            return 12;
439
        elif dcs == 72:
440
            return 13;
441
        elif dcs == 73:
442
            return 14;
443
        elif dcs == 74:
444
            return 15;
445
        elif dcs == 114:
446
            return 16;
447
        elif dcs == 115:
448
            return 16;
449
        elif dcs == 116:
450
            return 18;
451
        elif dcs == 122:
452
            return 19;
453
        elif dcs == 125:
454
            return 20;
455
        elif dcs == 131:
456
            return 21;
457
        elif dcs == 132:
458
            return 22;
459
        elif dcs == 134:
460
            return 23;
461
        elif dcs == 143:
462
            return 24;
463
        elif dcs == 145:
464
            return 25;
465
        elif dcs == 152:
466
            return 26;
467
        elif dcs == 155:
468
            return 27;
469
        elif dcs == 156:
470
            return 28;
471
        elif dcs == 162:
472
            return 29;
473
        elif dcs == 165:
474
            return 30;
475
        elif dcs == 172:
476
            return 31;
477
        elif dcs == 174:
478
            return 32;
479
        elif dcs == 205:
480
            return 33;
481
        elif dcs == 212:
482
            return 34;
483
        elif dcs == 223:
484
            return 35;
485
        elif dcs == 225:
486
            return 36;
487
        elif dcs == 226:
488
            return 37;
489
        elif dcs == 243:
490
            return 38;
491
        elif dcs == 244:
492
            return 39;
493
        elif dcs == 245:
494
            return 40;
495
        elif dcs == 246:
496
            return 41;
497
        elif dcs == 251:
498
            return 42;
499
        elif dcs == 252:
500
            return 43;
501
        elif dcs == 255:
502
            return 44;
503
        elif dcs == 261:
504
            return 45;
505
        elif dcs == 263:
506
            return 46;
507
        elif dcs == 265:
508
            return 47;
509
        elif dcs == 266:
510
            return 48;
511
        elif dcs == 271:
512
            return 49;
513
        elif dcs == 274:
514
            return 50;
515
        elif dcs == 306:
516
            return 51;
517
        elif dcs == 311:
518
            return 52;
519
        elif dcs == 315:
520
            return 53;
521
        elif dcs == 325:
522
            return 54;
523
        elif dcs == 331:
524
            return 55;
525
        elif dcs == 332:
526
            return 56;
527
        elif dcs == 343:
528
            return 57;
529
        elif dcs == 346:
530
            return 58;
531
        elif dcs == 351:
532
            return 59;
533
        elif dcs == 356:
534
            return 60;
535
        elif dcs == 364:
536
            return 61;
537
        elif dcs == 365:
538
            return 62;
539
        elif dcs == 371:
540
            return 63;
541
        elif dcs == 411:
542
            return 64;
543
        elif dcs ==412:
544
            return 65;
545
        elif dcs == 413:
546
            return 66;
547
        elif dcs == 423:
548
            return 67;
549
        elif dcs == 431:
550
            return 68;
551
        elif dcs == 432:
552
            return 69;
553
        elif dcs == 445:
554
            return 70;
555
        elif dcs == 446:
556
            return 71;
557
        elif dcs == 452:
558
            return 72;
559
        elif dcs == 454:
560
            return 73;
561
        elif dcs == 455:
562
            return 74;
563
        elif dcs == 462:
564
            return 75;
565
        elif dcs == 464:
566
            return 76;
567
        elif dcs == 465:
568
            return 77;
569
        elif dcs == 466:
570
            return 78;
571
        elif dcs == 503:
572
            return 79;
573
        elif dcs == 506:
574
            return 80;
575
        elif dcs == 513:
576
            return 81;
577
        elif dcs == 523:
578
            return 82;
579
        elif dcs == 526:
580
            return 83;
581
        elif dcs == 532:
582
            return 84;
583
        elif dcs == 546:
584
            return 85;
585
        elif dcs == 565:
586
            return 86;
587
        elif dcs == 606:
588
            return 87;
589
        elif dcs == 612:
590
            return 88;
591
        elif dcs == 624:
592
            return 89;
593
        elif dcs == 627:
594
            return 90;
595
        elif dcs == 631:
596
            return 91;
597
        elif dcs == 632:
598
            return 92;
599
        elif dcs == 654:
600
            return 93;
601
        elif dcs == 662:
602
            return 94;
603
        elif dcs == 664:
604
            return 95;
605
        elif dcs == 703:
606
            return 96;
607
        elif dcs == 712:
608
            return 97;
609
        elif dcs == 723:
610
            return 98;
611
        elif dcs == 731:
612
            return 99;
613
        elif dcs == 732:
614
            return 100;
615
        elif dcs == 734:
616
            return 101;
617
        elif dcs == 743:
618
            return 102;
619
        elif dcs == 754:
620
            return 103;
621
        else:
622
            return 0xff;
623

    
624
    def write_csv(self, filename = 'vxf20ab.csv'):
625
        with open(filename, 'w') as f:
626
            headers = ['Channel', 'RX on', 'RX DCS on', 'RX ARTS on', 'RX Frequency', 'RX DCS', 'TX on', 'TX DCS on', 'TX ARTS on', 'TX Frequency', 'TX DCS']
627
            writer = csv.writer(f)
628

    
629
            writer.writerow(headers)
630
            for ch in self.channels:
631
                writer.writerow([ch,
632
                self.channels[ch]['rx']['status']['rig'],
633
                self.channels[ch]['rx']['status']['dcs'],
634
                self.channels[ch]['rx']['status']['arts'],
635
                self.channels[ch]['rx']['frequency'],
636
                self.channels[ch]['rx']['dcs'],
637
                self.channels[ch]['tx']['status']['rig'],
638
                self.channels[ch]['tx']['status']['dcs'],
639
                self.channels[ch]['tx']['status']['arts'],
640
                self.channels[ch]['tx']['frequency'],
641
                self.channels[ch]['tx']['dcs']])
642
            
643
            writer.writerow(['Weather Frequency'])
644
            for wch in self.ch_weather:
645
                writer.writerow([wch])
646
    
647
    def read_csv(self, filename = 'vxf20ab.csv'):
648
        wch = False
649
        
650
        with open(filename, 'r') as f:
651
            reader = csv.DictReader(f)
652
            for row in reader:
653
                if(not wch):
654
                    if(row['Channel'] != 'Weather Frequency'):
655
                        channel = dict()
656
                        rx = dict()
657
                        tx = dict()
658
                        rx_status = dict()
659
                        tx_status = dict()
660
                    
661
                        ch = int(row['Channel'])
662
                        rx_status['rig'] = bool(row['RX on'])
663
                        rx_status['dcs'] = bool(row['RX DCS on'])
664
                        rx_status['arts'] = bool(row['RX ARTS on'])
665
                        rx['status'] = rx_status
666
                        rx['frequency'] = float(row['RX Frequency'])
667
                        rx['dcs'] = int(row['RX DCS'])
668
                
669
                        tx_status['rig'] = bool(row['TX on'])
670
                        tx_status['dcs'] = bool(row['TX DCS on'])
671
                        tx_status['arts'] = bool(row['TX ARTS on'])
672
                        tx['status'] = tx_status
673
                        tx['frequency'] = float(row['TX Frequency'])
674
                        tx['dcs'] = int(row['TX DCS'])
675
                        channel['rx'] = rx
676
                        channel['tx'] = tx
677
                        self.channels[ch] = channel
678
                    else:
679
                        wch = True
680
                else:
681
                    if row['Channel'] != '':
682
                        self.ch_weather.append(float(row['Channel']))
683
                    else:
684
                        self.ch_weather.append(None)
685
    
686
    def get_checksum(self, pgmbytes):
687
        cs = 0
688
        for i in pgmbytes:
689
            cs+=i
690
        
691
        first = pgmbytes[0]
692
        last = pgmbytes[-1]
693
        cs = cs - first - last
694
        if cs % 256 == last:
695
            return last
696
        else:
697
            return False
698
    
699
    def set_checksum(self, pgmbytes):
700
        cs = 0
701
        for i in pgmbytes:
702
            cs+=i
703
        
704
        cs = (cs - 1) % 256
705
        print(hex(cs))
706
        return cs
707
        
708
def main():
709
    myrig = vxf20()
710
    myrig.read_csv()
711
    myrig.write()
712
    myrig.read()
713
    print(myrig.channels)
714

    
715
if __name__ == '__main__':
716
    main()
(1-1/3)