예제 #1
0
 def __init__(self):
     super().__init__()
     self.myo = MyoManager(self.callback)
     self._auto = True
     self.average = []
     self.c = 0
     for type in EventType:
         self.handlers[type] = []
예제 #2
0
 def __init__(
         self):  # class init method; here i initialize a few variables
     super().__init__()
     self.myo = MyoManager(
         self.callback
     )  # instanciate the class MyoManager and register this class as the callback
     self._auto = True  # start with auto mode ON
     self.average = []
     self.c = 0
     for type in EventType:  # loop every possible EventType and initiliaze the dictionary handlers. In this dictionary every EventType is a key
         self.handlers[type] = []
예제 #3
0
    class __SingleTon(QObject):

        dim = 100
        myo = None
        handlers :dict = {}
        collecting = False

        @property
        def auto(self):
            return self._auto

        @auto.setter
        def auto(self, value):
            self.c = 0
            self.average = []
            self._auto = value

        def __init__(self):
            super().__init__()
            self.myo = MyoManager(self.callback)
            self._auto = True
            self.average = []
            self.c = 0
            for type in EventType:
                self.handlers[type] = []

        def startCollectingData(self):
            self.collecting = True
            self.myo.connect()
            #self.fps = PyQt5.QtCore.QTimer()


        def stopCollectingData(self):
            if self.collecting:
                self.collecting = False
                self.myo.disconnect()

        def callback(self, dict):  # TODO: probably a bottle neck since we are passing to this every event of myo (montgomery burns's illness >:D)
            if self._auto:
                diff = (time.clock() - dict["timestamp"]) * 100
                if diff < 4.5:
                    if len(self.average) <= self.dim:
                        self.average.append(diff)
                    else:
                        self.average[self.c] = diff
                        self.c = self.c + 1
                        if self.c == self.dim:
                            self.c = 0
                    ave = sum(self.average) / len(self.average)
                    self.myo.refresh_rate = max(int(300 * ave), 0)
            if self.collecting:
                for handler in self.handlers[dict["type"]]:
                    handler(dict)
            else:
                if dict["type"] != EventType.orientation and dict["type"] != EventType.emg:
                    for handler in self.handlers[dict["type"]]:
                        handler(dict)

        def add_event_handler(self, type, handler):
            if not handler in self.handlers[type]:
                self.handlers[type].append(handler)

        def remove_event_handler(self, type, handler):
            if handler in self.handlers[type]:
                self.handlers[type].remove(handler)

        def request_rssi(self):
            self.myo.rssi = True

        def request_battery(self):
            self.myo.battery = True

        def request_lock(self):
            self.myo.lock = True

        def request_unlock(self):
            self.myo.unlock = True

        def setRefreshRate(self, value):
            self.myo.refresh_rate = value

        def __str__(self):
            return repr(self) + "\n" + repr(self.handlers)
