1
1
import sys
2
2
import argparse
3
3
4
- from PyQt5 .QtCore import QThread , pyqtSignal
4
+ from PyQt5 .QtCore import QThread , pyqtSignal , QSettings
5
5
from PyQt5 .QtWidgets import QApplication , QMainWindow , QVBoxLayout , QWidget , QHBoxLayout
6
6
from PyQt5 .QtWidgets import QPushButton , QFileDialog , QTreeWidget , QTreeWidgetItem , QAction , QSplitter , QTableWidgetItem
7
-
8
7
from PyQt5 .QtGui import QIcon
9
8
10
9
import pyqtgraph as pg
27
26
from pyqtgraph import ImageView
28
27
29
28
29
+
30
+
31
+ class dosparser ():
32
+ def __init__ (self ):
33
+ pass
34
+
35
+ def load_file (self , datafile : str , detector = None ):
36
+ pass
37
+
30
38
def parse_file (file_path ):
31
39
start_time = time .time ()
32
40
print ("Parser start" )
@@ -67,8 +75,10 @@ def parse_file(file_path):
67
75
68
76
69
77
np_spectrum = np .array (df_lines , dtype = float )
70
- time_column = np_spectrum [:, 0 ]
78
+ time_column = np_spectrum [:, 1 ]
79
+ print (time_column )
71
80
np_spectrum = np_spectrum [:, 8 :]
81
+ print (np_spectrum )
72
82
73
83
sums = np .sum (np_spectrum [:, 1 :], axis = 1 )
74
84
hist = np .sum (np_spectrum [:, 1 :], axis = 0 )
@@ -447,14 +457,6 @@ def write_i2c_block_data(self, address, register, value):
447
457
self .device .write (payload )
448
458
449
459
450
- def read_i2c_block_data (self , address , register , length ):
451
- data = []
452
- for i in range (length ):
453
- self .write_byte_data (address , register , i )
454
- byte = self .read_byte (address )
455
- data .append (byte )
456
- return data
457
-
458
460
def read_i2c_block_data (self , address , register , length ):
459
461
"""
460
462
I2C Block Read: i2c_smbus_read_i2c_block_data()
@@ -554,8 +556,8 @@ class HIDI2CCommunicationThread(QThread):
554
556
connect = pyqtSignal (bool )
555
557
sendAirdosStatus = pyqtSignal (dict )
556
558
557
- VID = 0x0403
558
- PID = 0x6030
559
+ # VID = 0x0403
560
+ # PID = 0x6030
559
561
VID = 0x1209
560
562
PID = 0x7aa0
561
563
I2C_INTERFACE = 0
@@ -641,16 +643,32 @@ def set_i2c_direction_to_usb(self, usb = True):
641
643
# Do usb se to prepne tak, ze bit[0] a bit[2] jsou rozdilne hodnoty, bit[1] a bit[3] jsou read-only
642
644
self .ftdi .write_byte_data (self .addr_switch , 0x01 , 0b011 )
643
645
else :
644
- # Do ATMEGA se to prepne tak, ze bit[0] a bit[2] maji stejne hodnoty hodnoty
646
+ # I2C do ATMEGA se to prepne tak, ze bit[0] a bit[2] maji stejne hodnoty hodnoty
645
647
self .ftdi .write_byte_data (self .addr_switch , 0x01 , 0b0000 )
646
648
647
649
@pyqtSlot ()
648
650
def connectSlot (self , state = True , power_off = False ):
649
651
print ("Connecting to HID device... " , state )
650
652
if state :
653
+
654
+ hid_interface_i2c = None
655
+ hid_interface_uart = None
656
+
657
+ for hidDevice in hid .enumerate (0 , 0 ):
658
+ print (hidDevice )
659
+ if hidDevice ['vendor_id' ] == self .VID and hidDevice ['product_id' ] == self .PID :
660
+ if hidDevice ['interface_number' ] == 0 :
661
+ hid_interface_i2c = hidDevice
662
+ else :
663
+ hid_interface_uart = hidDevice
664
+
651
665
self .dev = hid .device ()
652
- self .dev .open (self .VID , self .PID )
653
- print ("Connected to HID device" , self .dev )
666
+ #self.dev.open(self.VID, self.PID)
667
+ self .dev .open_path (hid_interface_i2c ['path' ])
668
+
669
+ self .dev_uart = hid .device ()
670
+ self .dev_uart .open_path (hid_interface_uart ['path' ])
671
+ print ("Connected to HID device" , self .dev , self .dev_uart )
654
672
655
673
self .dev .send_feature_report ([0xA1 , 0x20 ])
656
674
self .dev .send_feature_report ([0xA1 , 0x02 , 0x01 ])
@@ -698,6 +716,7 @@ def connectSlot(self, state = True, power_off = False):
698
716
self .set_i2c_direction_to_usb (False )
699
717
700
718
self .dev .close ()
719
+ self .dev_uart .close ()
701
720
self .dev = None
702
721
self .ftdi = None
703
722
self .connected .emit (False )
@@ -709,25 +728,46 @@ def get_time(self):
709
728
r02 = self .ftdi .read_byte_data (self .addr_rtc , 0x02 )
710
729
r03 = self .ftdi .read_byte_data (self .addr_rtc , 0x03 )
711
730
r04 = self .ftdi .read_byte_data (self .addr_rtc , 0x04 )
731
+ r05 = self .ftdi .read_byte_data (self .addr_rtc , 0x05 )
712
732
r06 = self .ftdi .read_byte_data (self .addr_rtc , 0x06 )
713
733
r07 = self .ftdi .read_byte_data (self .addr_rtc , 0x07 )
714
734
715
- sec100 = r00
716
- absdate = datetime .datetime .utcnow ()
717
- sec = ((r01 >> 4 ) & 0b111 ) * 10 + (r01 & 0b1111 )
718
- minu = ((r02 >> 4 ) & 0b111 ) * 10 + (r02 & 0b1111 )
719
- hourL = ((r03 >> 4 ) & 0b11 ) * 10 + (r03 & 0b1111 )
720
- hourM = ((r04 >> 4 ) & 0b11 ) * 10 + (r04 & 0b1111 )
721
- hourR = ((r06 >> 4 ) & 0b1 ) * 10 + (r06 & 0b1111 )
722
-
723
- hour = hourR << 8 | hourM << 4 | hourL
724
- date = datetime .timedelta (hours = hour , minutes = minu , seconds = sec , milliseconds = sec100 * 10 )
735
+ #r = self.ftdi.read_i2c_block_data(self.addr_rtc, 0x00, 8)
736
+
737
+ sec100 = r00 & 0b1111 + ((r00 & 0b11110000 ) >> 4 ) * 10
738
+ absdate = datetime .datetime .now (datetime .timezone .utc )
739
+ sec = r01 & 0b1111 + ((r01 & 0b01110000 ) >> 4 ) * 10
740
+ minu = r02 & 0b1111 + ((r02 & 0b01110000 ) >> 4 ) * 10
741
+ hour = r03 & 0b1111 + ((r03 & 0b11110000 ) >> 4 ) * 10
742
+ hour += r04 & 0b1111 * 100 + ((r04 & 0b11110000 ) >> 4 ) * 1000
743
+ hour += r05 & 0b1111 * 10000 + ((r05 & 0b11110000 ) >> 4 ) * 100000
744
+ #hour = r03 + r04*100 + r05*10000
745
+
746
+ print ("RTC data:" , r00 , r01 , r02 , r03 , r04 , r05 , r06 , r07 )
747
+ print ("RTC time: " , hour , minu , sec , sec100 )
748
+
749
+ date_delta = datetime .timedelta (hours = hour , minutes = minu , seconds = sec , milliseconds = sec100 * 10 )
750
+
751
+ return (absdate , date_delta )
752
+
753
+ def reset_time (self ):
754
+ reset_time = datetime .datetime .now (datetime .timezone .utc )
725
755
726
- return (absdate , date )
756
+ # self.ftdi.write_i2c_block_data(self.addr_rtc, 0x00, [0, 0, 0, 0, 0, 0, 0, 0])
757
+
758
+ self .ftdi .write_byte_data (self .addr_rtc , 0x00 , 0 )
759
+ self .ftdi .write_byte_data (self .addr_rtc , 0x01 , 0 )
760
+ self .ftdi .write_byte_data (self .addr_rtc , 0x02 , 0 )
761
+ self .ftdi .write_byte_data (self .addr_rtc , 0x03 , 0 )
762
+ self .ftdi .write_byte_data (self .addr_rtc , 0x04 , 0 )
763
+ self .ftdi .write_byte_data (self .addr_rtc , 0x05 , 0 )
764
+ self .ftdi .write_byte_data (self .addr_rtc , 0x06 , 0 )
765
+ self .ftdi .write_byte_data (self .addr_rtc , 0x07 , 0 )
727
766
728
- def get_battery ( self ):
767
+ print ( "Time reseted at..." , reset_time )
729
768
730
769
770
+ def get_battery (self ):
731
771
ibus_adc = (self .ftdi .read_byte_data (self .addr_charger , 0x28 ) >> 1 ) * 2
732
772
ibat_adc = (self .ftdi .read_byte_data (self .addr_charger , 0x2A ) >> 2 ) * 4
733
773
vbus_adc = (self .ftdi .read_byte_data (self .addr_charger , 0x2C ) >> 2 ) * 3.97 / 1000
@@ -778,7 +818,8 @@ def get_airdos_status(self):
778
818
data .update ({
779
819
'RTC' : {
780
820
'sys_time' : sys_date ,
781
- 'abs_time' : abstime
821
+ 'abs_time' : abstime ,
822
+ 'sys_begin_time' : abstime - sys_date
782
823
},
783
824
'CHARGER' : charger ,
784
825
'GAUGE' : gauge
@@ -834,8 +875,15 @@ def get_airdos_status(self):
834
875
self .set_i2c_direction_to_usb (False )
835
876
print ("Posilam..." , type (data ))
836
877
print (data )
837
- self .sendAirdosStatus .emit (data )
838
-
878
+ self .sendAirdosStatus .emit (data )
879
+
880
+
881
+ @pyqtSlot ()
882
+ def reset_rtc_time (self ):
883
+ self .set_i2c_direction_to_usb (True )
884
+ self .reset_time ()
885
+ self .set_i2c_direction_to_usb (False )
886
+
839
887
class HIDUARTCommunicationThread (QThread ):
840
888
connected = pyqtSignal (bool )
841
889
@@ -991,6 +1039,9 @@ def initUI(self):
991
1039
reload_button .clicked .connect (self .i2c_thread .get_airdos_status )
992
1040
i2c_layout .addWidget (reload_button )
993
1041
1042
+ reset_time_button = QPushButton ("Reset time" )
1043
+ reset_time_button .clicked .connect (self .i2c_thread .reset_rtc_time )
1044
+ i2c_layout .addWidget (reset_time_button )
994
1045
995
1046
uart_widget = QGroupBox ("UART" )
996
1047
uart_layout = QVBoxLayout ()
@@ -1081,16 +1132,26 @@ def initUI(self):
1081
1132
1082
1133
1083
1134
self .open_img_view_button = QPushButton ("Spectrogram" )
1135
+ self .open_img_view_button .setMaximumHeight (20 )
1084
1136
self .open_img_view_button .clicked .connect (self .open_spectrogram_view )
1085
1137
1138
+ self .upload_file_button = QPushButton ("Upload file" )
1139
+ self .upload_file_button .setMaximumHeight (20 )
1140
+ #self.upload_file_button.clicked.connect(self.upload_file_dialog)
1141
+
1142
+
1086
1143
1087
1144
log_view_widget = QWidget ()
1088
1145
1089
1146
self .left_panel = QSplitter (Qt .Vertical )
1090
1147
1091
1148
self .left_panel .addWidget (self .datalines_tree )
1092
1149
self .left_panel .addWidget (self .properties_tree )
1093
- self .left_panel .addWidget (self .open_img_view_button )
1150
+
1151
+ vb = QHBoxLayout ()
1152
+ vb .addWidget (self .open_img_view_button )
1153
+ vb .addWidget (self .upload_file_button )
1154
+ self .left_panel .setLayout (vb )
1094
1155
1095
1156
self .logView_splitter = QSplitter (Qt .Horizontal )
1096
1157
self .logView_splitter .addWidget (self .left_panel )
@@ -1168,13 +1229,105 @@ def open_spectrogram_view(self):
1168
1229
w .plot_data (matrix )
1169
1230
1170
1231
1232
+ class PreferencesVindow (QDialog ):
1233
+ def __init__ (self ):
1234
+ super ().__init__ ()
1235
+ self .initUI ()
1236
+
1237
+
1238
+ def DosportalTab (self ):
1239
+ #self.dosportal_tab_group = QGroupBox("DOSPORTAL settings")
1240
+ self .dosportal_tab_layout = QVBoxLayout ()
1241
+ settings = QSettings ("UST" , "dosview" )
1242
+
1243
+
1244
+ self .url = QLineEdit ()
1245
+ self .login = QLineEdit ()
1246
+ self .password = QLineEdit ()
1247
+
1248
+ # Load data from QSettings
1249
+ url = settings .value ("url" )
1250
+ if url is not None :
1251
+ self .url .setText (url )
1252
+ login = settings .value ("login" )
1253
+ if login is not None :
1254
+ self .login .setText (login )
1255
+
1256
+ password = settings .value ("password" )
1257
+ self .password .setEchoMode (QLineEdit .Password )
1258
+ if password is not None :
1259
+ self .password .setText (password )
1260
+
1261
+ vb = QHBoxLayout ()
1262
+ vb .addWidget (QLabel ("URL" ))
1263
+ vb .addWidget (self .url )
1264
+ self .dosportal_tab_layout .addLayout (vb )
1265
+
1266
+ vb = QHBoxLayout ()
1267
+ vb .addWidget (QLabel ("Login" ))
1268
+ vb .addWidget (self .login )
1269
+ self .dosportal_tab_layout .addLayout (vb )
1270
+
1271
+ vb = QHBoxLayout ()
1272
+ vb .addWidget (QLabel ("Password" ))
1273
+ vb .addWidget (self .password )
1274
+ self .dosportal_tab_layout .addLayout (vb )
1275
+
1276
+
1277
+ # Save data to QSettings
1278
+ def save_settings ():
1279
+ settings .setValue ("url" , self .url .text ())
1280
+ settings .setValue ("login" , self .login .text ())
1281
+ settings .setValue ("password" , self .password .text ())
1282
+
1283
+ # Connect save button to save_settings function
1284
+ save_button = QPushButton ("Save credentials" )
1285
+ save_button .clicked .connect (save_settings )
1286
+
1287
+ test_button = QPushButton ("Test connection" )
1288
+ test_button .clicked .connect (lambda : print ("Testing connection .... not implemented yet :-) " ))
1289
+
1290
+ vb = QHBoxLayout ()
1291
+ vb .addWidget (save_button )
1292
+ vb .addWidget (test_button )
1293
+
1294
+ self .dosportal_tab_layout .addLayout (vb )
1295
+
1296
+ self .dosportal_tab_layout .addStretch (1 )
1297
+ return self .dosportal_tab_layout
1298
+ #self.dosportal_tab_group.setLayout(self.dosportal_tab_layout)
1299
+ #return self.dosportal_tab_group
1300
+
1301
+
1302
+ def initUI (self ):
1303
+
1304
+ self .setWindowTitle ("DOSVIEW Preferences" )
1305
+ self .setGeometry (100 , 100 , 400 , 300 )
1306
+ self .layout = QVBoxLayout ()
1307
+ self .setLayout (self .layout )
1308
+
1309
+ self .tabs = QTabWidget ()
1310
+ self .layout .addWidget (self .tabs )
1311
+
1312
+ self .dosportal_tab = QWidget ()
1313
+ #self.dosportal_tab_layout = QVBoxLayout()
1314
+ self .dosportal_tab .setLayout ( self .DosportalTab () )
1315
+
1316
+ self .tabs .addTab (self .dosportal_tab , "DOSPORTAL" )
1317
+
1318
+
1319
+
1320
+ self .tabs .addTab (QWidget (), "Advanced" )
1321
+ #self.layout.addWidget(QPushButton("Save"))
1322
+
1171
1323
1172
1324
class App (QMainWindow ):
1173
1325
def __init__ (self , args ):
1174
1326
super ().__init__ ()
1175
1327
self .args = args
1176
1328
self .left = 100
1177
1329
self .top = 100
1330
+ self .settings = QSettings ("UST" , "dosview" )
1178
1331
self .title = 'dosview'
1179
1332
self .width = 640
1180
1333
self .height = 400
@@ -1251,6 +1404,9 @@ def initUI(self):
1251
1404
self .setGeometry (self .left , self .top , self .width , self .height )
1252
1405
self .setWindowIcon (QIcon ('media/icon_ust.png' ))
1253
1406
1407
+ self .restoreGeometry (self .settings .value ("geometry" , self .saveGeometry ()))
1408
+ self .restoreState (self .settings .value ("windowState" , self .saveState ()))
1409
+
1254
1410
self .tab_widget = QTabWidget ()
1255
1411
1256
1412
self .tab_widget .setCurrentIndex (0 )
@@ -1267,6 +1423,11 @@ def initUI(self):
1267
1423
1268
1424
1269
1425
tools = bar .addMenu ("&Tools" )
1426
+
1427
+ preferences = QAction ("Preferences" , self )
1428
+ preferences .triggered .connect (lambda : PreferencesVindow ().exec ())
1429
+ tools .addAction (preferences )
1430
+
1270
1431
tool_airdosctrl = QAction ("AirdosControl" , self )
1271
1432
tool_airdosctrl .triggered .connect (self .action_switch_airdoscontrol )
1272
1433
tools .addAction (tool_airdosctrl )
@@ -1324,6 +1485,12 @@ def open_new_file(self, flag):
1324
1485
self .openPlotTab (fn [0 ])
1325
1486
1326
1487
dlg .deleteLater ()
1488
+
1489
+ def closeEvent (self , event ):
1490
+ print ("Closing dosview..." )
1491
+ self .settings .setValue ("geometry" , self .saveGeometry ())
1492
+ self .settings .setValue ("windowState" , self .saveState ())
1493
+ event .accept ()
1327
1494
1328
1495
1329
1496
def main ():
0 commit comments