"""Отображение данных"""

import sys
import os.path
import datetime
import time

import numpy as np

from PyQt5.QtCore import QIODevice
from PyQt5.QtSerialPort import QSerialPortInfo, QSerialPort

from PyQt5.QtGui import *
from PyQt5 import QtWidgets, uic, QtGui
from PyQt5.QtWidgets import QFileDialog
from PyQt5 import QtCore
from pyqtgraph import TextItem
import pyqtgraph as pg
import project.controller as my_data
from project import mes

# выбор режима чения из файла или из com-порта
MODE_COM_PORT = False
MODE_FILE = False

# объявили экземпляры класса, для обработки данных из файла или из com-порта
data_IN_FILE = my_data.DataClass()
data_IN_COM = my_data.DataClass()

# создание приложения
app = QtWidgets.QApplication(sys.argv)


class Ui(QtWidgets.QMainWindow):
    """Класс отображения данных"""

    def __init__(self):
        # создание графического отображения
        super(Ui, self).__init__()
        uic.loadUi('design_viewer_v1.ui', self)
        self.setWindowTitle("Pacemaker viewer")
        self.setWindowIcon(QtGui.QIcon("source/logo.ICO"))

        self.counter_com_port = []  # координата x для вывода графиков

        self.point = 0  # координата, откуда начинать отрисовку, если используется полоса прокрутки??
        self.file = ""  # файл
        self.file_name = ""  # наименование файла
        self.sub_mode_previous = -1  # предыдущее значение подрежима, для вывода времени зарядки конденсатора
        self.start_time_charging = 0 # начало подчета времени зарядки конденсатора
        self.end_time_charging = 0  # конец подчета времени зарядки конденсатора
        self.charging_time = 0  # время зарядки конденсатора
        self.U_cap_max = 0  # максимальное напряжение на конденсаторе

        # Создание графиков
        self.graph_init()

        def set_up_controls():
            """
            Настройка элементов управления в визуале
            """
            self.OpenB.setVisible(False)
            self.CloseB.setVisible(False)
            self.Play.setVisible(False)
            self.Pause.setVisible(False)
            self.horizontalScrollBar.setVisible(False)
            self.horizontalScrollBar.valueChanged.connect(self.on_scroll)
            self.radioButton_work_mode_com_port.toggled.connect(self.check_work_mode_viewer)
            self.Play.clicked.connect(self.on_play)
            self.Pause.clicked.connect(self.on_pause)
            self.OpenB.clicked.connect(self.on_open)
            self.CloseB.clicked.connect(self.on_close)
            self.Write_file.clicked.connect(self.write_file)
            self.Close_file.clicked.connect(self.close_file)
            self.Read.clicked.connect(self.on_start)
            self.Stop.clicked.connect(self.on_stop)
            self.Restart.clicked.connect(self.restart)
            self.SD_card_Box.currentTextChanged.connect(self.set_SD_card)
            self.Send_mode_Box.currentTextChanged.connect(self.set_send_mode)
            self.Port_ch.addItems(self.update_list())
            self.horizontalScrollBar.valueChanged.connect(self.on_scroll)
            self.RA_scale_BOX.currentTextChanged.connect(self.on_scale_change)
            self.f_count_spinBox.valueChanged.connect(self.set_fibr_cnt_max)
            self.t2_count_spinBox.valueChanged.connect(self.set_tachy_2_cnt_max)
            self.t1_count_spinBox.valueChanged.connect(self.set_tachy_1_cnt_max)

            self.RA_max_time_ms_BOX.editTextChanged.connect(self.set_RA_max_time_ms_BOX)
            self.RA_min_sensitivity_BOX.editTextChanged.connect(self.set_RA_min_sensitivity_BOX)
            self.RA_max_sensitivity_BOX.editTextChanged.connect(self.set_RA_max_sensitivity_BOX)
            self.RA_square_time_ms_BOX.editTextChanged.connect(self.set_RA_square_time_ms_BOX)
            self.RA_square_coeff_BOX.editTextChanged.connect(self.set_RA_square_coeff_BOX)
            self.RA_all_time_ms_BOX.editTextChanged.connect(self.set_RA_all_time_ms_BOX)
            self.Signal_Box.currentIndexChanged.connect(self.set_Signal_Box)
            self.Channel_Box.currentIndexChanged.connect(self.set_Channel_Box)
            self.DC_cut_Box.currentIndexChanged.connect(self.set_DC_cut_Box)
            self.HV_Box.currentIndexChanged.connect(self.set_HV_Box)
            self.LV_Box.currentIndexChanged.connect(self.set_LV_Box)