예제 #4
0
class KerasWindow(QMainWindow):
    def __init__(self, parent=None, keras_model=""):
        super(KerasWindow, self).__init__(parent)

        self.current_sum = 0
        self.emg = []
        self.myo = None
        self.check_timer = PTimer(self, self.check_sample)

        self.initUI()

        self.classificator = load_model(keras_model)

    def initUI(self):
        self.setWindowTitle("Classificator")

        self.setGeometry(240, 120, WIDTH, HEIGHT)
        self.setFixedSize(QSize(WIDTH, HEIGHT))

        device_group = QGroupBox(self)
        device_group.setGeometry(20, 10, 160, 190)
        device_group.setTitle("Device")
        device_group.setStyleSheet(ll_ss)

        act_group = QGroupBox(self)
        act_group.setGeometry(200, 10, 170, 190)
        act_group.setTitle("Actions")
        act_group.setStyleSheet(ll_ss)

        status_group = QGroupBox(self)
        status_group.setGeometry(390, 10, 150, 190)
        status_group.setTitle("Status")
        status_group.setStyleSheet(ll_ss)

        gesture_group = QGroupBox(self)
        gesture_group.setGeometry(20, 210, 520, 290)
        gesture_group.setTitle("Prediction")
        gesture_group.setStyleSheet(ll_ss)

        lbl = QLabel(act_group)
        lbl.setText("EMG(Hz):")
        lbl.move(18, 25)

        self.emg_freq = QSpinBox(act_group)
        self.emg_freq.setMinimum(1)
        self.emg_freq.setMaximum(200)
        self.emg_freq.setValue(200)
        self.emg_freq.move(act_group.width() - 65, 25)

        lbl = QLabel(act_group)
        lbl.setText("Time(ms):")
        lbl.move(18, 55)

        self.dur = QSpinBox(act_group)
        self.dur.setMinimum(1)
        self.dur.setSingleStep(10)
        self.dur.setMaximum(5000)
        self.dur.setValue(3000)
        self.dur.setGeometry(act_group.width() - 71, 55, 55, 25)

        self.startbtn = QPushButton(act_group)
        self.startbtn.setText("Start")
        self.startbtn.setGeometry(10, 85, 150, 25)
        self.startbtn.clicked.connect(self.start)
        self.startbtn.setEnabled(False)

        self.dev_name = QLabel(device_group)
        self.dev_name.setText("Name: <unknown>")
        self.dev_name.setMaximumWidth(device_group.width() - 30)
        self.dev_name.move(15, 25)

        self.dev_batt = QLabel(device_group)
        self.dev_batt.setText("Battery: <unknown>")
        self.dev_batt.setMaximumWidth(device_group.width() - 30)
        self.dev_batt.move(15, 55)

        dev_con = QLabel(device_group)
        dev_con.setText("Connected: ")
        dev_con.setMaximumWidth(device_group.width() - 30)
        dev_con.move(15, 85)

        self.dev_con_color = QFrame(device_group)
        self.dev_con_color.setStyleSheet(
            "background-color:red;border-radius:10px;")
        self.dev_con_color.setGeometry(device_group.width() - 15 - 20, 83, 20,
                                       20)

        self.conbtn = QPushButton(device_group)
        self.conbtn.setText("Connect")
        self.conbtn.setEnabled(True)
        self.conbtn.setGeometry(10, 110, device_group.width() - 20, 25)
        self.conbtn.clicked.connect(self.connection)

        self.discbtn = QPushButton(device_group)
        self.discbtn.setText("Disconnect")
        self.discbtn.setGeometry(10, 145, device_group.width() - 20, 25)
        self.discbtn.setEnabled(False)
        self.discbtn.clicked.connect(self.disconnection)

        reclbl = QLabel(status_group)
        reclbl.setText("Recording: ")
        reclbl.setMaximumWidth(status_group.width() - 30)
        reclbl.move(15, 25)

        self.rec_con_color = QFrame(status_group)
        self.rec_con_color.setStyleSheet(
            "background-color:red;border-radius:10px;")
        self.rec_con_color.setGeometry(status_group.width() - 15 - 20, 23, 20,
                                       20)

        self.rec_proglbl = QLabel(status_group)
        self.rec_proglbl.setText("Progress: 0%")
        self.rec_proglbl.setMaximumWidth(status_group.width() - 30)
        self.rec_proglbl.setGeometry(15, 55, status_group.width() - 30, 25)

        self.rec_prog = QProgressBar(status_group)
        self.rec_prog.setMaximum(100)
        self.rec_prog.setGeometry(15, 90, status_group.width() - 30, 10)

        x = 15
        y = 30
        self.prediction_bars = []
        for g in gestures_list:
            lbl = QLabel(gesture_group)
            lbl.setText(g + ":")
            lbl.setGeometry(x, y, 100, 25)

            progress = QProgressBar(gesture_group)
            progress.setMaximum(100)
            progress.setGeometry(100, y + 10, gesture_group.width() - 140, 10)

            self.prediction_bars.append(progress)

            y = y + 25

    def connection(self):
        if not self.myo:
            self.myo = MyoManager(sender=self)

        if not self.myo.connected:
            self.myo.connect()

    def disconnection(self):
        if self.myo:
            if self.myo.connected:
                self.myo.disconnect()

    def refresh_list(self):
        set = self.project["sets"][self.wheres.currentIndex()]
        gesture = self.project["gestures"][self.gestures.currentIndex()]
        self.list_data_for_set_and_gesture(set, gesture)

    def start(self):
        if self.startbtn.isEnabled():
            self.startbtn.setEnabled(False)
            self.start_sampling()

    def callback(self, dict):
        type = dict["type"]
        data = dict["data"]
        if type == EventType.connected:
            self.dev_con_color.setStyleSheet(
                "background-color:green;border-radius:10px;")
            self.dev_name.setText("Name: " + repr(data["name"]))
            self.dev_batt.setText("Battery: <unknown>")
            self.conbtn.setEnabled(False)
            self.discbtn.setEnabled(True)
            self.startbtn.setEnabled(True)
        elif type == EventType.battery_level:
            self.dev_batt.setText("Battery: " + str(data["battery"]) + "%")
        elif type == EventType.disconnected:
            self.dev_con_color.setStyleSheet(
                "background-color:red;border-radius:10px;")
            self.dev_name.setText("Name: <unknown>")
            self.dev_batt.setText("Battery: <unknown>")
            self.conbtn.setEnabled(True)
            self.discbtn.setEnabled(False)
            self.startbtn.setEnabled(False)

        self.repaint()

    def start_sampling(self):
        self.rec_con_color.setStyleSheet(
            "background-color:green;border-radius:10px;")

        self.rec_con_color.repaint()

        self.emg.clear()

        duration = self.dur.value() / 1000

        emg_timer = PTimer(self, self.sample_emg)
        emg_timer.setTickCount(int(duration * self.emg_freq.value()))
        emg_timer.start(1000 / self.emg_freq.value())

        self.check_timer.start(100)

    def check_sample(self):
        duration = self.dur.value() / 1000
        emg_ended = len(self.emg) == duration * self.emg_freq.value()
        if emg_ended:
            self.sample_ended()
            self.check_timer.stop()

    def sample_emg(self):
        self.emg.append(self.myo.listener.emg)
        perc = int(
            len(self.emg) * 100 /
            (self.dur.value() / 1000 * self.emg_freq.value()))
        self.rec_proglbl.setText("Progress: " + str(perc) + "%")
        self.rec_prog.setValue(perc)

    def add_log(self, str="", flag=False):
        pass

    def sample_ended(self):
        self.rec_con_color.setStyleSheet(
            "background-color:red;border-radius:10px;")

        self.rec_con_color.repaint()

        x = []
        for i in range(600):
            for p in range(8):
                x.append(self.emg[i][p])

        x = np.reshape(x, [1, 600, 8])

        prediction = self.classificator.predict(x)

        for i in range(10):
            self.prediction_bars[i].setValue(prediction[0, i] * 100)

        index = np.argmax(prediction)

        #self.add_log("Predicted: " + gestures_csv[index] + ' with ' + format(prediction[0, index] * 100, '.2f') + '%')
        #self.add_log("Full list: ")
        #dim = 20
        #for i in range(10):
        #    perc = prediction[0, i]
        #    self.add_log(gestures_csv[i] + ": " + " " * (max - len(gestures_csv[i])) + "*" * int(dim * perc), False)

        self.startbtn.setEnabled(True)

    def closeEvent(self, QCloseEvent):
        self.parent().show()
        self.disconnection()
