diff --git a/lib/disk.py b/lib/disk.py index e01aa9b8494dcdffcc72f346d036462dfdb71d7a..63c6032194912bce67a58449c0e3a77d87068a93 100644 --- a/lib/disk.py +++ b/lib/disk.py @@ -1,6 +1,7 @@ # -*- encoding: utf-8 -*- import os +import re class Disk(object): @@ -48,3 +49,90 @@ class Disk(object): num /= 1024.0 return "%.1f %s%s" % (num, "Yi", suffix) + + @staticmethod + def create_capture_folder(path, samp_rate, freq, tag): + """ + Create capture folder with spezific name scheme. + """ + if not Disk.path_writeble(path): + return None + else: + su_folders = Disk.get_su_created_folders(path) + last_id = Disk.last_used_id(su_folders) + new_id = Disk.create_new_su_id(last_id + 1) + + folder_string = new_id + "-" + \ + str(int(freq)) + "MHz-" + \ + str(int(samp_rate)) + "MHz-" + \ + tag.replace(" ", "_") + + new_folder_path = path + "/" + folder_string + new_folder_path = new_folder_path.replace("//", "/") + os.mkdir(new_folder_path) + + return new_folder_path + + @staticmethod + def get_su_created_folders(path): + """ + Return all su folders in given path. + """ + folders = [] + for folder in os.listdir(path): + folder_path = path + "/" + folder + folder_path = folder_path.replace("//", "/") + if os.path.isdir(folder_path): + folders.append(folder_path) + + su_folders = [] + for full_folder_path in folders: + last_folder = os.path.basename(os.path.normpath(full_folder_path)) + if Disk.is_su_folder(last_folder): + su_folders.append(full_folder_path) + + return su_folders + + @staticmethod + def is_su_folder(folder_name): + """ + Check given folder for matching su folder structure. + """ + if re.search(r"^\d{5}-\d+.*", folder_name): + return True + else: + return False + + @staticmethod + def last_used_id(folders): + """ + Return last used su id in given folder. + """ + highest_id = 0 + for folder in folders: + last_folder = os.path.basename(os.path.normpath(folder)) + match = re.search(r"^\d{5}", last_folder) + if match: + new_id = int(match.group()) + if new_id > highest_id: + highest_id = new_id + + return highest_id + + @staticmethod + def create_folder(path): + """ + Create + """ + if not os.path.exists(path): + os.makedirs(path) + + @staticmethod + def create_new_su_id(new_id): + """ + Create new su path id. + """ + max_length = 5 + id_length = len(str(new_id)) + + return ("0"*(max_length-id_length)) + str(new_id) diff --git a/lib/gr/file_sink.py b/lib/gr/file_sink.py index bf78fcbf6bd834b2035a292f843348fda44af2a2..0d6729d686e0b5a208d3e6f5df14aaf69a18f862 100644 --- a/lib/gr/file_sink.py +++ b/lib/gr/file_sink.py @@ -46,6 +46,7 @@ class FileSink(gr.top_block): Capture alias """ # self.capture() + print("capture started") def capture(self): """ @@ -57,7 +58,6 @@ class FileSink(gr.top_block): self.wait() logging.info("Capture '%s' done." % self.file_path) - def get_samp_rate(self): return self.samp_rate @@ -99,4 +99,4 @@ class FileSink(gr.top_block): # Connections ################################################## self.connect((self.blocks_head_0, 0), (self.blocks_file_sink_0, 0)) - self.connect((self.osmosdr_source_0, 0), (self.blocks_head_0, 0)) \ No newline at end of file + self.connect((self.osmosdr_source_0, 0), (self.blocks_head_0, 0)) diff --git a/lib/gui/gui.py b/lib/gui/gui.py index 78cae967bf49d03e09d9c04779e6a28ea1de18c7..caa4526d3d3c48de2042ddf30216417583b44612 100644 --- a/lib/gui/gui.py +++ b/lib/gui/gui.py @@ -37,10 +37,12 @@ class SuGui(QtWidgets.QMainWindow): self.lineEdit_dump_file.setCursorPosition(0) self.refresh_hw_button() self.button_stop.setEnabled(False) + self.button_results.setEnabled(False) # button events self.button_start.clicked.connect(self.start_button) self.button_stop.clicked.connect(self.stop_button) self.button_close.clicked.connect(self.close_button) + self.button_results.clicked.connect(self.results_button) self.button_nf_detect.clicked.connect(self.nf_button) self.button_hw_refresh.clicked.connect(self.refresh_hw_button) self.comboBox_env.currentIndexChanged.connect(self.configure_env) @@ -57,9 +59,9 @@ class SuGui(QtWidgets.QMainWindow): # radio buttons self.radio_buttons_samp_rate_and_time = { # samp_rate - self.rb_1mhz: 1e6, - self.rb_2mhz: 2e6, - self.rb_3mhz: 3e6, + self.rb_1mhz: 1.4e6, + self.rb_2mhz: 2.4e6, + self.rb_3mhz: 3.2e6, # time to measure in seconds self.rb_1m: 60, self.rb_5m: 300, @@ -93,10 +95,17 @@ class SuGui(QtWidgets.QMainWindow): if self._check_dependencies_before_start_capture(): options = self._extract_options() print(options) + capture_path = Disk.create_capture_folder( + options['dump_file_path'], + options['samp_rate'], + options['freq'], + options['tag'] + ) + print(capture_path) file_sink = FileSink(options['samp_rate'], options['freq'], options['capture_time'], - options['dump_file_path']) + capture_path + "/data.iq") self.button_stop.setEnabled(True) self.button_start.setEnabled(False) @@ -159,6 +168,9 @@ class SuGui(QtWidgets.QMainWindow): logging.info("Close application") QtCore.QCoreApplication.instance().quit() + def results_button(self): + pass + def refresh_hw_button(self): """ Refresh combo box with current connected hardware. @@ -225,6 +237,14 @@ class SuGui(QtWidgets.QMainWindow): else: self.label_disk_space.setStyleSheet('color: black') + # check if captures already exists + if len(Disk.get_su_created_folders( + self.lineEdit_dump_file.text() + )) > 0: + self.button_results.setEnabled(True) + else: + self.button_results.setEnabled(False) + def check_nf(self): """ @@ -259,7 +279,7 @@ class SuGui(QtWidgets.QMainWindow): def _check_samp_rate(self): if self.rb_868.isChecked(): - self.rb_1mhz.setEnabled(False) + self.rb_1mhz.setEnabled(True) if self.rb_1mhz.isChecked(): self.rb_1mhz.setChecked(False) @@ -306,12 +326,9 @@ class SuGui(QtWidgets.QMainWindow): dump_file with current timestamp located in the home of current user. Example: - /home/user/su/dump_file-1942_05_23-13_37_23.iq + /home/user/su/00001-868e6-2e6-dump_file/data.iq """ - dt = datetime.datetime.now().strftime("%Y_%m_%d-%H_%M_%S") - path = os.path.expanduser("~") + "/su/dump_file-" + dt + ".iq" - - return path + return os.path.expanduser("~") + "/su/" def _extract_selected_hardware_device(self): """ @@ -410,8 +427,6 @@ class SuGui(QtWidgets.QMainWindow): def _extract_options(self): """ Extract selected options from gui. - - Buttons """ freq_button = self._get_checked_freq_button() time_and_samp_rate_buttons = \ @@ -429,5 +444,6 @@ class SuGui(QtWidgets.QMainWindow): options['dump_file_path'] = self.lineEdit_dump_file.text() # dropdown boxes options['device'] = self._extract_selected_hardware_device() + options['tag'] = self.lineEdit_tag.text() return options diff --git a/lib/gui/su_mainwindow.ui b/lib/gui/su_mainwindow.ui index 91174614e348c0561c5e6f2cbb346e87c1fa26be..735dccfd55ada2ac3a14b97e9fc959f360be73bf 100644 --- a/lib/gui/su_mainwindow.ui +++ b/lib/gui/su_mainwindow.ui @@ -6,7 +6,7 @@ <rect> <x>0</x> <y>0</y> - <width>563</width> + <width>721</width> <height>348</height> </rect> </property> @@ -17,8 +17,8 @@ <widget class="QPushButton" name="button_start"> <property name="geometry"> <rect> - <x>410</x> - <y>30</y> + <x>570</x> + <y>10</y> <width>141</width> <height>31</height> </rect> @@ -168,8 +168,8 @@ <widget class="QPushButton" name="button_stop"> <property name="geometry"> <rect> - <x>410</x> - <y>70</y> + <x>570</x> + <y>50</y> <width>141</width> <height>31</height> </rect> @@ -200,7 +200,7 @@ </rect> </property> <property name="text"> - <string extracomment="1e6">1 MHz</string> + <string extracomment="1e6">1.7 MHz</string> </property> </widget> <widget class="QRadioButton" name="rb_3mhz"> @@ -213,7 +213,7 @@ </rect> </property> <property name="text"> - <string extracomment="3e6">3 MHz</string> + <string extracomment="3e6">3.2 MHz</string> </property> </widget> <widget class="QRadioButton" name="rb_2mhz"> @@ -226,7 +226,7 @@ </rect> </property> <property name="text"> - <string extracomment="2e6">2 MHz</string> + <string extracomment="2e6">2.4 MHz</string> </property> <property name="checked"> <bool>true</bool> @@ -243,7 +243,7 @@ </rect> </property> <property name="title"> - <string>I/Q dump path</string> + <string>Capture folder path</string> </property> <widget class="QLineEdit" name="lineEdit_dump_file"> <property name="geometry"> @@ -288,8 +288,8 @@ <widget class="QPushButton" name="button_close"> <property name="geometry"> <rect> - <x>410</x> - <y>280</y> + <x>570</x> + <y>290</y> <width>141</width> <height>31</height> </rect> @@ -302,9 +302,9 @@ <property name="geometry"> <rect> <x>410</x> - <y>110</y> + <y>100</y> <width>141</width> - <height>171</height> + <height>211</height> </rect> </property> <property name="text"> @@ -362,7 +362,7 @@ <rect> <x>150</x> <y>10</y> - <width>201</width> + <width>241</width> <height>61</height> </rect> </property> @@ -374,7 +374,7 @@ <rect> <x>10</x> <y>30</y> - <width>181</width> + <width>221</width> <height>22</height> </rect> </property> @@ -383,8 +383,8 @@ <widget class="QProgressBar" name="progressBar"> <property name="geometry"> <rect> - <x>410</x> - <y>2</y> + <x>570</x> + <y>130</y> <width>141</width> <height>21</height> </rect> @@ -429,13 +429,52 @@ </property> </widget> </widget> + <widget class="QGroupBox" name="box_tag"> + <property name="geometry"> + <rect> + <x>410</x> + <y>10</y> + <width>141</width> + <height>61</height> + </rect> + </property> + <property name="title"> + <string>Tag</string> + </property> + <widget class="QLineEdit" name="lineEdit_tag"> + <property name="geometry"> + <rect> + <x>10</x> + <y>30</y> + <width>121</width> + <height>22</height> + </rect> + </property> + <property name="text"> + <string>capture 1</string> + </property> + </widget> + </widget> + <widget class="QPushButton" name="button_results"> + <property name="geometry"> + <rect> + <x>570</x> + <y>90</y> + <width>141</width> + <height>31</height> + </rect> + </property> + <property name="text"> + <string>Results</string> + </property> + </widget> </widget> <widget class="QMenuBar" name="menubar"> <property name="geometry"> <rect> <x>0</x> <y>0</y> - <width>563</width> + <width>721</width> <height>19</height> </rect> </property> diff --git a/tests/lib/test_disk.py b/tests/lib/test_disk.py index 9dbfa9b3a599aa08af35d1e3afa140dce4ad1784..e693cd79457f532705f4a688006f51435067de2b 100644 --- a/tests/lib/test_disk.py +++ b/tests/lib/test_disk.py @@ -1,7 +1,9 @@ # -*- encoding: utf-8 -*- import pytest -from os.path import expanduser +import os + +from os.path import expanduser, exists from lib.disk import Disk @@ -17,3 +19,37 @@ class TestDisk: def test_sizeof_fmt(self): assert Disk.sizeof_fmt(2691532) == "2.6 MiB" + + def test_get_su_created_folders(self): + zero_su_folders = len(Disk.get_su_created_folders("/etc")) + one_folder = len(Disk.get_su_created_folders("/home/meise/tmp")) + assert zero_su_folders == 0 + assert one_folder == 1 + + def test_is_su_folder(self): + assert Disk.is_su_folder("00001-868e6-2e6-1m-home_matic") == True + assert Disk.is_su_folder("foobar") == False + + def test_last_used_id(self): + folders = ["00001-868", "00002-433", "00009-868-2e6-1m-home_matic"] + assert Disk.last_used_id(folders) == 9 + + def test_create_folder(self): + path = r"/tmp/su_test_folder" + Disk.create_folder(path) + exists = os.path.exists(path) + + assert exists == True + + if exists: + os.rmdir(path) + + def test_create_new_su_id(self): + assert Disk.create_new_su_id(9) == "00009" + assert Disk.create_new_su_id(1337) == "01337" + + def test_create_capture_folder(self): + new_path = Disk.create_capture_folder("/home/meise/tmp/", "2.4e6", + "868e6", "HomeMatic test 1") + + assert new_path == "/home/meise/tmp/00002-868e6-2.4e6-HomeMatic_test_1"