Esempio n. 1
0
 def run(self):
     modbus = Modbus.Modbus('paulharrison.hopto.org')
     while True:
         item = []
         try:
             # Order: [current, power, voltage]
             current_avg = modbus.read(3008,
                                       2)  # 3008 stores average current
             power_avg = modbus.read(3058, 2)  # 3058 stores average power
             voltage_avg = modbus.read(3024,
                                       2)  # 3024 stores average voltage
             total_energy = modbus.read(45098, 2)
             A = modbus.read(45118, 2)
             B = modbus.read(45120, 2)
             C = modbus.read(45122, 2)
             D = modbus.read(45124, 2)
             item.append(current_avg)
             item.append(power_avg)
             item.append(voltage_avg)
             item.append(total_energy)
             item.append(A)
             item.append(B)
             item.append(C)
             item.append(D)
             time.sleep(60)
         except struct.error:
             print('Struct Error exception', file=sys.stderr)
             time.sleep(2)
             os._exit(1)
         except ModbusException:
             print('Modbus I/O exception', file=sys.stderr)
             time.sleep(2)
             os._exit(1)
         self.q.put(item)
Esempio n. 2
0
def getBinder(port, echo=None):
    """Try to open Modbus(port) and determine Binder instrument
echo - open modbus with echo True/False; if None, try both
returns Binder instance or None in case of failure"""
    logger = logging.getLogger('getBinder')
    if echo is None:
        echos = (False, True)
    else:
        echos = (bool(echo), )

    b = None
    for echo in echos:
        try:
            m = Modbus(port, echo=echo)
            logger.info('Using serial %s with echo %s', repr(m.ser), echo)
        except (FileNotFoundError, ModbusError):
            logger.exception('Opening serial port failed')
            m.ser.close()
            return None
        for btype, bcls in BinderTypes.items():
            try:
                logger.debug('Trying chamber %s', btype)
                b = bcls(m)
                b.get_state()
            except ModbusError:
                logger.debug('failed')
                if b is not None:
                    b.__del__()
                    b = None
            else:
                logger.debug('chamber is %s', btype)
                return b
    return None
Esempio n. 3
0
                    required=True,
                    help='modbus port')
parser.add_argument('-u',
                    '--unit',
                    type=int,
                    required=True,
                    help='modbus unit')
parser.add_argument('-t',
                    '--type',
                    type=str,
                    required=True,
                    help='inverter type')

args = parser.parse_args()

wr = Modbus(args, logger=TableLogger())

if args.type == "tripower":
    add_tripower_register(wr)
elif args.type == "sbstorage":
    add_sbstorage_register(wr)
elif args.type == "sbxx-1av-41":
    add_sbxx_1av_41_register(wr)
else:
    sys.exit("Unknown inverter type.")

if args.list:
    wr.list_available_registers()
else:
    for register in args.registers:
        wr.poll_register(register)
Esempio n. 4
0
def KeyThread(modbus, scope):
    '''Thread to get command from console.'''
    global f

    key = input("Press Enter to continue...\n> ")
    f.close()
    print("bye-bye")
    os.kill(os.getpid(), signal.SIGINT)


if __name__ == '__main__':
    global data
    global f
    global ReadingADC

    modbus = Modbus("/dev/ttyUSB0", 115200, 5)
    scope = Scope()
    data = [[] for i in range(modbus.GetNumChannels())]
    rt = threading.Thread(target=ReadThread, args=(modbus, scope, 0.01))
    wt = threading.Thread(target=WriteThread, args=(scope, ))
    kt = threading.Thread(target=KeyThread, args=(
        modbus,
        scope,
    ))
    filename = "data-" + time.strftime("%Y%m%d%H%M%S") + ".txt"
    f = open(filename, "w")

    # Bind data to scope.
    scope.data = data
    # Send start sample command to oscilloscope.
    modbus.StartSample()
Esempio n. 5
0

if __name__ == '__main__':

    # Pipes to Webapp
    SERIAL_CHILD, SERIAL_PARENT = Pipe()

    # Pipes for encoder
    ENCODER_CHILD, ENCODER_PARENT = Pipe()

    # Queues for sql database connector
    RECORD_QUEUE = Queue()
    DATA_QUEUE = Queue()

    # Start AquaTROLL
    TROLL = Modbus(DATA_QUEUE)

    # Starts camera
    CAMERA_PROCESS = Process(target=Camera.start_camera,
                             args=((2592, 1944), 300, "Images", RECORD_QUEUE))
    CAMERA_PROCESS.start()

    # Starts sql database connector that handles writing and reading(broadcasts to socket)
    DATABASE_CONNECTOR = Process(target=sqlConnector.start_sqlConnector,\
    args=(RECORD_QUEUE,DATA_QUEUE))

    # DATABASE_CONNECTOR = Process(target=sqlConnector.start_sqlConnector,\
    #     args=(RECORD_QUEUE,DATA_QUEUE, ENCODER_PARENT))
    DATABASE_CONNECTOR.start()

    # Starts thread that runs serial communication.
