#!D:/IDE/anaconda3/envs/Microscope_Scan python
# -*- coding: UTF-8 -*-
"""
@FileName：HardWareUnit.py
@Description：
@Author：XSH
@Time：2025/11/15 16:32
@Department：研发部
@Copyright：©2025 乐辰生物
"""
import win32serviceutil
from PyQt5                          import Qt
from AppInterfaces.ImplInterfaces   import *
from AppInterfaces.AppTimeLoop      import AppTimeLoop
from AppUtils.Comparator            import Comparator
from AppContexts.Contexts           import ModBusContext, ModBusRegister, AxisContext
from AppUtils.AppBitUtils           import AppBitUtils
from AppUtils.AppUtils              import AppUtils
from AppSettings.Settings           import *
from AppCore.Levels                 import *
class HardWareUnit:

    @staticmethod
    def restart_windows_service(service_name):
        import os
        try:
            os.system(f'NET STOP {service_name}')
        except OSError:
            print("system error")
        try:
            os.system(f'NET START {service_name}')
        except OSError:
            print("system error")

    @staticmethod
    def ReadBool(handle: ModBusImplInterface, Register: ModBusRegister) -> bool:
        result: bool = False
        if isinstance(handle, ModBusImplInterface) and handle.IsOpen and isinstance(Register, ModBusRegister):
            try:
                result = True if handle.ReadState(Register.Addr) == 1 else 0
            except Exception as e:
                AppUtils.print_Exception(e)

        return result

    @staticmethod
    def WaitSendBool(handle: ModBusImplInterface, Register: ModBusRegister, value: bool, MaxCount: int = 10) -> int:
        isWarning: int = RECODE_FAILURE
        if not isinstance(handle, ModBusImplInterface):
            return isWarning
        try:
            if not handle.isAvailable:
                handle.ReConnected()
            if not handle.isAvailable:
                return isWarning
            for i in range(int(MaxCount) if isinstance(MaxCount, (int, float)) else 10):
                isWarning = handle.SendState(Register.Addr, value)
                if isWarning == RECODE_SUCCEED:
                    break
                AppTimeLoop.processEvents(10)
        except Exception as e:

            AppUtils.print_Exception(e)
        return isWarning

    @staticmethod
    def SendBool(handle: ModBusImplInterface, Register: ModBusRegister, value: bool) -> int:
        result: int = RECODE_FAILURE
        if isinstance(handle, ModBusImplInterface) and handle.IsOpen and isinstance(Register, ModBusRegister):
            try:
                result = handle.SendState(Register.Addr, value)
            except Exception as e:
                AppUtils.print_Exception(e)

        return result

    @staticmethod
    def ReadUInt16(handle: ModBusImplInterface, Register: ModBusRegister) -> int:
        result: int = 0
        if isinstance(handle, ModBusImplInterface) and handle.IsOpen and isinstance(Register, ModBusRegister):
            try:
                result = handle.ReadUInt16(Register.Addr)
            except Exception as e:
                AppUtils.print_Exception(e)

        return result

    @staticmethod
    def SendUInt16(handle: ModBusImplInterface, Register: ModBusRegister, value: int) -> int:
        isWrong: int = RECODE_FAILURE
        if isinstance(handle, ModBusImplInterface) and handle.IsOpen and isinstance(Register, ModBusRegister):
            try:
                isWrong = handle.SendUInt16(Register.Addr, value)
            except Exception as e:
                AppUtils.print_Exception(e)
        return isWrong

    @staticmethod
    def WaitSendUInt16(handle: ModBusImplInterface, Register: ModBusRegister, value: int, MaxCount: int = 10) -> int:
        isWarning: int = RECODE_FAILURE
        if not isinstance(handle, ModBusImplInterface):
            return isWarning
        try:
            if not handle.isAvailable:
                handle.ReConnected()
            if not handle.isAvailable:
                return isWarning
            for i in range(int(MaxCount) if isinstance(MaxCount, (int, float)) else 10):
                isWarning = handle.SendUInt16(Register.Addr, value)
                if isWarning == RECODE_SUCCEED:
                    break
                AppTimeLoop.processEvents(10)
        except Exception as e:
            AppUtils.print_Exception(e)
        return isWarning

    @staticmethod
    def ReadFloat(handle: ModBusImplInterface, Register: ModBusRegister) -> float:
        result: float = 0
        if isinstance(handle, ModBusImplInterface) and handle.IsOpen and isinstance(Register, ModBusRegister):
            try:
                result = handle.ReadFloat(Register.Addr)
            except Exception as e:
                AppUtils.print_Exception(e)
        return result

    @staticmethod
    def SendFloat(handle: ModBusImplInterface, Register: ModBusRegister, value: float) -> int:
        isWrong: int = RECODE_FAILURE
        if isinstance(handle, ModBusImplInterface) and handle.IsOpen and isinstance(Register, ModBusRegister):
            try:
                isWrong = handle.SendFloat(Register.Addr, value)
            except Exception as e:
                AppUtils.print_Exception(e)
        return isWrong

    @staticmethod
    def WaitSendFloat(handle: ModBusImplInterface, Register: ModBusRegister, value: (int, float), MaxCount: int = 10) -> int:
        isWarning: int = RECODE_FAILURE
        if not isinstance(handle, ModBusImplInterface):
            return isWarning
        try:
            if not handle.isAvailable:
                handle.ReConnected()
            if not handle.isAvailable:
                return isWarning
            for i in range(int(MaxCount) if isinstance(MaxCount, (int, float)) else 10):
                isWarning = handle.SendFloat(Register.Addr, value)
                if isWarning == RECODE_SUCCEED:
                    break
                AppTimeLoop.processEvents(10)
        except Exception as e:
            AppUtils.print_Exception(e)
        return isWarning

    @staticmethod
    def ReadFloats(handle: ModBusImplInterface, Register: ModBusRegister, Count: int) -> list[float]:
        result: list[float] = [0.0] * Count
        if isinstance(handle, ModBusImplInterface) and handle.IsOpen and isinstance(Register, ModBusRegister):
            try:
                result = handle.ReadFloats(Register.Addr, Count, result)
            except Exception as e:
                AppUtils.print_Exception(e)

        return result

    @staticmethod
    def WaitSendFloats(handle: ModBusImplInterface, Register: ModBusRegister, values: list[float], MaxCount: int = 10) -> int:
        isWarning: int = RECODE_FAILURE
        if not isinstance(handle, ModBusImplInterface):
            return isWarning
        try:
            if not handle.isAvailable:
                handle.ReConnected()
            if not handle.isAvailable:
                return isWarning
            for i in range(int(MaxCount) if isinstance(MaxCount, (int, float)) else 10):
                isWarning = handle.SendFloats(Register.Addr, values)
                if isWarning == RECODE_SUCCEED:
                    break
                AppTimeLoop.processEvents(10)
        except Exception as e:
            AppUtils.print_Exception(e)
        return isWarning

    @staticmethod
    def SendFloats(handle: ModBusImplInterface, Register: ModBusRegister, values: list[float]) -> int:
        isWrong: int = RECODE_FAILURE
        if isinstance(handle, ModBusImplInterface) and handle.IsOpen and isinstance(Register, ModBusRegister):
            try:
                isWrong = handle.SendFloats(Register.Addr, values)
            except Exception as e:
                AppUtils.print_Exception(e)

        return isWrong

    @staticmethod
    def axis_move_enable(axis: AxisImplInterface, enable: (bool, int)):
        isWrong: int = RECODE_FAILURE
        if isinstance(axis, AxisImplInterface):
            try:
                isWrong = axis.setScanMoveEnable(enable)
            except Exception as e:
                AppUtils.print_Exception(e)
            AppTimeLoop.delay(4)
        return isWrong

    @staticmethod
    def axis_move_enable_xy(axis_x: AxisImplInterface, axis_y: AxisImplInterface, enable: (bool, int)):
        isWrong: int = RECODE_FAILURE
        if isinstance(axis_x, AxisImplInterface) and isinstance(axis_y, AxisImplInterface):
            handler: ModBusImplInterface
            handler = axis_x.send_handler()
            if not isinstance(handler, ModBusImplInterface) :
                handler = axis_x.new_handler
            if not isinstance(handler, ModBusImplInterface) :
                handler = axis_y.new_handler
            if not isinstance(handler, ModBusImplInterface) :
                return isWrong
            if not handler.isAvailable:
                handler.ReOpen()
            if handler.isAvailable:
                _enable: bool = True if isinstance(enable, (bool, int)) and enable else False
                status: int = AppBitUtils.set_bit(0, AXIS_STATUS_REGISTER_1, 1 if _enable else 0)
                x_warning = HardWareUnit.SendUInt16(handler, axis_x.Parameter.StatusRegister, status)
                y_warning = HardWareUnit.SendUInt16(handler, axis_y.Parameter.StatusRegister, status)
                AppTimeLoop.delay(4)
                isWrong = RECODE_SUCCEED if RECODE_SUCCEED == x_warning and RECODE_SUCCEED == y_warning else RECODE_FAILURE
            # x_warning = axis_x.setScanMoveEnable(enable)
            # y_warning = axis_y.setScanMoveEnable(enable)




        return isWrong

    @staticmethod
    def axis_scan_move_enable(axis: AxisImplInterface, target: (int, float), enable: (int, bool)) -> int:
        isWrong: int = RECODE_FAILURE
        if not isinstance(axis, AxisImplInterface):
            return isWrong
        if enable:
            if not isinstance(target, (int, float)):
                return isWrong
            isWrong = axis.setMoveTarget(float(target), False)
        if RECODE_SUCCEED == isWrong:
            isWrong = axis.setScanMoveEnable(enable)
        if RECODE_SUCCEED == isWrong:
            AppTimeLoop.delay(4)
        return isWrong

    @staticmethod
    def axis_scan_move_enable_xy(axis_x: AxisImplInterface, axis_y: AxisImplInterface, x_value: (int, float), y_value: (int, float)) -> int:
        isWrong: int = RECODE_FAILURE
        if not isinstance(axis_x, AxisImplInterface) or not isinstance(axis_y, AxisImplInterface):
            return isWrong

        if not isinstance(x_value, (float, int)) or not isinstance(y_value, (float, int)):
            return isWrong
        _xPosition: float = round(float(x_value), 4)
        _yPosition: float = round(float(y_value), 4)
        x_warning: int = RECODE_FAILURE
        y_warning: int = RECODE_FAILURE
        handler: ModBusImplInterface
        handler = axis_x.send_handler()
        if not isinstance(handler, ModBusImplInterface):
            handler = axis_x.new_handler
        if not isinstance(handler, ModBusImplInterface):
            return isWrong
        if not handler.isAvailable:
            handler.ReOpen()

        if handler.isAvailable:
            status: int = AppBitUtils.set_bit(0, AXIS_STATUS_REGISTER_1, 1)
            x_warning = HardWareUnit.SendFloat(handler, axis_x.Parameter.MovePosition, _xPosition)
            y_warning = HardWareUnit.SendFloat(handler, axis_y.Parameter.MovePosition, _yPosition)
            AppTimeLoop.delay(4)
            isWrong = RECODE_SUCCEED if RECODE_SUCCEED == x_warning and RECODE_SUCCEED == y_warning else RECODE_FAILURE
            if RECODE_SUCCEED != isWrong:
                return isWrong
            x_warning = HardWareUnit.SendUInt16(handler, axis_x.Parameter.StatusRegister, status)
            y_warning = HardWareUnit.SendUInt16(handler, axis_y.Parameter.StatusRegister, status)
            AppTimeLoop.delay(4)
        isWrong = RECODE_SUCCEED if RECODE_SUCCEED == x_warning and RECODE_SUCCEED == y_warning else RECODE_FAILURE

        return isWrong

    @staticmethod
    def axis_move_complete(axis: AxisImplInterface, target: (bool, int)):
        isWrong: int = RECODE_FAILURE
        if isinstance(axis, AxisImplInterface):
            isWrong = axis.waitmoveComplete(target)
        return isWrong

    @staticmethod
    def axis_move_complete_xy(axis_x: AxisImplInterface, axis_y: AxisImplInterface, x_value: (int, float), y_value: (int, float)) -> int:
        isWrong: int = RECODE_FAILURE
        if not isinstance(axis_x, AxisImplInterface) or not isinstance(axis_y, AxisImplInterface):
            return isWrong
        if not isinstance(x_value, (int, float)) or not isinstance(y_value, (int, float)):
            return isWrong
        isWrong = HardWareUnit.axis_waitmoveComplete(axis_x, axis_y, float(round(x_value, 4)), float(round(y_value, 4)))
        return isWrong

    @staticmethod
    def axis_waitmoveComplete(axis_x: AxisImplInterface, axis_y: AxisImplInterface, x_value: (int, float), y_value: (int, float)) -> int:
        isWrong: int = RECODE_FAILURE
        if not isinstance(axis_x, AxisImplInterface) or not isinstance(axis_y, AxisImplInterface):
            return isWrong
        if not isinstance(x_value, (int, float)) or not isinstance(y_value, (int, float)):
            return isWrong
        x_warning       : int = RECODE_FAILURE
        y_warning       : int = RECODE_FAILURE
        waittimes       : int = 120000
        endtime         : Qt.QDateTime
        status          : int
        _position       : float = -1.0
        _isMoveDone     : int = 0
        _isMoveAlarm    : int
        handler         : ModBusImplInterface = axis_x.readhandler
        if isinstance(handler, ModBusImplInterface) and handler.isAvailable and axis_x.hasParameter and axis_y.hasParameter:
            endtime = Qt.QDateTime.currentDateTime().addMSecs(waittimes)
            while True:

                if x_warning != RECODE_SUCCEED:
                    x_status = HardWareUnit.ReadUInt16(handler, axis_x.Parameter.ReadOnlyRegister)
                    if isinstance(x_status, int):
                        _isMoveDone = AppBitUtils.get_bit(x_status, READONLY_AXIS_STATUS_REGISTER_1)
                        if _isMoveDone == 1:

                            _position = HardWareUnit.ReadFloat(handler, axis_x.Parameter.CurrentPosition)
                            if isinstance(_position, float) and Comparator(_position) == round(float(x_value), 4):
                                x_warning = RECODE_SUCCEED
                        _isMoveAlarm = AppBitUtils.get_bit(x_status, READONLY_AXIS_STATUS_REGISTER_2)
                        if _isMoveAlarm == 1:
                            HardWareUnit.axis_move(axis_x, x_value)

                if y_warning != RECODE_SUCCEED:
                    y_status = HardWareUnit.ReadUInt16(handler, axis_y.Parameter.ReadOnlyRegister)
                    if isinstance(y_status, int):
                        _isMoveDone = AppBitUtils.get_bit(y_status, READONLY_AXIS_STATUS_REGISTER_1)
                        if _isMoveDone == 1:
                            _position = HardWareUnit.ReadFloat(handler, axis_y.Parameter.CurrentPosition)
                            if isinstance(_position, float) and Comparator(_position) == round(float(y_value), 4):
                                y_warning = RECODE_SUCCEED
                        _isMoveAlarm = AppBitUtils.get_bit(y_status, READONLY_AXIS_STATUS_REGISTER_2)
                        if _isMoveAlarm == 1:
                            HardWareUnit.axis_move(axis_y, y_value)
                if RECODE_SUCCEED == x_warning and RECODE_SUCCEED == y_warning:
                    break
                if Qt.QDateTime.currentDateTime() > endtime:
                    break

                AppTimeLoop.processGlobalEvents(50)
            isWrong = RECODE_SUCCEED if RECODE_SUCCEED == x_warning and RECODE_SUCCEED == y_warning else RECODE_FAILURE
        return isWrong

    @staticmethod
    def axis_scan_move(axis_x: AxisImplInterface, position: (int, float)) -> int:
        isWrong: int = RECODE_FAILURE
        if isinstance(axis_x, AxisImplInterface):
            isWrong = axis_x.setScanMove(position)
            AppTimeLoop.delay(4)
        return isWrong

    @staticmethod
    def axis_scan_move_xy(axis_x: AxisImplInterface, axis_y: AxisImplInterface, x_value: (int, float) , y_value: (int, float)) -> int:
        isWrong: int = RECODE_FAILURE
        if not isinstance(axis_x, AxisImplInterface) or not isinstance(axis_y, AxisImplInterface):
            return isWrong
        if not isinstance(x_value, (int, float)) or not isinstance(y_value, (int, float)):
            return isWrong
        x_Wrong = axis_x.setScanMove(float(x_value))
        y_Wrong = axis_y.setScanMove(float(y_value))
        AppTimeLoop.delay(4)
        isWrong = RECODE_SUCCEED if RECODE_SUCCEED == x_Wrong and RECODE_SUCCEED == y_Wrong else RECODE_FAILURE
        return isWrong

    @staticmethod
    def axis_home(axis_x: AxisImplInterface) -> int:
        isWrong: int = RECODE_FAILURE
        if not isinstance(axis_x, AxisImplInterface):
            return isWrong
        isWrong: int = axis_x.home()
        return isWrong

    @staticmethod
    def axis_home_xy(axis_x: AxisImplInterface, axis_y: AxisImplInterface) -> int:
        isWrong: int = RECODE_FAILURE
        if not isinstance(axis_x, AxisImplInterface) or not isinstance(axis_y, AxisImplInterface):
            return isWrong
        isWrong: int = axis_x.home()
        if isWrong != RECODE_SUCCEED:
            return isWrong
        isWrong = axis_y.home()
        return isWrong



    @staticmethod
    def axis_waithome(axis_x: AxisImplInterface) -> int:
        isWrong: int = RECODE_FAILURE
        if not isinstance(axis_x, AxisImplInterface):
            return isWrong

        isWrong: int = axis_x.home()
        if isWrong != RECODE_SUCCEED:
            return isWrong
        isWrong = axis_x.waitForReturning()
        return isWrong

    @staticmethod
    def axis_waithome_xy(axis_x: AxisImplInterface, axis_y: AxisImplInterface) -> int:
        isWrong: int = RECODE_FAILURE
        if not isinstance(axis_x, AxisImplInterface) or not isinstance(axis_y, AxisImplInterface):
            return isWrong
        isWrong: int = axis_x.home()
        if isWrong != RECODE_SUCCEED:
            return isWrong
        isWrong = axis_y.home()
        if isWrong != RECODE_SUCCEED:
            return isWrong
        isWrong = axis_x.waitForReturning()
        if isWrong != RECODE_SUCCEED:
            return isWrong
        isWrong = axis_y.waitForReturning()
        if isWrong != RECODE_SUCCEED:
            return isWrong
        return isWrong

    @staticmethod
    def axis_jop_move(axis: AxisImplInterface, direction: int, velocity: (int, float), max_limit: (int, float)):
        isWrong: int = RECODE_FAILURE
        if not isinstance(axis, AxisImplInterface):
            return isWrong
        MoveDir   : int = getattr(axis, 'MoveDir', MoveDirection.STOP)
        JopMove   : int = getattr(axis, 'JopMove', False)
        Direction: int = direction if direction in MoveDirection.all() else MoveDirection.STOP
        if isinstance(MoveDir, int):
            if JopMove and Direction == MoveDir:
                return RECODE_SUCCEED
            else:
                axis.setForward (False)
                axis.setBackward(False)
                JopMove = False
        if JopMove:
            axis.setForward (False)
            axis.setBackward(False)
        isWrong, position = axis.get_position()
        if isWrong != RECODE_SUCCEED or not isinstance(position, (int, float)):
            return isWrong


        if Direction != MoveDirection.STOP:
            axis.changedJopParameter(velocity)
            AppTimeLoop.delay(4)
            if Direction == MoveDirection.Forward:
                if Comparator(position) >= float(max_limit):
                    return RECODE_SUCCEED
                isWrong = axis.setForward(True)
            elif Direction == MoveDirection.Backward:
                if axis.Level == AxisLevel.AxisX:
                    isWrong = axis.setBackward(True)
                else:
                    if Comparator( position) <= 0:
                        axis.setForward(False)
                        axis.setBackward(False)
                        return RECODE_SUCCEED
                    else:
                        isWrong = axis.setBackward(True)




            else:
                axis.setForward (False)
                axis.setBackward(False)
        else:
            axis.setForward (False)
            axis.setBackward(False)

        setattr(axis, 'MoveDir'     , Direction)
        setattr(axis, 'JopMove'     , RECODE_SUCCEED == isWrong and Direction != MoveDirection.STOP)
        return isWrong



    @staticmethod
    def axis_jop_move_xy(axis_x: AxisImplInterface, axis_y: AxisImplInterface, x_direction: int, y_direction: int, velocity_x: (int, float), velocity_y: (int, float), max_limit_x: (int, float), max_limit_y: (int, float)) -> int:
        isWrong: int = RECODE_FAILURE
        if not isinstance(axis_x, AxisImplInterface) or not isinstance(axis_y, AxisImplInterface):
            return isWrong
        isWrong = HardWareUnit.axis_jop_move(axis_x, x_direction, velocity_x, max_limit_x)
        if isWrong == RECODE_SUCCEED:
            isWrong = HardWareUnit.axis_jop_move(axis_y, y_direction, velocity_y, max_limit_y)
        if isWrong != RECODE_SUCCEED:
            HardWareUnit.axis_jop_stop_xy(axis_x, axis_y)
        return isWrong


    @staticmethod
    def axis_jop_stop(axis: AxisImplInterface) -> int:
        isWrong: int = RECODE_FAILURE
        if not isinstance(axis, AxisImplInterface):
            return isWrong
        axis.setBackward(False)
        axis.setForward(False)
        setattr(axis, 'MoveDir', MoveDirection.STOP )
        setattr(axis, 'JopMove', True               )
        return RECODE_SUCCEED


    @staticmethod
    def axis_jop_stop_xy(axis_x: AxisImplInterface, axis_y: AxisImplInterface) -> int:
        isWrong: int = RECODE_FAILURE
        if not isinstance(axis_x, AxisImplInterface) or not isinstance(axis_y, AxisImplInterface):
            return isWrong
        axis_x.setBackward(False)
        axis_x.setForward(False)
        axis_y.setBackward(False)
        axis_y.setForward(False)
        setattr(axis_x, 'MoveDir', MoveDirection.STOP)
        setattr(axis_x, 'JopMove', True)
        setattr(axis_y, 'MoveDir', MoveDirection.STOP)
        setattr(axis_y, 'JopMove', True)
        return RECODE_SUCCEED

    @staticmethod
    def axis_rel_move(axis: AxisImplInterface, value: (int, float)) -> int:
        isWrong: int = RECODE_FAILURE
        if not isinstance(axis, AxisImplInterface):
            return isWrong
        if isinstance(value, (float, int)):
            position: float
            isWrong, position = axis.getPosition()
            if RECODE_SUCCEED != isWrong or not isinstance(position, (int, float)):
                return isWrong
            target: float = float(round(float(position) + float(value), 4))
            isWrong = axis.move(target)
            return isWrong
        return isWrong

    @staticmethod
    def axis_rel_move_xy(axis_x: AxisImplInterface, axis_y: AxisImplInterface, x_value: (int, float) , y_value: (int, float)) -> int:
        isWrong: int = RECODE_FAILURE
        if isinstance(x_value, (float, int)) and isinstance(y_value, (int, float)):
            x_position: float
            y_position: float
            x_target  : float
            y_target  : float
            isWrong, x_position, y_position = HardWareUnit.get_axis_position_xy(axis_x, axis_y)
            if RECODE_SUCCEED != isWrong or not isinstance(x_position, (int, float)) or not isinstance(y_position, (int, float)):
                return isWrong
            x_target: float = round(float(x_position) + float(x_value), 4)
            y_target: float = round(float(y_position) + float(y_value), 4)
            isWrong = HardWareUnit.axis_move_xy(axis_x, axis_y, x_target, y_target)
        return isWrong

    @staticmethod
    def axis_rel_waitmove(axis: AxisImplInterface, value: (int, float)) -> int:
        isWrong: int = RECODE_FAILURE
        if not isinstance(axix, AxisImplInterface):
            return isWrong
        if isinstance(value, (float, int)):
            position: float
            isWrong, position = axis.getPosition()
            if RECODE_SUCCEED != isWrong or not isinstance(position, (int, float)):
                return isWrong
            target: float = round(float(position) + float(value), 4)
            isWrong = axis.waitmove(target)
            return isWrong
        return isWrong

    @staticmethod
    def axis_rel_waitmove_xy(axis_x: AxisImplInterface, axis_y: AxisImplInterface, x_value: (int, float), y_value: (int, float)) -> int:
        isWrong: int = RECODE_FAILURE
        if isinstance(x_value, (float, int)) and isinstance(y_value, (int, float)):
            x_position: float
            y_position: float
            x_target: float
            y_target: float
            isWrong, x_position, y_position = HardWareUnit.get_axis_position_xy(axis_x, axis_y)
            if RECODE_SUCCEED != isWrong or not isinstance(x_position, (int, float)) or not isinstance(y_position, (int, float)):
                return isWrong
            x_target: float = round(float(x_position) + float(x_value), 4)
            y_target: float = round(float(y_position) + float(y_value), 4)
            isWrong = HardWareUnit.axis_waitmove_xy(axis_x, axis_y, x_target, y_target)
        return isWrong

    @staticmethod
    def axis_move(axis: AxisImplInterface, position: (int, float), **args) -> int:
        isWrong: int = RECODE_FAILURE
        if not isinstance(axis, AxisImplInterface):
            return isWrong
        if isinstance(position, (float, int)):
            _position: float = round(float(position), 4)
            isWrong = HardWareUnit.axis_move_enable(axis, False)
            AppTimeLoop.delay(4)
            if RECODE_SUCCEED != isWrong:
                return isWrong

            if RECODE_SUCCEED != axis.setMoveParameter(_position):
                return isWrong
            isWrong = HardWareUnit.axis_move_enable(axis, True)
            AppTimeLoop.delay(4)
        return isWrong

    @staticmethod
    def axis_move_xy(axis_x: AxisImplInterface, axis_y: AxisImplInterface, xPosition: (int, float), yPosition: (int, float)) -> int:
        isWrong: int = RECODE_FAILURE
        if not isinstance(axis_x, AxisImplInterface) or not isinstance(axis_y, AxisImplInterface):
            return isWrong

        if not isinstance(xPosition, (float, int)) or not isinstance(yPosition, (float, int)):
            return isWrong
        _xPosition: float = round(float(xPosition), 4)
        _yPosition: float = round(float(yPosition), 4)
        isWrong = HardWareUnit.axis_move_enable_xy(axis_x, axis_y, False)
        if RECODE_SUCCEED != isWrong:
            return isWrong
        isWrong = HardWareUnit.axis_move_parameter_xy(axis_x, axis_y, _xPosition, _yPosition)
        if RECODE_SUCCEED != isWrong:
            return isWrong
        isWrong = HardWareUnit.axis_move_enable_xy(axis_x, axis_y, True)
        return isWrong

    @staticmethod
    def axis_move_parameter(axis: AxisImplInterface, position: (int, float)) -> int:
        isWrong: int = RECODE_FAILURE
        if not isinstance(axis, AxisImplInterface) or not isinstance(position, (int, float)):
            return isWrong
        isWrong = axis.setMoveParameter(round(float(position), 4))
        return isWrong

    @staticmethod
    def axis_move_parameter_xy(axis_x: AxisImplInterface, axis_y: AxisImplInterface, xPosition: (int, float), yPosition: (int, float)) -> int:
        isWrong: int = RECODE_FAILURE
        if not isinstance(axis_x, AxisImplInterface) or not isinstance(axis_y, AxisImplInterface):
            return isWrong
        if not isinstance(xPosition, (int, float)) or not isinstance(yPosition, (int, float)):
            return isWrong
        x_Wrong = axis_x.setMoveParameter(xPosition)
        y_Wrong = axis_y.setMoveParameter(yPosition)
        AppTimeLoop.delay(4)
        isWrong = RECODE_SUCCEED if RECODE_SUCCEED == x_Wrong and RECODE_SUCCEED == y_Wrong else RECODE_FAILURE
        return isWrong

    @staticmethod
    def axis_move_target_xy(axis_x: AxisImplInterface, axis_y: AxisImplInterface, xPosition: (int, float), yPosition: (int, float)) -> int:
        isWrong: int = RECODE_FAILURE
        if not isinstance(axis_x, AxisImplInterface) or not isinstance(axis_y, AxisImplInterface):
            return isWrong
        if not isinstance(xPosition, (int, float)) or not isinstance(yPosition, (int, float)):
            return isWrong
        x_Wrong = axis_x.setMoveTarget(xPosition, False)
        y_Wrong = axis_y.setMoveTarget(yPosition, False)
        AppTimeLoop.delay(4)
        isWrong = RECODE_SUCCEED if RECODE_SUCCEED == x_Wrong and RECODE_SUCCEED == y_Wrong else RECODE_FAILURE
        return isWrong

    @staticmethod
    def axis_waitmove(axis: AxisImplInterface, position: (int, float)) -> int:
        isWrong: int = RECODE_FAILURE
        if not isinstance(axis, AxisImplInterface):
            return isWrong
        if isinstance(position, (float, int)):
            _position: float = round(float(position), 4)
            isWrong = HardWareUnit.axis_move_enable(axis, False)
            if RECODE_SUCCEED != isWrong:
                return isWrong
            isWrong = HardWareUnit.axis_move_parameter(axis, _position)
            if RECODE_SUCCEED != isWrong:
                return isWrong

            isWrong = HardWareUnit.axis_move(axis, _position)
            if RECODE_SUCCEED != isWrong:
                return isWrong
            isWrong = axis.waitmoveComplete(_position)
            for count in range(0, 3):
                if RECODE_SUCCEED == isWrong:
                    break
                HardWareUnit.axis_move(axis, _position)
                isWrong = axis.waitmoveComplete(_position)
        return isWrong

    @staticmethod
    def get_axis_position(axis: (AxisImplInterface, HookImplInterface)) -> (int, float):
        isWrong: int = RECODE_FAILURE
        position: float = None
        if isinstance(axis, AxisImplInterface):
            isWrong, position = axis.getPosition()
        elif isinstance(axis, HookImplInterface):
            isWrong, position = axis.getPosition()
        return isWrong, position

    @staticmethod
    def get_axis_position_xy(axis_x: (AxisImplInterface, HookImplInterface), axis_y: (AxisImplInterface, HookImplInterface)) -> (int, float, float):
        isWrong: int = RECODE_FAILURE
        x_position: float = None
        y_position: float = None
        if isinstance(axis_x, AxisImplInterface):
            isWrong, x_position = axis_x.getPosition()
        elif isinstance(axis_x, HookImplInterface):
            isWrong, x_position = axis_x.getPosition()

        if RECODE_SUCCEED != isWrong:
            return isWrong, x_position, y_position
        if isinstance(axis_y, AxisImplInterface):
            isWrong, y_position = axis_y.getPosition()
        elif isinstance(axis_y, HookImplInterface):
            isWrong, y_position = axis_y.getPosition()
        return isWrong, x_position, y_position

    @staticmethod
    def axis_load_velocity(axis: AxisImplInterface):
        if isinstance(axis, AxisImplInterface):
            axis.reload_velocity()

    @staticmethod
    def axis_xy_load_velocity(axis_x: AxisImplInterface, axis_y: AxisImplInterface):
        if isinstance(axis_x, AxisImplInterface):
            axis_x.reload_velocity()

        if isinstance(axis_y, AxisImplInterface):
            axis_y.reload_velocity()

    @staticmethod
    def axis_reset(axis: AxisImplInterface):
        if isinstance(axis, AxisImplInterface):
            axis.Reset(True)

    @staticmethod
    def axis_xy_reset(axis_x: AxisImplInterface, axis_y: AxisImplInterface):
        isWrong: int = RECODE_FAILURE
        if isinstance(axis_x, AxisImplInterface):
            isWrong = axis_x.Reset(True)
            if RECODE_SUCCEED != isWrong:
                return isWrong
        if isinstance(axis_y, AxisImplInterface):
            isWrong = axis_y.Reset(True)
            if RECODE_SUCCEED != isWrong:
                return isWrong
        return isWrong

    @staticmethod
    def axis_waitmove_xy(axis_x: AxisImplInterface, axis_y: AxisImplInterface, xPosition: (int, float), yPosition: (int, float)) -> int:
        isWrong: int = RECODE_FAILURE
        if not isinstance(axis_x, AxisImplInterface) or not isinstance(axis_y, AxisImplInterface):
            return isWrong
        isWrong = HardWareUnit.axis_move_enable_xy(axis_x, axis_y, False)
        if RECODE_SUCCEED != isWrong:
            return isWrong
        if isinstance(xPosition, (float, int)) and isinstance(yPosition, (float, int)):
            _xPosition: float = float(round(xPosition, 4))
            _yPosition: float = float(round(yPosition, 4))
            isWrong = HardWareUnit.axis_move_parameter_xy(axis_x, axis_y, _xPosition, _yPosition)
            if RECODE_SUCCEED != isWrong:
                return isWrong

            isWrong = HardWareUnit.axis_move_enable_xy(axis_x, axis_y, True)
            if RECODE_SUCCEED != isWrong:
                return isWrong
            isWrong = HardWareUnit.axis_move_complete_xy(axis_x, axis_y, _xPosition, _yPosition)
            if RECODE_SUCCEED == isWrong:
                return isWrong
            # print(f"移动XY时间:{begin.msecsTo(Qt.QDateTime.currentDateTime())}ms")
            for count in range(0, 2):
                isWrong = HardWareUnit.axis_move_complete_xy(axis_x, axis_y, _xPosition, _yPosition)
                if RECODE_SUCCEED == isWrong:
                    return isWrong
        return isWrong

    @staticmethod
    def axis_waitmove_scanning_xy(axis_x: AxisImplInterface, axis_y: AxisImplInterface, xPosition: (int, float), yPosition: (int, float)) -> int:
        isWrong: int = RECODE_FAILURE
        if not isinstance(axis_x, AxisImplInterface) or not isinstance(axis_y, AxisImplInterface):
            return isWrong
        isWrong = HardWareUnit.axis_move_enable_xy(axis_x, axis_y, False)
        if RECODE_SUCCEED != isWrong:
            return isWrong
        if isinstance(xPosition, (float, int)) and isinstance(yPosition, (float, int)):
            _xPosition: float = float(round(xPosition, 4))
            _yPosition: float = float(round(yPosition, 4))
            isWrong = HardWareUnit.axis_move_target_xy(axis_x, axis_y, _xPosition, _yPosition)
            if RECODE_SUCCEED != isWrong:
                return isWrong

            isWrong = HardWareUnit.axis_move_enable_xy(axis_x, axis_y, True)
            if RECODE_SUCCEED != isWrong:
                return isWrong
            isWrong = HardWareUnit.axis_move_complete_xy(axis_x, axis_y, _xPosition, _yPosition)
            if RECODE_SUCCEED == isWrong:
                return isWrong
            # print(f"移动XY时间:{begin.msecsTo(Qt.QDateTime.currentDateTime())}ms")
            for count in range(0, 2):
                isWrong = HardWareUnit.axis_move_complete_xy(axis_x, axis_y, _xPosition, _yPosition)
                if RECODE_SUCCEED == isWrong:
                    return isWrong
        return isWrong