예제 #5
0
    def connection(self):
        if not self.myo:
            self.myo = MyoManager(sender=self)

        if not self.myo.connected:
            self.myo.connect()
예제 #6
0
    class __SingleTon(QObject):

        dim = 100  # Dimension of the n° latest data to store in a vector.
        myo = None  # Variable to store the myo data type.
        handlers: dict = {
        }  # Here i wanted to use this class for everything so i created a dictionary to keep track of all the handlers that were registered.
        collecting = False  # Did we started yet?

        @property
        def auto(
            self
        ):  # The purpose of the 'auto' property is to have a way of limiting the refresh rate in order to mantain the application responding to user events
            return self._auto

        @auto.setter  # setter; here i initialize a few variables
        def auto(self, value):
            self.c = 0  # variable counter
            self.average = []  # array to store timestamps
            self._auto = value

        def __init__(
                self):  # class init method; here i initialize a few variables
            super().__init__()
            self.myo = MyoManager(
                self.callback
            )  # instanciate the class MyoManager and register this class as the callback
            self._auto = True  # start with auto mode ON
            self.average = []
            self.c = 0
            for type in EventType:  # loop every possible EventType and initiliaze the dictionary handlers. In this dictionary every EventType is a key
                self.handlers[type] = []

        def startCollectingData(self):  # Start collecting data
            self.collecting = True
            self.myo.connect(
            )  # connect to myo is stopped or not already started
            #self.fps = PyQt5.QtCore.QTimer()

        def stopCollectingData(self):  # Stop collecting data
            if self.collecting:
                self.collecting = False
                self.myo.disconnect()  # disconnect the armband

        def callback(
            self, dict
        ):  # TODO: probably a bottle neck since we are passing to this every event of myo (montgomery burns's illness >:D)
            if self._auto:  # if auto then try to limit refresh rate
                diff = (
                    time.clock() - dict["timestamp"]
                ) * 100  # calculate the difference between the current timestamp and the last one that we stored in last callback
                if diff < 4.5:  # 4.5 is an hard-coded value to avoid collecting 'spikes'
                    if len(
                            self.average
                    ) <= self.dim:  # NOTE: the vector 'average' here is used a circular vector
                        self.average.append(diff)
                    else:
                        self.average[self.c] = diff
                        self.c = self.c + 1
                        if self.c == self.dim:
                            self.c = 0
                    ave = sum(self.average) / len(
                        self.average)  # calculate the average response time
                    self.myo.refresh_rate = max(int(
                        300 * ave), 0)  # set the appropriate refresh rate
            if self.collecting:
                for handler in self.handlers[dict["type"]]:
                    handler(
                        dict
                    )  # if started inform every handlers that we have new data available
            else:
                if dict["type"] != EventType.orientation and dict[
                        "type"] != EventType.emg:
                    for handler in self.handlers[dict["type"]]:
                        handler(
                            dict
                        )  # send to handlers new data when we are not listening yet (like a disconnection)

        def add_event_handler(self, type, handler):  # method to add an handler
            if not handler in self.handlers[type]:
                self.handlers[type].append(handler)

        def remove_event_handler(self, type,
                                 handler):  # method to remove an handler
            if handler in self.handlers[type]:
                self.handlers[type].remove(handler)

        def request_rssi(self):
            self.myo.rssi = True

        def request_battery(self):
            self.myo.battery = True

        def request_lock(self):
            self.myo.lock = True

        def request_unlock(self):
            self.myo.unlock = True

        def setRefreshRate(self, value):
            self.myo.refresh_rate = value

        def __str__(self):
            return repr(self) + "\n" + repr(self.handlers)