Esempio n. 6
0
    parser.add_argument("serialPort", help="The serial port device to use")
    parser.add_argument("--httpListenPort", help="The port for the HTTP server to listen on", type=int, default=8080)
    parser.add_argument("--verbose", help="Use verbose logging", action="store_true")
    args = parser.parse_args()

    logging.basicConfig()
    log = logging.getLogger()
    if args.verbose:
        log.setLevel(logging.DEBUG)
    else:
        log.setLevel(logging.INFO)

    log.info("Listening on port {}, using device {}".format(args.httpListenPort, args.serialPort))

    loop, client = AsyncModbusSerialClient(schedulers.ASYNC_IO, port=args.serialPort, baudrate=19200, method="rtu")
    modbus = Modbus(client.protocol)
    handler = HttpHandler(modbus)
    app = web.Application()
    app.add_routes([
        web.get("/", handler.handle_root),
        web.get("/summary", handler.get_summary),
        web.get("/mode/{flag}", handler.get_mode_status),
        web.post("/mode/{flag}", handler.set_mode_status),
        web.post("/setSetting/{setting}/{value}", handler.set_setting)
    ])

    try:
        loop.run_until_complete(web._run_app(app, port=args.httpListenPort))
    finally:
        loop.close()
Esempio n. 7
0
class RootWidget(FloatLayout):
    buttons_is_disable = False

    sync_param_process = False

    com_num = 1
    motor = Modbus()

    speed = -1
    accel_time = -1
    deccel_time = -1

    auto_speed = -1
    auto_accel_time = -1
    auto_deccel_time = -1

    manual_speed = -1
    manual_accel_time = -1
    manual_deccel_time = -1

    work_time = -1
    reverse = False
    auto_presets = []
    manual_presets = []
    selected_preset = -1

    com_input = ObjectProperty()
    connect_button = ObjectProperty()
    speed_input = ObjectProperty()
    speed_error_img = ObjectProperty()
    accel_time_input = ObjectProperty()
    accel_error_img = ObjectProperty()
    deccel_time_input = ObjectProperty()
    deccel_error_img = ObjectProperty()
    work_time_input = ObjectProperty()
    work_error_img = ObjectProperty()
    motor_switch = ObjectProperty()
    apply_param_button = ObjectProperty()
    preset_button = ObjectProperty()
    add_preset_button = ObjectProperty()
    del_preset_button = ObjectProperty()
    sync_params_button = ObjectProperty()

    def error(self, text):
        ErrorPopup(text)

    def resource_path(self, relative_path):
        print(resource_path(relative_path))
        return resource_path(relative_path)

    def save_params(self):

        with open(appdata_path + 'settings.txt', 'w') as f:
            f.write(str(self.com_num) + '\n')
            f.write(str(self.auto_speed) + '\n')
            f.write(str(self.auto_accel_time) + '\n')
            f.write(str(self.auto_deccel_time) + '\n')
            f.write(str(self.work_time) + '\n')
            f.write(str(self.reverse) + '\n')
            f.write(str(self.manual_speed) + '\n')
            f.write(str(self.manual_accel_time) + '\n')
            f.write(str(self.manual_deccel_time) + '\n')

    def load_params(self):
        try:
            f = open(appdata_path + 'settings.txt')
            self.com_num = int(f.readline())
            auto_speed = f.readline().strip()
            if auto_speed != '-1':
                self.speed_input.text = auto_speed
                self.accel_time_input.text = f.readline().strip()
                self.deccel_time_input.text = f.readline().strip()
                self.work_time_input.text = f.readline().strip()
                self.work_time = int(self.work_time_input.text)
                self.reverse = f.readline().strip() == 'True'
            else:
                for i in range(4):
                    f.readline()

            manual_speed = int(f.readline())
            if manual_speed != -1:
                self.manual_speed = manual_speed
                self.manual_accel_time = int(f.readline())
                self.manual_deccel_time = int(f.readline())
            f.close()
        except:
            print('load params error')

    def save_presets(self):
        with open(appdata_path + 'presets.prs', 'wb') as f:
            presets = [self.auto_presets, self.manual_presets]
            pickle.dump(presets, f)

    def load_presets(self):
        try:
            with open(appdata_path + 'presets.prs', 'rb') as f:
                presets = pickle.load(f)
                self.auto_presets = presets[0]
                self.manual_presets = presets[1]
        except:
            self.auto_presets = []
            self.manual_presets = []

    def check_param_equals(self):
        if int(self.speed_input.text) != self.speed:
            self.speed_error_img.color = (1, 1, 1, 1)
        else:
            self.speed_error_img.color = (1, 1, 1, 0)
        if int(self.accel_time_input.text) != self.accel_time:
            self.accel_error_img.color = (1, 1, 1, 1)
        else:
            self.accel_error_img.color = (1, 1, 1, 0)
        if int(self.deccel_time_input.text) != self.deccel_time:
            self.deccel_error_img.color = (1, 1, 1, 1)
        else:
            self.deccel_error_img.color = (1, 1, 1, 0)
        if int(self.work_time_input.text) != self.work_time:
            self.work_error_img.color = (1, 1, 1, 1)
        else:
            self.work_error_img.color = (1, 1, 1, 0)

    def set_param(self, register, value):
        if myApp.auto_mode:
            if register == ServoReg.SPEED:
                self.auto_speed = self.speed = value
                self.speed_input.text = str(value)
            elif register == ServoReg.ACCEL_TIME:
                self.auto_accel_time = self.accel_time = value
                self.accel_time_input.text = str(value)
            elif register == ServoReg.DECCEL_TIME:
                self.auto_deccel_time = self.deccel_time = value
                self.deccel_time_input.text = str(value)
        else:
            if register == ServoReg.SPEED:
                self.manual_speed = self.speed = value
                self.speed_input.text = str(value)
            elif register == ServoReg.ACCEL_TIME:
                self.manual_accel_time = self.accel_time = value
                self.accel_time_input.text = str(value)
            elif register == ServoReg.DECCEL_TIME:
                self.manual_deccel_time = self.deccel_time = value
                self.deccel_time_input.text = str(value)

        if register == ServoReg.DECCEL_TIME and self.sync_param_process:
            self.sync_param_process = False
            if self.motor_switch.active:
                self.disable_buttons(False)

        self.check_param_equals()
        self.save_params()

    def servo_sync_params(self, instance):
        self.sync_param_process = True
        self.disable_buttons(True)
        registers = [ServoReg.SPEED, ServoReg.ACCEL_TIME, ServoReg.DECCEL_TIME]
        for register in registers:

            def check_answer(*args, **kwargs):
                try:
                    ans = kwargs['ans']
                    register = kwargs['register']
                    if ans[:7] == ':010302':
                        myApp.root_widget.set_param(register,
                                                    int(ans[7:11], 16))
                except:
                    pass

            self.motor.get_param(register, check_answer)

    def add_preset_popup(self, instance):
        popup = AddPresetPopup()
        popup.open()

    def add_preset(self, name):
        preset = Preset(name, int(self.speed_input.text),
                        int(self.accel_time_input.text),
                        int(self.deccel_time_input.text),
                        int(self.work_time_input.text))
        if myApp.auto_mode:
            self.auto_presets.append(preset)
        else:
            self.manual_presets.append(preset)
        self.save_presets()
        self.update_presets_dropdown()

    def del_preset(self):
        if self.selected_preset >= 0:
            if myApp.auto_mode:
                del self.auto_presets[self.selected_preset]
            else:
                del self.manual_presets[self.selected_preset]
            self.save_presets()
            self.update_presets_dropdown()
            self.preset_button.text = 'Пресет'

    def del_preset_btn(self, instance):
        if self.selected_preset >= 0:
            quest_popup = QuestionPopup()
            quest_popup.ok_func = self.del_preset
            quest_popup.question.text = 'Вы действительно хотите удалить пресет?'
            quest_popup.open()

    def select_preset(self, instance):
        self.selected_preset = int(instance.id)
        if myApp.auto_mode:
            preset = self.auto_presets[self.selected_preset]
        else:
            preset = self.manual_presets[self.selected_preset]
        self.preset_button.text = instance.text
        self.speed_input.text = str(preset.speed)
        self.accel_time_input.text = str(preset.accel_time)
        self.deccel_time_input.text = str(preset.deccel_time)
        self.work_time_input.text = str(preset.work_time)
        self.dropdown.dismiss()
        self.check_param_equals()

    def com_changed(self, instance, value):
        try:
            if len(instance.text) > 2:
                instance.text = value[:-1]
            self.com_num = int(value)
            self.save_params()
        except:
            instance.text = value[:-1]

    def change_connect(self, instance):
        if not self.motor.is_connect:
            self.connect()
        else:
            self.disconnect()

    def connect(self):
        self.motor.connect(self.com_num, myApp)
        if not self.motor.is_connect:
            pass
        else:
            self.connect_button.text = 'Отключиться'
            self.motor_switch.disabled = False
            self.apply_param_button.disabled = False
            self.sync_params_button.disabled = False
        self.servo_sync_params(None)

    def disconnect(self):
        self.motor.disconnect()
        if not self.motor.is_connect:
            self.connect_button.text = 'Соединиться'
            self.motor_switch.active = False
            self.motor_switch.disabled = True
            self.apply_param_button.disabled = True
            self.sync_params_button.disabled = True
            self.disable_buttons(True)

    def disable_buttons(self, val):
        self.buttons_is_disable = val
        myApp.mode_widget.disable_buttons(val)

    def motor_change_state(self, instance, value):
        if value:

            def check_motor_is_on(*args, **kwargs):
                ans = kwargs['ans']
                right_ans = kwargs['right_ans']
                if ans == right_ans:
                    myApp.root_widget.disable_buttons(not value)

            self.motor.servo_on(func=check_motor_is_on)
        else:
            self.motor.servo_off()
            self.disable_buttons(not value)

    def servo_set_params(self, instance):
        def apply_param(*args, **kwargs):
            ans = kwargs['ans']
            right_ans = kwargs['right_ans']
            if ans == right_ans:
                register = int(ans[5:9], 16)
                value = int(ans[9:13], 16)
                myApp.root_widget.set_param(register, value)

        speed = int(self.speed_input.text)
        accel_time = int(self.accel_time_input.text)
        deccel_time = int(self.deccel_time_input.text)
        values = [speed, accel_time, deccel_time]
        registers = [ServoReg.SPEED, ServoReg.ACCEL_TIME, ServoReg.DECCEL_TIME]
        self.sync_param_process = True
        self.disable_buttons(True)
        for i, val in enumerate(values):
            try:
                if val < 0:
                    val = 0
                if i == 0 and val == 0:
                    val = 100
                self.motor.set_param(register=registers[i],
                                     value=val,
                                     func=apply_param)
            except:
                pass
        try:
            self.work_time = int(self.work_time_input.text)
        except:
            pass
        self.save_params()

    def update_presets_dropdown(self):
        self.preset_button.text = 'Пресет'
        self.selected_preset = -1
        self.dropdown.clear_widgets()
        if myApp.auto_mode:
            presets = self.auto_presets
        else:
            presets = self.manual_presets
        for index, preset in enumerate(presets):
            btn = Button(id=str(index),
                         text=str(preset.name),
                         size_hint_y=None,
                         height=25)
            btn.bind(on_release=self.select_preset)
            self.dropdown.add_widget(btn)

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        try:
            self.load_params()
        except:
            pass
        self.load_presets()
        self.com_input.text = str(self.com_num)
        print('com bind')
        self.com_input.bind(text=self.com_changed)
        self.connect_button.bind(on_press=self.change_connect)

        self.motor_switch.bind(active=self.motor_change_state)
        self.motor_switch.disabled = True

        self.dropdown = DropDown()
        self.update_presets_dropdown()
        self.preset_button.bind(on_release=self.dropdown.open)

        print('buttons bind')
        self.add_preset_button.bind(on_press=self.add_preset_popup)
        self.del_preset_button.bind(on_press=self.del_preset_btn)

        self.apply_param_button.bind(on_press=self.servo_set_params)
        self.apply_param_button.disabled = True
        self.sync_params_button.bind(on_press=self.servo_sync_params)
        self.sync_params_button.disabled = True
        print('root_widget builded.')
Esempio n. 8
0
class ServolineMotorApp(MainForm):
    reverse = False
    mode = 'auto'
    motor = Modbus()

    auto_speed = 50
    auto_accel_time = 200
    auto_deccel_time = 200
    auto_work_time = 0

    manual_speed = 50
    manual_accel_time = 200
    manual_deccel_time = 200

    auto_groups = []
    auto_groups_id = -1
    auto_presets = []
    manual_presets = []
    auto_presets_id = -1
    manual_presets_id = -1

    sync_param_process = False
    settings_file = DictionaryParser(appdata_path + 'settings.txt')

    def save_params(self):
        params = {'com': self.com.get()}
        auto = {
            'speed': self.auto_speed,
            'accel_time': self.auto_accel_time,
            'deccel_time': self.auto_deccel_time,
            'work_time': self.auto_work_time,
            'preset_id': self.auto_presets_id,
            'group_id': self.auto_groups_id,
            'reverse': self.reverse
        }
        manual = {
            'speed': self.manual_speed,
            'accel_time': self.manual_accel_time,
            'deccel_time': self.manual_deccel_time,
            'preset_id': self.manual_presets_id
        }
        params['auto'] = auto
        params['manual'] = manual
        try:
            self.settings_file.save_dict(params)
        except:
            print('save params error')

    def load_params(self):
        try:
            params = self.settings_file.load_dict()
            self.com.set(params['com'])
            auto = params['auto']
            self.auto_speed = auto['speed']
            self.auto_accel_time = auto['accel_time']
            self.auto_deccel_time = auto['deccel_time']
            self.auto_presets_id = auto['preset_id']
            self.auto_groups_id = auto.get('group_id', -1)
            self.reverse = auto['reverse']

            manual = params['manual']
            self.manual_speed = manual['speed']
            self.manual_accel_time = manual['accel_time']
            self.manual_deccel_time = manual['deccel_time']
            self.manual_presets_id = manual['preset_id']

            self.speed.set(self.auto_speed)
            self.accel_time.set(self.auto_accel_time)
            self.deccel_time.set(self.auto_deccel_time)
            self.work_time.set(self.auto_work_time)
        except:
            print('load params error')

    def save_presets(self):
        id = self.combobox_presets.current()
        if self.mode == 'auto':
            self.auto_presets_id = id
        else:
            self.manual_presets_id = id
        self.save_params()
        with open(appdata_path + 'presets.prs', 'wb') as f:
            presets = [self.auto_presets, self.manual_presets]
            pickle.dump(presets, f)
        with open(appdata_path + 'groups.prs', 'wb') as f:
            pickle.dump(self.auto_groups, f)

    def load_presets(self):
        try:
            with open(appdata_path + 'presets.prs', 'rb') as f:
                presets = pickle.load(f)
                self.auto_presets = presets[0]
                self.manual_presets = presets[1]
        except:
            self.auto_presets = []
            self.manual_presets = []

        try:
            with open(appdata_path + 'groups.prs', 'rb') as f:
                self.auto_groups = pickle.load(f)
        except:
            self.auto_groups = []
            self.auto_groups_id = -1

    def check_param_equals(self):
        pass

    def enable_buttons(self, val):
        self.auto.enable_buttons(val)
        self.manual.enable_buttons(val)

    def change_connect(self):
        if not self.motor.is_connect:
            self.connect()
        else:
            self.disconnect()

    def connect(self):
        self.motor.connect(self.com.get(), self)
        if self.motor.is_connect:
            self.btn_connect['text'] = 'Отключиться'
            self.switch_motor['state'] = 'normal'
        self.servo_sync_params()
        self.preset_var.set('Выбрать пресет')

    def disconnect(self):
        self.motor.disconnect()
        if not self.motor.is_connect:
            self.btn_connect['text'] = 'Подключиться'
            self.switch_motor.set_val(False)
            self.switch_motor['state'] = 'disabled'
            self.enable_buttons(True)

    def motor_change_state(self, value):
        if value:

            def check_motor_is_on(*args, **kwargs):
                ans = kwargs['ans']
                right_ans = kwargs['right_ans']
                if ans == right_ans:
                    self.enable_buttons(value)

            self.motor.servo_on(right_func=check_motor_is_on)
        else:
            self.motor.servo_off()
            self.enable_buttons(value)

    def set_param_in_entry(self, register, value):
        if self.mode == 'auto':
            if register == ServoReg.SPEED:
                self.auto_speed = value
                self.speed.set(value)
            elif register == ServoReg.ACCEL_TIME:
                self.auto_accel_time = value
                self.accel_time.set(value)
            elif register == ServoReg.DECCEL_TIME:
                self.auto_deccel_time = value
                self.deccel_time.set(value)
        else:
            if register == ServoReg.SPEED:
                self.manual_speed = value
                self.speed.set(value)
            elif register == ServoReg.ACCEL_TIME:
                self.manual_accel_time = value
                self.accel_time.set(value)
            elif register == ServoReg.DECCEL_TIME:
                self.manual_deccel_time = value
                self.deccel_time.set(value)

        if register == ServoReg.DECCEL_TIME and self.sync_param_process:
            self.sync_param_process = False
            if self.switch_motor.val:
                self.enable_buttons(True)

        self.check_param_equals()
        self.save_params()

    def servo_sync_params(self):
        self.sync_param_process = True
        registers = [ServoReg.SPEED, ServoReg.ACCEL_TIME, ServoReg.DECCEL_TIME]
        for register in registers:

            def check_answer(*args, **kwargs):
                try:
                    ans = kwargs['ans']
                    register = kwargs['register']
                    if ans[:7] == ':010302':
                        self.set_param_in_entry(register, int(ans[7:11], 16))
                except:
                    pass

            self.motor.get_param(register=register, right_func=check_answer)

    def servo_set_params(self):
        if self.motor.is_connect:

            def apply_param(*args, **kwargs):
                ans = kwargs['ans']
                right_ans = kwargs['right_ans']
                if ans == right_ans:
                    register = int(ans[5:9], 16)
                    value = int(ans[9:13], 16)
                    self.set_param_in_entry(register, value)
                else:
                    self.error('param apply on motor error')

            speed = self.speed.get()
            accel_time = self.accel_time.get()
            deccel_time = self.deccel_time.get()
            values = [speed, accel_time, deccel_time]
            registers = [
                ServoReg.SPEED, ServoReg.ACCEL_TIME, ServoReg.DECCEL_TIME
            ]
            self.sync_param_process = True
            for i, val in enumerate(values):

                def set_param_on_motor(*args, **kwargs):
                    try:
                        ans = kwargs['ans']
                        current_val = kwargs['current_val']
                        register = kwargs['register']
                        # set_param if difference
                        if (ans[:7] == ':010302' and int(ans[7:11], 16) !=
                                current_val) or (ans[:7] != ':010302'):
                            try:
                                if current_val < 0:
                                    current_val = 0
                                if i == 0 and current_val == 0:
                                    current_val = 100
                                self.motor.set_param(register=register,
                                                     value=current_val,
                                                     right_func=apply_param)
                            except:
                                self.error('error set param on motor in if')
                    except:
                        self.error('error set param on motor')

                self.motor.get_param(register=registers[i],
                                     right_func=set_param_on_motor,
                                     current_val=val)

            try:
                self.auto_work_time = int(self.work_time.get())
            except:
                pass
            self.save_params()
            self.enable_buttons(self.switch_motor.val)

    def param_changed(self):
        values = ['speed', 'accel_time', 'deccel_time']
        for val in values:
            if eval('self.' + str(self.mode) + '_' + str(val) +'!=self.' + str(val) + '.get()')or\
                    (self.auto_work_time!=self.work_time.get()):
                self.image_speed_error.place(x=230, y=50)

    def param_change_complete(self):
        values = ['speed', 'accel_time', 'deccel_time']
        for val in values:
            if eval('self.' + str(self.mode) + '_' + str(val) +'!=self.' + str(val) + '.get()')or\
                    (self.auto_work_time!=self.work_time.get()):
                self.save_params()
                self.servo_set_params()
                if self.mode == 'auto':
                    self.auto_presets_id = -1
                else:
                    self.manual_presets_id = -1
                break

        if (self.mode == 'auto' and self.auto_presets_id == -1)or\
                (self.mode == 'manual' and self.manual_presets_id == -1):
            self.preset_var.set('Выбрать пресет')

        self.image_speed_error.place_forget()

    def change_mode(self):
        self.enable_buttons(False)
        if self.mode == 'auto':
            self.mode = 'manual'
            self.auto.hide()
            self.manual.show()
            self.auto_speed = self.speed.get()
            self.auto_accel_time = self.accel_time.get()
            self.auto_deccel_time = self.deccel_time.get()
            self.auto_work_time = self.work_time.get()
            self.speed.set(self.manual_speed)
            self.accel_time.set(self.manual_accel_time)
            self.deccel_time.set(self.manual_deccel_time)
            self.work_time.set(0)
            self.hide_groups_menu()
            id_pres = self.manual_presets_id
            self.update_presets_combobox()
        else:
            self.mode = 'auto'
            self.manual.hide()
            self.auto.show()
            self.manual_speed = self.speed.get()
            self.manual_accel_time = self.accel_time.get()
            self.manual_deccel_time = self.deccel_time.get()
            self.speed.set(self.auto_speed)
            self.accel_time.set(self.auto_accel_time)
            self.deccel_time.set(self.auto_deccel_time)
            self.work_time.set(self.auto_work_time)
            self.show_groups_menu()
            id_pres = self.auto_presets_id
            if self.auto_presets_id > -1:
                self.group_selected(None, pr_sel_index=self.auto_presets_id)
            else:
                self.update_presets_combobox()

        self.servo_set_params()
        if id_pres > -1:
            self.combobox_presets.current(id_pres)
        else:
            self.preset_var.set('Выбрать пресет')

    def show_group_window(self, new=False):
        self.group_master = Toplevel(self.master)
        if new:
            self.group_window = GroupSettingsWindow(self, self.group_master)
        else:
            self.group_window = GroupSettingsWindow(self, self.group_master,
                                                    self.auto_groups_id)

    def show_add_preset_window(self):
        self.add_preset_master = Toplevel(self.master)
        self.add_preset_window = AddPresetWindow(self, self.add_preset_master)

    def show_preset_settings_window(self):
        self.pr_st_master = Toplevel(self.master)
        self.pr_st_window = PresetSettingsWindow(self, self.pr_st_master,
                                                 self.get_cur_preset())

    def get_cur_preset(self):
        index = self.combobox_presets.current()
        if self.mode == 'auto':
            if self.auto_groups_id == -1:
                return self.auto_presets[index]
            else:
                return self.auto_groups[self.auto_groups_id].presets[index]
        else:
            return self.manual_presets[index]

    def get_cur_group(self):
        return self.auto_groups[self.auto_groups_id]

    def add_preset(self, name):
        preset = Preset(name, self.speed.get(), self.accel_time.get(),
                        self.deccel_time.get())
        if self.mode == 'auto':
            preset.work_time = self.work_time.get()
            if self.auto_groups_id == -1:
                self.auto_presets.append(preset)
            else:
                self.auto_groups[self.auto_groups_id].presets.append(preset)
                self.group_selected(None,
                                    len(self.get_cur_group().presets) - 1)
                self.save_presets()
                return
        else:
            self.manual_presets.append(preset)

        self.save_presets()
        self.update_presets_combobox()
        index = len(self.combobox_presets['values']) - 1
        self.combobox_presets.current(index)

    def change_preset(self):
        index = self.combobox_presets.current()
        if self.mode == 'auto':
            preset = self.auto_presets[index]
            preset.work_time = self.work_time.get()
        else:
            preset = self.manual_presets[index]
        preset.speed = self.speed.get()
        preset.accel_time = self.accel_time.get()
        preset.deccel_time = self.deccel_time.get()
        self.save_presets()

    def save_preset(self, preset):
        cur_preset = self.get_cur_preset()
        for attr in cur_preset.__dict__.keys():
            cur_preset.__dict__[attr] = preset.__dict__[attr]
        self.save_presets()
        self.group_selected(None, self.auto_presets_id)

    def del_preset(self):
        index = self.combobox_presets.current()
        if self.mode == 'auto':
            if self.auto_groups_id == -1:
                del self.auto_presets[index]
            else:
                del self.auto_groups[self.auto_groups_id].presets[index]
                self.group_selected(None)
        else:
            del self.manual_presets[index]
        self.update_presets_combobox()
        self.preset_var.set('Выбрать пресет')
        self.save_presets()

    def up_group(self):
        id = self.combobox_preset_groups.current()
        if id > 0 and id < len(self.auto_groups):
            group = self.auto_groups[id]
            self.auto_groups[id] = self.auto_groups[id - 1]
            self.auto_groups[id - 1] = group
            self.update_groups_combobox()
            self.combobox_preset_groups.current(id - 1)
            self.auto_groups_id = self.combobox_preset_groups.current()
            self.save_presets()

    def down_group(self):
        id = self.combobox_preset_groups.current()
        if id > -1 and id < len(self.auto_groups) - 1:
            group = self.auto_groups[id]
            self.auto_groups[id] = self.auto_groups[id + 1]
            self.auto_groups[id + 1] = group
            self.update_groups_combobox()
            self.combobox_preset_groups.current(id + 1)
            self.auto_groups_id = self.combobox_preset_groups.current()
            self.save_presets()

    def up_preset(self):
        if self.mode == 'manual' or self.auto_groups_id == -1:
            preset_list = eval('self.' + self.mode + '_presets')
        else:
            preset_list = self.get_cur_group().presets
        id = self.combobox_presets.current()
        if id > 0 and id < len(preset_list):
            preset = preset_list[id]
            preset_list[id] = preset_list[id - 1]
            preset_list[id - 1] = preset
            self.update_presets_combobox()
            self.combobox_presets.current(id - 1)
            self.auto_presets_id = self.combobox_presets.current()
            self.save_presets()

    def down_preset(self):
        if self.mode == 'manual' or self.auto_groups_id == -1:
            preset_list = eval('self.' + self.mode + '_presets')
        else:
            preset_list = self.get_cur_group().presets
        id = self.combobox_presets.current()
        if id > -1 and id < len(preset_list) - 1:
            preset = preset_list[id]
            preset_list[id] = preset_list[id + 1]
            preset_list[id + 1] = preset
            self.update_presets_combobox()
            self.combobox_presets.current(id + 1)
            self.auto_presets_id = self.combobox_presets.current()
            self.save_presets()

    def group_selected(self, event, pr_sel_index=0):
        index = self.combobox_preset_groups.current()
        self.auto_groups_id = index
        if self.mode == 'auto':
            group = self.auto_groups[index]
            self.update_presets_combobox()
            if len(group.presets) > 0:
                self.combobox_presets.current(pr_sel_index)
                self.preset_selected(None)
            else:
                self.preset_var.set('Нет пресетов')

    def save_group(self, name, presets_ids, group_id=-1):
        presets = [self.auto_presets[pr_id] for pr_id in presets_ids]
        if group_id < 0:
            group = Group(name, presets)
            self.auto_groups.append(group)
        else:
            self.auto_groups[group_id].name = name
            self.auto_groups[group_id].presets = presets
        self.save_presets()
        self.update_groups_combobox()
        if group_id < 0:
            self.combobox_preset_groups.current(len(self.auto_groups) - 1)
        else:
            self.combobox_preset_groups.current(group_id)
        self.group_selected(None)

    def delete_group(self, id):
        self.auto_groups.pop(id)
        self.auto_groups_id = -1
        self.save_params()
        self.save_presets()
        self.update_groups_combobox()
        self.update_presets_combobox()

    def preset_selected(self, event):
        preset = self.get_cur_preset()
        if self.mode == 'auto':
            self.auto_speed = preset.speed
            self.auto_accel_time = preset.accel_time
            self.auto_deccel_time = preset.deccel_time
            self.auto_work_time = preset.work_time
            self.auto_presets_id = self.combobox_presets.current()
        else:
            self.manual_speed = preset.speed
            self.manual_accel_time = preset.accel_time
            self.manual_deccel_time = preset.deccel_time
            self.manual_presets_id = self.combobox_presets.current()
        self.speed.set(preset.speed)
        self.accel_time.set(preset.accel_time)
        self.deccel_time.set(preset.deccel_time)
        if hasattr(preset, 'work_time'):
            self.work_time.set(preset.work_time)
        else:
            self.work_time.set(0)

        self.servo_set_params()
        self.save_params()

    def update_groups_combobox(self):
        group_names = []
        for group in self.auto_groups:
            group_names.append(group.name)
        self.combobox_preset_groups['values'] = group_names

        if len(group_names) == 0:
            self.preset_groups_var.set('Все пресеты')

    def update_presets_combobox(self):
        preset_names = []
        if self.mode == 'auto':
            if self.auto_groups_id > -1:
                group = self.auto_groups[self.auto_groups_id]
                preset_list = group.presets
            else:
                preset_list = self.auto_presets
        else:
            preset_list = self.manual_presets
        for preset in preset_list:
            preset_names.append(preset.name)
        self.combobox_presets['values'] = preset_names

    def show_notify_window(self, title, text):
        self.notify_master = Toplevel(self.master)
        self.notify_window = NotifyWindow(self, self.notify_master, title,
                                          text)

    def error(self, text):
        self.show_notify_window('Ошибка', text)

    def set_default_settings(self):
        self.preset_var.set('Выбрать пресет')
        self.preset_groups_var.set('Все пресеты')
        self.width = 400
        self.height = 360
        self.master.geometry('%dx%d' % (self.width, self.height))
        self.master.title("Servoline Motor")
        self.master.iconbitmap("icon.ico")
        self.master.resizable(False, False)

    def show_groups_menu(self):
        self.show_element(self.combobox_preset_groups)
        self.show_element(self.btn_group_settings)
        self.show_element(self.btn_group_add)
        self.show_element(self.btn_up_group)
        self.show_element(self.btn_down_group)

    def hide_groups_menu(self):
        self.hide_element(self.combobox_preset_groups)
        self.hide_element(self.btn_group_settings)
        self.hide_element(self.btn_group_add)
        self.hide_element(self.btn_up_group)
        self.hide_element(self.btn_down_group)

    def __init__(self, master):
        self.master = master
        super().__init__(self.master)
        self.set_default_settings()
        self.load_params()
        self.load_presets()
        self.update_groups_combobox()
        if self.auto_groups_id > -1:
            self.combobox_preset_groups.current(self.auto_groups_id)
        self.update_presets_combobox()
        if self.auto_presets_id > -1:
            self.combobox_presets.current(self.auto_presets_id)
            preset = self.auto_presets[self.auto_presets_id]
            self.speed.set(preset.speed)
            self.accel_time.set(preset.accel_time)
            self.deccel_time.set(preset.deccel_time)
            self.work_time.set(preset.work_time)

        self.auto = AutoMode(self)
        self.manual = ManualMode(self)
        self.auto.show()

        self.btn_connect.bind_release(self.change_connect)

        self.switch_motor.bind_sw(self.motor_change_state)
        self.switch_motor.val = True
        self.switch_motor.change_val()

        self.btn_group_settings.bind_release(self.show_group_window)
        self.btn_group_add.bind_release(
            lambda: self.show_group_window(new=True))
        self.btn_up_group.bind_release(self.up_group)
        self.btn_down_group.bind_release(self.down_group)

        self.btn_preset_settings.bind_release(self.show_preset_settings_window)
        self.btn_add_preset.bind_release(self.show_add_preset_window)
        self.btn_up_preset.bind_release(self.up_preset)
        self.btn_down_preset.bind_release(self.down_preset)