# fixed
            self.High_Tf_spinBox.valueChanged.connect(self.set_High_Tf_spinBox)
            self.High_Tt2_spinBox.valueChanged.connect(self.set_High_Tt2_spinBox)
            self.High_Tt1_spinBox.valueChanged.connect(self.set_High_Tt1_spinBox)
            self.f_count_spinBox.valueChanged.connect(self.set_f_count_spinBox)
            #
            self.Work_Mode_pacemaker.editTextChanged.connect(self.set_Work_Mode_pacemaker)
            self.hv_step_number_spinBox.valueChanged.connect(self.set_hv_step_number_spinBox)
            self.min_energy_spinBox.valueChanged.connect(self.set_min_energy_spinBox)
            self.max_energy_spinBox.valueChanged.connect(self.set_max_energy_spinBox)
            self.hv_polarity_BOX.editTextChanged.connect(self.set_hv_polarity_BOX)
            self.hv_blind_time_spinBox.valueChanged.connect(self.set_hv_blind_time_spinBox)
            self.standby_timer_spinBox.valueChanged.connect(self.set_standby_timer_spinBox)
            self.redet_num_spinBox.valueChanged.connect(self.set_redet_num_spinBox)
            self.redet_bad_spinBox.valueChanged.connect(self.set_redet_bad_spinBox)
            self.Spi_spot_set_spinBox.valueChanged.connect(self.set_Spi_spot_set_spinBox)
            self.hv_mode_BOX.editTextChanged.connect(self.set_hv_mode_BOX)
            self.t1_hv_phase_1_duration_SpinBox.valueChanged.connect(self.set_t1_hv_phase_1_duration_SpinBox)
            self.t2_hv_switch_duration_SpinBox.valueChanged.connect(self.set_t2_hv_switch_duration_SpinBox)
            self.t3_hv_phase_2_duration_SpinBox.valueChanged.connect(self.set_t3_hv_phase_2_duration_SpinBox)
            self.u1_hv_switching_voltage_spinBox.valueChanged.connect(self.set_u1_hv_switching_voltage_spinBox)
            self.u2_hv_cutoff_voltage_spinBox.valueChanged.connect(self.set_u2_hv_cutoff_voltage_spinBox)
            self.lv_polarity_BOX.editTextChanged.connect(self.set_lv_polarity_BOX)
            self.lv_mode_BOX.editTextChanged.connect(self.set_lv_mode_BOX)
            self.u_lv_voltage_SpinBox.valueChanged.connect(self.set_u_lv_voltage_SpinBox)
            self.t1_lv_shock_time_SpinBox.valueChanged.connect(self.set_t1_lv_shock_time_SpinBox)
            self.t2_lv_relax_time_spinBox.valueChanged.connect(self.set_t2_lv_relax_time_spinBox)
            self.burst_cnt_spinBox.valueChanged.connect(self.set_burst_cnt_spinBox)
            self.burst_voltage_SpinBox.valueChanged.connect(self.set_burst_voltage_SpinBox)
            self.burst_period_spinBox.valueChanged.connect(self.set_burst_period_spinBox)
            self.u1_hv_switching_voltage_l.setVisible(False)
            self.u2_hv_cutoff_voltage_l.setVisible(False)
            self.u1_hv_switching_voltage_spinBox.setVisible(False)
            self.u2_hv_cutoff_voltage_spinBox.setVisible(False)
            self.burst_frame.setVisible(False)

        set_up_controls()

        # создание соединения с устройством для передачи данных
        self.serial = QSerialPort()
        self.serial.setBaudRate(115200)
        self.serial.readyRead.connect(self.on_read)

        self.send_mode = 1

        # Создание таймера для отрисовки графиков
        self.timer = QtCore.QTimer()
        self.timer.timeout.connect(self.timerEvent)
        self.timer.start(20)

        # Создание таймера для отображения параметров стимулятора
        self.timer_LS = QtCore.QTimer()
        self.timer_LS.timeout.connect(self.timerEvent_param)
        self.timer_LS.start(2000)

    def write_file(self):
        """
        Открытие на запись файла
        """
        self.file, file_name = my_data.write_file()
        self.Write_file.setStyleSheet('background-color: green; color: white')
        self.Fname_w_label.setText(os.path.abspath(file_name))

    def close_file(self):
        """
        Закончить запись и закрыть файл
        """
        self.Fname_w_label.setText('')
        self.Write_file.setStyleSheet('background-color: grey; color: black')
        self.file = my_data.close_file(self.file)

    def restart(self):
        """
        Перезагрузка устройства
        """
        param = 1
        my_data.state_packet(self.send_mode, self.serial, 0x1D, param, 1, int)

    def timerEvent_param(self):
        """Запуск по таймеру, для синхронизации параметров стимулятора"""
        if MODE_COM_PORT:
            self.synchronise_param(data_IN_COM)
        if MODE_FILE:
            self.synchronise_param(data_IN_FILE)
        # отрисовка
        app.processEvents()

    def synchronise_param(self, data_in):
        """Синхронизация параметров стимулятора"""
        self.SD_card_Box.setCurrentIndex(int(data_in.sd_card))
        self.Signal_Box.setCurrentIndex(int(data_in.signal))
        self.Channel_Box.setCurrentIndex(int(data_in.channel))
        self.DC_cut_Box.setCurrentIndex(int(data_in.dc_cut))
        self.HV_Box.setCurrentIndex(int(data_in.hv))
        self.LV_Box.setCurrentIndex(int(data_in.lv))
        self.RA_max_time_ms_BOX.setEditText(str(data_in.max_search_time))
        self.RA_min_sensitivity_BOX.setEditText(str(data_in.min_treshold))
        self.RA_max_sensitivity_BOX.setEditText(str(data_in.max_treshold))
        self.RA_square_time_ms_BOX.setEditText(str(data_in.square_time))
        self.RA_square_coeff_BOX.setEditText(f'{data_in.square_coef: .2f}')
        self.RA_all_time_ms_BOX.setEditText(str(data_in.max_time))
        self.High_Tf_spinBox.setValue(data_in.fibr_tres)
        self.High_Tt2_spinBox.setValue(data_in.tachy_2_tres)
        self.High_Tt1_spinBox.setValue(data_in.tachy_1_tres)
        self.f_count_spinBox.setValue(data_in.fibr_max_tres)
        self.hv_step_number_spinBox.setValue(data_in.hv_step_number)
        self.min_energy_spinBox.setValue(data_in.min_energy)
        self.max_energy_spinBox.setValue(data_in.max_energy)
        self.hv_blind_time_spinBox.setValue(data_in.hv_blind_time)
        self.standby_timer_spinBox.setValue(data_in.standby_timer)
        self.redet_num_spinBox.setValue(data_in.redet_num)
        self.redet_bad_spinBox.setValue(data_in.redet_bad)
        self.Work_Mode_pacemaker.setCurrentIndex(data_in.Work_Mode_pacemaker)
        self.Spi_spot_set_spinBox.setValue(data_in.spi_pot_set)
        self.hv_polarity_BOX.setCurrentIndex(data_in.hv_polarity)#fixed
        self.hv_mode_BOX.setCurrentIndex(data_in.hv_mode)#fixed
        self.t1_hv_phase_1_duration_SpinBox.setValue(data_in.hv_phase_1_duration / 10.0)
        self.t3_hv_phase_2_duration_SpinBox.setValue(data_in.hv_phase_2_duration / 10.0)
        self.t2_hv_switch_duration_SpinBox.setValue(data_in.hv_switch_duration / 10.0)
        self.u1_hv_switching_voltage_spinBox.setValue(data_in.hv_switching_voltage)
        self.u2_hv_cutoff_voltage_spinBox.setValue(data_in.hv_cutoff_voltage)
        self.lv_polarity_BOX.setCurrentIndex(data_in.lv_polarity)
        self.lv_mode_BOX.setCurrentIndex(data_in.lv_mode)

        self.t1_lv_shock_time_SpinBox.setValue(data_in.lv_shock_time / 10.0)
        self.t2_lv_relax_time_spinBox.setValue(data_in.lv_relax_time)
        self.u_lv_voltage_SpinBox.setValue(data_in.lv_voltage / 10.0)

        self.burst_cnt_spinBox.setValue(data_in.burst_cnt)
        self.burst_voltage_SpinBox.setValue(data_in.burst_voltage / 10.0)
        self.burst_period_spinBox.setValue(data_in.burst_period) #fixed


    def timerEvent(self):
        if MODE_COM_PORT:
            self.draw_data(data_IN_COM)
        if MODE_FILE:
            scale = self.get_scale()
            points_count = scale * my_data.DATA_RATE
            if points_count < data_IN_FILE.data_length:
                data_IN_FILE.data_length = points_count
            self.horizontalScrollBar.setValue(data_IN_FILE.i)
            data_IN_FILE.parse_list(data_IN_FILE.chunk[data_IN_FILE.i:data_IN_FILE.i + 640])
            data_IN_FILE.i += 640
            self.graph_1.setXRange(self.counter_com_port[0], self.counter_com_port[0] + scale)
            self.graph_2.setXRange(self.counter_com_port[0], self.counter_com_port[0] + scale)
            self.graph_3.setXRange(self.counter_com_port[0], self.counter_com_port[0] + scale)
            self.draw_data(data_IN_FILE)

        # отрисовка
        app.processEvents()

    def on_start(self):
        """
        Старт обмена с com-портом
        """
        global MODE_COM_PORT
        data_IN_COM.clear_data()
        self.serial.setPortName(self.Port_ch.currentText())
        self.serial.open(QIODevice.ReadWrite)
        self.serial.flush()
        self.serial.write(mes.encode())
        self.on_close()
        MODE_COM_PORT = True
        self.graph_init()
        scale = self.get_scale()
        data_IN_COM.data_length = scale * my_data.DATA_RATE
        data_IN_COM.update_data(data_IN_COM.data_length)
        self.counter_com_port = list(map(lambda x: x / my_data.DATA_RATE, range(0, data_IN_COM.data_length)))

    def graph_init(self):
        """
        Создние графиков
        """
        # Создание графиков
        self.curve10 = self.graph_1.plot(pen=(0, 0, 255))
        self.curve20 = self.graph_2.plot(pen=(0, 0, 0))
        pen_din_tres = pg.mkPen(color=(255, 0, 0), width=1)
        self.curve21 = self.graph_2.plot(pen=pen_din_tres)
        pen_peak = None
        self.curve22 = self.graph_2.plot(pen=pen_peak)
        self.curve23 = self.graph_2.plot(pen=pen_peak)
        pen_min_tres = pg.mkPen(color=(0, 255, 0), width=2, style=QtCore.Qt.DashLine)
        pen_max_tres = pg.mkPen(color=(0, 0, 255), width=2, style=QtCore.Qt.DashLine)
        self.curve24 = self.graph_2.plot(pen=pen_min_tres)
        self.curve25 = self.graph_2.plot(pen=pen_max_tres)
        self.curve26 = self.graph_2.plot(pen=(0, 0, 0))
        self.curve30 = self.graph_3.plot(pen=(0, 0, 255))

        def edit_graph(graph):
            """
            Форматирование полей графиков
            :param graph: поле графика
            """
            graph.showGrid(x=True, y=True)
            graph.setBackground('w')
            # делаем поле графика нечувствительным к мышке
            graph.setMouseEnabled(x=False, y=False)
            graph.hideButtons()
            graph.getPlotItem().setMenuEnabled(False)
            graph.addLegend(enableMouse=False)

        edit_graph(self.graph_1)
        edit_graph(self.graph_2)
        edit_graph(self.graph_3)

    def graph_clear(self):
        """
        Очистка графиков
        """
        self.graph_1.clear()
        self.graph_2.clear()
        self.graph_3.clear()

    def on_read(self):
        """
        Чтение серии данных
        """
        rx = self.serial.readAll()
        if self.file != "":
            my_data.write_in_file(self.file, rx)
        data_IN_COM.parse_list(rx)

    def draw_data(self, data_in):
        """
        Отрисовка данных
        :param data_in: модель данных
        """
        self.curve10.setData(self.counter_com_port, data_in.ECG_RA)
        self.curve20.setData(self.counter_com_port, data_in.ECG_RA_pos_sig)
        self.curve21.setData(self.counter_com_port, data_in.ECG_RA_din_threshold)
        self.curve26.setData(self.counter_com_port, np.zeros(len(data_in.ECG_RA)))
        self.curve24.setData(self.counter_com_port, data_in.ECG_RA_min_threshold)
        self.curve25.setData(self.counter_com_port, data_in.ECG_RA_max_threshold)
        self.curve30.setData(self.counter_com_port, data_in.Last_RR_poz_rel)
        self.Vs_cnt_label.setText(str(data_in.Vs_cnt))
        self.Vp_cnt_label.setText(str(data_in.Vp_cnt))
        self.Vn_cnt_label.setText(str(data_in.Vn_cnt))
        self.U_batt_label.setText(str(float(data_in.bat_volt / 1000)))
        self.U_batt_p_label.setText(str(data_in.bat_pers))
        U_cap = float(data_in.hv_volt / 10)
        self.U_cap_label.setText(str(U_cap))
        if U_cap > self.U_cap_max:
            self.U_cap_max = U_cap
        self.Umax_cap_label.setText(str(self.U_cap_max))
        self.now_energy_label.setText(str(data_in.now_energy))
        self.filt_period_label.setText(str(data_in.filt_period))
        self.last_period_label.setText(str(data_in.last_period_stat))
        self.hv_step_cnt_label.setText(str(data_in.hv_step_cnt))

        self.progressBar_f.setValue(data_in.fibr_cnt)
        self.progressBar_t2.setValue(data_in.tachy_2_cnt)
        self.progressBar_t1.setValue(data_in.tachy_1_cnt)
        self.progressBar_n.setValue(data_in.norm_cnt)

        if data_in.terapy_now == 0:
            self.terapy_nowB.setStyleSheet('background-color: green; color: white')
            self.terapy_nowB.setText("Поиск корзин")
        if data_in.terapy_now == 1:
            self.terapy_nowB.setStyleSheet('background-color: red; color: white')
            self.terapy_nowB.setText("Терапия фибрилляции")

        if data_in.terapy_now == 2:
            self.terapy_nowB.setStyleSheet('background-color: yellow; color: black')
            self.terapy_nowB.setText("Терапия сильной тахикардии")

        if data_in.terapy_now == 3:
            self.terapy_nowB.setStyleSheet('background-color: yellow; color: black')
            self.terapy_nowB.setText("Терапия слабой тахикардии")

        if data_in.sub_mode == 0:
            self.sub_modeB.setStyleSheet('background-color: green; color: white')
            self.sub_modeB.setText("Терапия неактивна")
        if data_in.sub_mode == 1:
            self.sub_modeB.setStyleSheet('background-color: blue; color: white')
            self.sub_modeB.setText("Зарядка конденсатора")

        if data_in.sub_mode == 2:
            self.sub_modeB.setStyleSheet('background-color: yellow; color: black')
            self.sub_modeB.setText("Редетекция")

        if data_in.sub_mode == 3:
            self.sub_modeB.setStyleSheet('background-color: red; color: white')
            self.sub_modeB.setText("Стимуляция")
        if data_in.sub_mode == 4:
            self.sub_modeB.setStyleSheet('background-color: grey; color: black')
            self.sub_modeB.setText("Терапия не сработала")

        # Вывод времени зарядки конденсатора
        if data_in.sub_mode == 1 and self.sub_mode_previous != 1:
            self.start_time_charging = time.time()
        if data_in.sub_mode == 1 and self.sub_mode_previous == 1:
            self.end_time_charging = time.time()
        self.sub_mode_previous = data_in.sub_mode
        self.charge_timer_label.setText(f"{(self.end_time_charging - self.start_time_charging):.2f}")

        # так удаляются элементы
        # стирание элементов спереди
        all_items = self.graph_1.items()  # Получаем все элементы
        text_items = [item for item in all_items if isinstance(item, TextItem)]
        for text_item in text_items:
            if data_in.draw_cnt / my_data.DATA_RATE - 0.02 < text_item.pos().x() and data_in.draw_cnt / my_data.DATA_RATE + 0.1 > text_item.pos().x():
                self.graph_1.removeItem(text_item)

        if data_in.V_print:
            data_in.V_print = 0
            if data_in.draw_last_QRS == 0:
                self.text = pg.TextItem('Vs\nT:' + str(data_in.draw_last_period))
                self.text.setColor('green')
                self.text.setFont(QFont('Arial', 7))
                self.text.setPos(data_in.draw_cnt_last / my_data.DATA_RATE, (0 if data_in.dc_cut else 15))
                self.graph_1.addItem(self.text)
            if data_in.draw_last_QRS == 1:
                self.text = pg.TextItem('Vp\nT:' + str(data_in.draw_last_period))
                self.text.setColor('red')
                self.text.setPos(data_in.draw_cnt_last / my_data.DATA_RATE, (0 if data_in.dc_cut else 15))
                self.graph_1.addItem(self.text)

    def on_stop(self):
        self.close_file()
        global MODE_COM_PORT
        MODE_COM_PORT = False
        self.graph_clear()
        # Создание графиков
        self.graph_init()
        self.serial.flush()
        self.serial.close()
        data_IN_COM.clear_data()
        self.terapy_nowB.setStyleSheet('background-color: lightGray; color: black')
        self.terapy_nowB.setText("")
        self.sub_modeB.setStyleSheet('background-color: lightGray; color: black')
        self.sub_modeB.setText("")
        self.last_period_label.setText("")
        self.filt_period_label.setText("")
        self.Vs_cnt_label.setText("")
        self.Vp_cnt_label.setText("")
        self.Vn_cnt_label.setText("")
        self.progressBar_f.setValue(0)
        self.progressBar_t2.setValue(0)
        self.progressBar_t1.setValue(0)
        self.progressBar_n.setValue(0)
        self.hv_step_cnt_label.setText("")
        self.now_energy_label.setText("")
        self.HR_label.setText("")
        self.OpenB.setEnabled(True)
        self.CloseB.setEnabled(True)

    def on_open(self):
        """
        Открыть файл для чтения
        """
        global MODE_FILE
        self.on_close()
        file, _ = QFileDialog.getOpenFileName(self, 'Open File')
        if file:
            self.timer.start()
            self.timer_LS.start()
            data_IN_FILE.clear_data()
            self.file_name = file
            self.Fname_label.setText(self.file_name)
            my_data.get_data_bin(self.file_name, data_IN_FILE)
            self.counter_com_port = list(map(lambda x: x / my_data.DATA_RATE, range(0, data_IN_FILE.data_length)))
            self.horizontalScrollBar.setMinimum(0)
            self.horizontalScrollBar.setMaximum(len(data_IN_FILE.chunk))
        MODE_FILE = True

    def on_play(self):
        """
        Запустить отрисовку
        """
        self.timer.start()
        self.timer_LS.start()

    def on_pause(self):
        """
        Остановить отрисовку
        """
        self.timer.stop()
        self.timer_LS.stop()


    def draw_file(self):
        scale = self.get_scale()
        size = scale * my_data.DATA_RATE
        for x in range(self.point, data_IN_FILE.data_length, 20):
            self.curve10.setData(self.counter_com_port[x: x + size], data_IN_FILE.ECG_RA[x: x + size])
            self.curve20.setData(self.counter_com_port[x: x + size], data_IN_FILE.ECG_RA_pos_sig[x: x + size])
            self.curve21.setData(self.counter_com_port[x: x + size], data_IN_FILE.ECG_RA_din_threshold[x: x + size])
            self.curve26.setData(self.counter_com_port[x: x + size], np.zeros(len(self.counter_com_port[x: x + size])))
            self.curve24.setData(self.counter_com_port[x: x + size], data_IN_FILE.ECG_RA_min_threshold[x: x + size])
            self.curve25.setData(self.counter_com_port[x: x + size], data_IN_FILE.ECG_RA_max_threshold[x: x + size])
            self.curve30.setData(self.counter_com_port[x: x + size], data_IN_FILE.Last_RR_poz_rel[x: x + size])
            app.processEvents()
            time.sleep(0.05)

    def re_scale(self):
        scale = self.get_scale()
        if len(data_IN_FILE.counter) != 0:
            position = self.horizontalScrollBar.value()
            # self.point = int((len(data_IN_FILE.counter) / my_data.DATA_RATE) * (position / 1000))
            # data_IN_FILE.i = self.point
            data_IN_FILE.i = position

    def on_scroll(self):
        self.re_scale()

    def on_close(self):
        """
        Закрыть открытый для чтения файл
        """
        global MODE_FILE
        MODE_FILE = False
        # очистка графиков
        self.graph_clear()
        # Пересоздание графиков
        self.graph_init()
        # очистка модели
        data_IN_FILE.clear_data()

        self.Fname_label.setText('')

    def get_scale(self):
        scale = int(self.RA_scale_BOX.currentText())
        return scale

    def on_scale_change(self):
        scale = self.get_scale()
        data_IN_COM.data_length = scale * my_data.DATA_RATE
        data_IN_COM.update_data(data_IN_COM.data_length)

        if MODE_FILE:
            self.draw_file()

        all_items = self.graph_1.items()  # Получаем все элементы
        text_items = [item for item in all_items if isinstance(item, TextItem)]
        for text_item in text_items:
            self.graph_1.removeItem(text_item)
        self.counter_com_port = list(map(lambda x: x / my_data.DATA_RATE, range(0, data_IN_COM.data_length)))

    def update_list(self):
        """Создание списка доступных для ввода/вывода портов"""
        portlist = []  # создадим пустой список в который и будем всё записывать
        ports = QSerialPortInfo().availablePorts()  # доступные порты для обмена данными
        for port in ports:
            portlist.append(port.portName())
        return portlist

    def check_work_mode_viewer(self):
        """
        Выбор режима работы (чтение данных из файла/из com-порта), в случае чего некоторые элементы отображения
        становятся видимыми и доступными, а другие наоборот становятся недоступными.
        """
        if self.radioButton_work_mode_com_port.isChecked():
            self.OpenB.setVisible(False)
            self.CloseB.setVisible(False)
            self.Play.setVisible(False)
            self.Pause.setVisible(False)
            self.label_com_port.setVisible(True)
            self.Fname_w_label.setVisible(True)
            self.Port_ch.setVisible(True)
            self.Read.setVisible(True)
            self.Stop.setVisible(True)
            self.Write_file.setVisible(True)
            self.Close_file.setVisible(True)
            self.Restart.setVisible(True)
            self.horizontalScrollBar.setVisible(False)
        else:
            self.on_stop()
            self.OpenB.setVisible(True)
            self.CloseB.setVisible(True)
            self.Play.setVisible(True)
            self.Pause.setVisible(True)
            self.label_com_port.setVisible(False)
            self.Fname_w_label.setVisible(False)
            self.Port_ch.setVisible(False)
            self.Read.setVisible(False)
            self.Stop.setVisible(False)
            self.Write_file.setVisible(False)
            self.Close_file.setVisible(False)
            self.Restart.setVisible(False)
            self.horizontalScrollBar.setVisible(True)

    def set_send_mode(self):
        """Установка режима передачи данных (Bluetooth/433)"""
        self.send_mode = int(self.Send_mode_Box.currentIndex())

    #  настройка параметров работы стимулятора с помощью программы
    def set_DC_cut_Box(self):
        """Настройка вывода сигнала с/без постоянной составляющей"""
        param = int(self.DC_cut_Box.currentIndex())
        my_data.state_packet(self.send_mode, self.serial, 0x21, param, 1, int)

    def set_HV_Box(self):
        """Настройка активации режима высоковольтной стимуляции"""
        param = int(self.HV_Box.currentIndex())
        my_data.state_packet(self.send_mode, self.serial, 0x0F, param, 1, int)

    def set_LV_Box(self):
        """Настройка активации режима низковольтной стимуляции"""
        param = int(self.LV_Box.currentIndex())
        my_data.state_packet(self.send_mode, self.serial, 0x0E, param, 1, int)

    def set_Signal_Box(self):
        """Настройка вывода сигнала с/без фильтром(а)"""
        param = int(self.Signal_Box.currentIndex())
        my_data.state_packet(self.send_mode, self.serial, 0x1E, param, 1, int)

    def set_Channel_Box(self):
        """Установка активного канала передачи"""
        param = int(self.Channel_Box.currentIndex())
        my_data.state_packet(self.send_mode, self.serial, 0x1F, param, 1, int)

    def set_SD_card(self):
        """Установка режима записи на карту памяти"""
        param = int(self.SD_card_Box.currentIndex())
        my_data.state_packet(self.send_mode, self.serial, 0x20, param, 1, int)

    def set_Spi_spot_set_spinBox(self):
        """Установка коэффициента усиления сигнала"""
        param = int(self.Spi_spot_set_spinBox.value())
        my_data.state_packet(self.send_mode, self.serial, 0x1C, param, 1, int)

    def set_Work_Mode_pacemaker(self):
        """Установка текущего режима работы стимулятора(без/с стимуляцией или в режиме принудительной стимуляции)"""
        param = int(self.Work_Mode_pacemaker.currentIndex())  # << 20
        my_data.state_packet(self.send_mode, self.serial, 0x05, param, 2, int)

    def set_RA_max_time_ms_BOX(self):
        """Установка длительности поиска максимума"""
        param = int(self.RA_max_time_ms_BOX.currentText())
        my_data.state_packet(self.send_mode, self.serial, 0x0D, param, 2, int)

    def set_RA_min_sensitivity_BOX(self):
        """Установка минимальной чувствительности"""
        param = float(self.RA_min_sensitivity_BOX.currentText())
        my_data.state_packet(self.send_mode, self.serial, 0x01, param, 4, float)

    def set_RA_max_sensitivity_BOX(self):
        """Установка максимальной чувствительности"""
        param = float(self.RA_max_sensitivity_BOX.currentText())
        my_data.state_packet(self.send_mode, self.serial, 0x02, param, 4, float)

    def set_RA_square_time_ms_BOX(self):
        """Установка длительности защиты от Т волны"""
        param = int(self.RA_square_time_ms_BOX.currentText())
        my_data.state_packet(self.send_mode, self.serial, 0x07, param, 2, int)

    def set_RA_square_coeff_BOX(self):
        """Установка порога чувствительности Т волны"""
        param = float(self.RA_square_coeff_BOX.currentText())
        my_data.state_packet(self.send_mode, self.serial, 0x03, param, 4, float)

    def set_RA_all_time_ms_BOX(self):
        """Установка максимального размера RR-интервала"""
        param = int(self.RA_all_time_ms_BOX.currentText())
        my_data.state_packet(self.send_mode, self.serial, 0x09, param, 2, int)

    def set_High_Tf_spinBox(self):
        """Установка длительности RR-интервала для определения события как фибрилляции"""
        param = self.High_Tf_spinBox.value()
        my_data.state_packet(self.send_mode, self.serial, 0x10, param, 2, int)

    def set_High_Tt2_spinBox(self):
        """Установка длительности RR-интервала для определения события как тахикардии 2ст"""
        param = self.High_Tt2_spinBox.value()
        my_data.state_packet(self.send_mode, self.serial, 0x11, param, 2, int)

    def set_High_Tt1_spinBox(self):
        """Установка длительности RR-интервала для определения события как тахикардии 1ст"""
        param = self.High_Tt1_spinBox.value()
        my_data.state_packet(self.send_mode, self.serial, 0x12, param, 2, int)

    def set_f_count_spinBox(self):
        """Установка порога корзины фибрилляции"""
        param = self.f_count_spinBox.value()
        my_data.state_packet(self.send_mode, self.serial, 0x13, param, 1, int)

    def set_hv_step_number_spinBox(self):
        """Установка количества ступеней BB - терапии"""
        param = self.hv_step_number_spinBox.value()
        my_data.state_packet(self.send_mode, self.serial, 0x14, param, 1, int)

    def set_min_energy_spinBox(self):
        """Установка минимальной энергии стимулятора"""
        param = self.min_energy_spinBox.value()
        my_data.state_packet(self.send_mode, self.serial, 0x15, param, 2, int)

    def set_max_energy_spinBox(self):
        """Установка максимальной энергии стимулятора"""
        param = self.max_energy_spinBox.value()
        my_data.state_packet(self.send_mode, self.serial, 0x16, param, 2, int)

    def set_hv_blind_time_spinBox(self):
        """Установка времени слепоты после разряда"""
        param = self.hv_blind_time_spinBox.value()
        my_data.state_packet(self.send_mode, self.serial, 0x18, param, 2, int)

    def set_standby_timer_spinBox(self):
        """Установка таймаута отключения"""
        param = self.standby_timer_spinBox.value()
        my_data.state_packet(self.send_mode, self.serial, 0x1B, param, 4, int)

    def set_redet_num_spinBox(self):
        """Установка размера буффера редетекции"""
        param = self.redet_num_spinBox.value()
        my_data.state_packet(self.send_mode, self.serial, 0x19, param, 1, int)

    def set_redet_bad_spinBox(self):
        """Установка порога буффера редетекции"""
        param = self.redet_bad_spinBox.value()
        my_data.state_packet(self.send_mode, self.serial, 0x1A, param, 1, int)

    def set_fibr_cnt_max(self):
        """Визуализация корзины фибрилляции"""
        # + отправить стимулятору
        self.progressBar_f.setMaximum(self.f_count_spinBox.value())

    def set_tachy_2_cnt_max(self):
        """Визуализация корзины тахикардии 2ст"""
        self.progressBar_t2.setMaximum(self.t2_count_spinBox.value())

    def set_tachy_1_cnt_max(self):
        """Визуализация корзины тахикардии 1ст"""
        self.progressBar_t1.setMaximum(self.t1_count_spinBox.value())

    def set_hv_polarity_BOX(self):
        """Выбор полярности"""
        param = int(self.hv_polarity_BOX.currentIndex())
        match param:
            case 0:
                self.picture_1.setVisible(True)
                self.picture_2.setVisible(False)
                self.picture_3.setVisible(False)
            case 1:
                self.picture_2.setVisible(True)
                self.picture_1.setVisible(False)
                self.picture_3.setVisible(False)
            case 2:
                self.picture_3.setVisible(True)
                self.picture_1.setVisible(False)
                self.picture_2.setVisible(False)
        my_data.state_packet(self.send_mode, self.serial, 0x30, param, 1, int)

    def set_hv_mode_BOX(self):
        """Выбор режима высоковольтной стимуляции"""
        param = int(self.hv_mode_BOX.currentIndex())
        match param:
            case 0:
                self.picture_4.setVisible(True)
                self.picture_5.setVisible(False)
                self.u1_hv_switching_voltage_l.setVisible(False)
                self.u2_hv_cutoff_voltage_l.setVisible(False)
                self.u1_hv_switching_voltage_spinBox.setVisible(False)
                self.u2_hv_cutoff_voltage_spinBox.setVisible(False)
            case 1:
                self.picture_5.setVisible(True)
                self.picture_4.setVisible(False)
                self.u1_hv_switching_voltage_l.setVisible(True)
                self.u2_hv_cutoff_voltage_l.setVisible(True)
                self.u1_hv_switching_voltage_spinBox.setVisible(True)
                self.u2_hv_cutoff_voltage_spinBox.setVisible(True)
        my_data.state_packet(self.send_mode, self.serial, 0x31, param, 1, int)

    def set_t1_hv_phase_1_duration_SpinBox(self):
        """Выбор времени положительной полуволны"""
        param = int(self.t1_hv_phase_1_duration_SpinBox.value()*10)
        my_data.state_packet(self.send_mode, self.serial, 0x32, param, 1, int)

    def set_t2_hv_switch_duration_SpinBox(self):
        """Выбор времени задержки"""
        param = int(self.t2_hv_switch_duration_SpinBox.value()*10)
        my_data.state_packet(self.send_mode, self.serial, 0x34, param, 1, int)

    def set_t3_hv_phase_2_duration_SpinBox(self):
        """Выбор времени отрицательной полуволны"""
        param = int(self.t3_hv_phase_2_duration_SpinBox.value()*10)
        my_data.state_packet(self.send_mode, self.serial, 0x33, param, 1, int)

    def set_u1_hv_switching_voltage_spinBox(self):
        """Выбор процента от максимального напряжения для смены полярности"""
        param = int(self.u1_hv_switching_voltage_spinBox.value())
        my_data.state_packet(self.send_mode, self.serial, 0x35, param, 1, int)

    def set_u2_hv_cutoff_voltage_spinBox(self):
        """Выбор процента от максимального напряжения для окончания стимуляции"""
        param = int(self.u2_hv_cutoff_voltage_spinBox.value())
        my_data.state_packet(self.send_mode, self.serial, 0x36, param, 1, int)

    def set_lv_mode_BOX(self):
        """Выбор режима низковольтной стимуляции"""
        param = self.lv_mode_BOX.currentIndex()
        match param:
            case 1:
                self.burst_frame.setVisible(True)
            case _:
                self.burst_frame.setVisible(False)
        my_data.state_packet(self.send_mode, self.serial, 0x23, param, 1, int)

        # if param == 3:
        #     my_data.state_packet(self.send_mode, self.serial, 0x23, 15, 1, int)
        # else:
        #     my_data.state_packet(self.send_mode, self.serial, 0x23, param, 1, int)


    def set_lv_polarity_BOX(self):
        """Выбор полярности для НВ"""
        param = int(self.lv_polarity_BOX.currentIndex())
        my_data.state_packet(self.send_mode, self.serial, 0x22, param, 1, int)

    def set_u_lv_voltage_SpinBox(self):
        """Выбор напряжения НВ стимуляции"""
        param = int(self.u_lv_voltage_SpinBox.value()*10)
        my_data.state_packet(self.send_mode, self.serial, 0x26, param, 1, int)

    def set_t1_lv_shock_time_SpinBox(self):
        """Выбор времени импульса НВ стимуляции"""
        param = int(self.t1_lv_shock_time_SpinBox.value() * 10)
        my_data.state_packet(self.send_mode, self.serial, 0x24, param, 1, int)
    def set_t2_lv_relax_time_spinBox(self):
        """Выбор времени стабилизации после НВ стимуляции"""
        param = int(self.t2_lv_relax_time_spinBox.value())
        my_data.state_packet(self.send_mode, self.serial, 0x25, param, 1, int)
    def set_burst_cnt_spinBox(self):
        """Выбор количества импульсов в пачке при НВ стимуляции"""
        param = self.burst_cnt_spinBox.value()
        my_data.state_packet(self.send_mode, self.serial, 0x27, param, 1, int)
    def set_burst_voltage_SpinBox(self):
        """Выбор напряжения импульсов при НВ стимуляции"""
        param = int(self.burst_voltage_SpinBox.value() * 10)
        my_data.state_packet(self.send_mode, self.serial, 0x28, param, 1, int)
    def set_burst_period_spinBox(self):
        """Выбор периода следования импульсов при НВ стимуляции"""
        param = self.burst_period_spinBox.value()
        my_data.state_packet(self.send_mode, self.serial, 0x29, param, 2, int)