예제 #7
0
class MainWindow(QMainWindow):

    def __init__(self, parent=None, data_set = ""):
        super(MainWindow, self).__init__(parent)

        self.current_sum = 0
        self.emg = []
        self.imu = []
        self.myo = None
        self.check_timer = PTimer(self, self.check_sample)

        self.read_data_set(data_set)

        self.initUI()

    def read_data_set(self, data_set):
        with open(data_set) as f:
            self.project = json.load(f)

    def initUI(self):
        self.setWindowTitle(self.project["name"])

        self.setGeometry(240, 120, WIDTH, HEIGHT)
        self.setFixedSize(QSize(WIDTH, HEIGHT))

        files_group = QGroupBox(self)
        files_group.setGeometry(20, 10, 590, 300)
        files_group.setTitle("Files")
        files_group.setStyleSheet(ll_ss)

        act_group = QGroupBox(self)
        act_group.setGeometry(630, 10, 170, 300)
        act_group.setTitle("Actions")
        act_group.setStyleSheet(ll_ss)

        log_group = QGroupBox(self)
        log_group.setGeometry(20, 320, 430, 190)
        log_group.setTitle("Log")
        log_group.setStyleSheet(ll_ss)

        device_group = QGroupBox(self)
        device_group.setGeometry(470, 320, 160, 190)
        device_group.setTitle("Device")
        device_group.setStyleSheet(ll_ss)

        status_group = QGroupBox(self)
        status_group.setGeometry(650, 320, 150, 190)
        status_group.setTitle("Status")
        status_group.setStyleSheet(ll_ss)

        self.wheres = QComboBox(act_group)
        self.gestures = QComboBox(act_group)

        self.wheres.setGeometry(10, 30, 150, 25)

        for w in self.project["sets"]:
            self.wheres.addItem(w)
        self.wheres.currentIndexChanged.connect(self.refresh_list)

        self.gestures.setGeometry(10, 70, 150, 25)

        for g in self.project["gestures"]:
            self.gestures.addItem(g)
        self.gestures.currentIndexChanged.connect(self.refresh_list)

        lbl = QLabel(act_group)
        lbl.setText("EMG(Hz):")
        lbl.move(18, 111)

        self.emg_freq = QSpinBox(act_group)
        self.emg_freq.setMinimum(1)
        self.emg_freq.setMaximum(200)
        self.emg_freq.setValue(self.project["emg_freq"])
        self.emg_freq.move(act_group.width() - 65, 110)

        lbl = QLabel(act_group)
        lbl.setText("IMU(Hz):")
        lbl.move(18, 146)

        self.imu_freq = QSpinBox(act_group)
        self.imu_freq.setMinimum(1)
        self.imu_freq.setMaximum(50)
        self.imu_freq.setValue(self.project["emg_freq"])
        self.imu_freq.setGeometry(act_group.width() - 65, 145, 49, 20)

        lbl = QLabel(act_group)
        lbl.setText("Time(ms):")
        lbl.move(18, 181)

        self.dur = QSpinBox(act_group)
        self.dur.setMinimum(1)
        self.dur.setSingleStep(10)
        self.dur.setMaximum(5000)
        self.dur.setValue(self.project["duration"])
        self.dur.setGeometry(act_group.width() - 71, 181, 55, 20)

        self.imu_check = QCheckBox(act_group)
        self.imu_check.setText("Include IMU")
        self.imu_check.setChecked(self.project["imu_check"] == 1)
        self.imu_check.move(16, 215)

        self.startbtn = QPushButton(act_group)
        self.startbtn.setText("Start")
        self.startbtn.setStyleSheet("QPushButton::disabled{background-color: rgb(245, 245, 245);color: rgb(140, 140, 140); border: none; border-radius:5px;} QPushButton::enabled{background-color: rgb(0, 99, 225);color: white; border: none; border-radius:5px;}")
        self.startbtn.setGeometry(15, 250, 140, 22)
        self.startbtn.clicked.connect(self.start)
        self.startbtn.setEnabled(False)

        self.log_txt = QPlainTextEdit(log_group)
        self.log_txt.setStyleSheet(ll_ss_txt)
        self.log_txt.setGeometry(15, 25, log_group.width() - 30, log_group.height() - 40)
        self.log_txt.textChanged.connect(self.scroll_log_view)
        self.log_txt.setReadOnly(True)
        self.add_log("Application Started")

        self.dev_name = QLabel(device_group)
        self.dev_name.setText("Name: <unknown>")
        self.dev_name.setMaximumWidth(device_group.width() - 30)
        self.dev_name.move(15, 25)

        self.dev_batt = QLabel(device_group)
        self.dev_batt.setText("Battery: <unknown>")
        self.dev_batt.setMaximumWidth(device_group.width() - 30)
        self.dev_batt.move(15, 55)

        dev_con = QLabel(device_group)
        dev_con.setText("Connected: ")
        dev_con.setMaximumWidth(device_group.width() - 30)
        dev_con.move(15, 85)

        self.dev_con_color = QFrame(device_group)
        self.dev_con_color.setStyleSheet("background-color:red;border-radius:10px;")
        self.dev_con_color.setGeometry(device_group.width() - 15 - 20, 83, 20, 20)

        self.conbtn = QPushButton(device_group)
        self.conbtn.setText("Connect")
        self.conbtn.setEnabled(True)
        self.conbtn.setGeometry(10, 110, device_group.width() - 20, 25)
        self.conbtn.clicked.connect(self.connection)

        self.discbtn = QPushButton(device_group)
        self.discbtn.setText("Disconnect")
        self.discbtn.setGeometry(10, 145, device_group.width() - 20, 25)
        self.discbtn.setEnabled(False)
        self.discbtn.clicked.connect(self.disconnection)

        reclbl = QLabel(status_group)
        reclbl.setText("Recording: ")
        reclbl.setMaximumWidth(status_group.width() - 30)
        reclbl.move(15, 25)

        self.rec_con_color = QFrame(status_group)
        self.rec_con_color.setStyleSheet("background-color:red;border-radius:10px;")
        self.rec_con_color.setGeometry(status_group.width() - 15 - 20, 23, 20, 20)

        self.rec_proglbl = QLabel(status_group)
        self.rec_proglbl.setText("Progress: 0%")
        self.rec_proglbl.setMaximumWidth(status_group.width() - 30)
        self.rec_proglbl.setGeometry(15, 55, status_group.width() - 30, 25)

        self.rec_prog = QProgressBar(status_group)
        self.rec_prog.setMaximum(100)
        self.rec_prog.setGeometry(15, 90, status_group.width() - 30, 10)

        self.fileslbl = QLabel(status_group)
        self.fileslbl.setText("Files: ")
        self.fileslbl.setMaximumWidth(status_group.width() - 30)
        self.fileslbl.setGeometry(15, 110, status_group.width() - 30, 25)

        self.listview = PListView(files_group, ll_ss_txt, self.project)
        self.listview.setGeometry(15, 25, files_group.width() - 30, files_group.height() - 40)
        self.listview.setSelectionMode(QAbstractItemView.ExtendedSelection)

        self.listview.doubleClicked.connect(self.view_data)
        self.listview.contextMenuShowed.connect(self.view_data)
        self.listview.contextMenuDifferenced.connect(self.show_diff_data)
        self.listview.contextMenuAveraged.connect(self.show_ave_data)
        self.listview.contextMenuShowedFinder.connect(self.show_finder)
        self.listview.contextMenuMoved.connect(self.move_data)
        self.listview.contextMenuDeleted.connect(self.delete_data)
        self.model = QStringListModel()
        self.listview.setModel(self.model)

        self.list_data_for_set_and_gesture(self.project["sets"][0], self.project["gestures"][0])

        self.add_log("Loading dataset...")
        total = 0
        for set in self.project["sets"]:
            for gesture in self.project["gestures"]:
                path = self.project["location"] + "/" + set + "/" + gesture
                sum = 0
                for f in os.listdir(path):
                    if not f.startswith("."):
                        sum = sum + 1
                total = total + sum
                self.add_log("Found " + str(sum) + " files at " + set + "/" + gesture, False)
        self.add_log("Found " + str(total) + " files")

    def connection(self):
        if not self.myo:
            self.myo = MyoManager(sender=self)

        if not self.myo.connected:
            self.myo.connect()

    def disconnection(self):
        if self.myo:
            if self.myo.connected:
                self.myo.disconnect()

    def view_data(self):
        for index in self.listview.selectedIndexes():
            path = self.project["location"] + "/" + self.project["sets"][self.wheres.currentIndex()] + "/" + self.project["gestures"][self.gestures.currentIndex()] + "/" + index.data() + ".json"
            w = ViewDataWindow(self, [path])
            w.show()

    def show_diff_data(self):
        paths = []
        for index in self.listview.selectedIndexes():
            paths.append(self.project["location"] + "/" + self.project["sets"][self.wheres.currentIndex()] + "/" + self.project["gestures"][self.gestures.currentIndex()] + "/" + index.data() + ".json")
        w = ViewDataWindow(self, paths, 'diff')
        w.show()

    def show_ave_data(self):
        paths = []
        for index in self.listview.selectedIndexes():
            paths.append(self.project["location"] + "/" + self.project["sets"][self.wheres.currentIndex()] + "/" + self.project["gestures"][self.gestures.currentIndex()] + "/" + index.data() + ".json")
        w = ViewDataWindow(self, paths, 'ave')
        w.show()

    def show_finder(self):
        args = ["open", "-R"]
        for index in self.listview.selectedIndexes():
            args.append(self.project["location"] + "/" + self.project["sets"][self.wheres.currentIndex()] + "/" + self.project["gestures"][self.gestures.currentIndex()] + "/" + index.data() + ".json")
        call(args)

    def move_data(self, action:QAction):
        tmp = {}
        for index in self.listview.selectedIndexes():
            tmp[str(index.row())] = index.data()

        for row, data in sorted(tmp.items(), reverse=True):
            self.current_sum = self.current_sum - 1
            where = action.parent().title()
            gesture = action.text()
            src = self.project["location"] + "/" + self.project["sets"][self.wheres.currentIndex()] + "/" + self.project["gestures"][self.gestures.currentIndex()] + "/" + data + ".json"
            dest = self.project["location"] + "/" + where + "/" + gesture + "/" + data + ".json"
            shutil.copy(src, dest)
            os.remove(src)
            self.model.removeRow(int(row))
            
        self.fileslbl.setText("Files: " + str(self.current_sum))

    def delete_data(self):
        result = QMessageBox.question(
            self, 'Yes', 'Are you sure you want to delete this file',
            QMessageBox.Yes | QMessageBox.No, defaultButton=QMessageBox.Yes)
        if result == QMessageBox.Yes:
            tmp = {}
            for index in self.listview.selectedIndexes():
                tmp[str(index.row())] = index.data()

            for row, data in sorted(tmp.items(), reverse=True):
                self.current_sum = self.current_sum - 1
                path = self.project["location"] + "/" + self.project["sets"][self.wheres.currentIndex()] + "/" + self.project["gestures"][self.gestures.currentIndex()] + "/" + data + ".json"
                os.remove(path)
                self.model.removeRow(int(row))

            self.fileslbl.setText("Files: " + str(self.current_sum))

    def scroll_log_view(self):
        self.log_txt.verticalScrollBar().setValue(self.log_txt.document().size().height())

    def list_data_for_set_and_gesture(self, set, gesture):
        self.model.setStringList({})
        path = self.project["location"] + "/" + set + "/" + gesture
        os.chdir(path)
        files = filter(os.path.isfile, os.listdir(path))
        files = [os.path.join(path, f) for f in files]  # add path to each file
        files.sort(key=lambda x: os.path.getmtime(x))
        self.current_sum = 0
        for file in files:
            f = os.path.basename(file).replace(".json", "")
            if f.startswith("."):
                continue
            self.current_sum = self.current_sum + 1
            self.model.insertRow(self.model.rowCount())
            index = self.model.index(self.model.rowCount() - 1)
            self.model.setData(index, f)

        self.fileslbl.setText("Files: " + str(self.current_sum))

    def add_log(self, str, date = True):
        if date:
            #self.log_txt.insertHtml("<p>[" + datetime.datetime.now().strftime("%H:%M:%S") + "]: " + str + "<br></p>")
            self.log_txt.appendPlainText("[" + datetime.datetime.now().strftime("%H:%M:%S") + "]: " + str)
        else:
            #self.log_txt.insertHtml("<p>" + str + "<br></p>")
            self.log_txt.appendPlainText(str)
        #self.log_txt.repaint()

    def refresh_list(self):
        set = self.project["sets"][self.wheres.currentIndex()]
        gesture = self.project["gestures"][self.gestures.currentIndex()]
        self.list_data_for_set_and_gesture(set, gesture)

    def start(self):
        if self.startbtn.isEnabled():
            self.listview.clearFocus()
            # index = QModelIndex()
            # self.listview.setCurrentIndex(index)
            self.startbtn.setEnabled(False)
            self.start_sampling()

    def callback(self, dict):
        type = dict["type"]
        data = dict["data"]
        if type == EventType.connected:
            self.dev_con_color.setStyleSheet("background-color:green;border-radius:10px;")
            self.dev_name.setText("Name: " + repr(data["name"]))
            self.dev_batt.setText("Battery: <unknown>")
            self.conbtn.setEnabled(False)
            self.discbtn.setEnabled(True)
            self.startbtn.setEnabled(True)
        elif type == EventType.battery_level:
            self.dev_batt.setText("Battery: " + str(data["battery"]) + "%")
        elif type == EventType.disconnected:
            self.dev_con_color.setStyleSheet("background-color:red;border-radius:10px;")
            self.dev_name.setText("Name: <unknown>")
            self.dev_batt.setText("Battery: <unknown>")
            self.conbtn.setEnabled(True)
            self.discbtn.setEnabled(False)
            self.startbtn.setEnabled(False)

        self.repaint()

    def start_sampling(self):
        self.add_log("Started sampling data")
        self.rec_con_color.setStyleSheet("background-color:green;border-radius:10px;")

        self.rec_con_color.repaint()

        self.emg.clear()
        self.imu.clear()

        duration = self.dur.value() / 1000

        emg_timer = PTimer(self, self.sample_emg)
        emg_timer.setTickCount(int(duration * self.emg_freq.value()))
        emg_timer.start(1000 / self.emg_freq.value())


        if self.imu_check.isChecked():
            imu_timer = PTimer(self, self.sample_imu)
            imu_timer.setTickCount(int(duration * self.imu_freq.value()))
            imu_timer.start(1000 / self.imu_freq.value())

        self.check_timer.start(100)

    def check_sample(self):
        duration = self.dur.value() / 1000
        emg_ended = len(self.emg) == duration * self.emg_freq.value()
        imu_ended = (len(self.imu) == duration * self.imu_freq.value())
        if emg_ended and (not self.imu_check.isChecked() or (self.imu_check.isChecked() and imu_ended)):
            self.sample_ended()
            self.check_timer.stop()

    def sample_emg(self):
        self.emg.append(self.myo.listener.emg)
        perc = int(len(self.emg) * 100 / (self.dur.value() / 1000 * self.emg_freq.value()))
        self.rec_proglbl.setText("Progress: " + str(perc) + "%")
        self.rec_prog.setValue(perc)

    def sample_imu(self):
        self.imu.append(self.myo.listener.data)

    def sample_ended(self):
        self.rec_con_color.setStyleSheet("background-color:red;border-radius:10px;")

        self.rec_con_color.repaint()

        self.add_log("Sampled ended")
        self.add_log("Saving data")

        name = str(uuid.uuid4())
        path = self.project["location"] + "/" + self.project["sets"][self.wheres.currentIndex()] + "/" + self.project["gestures"][self.gestures.currentIndex()] + "/" + name + ".json"

        data = {
            "date" : datetime.datetime.now().strftime("%d/%m/%y/%H:%M:%S"),
            "duration" : self.dur.value(),
            "emg" : {
                "frequency" : self.emg_freq.value(),
                "data" : self.emg
            }
        }

        if self.imu_check.isChecked():
            data["imu"] = {
                "frequency": self.imu_freq.value(),
                "data": self.imu
            }

        with open(path, 'w') as outfile:
            json.dump(data, outfile)

        self.add_log("Data saved")

        self.model.insertRow(self.model.rowCount())
        index = self.model.index(self.model.rowCount() - 1)
        self.model.setData(index, name)

        self.startbtn.setEnabled(True)

        self.current_sum = self.current_sum + 1
        self.fileslbl.setText("Files: " + str(self.current_sum))

    def keyPressEvent(self, event):
        if event.key() == 16777216:
            self.disconnection()
        elif event.key() == 16777220:
            if not self.listview.hasFocus() or len(self.listview.selectedIndexes()) == 0:
                if self.myo:
                    if self.myo.connected:
                        self.start()

    def closeEvent(self, QCloseEvent):
        self.parent().show()
        self.disconnection()