Skip to content
Snippets Groups Projects
Commit 550a40fd authored by Daniel Meißner's avatar Daniel Meißner Committed by Daniel Meißner
Browse files

gui: added connected rf hardware detection logic and gui widget

parent 8a59c858
No related branches found
No related tags found
No related merge requests found
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" viewBox="0 0 100 100" enable-background="new 0 0 100 100" xml:space="preserve"><g display="none"><polygon display="inline" points="85.982,15.043 14.018,15.043 41.006,42.031 41.006,84.957 58.996,72.963 58.996,42.031 "></polygon></g><g display="none"><path display="inline" d="M76.592,85.935l-11.32-17.052l7.006-6.496V15.922c0-1.024-0.832-1.856-1.859-1.856H29.314 c-1.027,0-1.861,0.832-1.861,1.856v46.465l7.17,6.644L23.408,85.935h6.404l8.775-13.227l0.07,0.064h22.414l0.238-0.221 l8.875,13.383H76.592z M62.004,64.233c-2.355,0-4.266-1.907-4.266-4.27c0-2.356,1.91-4.266,4.266-4.266 c2.357,0,4.27,1.909,4.27,4.266C66.273,62.326,64.361,64.233,62.004,64.233z M43.463,17.634h12.805v4.406H43.463V17.634z M33.859,26.169h32.012V45.38H33.859V26.169z M38.525,64.233c-2.357,0-4.268-1.907-4.268-4.27c0-2.356,1.91-4.266,4.268-4.266 c2.359,0,4.271,1.909,4.271,4.266C42.797,62.326,40.885,64.233,38.525,64.233z"></path></g><g><path d="M77.845,26.948c-6.625-7.896-16.55-12.932-27.689-12.932c-19.975,0-36.138,16.107-36.138,35.984h14.395 c0-11.961,9.765-21.691,21.786-21.691c7.191,0,13.567,3.501,17.538,8.867l-8.464,8.088l26.71-0.012V18.667L77.845,26.948z"></path><path d="M49.799,71.687c-7.193,0-13.565-3.5-17.539-8.867l8.464-8.086l-26.706,0.012V81.33l8.134-8.281 c6.625,7.896,16.551,12.935,27.69,12.935c19.978,0,36.141-16.11,36.141-35.986H71.584C71.584,61.956,61.819,71.687,49.799,71.687z"></path></g><g display="none"><polygon display="inline" points="32.01,14.02 67.99,50.002 32.01,85.98 "></polygon></g></svg>
\ No newline at end of file
......@@ -3,26 +3,75 @@
import sys
import os
import logging
import datetime
from PyQt5 import QtCore, QtGui, QtWidgets, uic
class SuGui(QtWidgets.QMainWindow):
import lib.hardware as hardware
class SuGui(QtWidgets.QMainWindow):
"""
GUI class used to realise the main window.
"""
def __init__(self):
"""
Instantiate GUI class and open window.
GUI elements are directly loaded and converted from UI file.
"""
super(SuGui, self).__init__()
uic.loadUi('lib/gui/su_mainwindow.ui', self)
uic.loadUi("lib/gui/su_mainwindow.ui", self)
self.show()
# setting some defaults
self.lineEdit_dump_file.setText(self._get_default_dump_file_path())
self.lineEdit_dump_file.setCursorPosition(0)
self.refresh_hw_button()
# button events
self.button_start.clicked.connect(self.buttonStart)
self.button_stop.clicked.connect(self.buttonStop)
self.button_close.clicked.connect(self.buttonClose)
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_hw_refresh.clicked.connect(self.refresh_hw_button)
def buttonStart(self):
pass
def start_button(self):
"""
Start button action in main window.
"""
if len(self.lineEdit_dump_file.text()) == 0:
QtWidgets.QMessageBox.about(self, "Dumpfile path missing…", \
"Please insert dump file path. ")
else:
pass
def buttonStop(self):
def stop_button(self):
"""
Stop button action in main window.
"""
pass
def buttonClose(self):
def close_button(self):
"""
Close button action in main window.
"""
logging.info("Close application")
QtCore.QCoreApplication.instance().quit()
def refresh_hw_button(self):
"""
Refresh combo box with current connected hardware.
"""
self.comboBox_hardware.clear()
for device in hardware.Hardware().get_connected_supported_devices():
text = device['id'] + ": " + device['name']
self.comboBox_hardware.insertItem(0, self.tr(text))
def _get_default_dump_file_path(self):
"""
Generate path for dump file. The default file path is defined as
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
"""
dt = datetime.datetime.now().strftime("%Y_%m_%d-%H_%M_%S")
path = os.path.expanduser("~") + "/su/dump_file-" + dt + ".iq"
return path
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SuMainWindow</class>
<widget class="QMainWindow" name="SuMainWindow">
<class>SU::MainWindow</class>
<widget class="QMainWindow" name="SU::MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>572</width>
<height>363</height>
<width>563</width>
<height>317</height>
</rect>
</property>
<property name="windowTitle">
......@@ -18,7 +18,7 @@
<property name="geometry">
<rect>
<x>410</x>
<y>80</y>
<y>30</y>
<width>141</width>
<height>31</height>
</rect>
......@@ -31,7 +31,7 @@
<property name="geometry">
<rect>
<x>10</x>
<y>20</y>
<y>10</y>
<width>101</width>
<height>61</height>
</rect>
......@@ -49,7 +49,7 @@
</rect>
</property>
<property name="text">
<string>433 MHz</string>
<string extracomment="433e6">433 MHz</string>
</property>
</widget>
<widget class="QRadioButton" name="rb_868">
......@@ -62,7 +62,7 @@
</rect>
</property>
<property name="text">
<string>868 MHz</string>
<string extracomment="868e6">868 MHz</string>
</property>
<property name="checked">
<bool>true</bool>
......@@ -73,9 +73,9 @@
<property name="geometry">
<rect>
<x>10</x>
<y>190</y>
<y>170</y>
<width>120</width>
<height>131</height>
<height>121</height>
</rect>
</property>
<property name="title">
......@@ -91,7 +91,7 @@
</rect>
</property>
<property name="text">
<string>1 min</string>
<string extracomment="60">1 min</string>
</property>
</widget>
<widget class="QRadioButton" name="rb_5m">
......@@ -104,7 +104,7 @@
</rect>
</property>
<property name="text">
<string>5 min</string>
<string extracomment="300">5 min</string>
</property>
</widget>
<widget class="QRadioButton" name="rb_10m">
......@@ -117,7 +117,10 @@
</rect>
</property>
<property name="text">
<string>10 min</string>
<string extracomment="600">10 min</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
<widget class="QRadioButton" name="rb_1h_2">
......@@ -130,11 +133,14 @@
</rect>
</property>
<property name="text">
<string>1h</string>
<string extracomment="36000">1h</string>
</property>
<property name="checked">
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
<widget class="QRadioButton" name="rb_1h">
<property name="geometry">
......@@ -146,7 +152,7 @@
</rect>
</property>
<property name="text">
<string>24 h</string>
<string extracomment="864000">24 h</string>
</property>
</widget>
</widget>
......@@ -154,7 +160,7 @@
<property name="geometry">
<rect>
<x>410</x>
<y>40</y>
<y>70</y>
<width>141</width>
<height>31</height>
</rect>
......@@ -167,9 +173,9 @@
<property name="geometry">
<rect>
<x>10</x>
<y>90</y>
<y>80</y>
<width>101</width>
<height>91</height>
<height>81</height>
</rect>
</property>
<property name="title">
......@@ -185,7 +191,7 @@
</rect>
</property>
<property name="text">
<string>1 MHz</string>
<string extracomment="1e6">1 MHz</string>
</property>
</widget>
<widget class="QRadioButton" name="rb_3mhz">
......@@ -198,7 +204,7 @@
</rect>
</property>
<property name="text">
<string>3 MHz</string>
<string extracomment="3e6">3 MHz</string>
</property>
</widget>
<widget class="QRadioButton" name="rb_2mhz">
......@@ -211,7 +217,7 @@
</rect>
</property>
<property name="text">
<string>2 MHz</string>
<string extracomment="2e6">2 MHz</string>
</property>
<property name="checked">
<bool>true</bool>
......@@ -221,10 +227,10 @@
<widget class="QGroupBox" name="box_iq_dump_file">
<property name="geometry">
<rect>
<x>160</x>
<y>20</y>
<x>150</x>
<y>80</y>
<width>241</width>
<height>91</height>
<height>81</height>
</rect>
</property>
<property name="title">
......@@ -274,7 +280,7 @@
<property name="geometry">
<rect>
<x>410</x>
<y>280</y>
<y>260</y>
<width>141</width>
<height>31</height>
</rect>
......@@ -286,10 +292,10 @@
<widget class="QLabel" name="label_status">
<property name="geometry">
<rect>
<x>160</x>
<y>150</y>
<width>211</width>
<height>61</height>
<x>410</x>
<y>110</y>
<width>141</width>
<height>131</height>
</rect>
</property>
<property name="text">
......@@ -299,13 +305,76 @@
<enum>Qt::PlainText</enum>
</property>
</widget>
<widget class="QGroupBox" name="box_hardware">
<property name="geometry">
<rect>
<x>150</x>
<y>170</y>
<width>241</width>
<height>61</height>
</rect>
</property>
<property name="title">
<string>RF hardware</string>
</property>
<widget class="QComboBox" name="comboBox_hardware">
<property name="geometry">
<rect>
<x>10</x>
<y>30</y>
<width>181</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QPushButton" name="button_hw_refresh">
<property name="geometry">
<rect>
<x>200</x>
<y>30</y>
<width>31</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normaloff>../../icons/5652.svg</normaloff>../../icons/5652.svg</iconset>
</property>
</widget>
</widget>
<widget class="QGroupBox" name="box_env">
<property name="geometry">
<rect>
<x>150</x>
<y>10</y>
<width>201</width>
<height>61</height>
</rect>
</property>
<property name="title">
<string>Select environment</string>
</property>
<widget class="QComboBox" name="comboBox_env">
<property name="geometry">
<rect>
<x>10</x>
<y>30</y>
<width>181</width>
<height>22</height>
</rect>
</property>
</widget>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>572</width>
<width>563</width>
<height>19</height>
</rect>
</property>
......
# -*- encoding: utf-8 -*-
import re
import subprocess
import sys
import os
import logging
class Hardware(object):
"""
Inspect system for supported via USB connected devices.
Currently supportd devices:
* HackRF One
* LTR-SDR DVB-T stick
"""
SUPPORTED_HARDWARE = {
"hackrfone": "1d50:cc15",
"rtlsdr": "0bda:2838",
}
def get_usb_devices(self):
"""
Parse lsusb output and return a list of dictionaries.
"""
devices = []
lsusb_output = subprocess.check_output("lsusb", shell=True)
for line in lsusb_output.split("\n"):
if re.match("^Bus", line):
device = self._parse_lsusb_line(line)
devices.append(device)
else:
continue
return devices
def get_connected_supported_devices(self):
"""
Get all connected devices
"""
devices = self.get_usb_devices()
connected_devices = []
for device in devices:
if self._supported_device(self, device):
connected_devices.append(device)
else:
continue
return connected_devices
@staticmethod
def _parse_lsusb_line(line):
"""
Splitt lsusb line in useful key values.
"""
device = {}
device_unsorted = line.split(" ")
device['bus'] = device_unsorted[1]
device['device'] = device_unsorted[3]
device['id'] = device_unsorted[5]
device['name'] = " ".join(device_unsorted[6:])
return device
@staticmethod
def _supported_device(self, device):
"""
Check if a given device is supported.
"""
return device['id'] in self.SUPPORTED_HARDWARE.values()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment