#!D:/IDE/anaconda3/envs/Microscope_Scan python
# -*- coding: UTF-8 -*-
"""
@FileName：AxisImpl.py
@Description：
@Author：XSH
@Time：2025/11/14 13:15
@Department：研发部
@Copyright：©2025 乐辰生物
"""
from AppSettings.Settings           import *
from AppUtils.utils                 import *
from AppInterfaces.AppTimeLoop import AppTimeLoop
from AppInterfaces.ImplInterfaces   import AxisImplInterface, ModBusImplInterface, ModBusPoolInterface
from AppContexts.Contexts           import AxisContext
from AppCore.Levels                 import AxisLevel
from AppUtils.HardWareUnit import HardWareUnit
class AxisImpl(Qt.QObject, AxisImplInterface):
    def __init__(self, context: AxisContext , pool: ModBusPoolInterface = None,parent: Qt.QObject = None, **args):
        super(AxisImpl, self).__init__(parent=parent)

        self.Parameter =    context if isinstance(context   , AxisContext           ) else None
        self.Manager   =    pool    if isinstance(pool      , ModBusPoolInterface   ) else None
        self.Initialization('AxisImpl', self, parent)
        Level = self.Parameter.Level if self.hasParameter else AxisLevel.AxisX
        self.setLevel(Level)



    
    def setLevel(self, level: int, **args):
        from AppCore.AppDBModels.ConfigModels.AxisVelocityModel import AxisVelocityModel
        _level          = level if level in AxisLevel.all() else AxisLevel.AxisX
        if not self.hasLevel or self.Level != _level:
            self.Level = _level
            self.initContext()
        MoveVelocity: float
        Acceleration: float
        Deceleration: float
        MoveVelocity, Acceleration, Deceleration = AxisVelocityModel.AxisSpeeds(self.Level)
        self.Parameter.MoveVelocity.Data       = MoveVelocity
        self.Parameter.Acceleration.Data       = Acceleration
        self.Parameter.Deceleration.Data       = Deceleration
        self.Parameter.JOPVelocity.Data        = MoveVelocity
        self.Parameter.JOPAcceleration.Data    = Acceleration
        self.Parameter.JOPDeceleration.Data    = Deceleration
        self.changedMoveParameter(MoveVelocity, Acceleration, Deceleration, True)

    def reload_velocity(self):
        if not self.hasLevel:
            return
        from AppCore.AppDBModels.ConfigModels.AxisVelocityModel import AxisVelocityModel
        MoveVelocity: float
        Acceleration: float
        Deceleration: float
        MoveVelocity, Acceleration, Deceleration = AxisVelocityModel.AxisSpeeds(self.Level)
        self.Parameter.MoveVelocity.Data    = MoveVelocity
        self.Parameter.Acceleration.Data    = Acceleration
        self.Parameter.Deceleration.Data    = Deceleration
        self.Parameter.JOPVelocity.Data     = MoveVelocity
        self.Parameter.JOPAcceleration.Data = Acceleration
        self.Parameter.JOPDeceleration.Data = Deceleration
        self.changedMoveParameter(MoveVelocity, Acceleration, Deceleration, True)
    


    
    def initContext(self):
        if not self.hasLevel:
            return
        if not self.hasParameter:
            self.Parameter = AxisContext()
            self.Parameter.setLevel(self.level)

    
    def home(self):
        isWrong: int = self.Reset(True)
        if RECODE_SUCCEED != isWrong:
            return isWrong
        isWrong = self.setHome(True)
        AppTimeLoop.delay(10)
        self.is_IsInitialize = RECODE_SUCCEED == isWrong
        return isWrong

    
    def hasAxisHome(self) -> int:
        isWrong: int = RECODE_FAILURE
        handler: ModBusImplInterface = self.readhandler
        if not isinstance(handler, ModBusImplInterface):
            handler = self.new_handler
        if not handler.isAvailable:
            handler.ReConnected()
        if handler.isAvailable:
            status = HardWareUnit.ReadUInt16(handler, self.Parameter.ReadOnlyRegister)
            if isinstance(status, int):
                _isHomeDone = AppBitUtils.get_bit(status, READONLY_AXIS_STATUS_REGISTER_3)
                _isHomeAlarm = AppBitUtils.get_bit(status, READONLY_AXIS_STATUS_REGISTER_4)
                isWrong = RECODE_SUCCEED if _isHomeDone == 1 and _isHomeAlarm != 1 else RECODE_FAILURE
        return isWrong

    
    def waitHome(self):
        isWrong = HardWareUnit.axis_waithome(self)
        return isWrong

    
    def move(self, position: float) -> int:
        self.setMove(False)
        AppTimeLoop.delay(5)
        isWrong: int = self.setMoveParameter(position)
        if RECODE_SUCCEED != isWrong:
            return isWrong
        isWrong = self.setMove(True)
        AppTimeLoop.delay(5)
        return isWrong

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

    def rel_waitmove(self, value: (int, float)) -> int:
        isWrong: int = RECODE_FAILURE
        if not isinstance(value, (int, float)):
            return isWrong
        position: float
        isWrong, position = self.getPosition()
        if RECODE_SUCCEED != isWrong or not isinstance(position, (int, float)):
            return isWrong
        target: float = float(round(float(position) + float(value), 4))
        isWrong = self.waitmove(target)
        return isWrong

    def waitmove(self, position: float) -> int:
        self.setMove(False)
        AppTimeLoop.delay(5)
        isWrong: int = self.setMoveParameter(position)

        if RECODE_SUCCEED != isWrong:
            return isWrong
        isWrong = self.setMove(True)
        AppTimeLoop.delay(5)
        if RECODE_SUCCEED != isWrong:
            return isWrong
        return self.waitmoveComplete(position)

    
    def waitForReturning(self, waittimes: int = 240000) -> int:
        isWrong             : int = RECODE_FAILURE
        waittime            : int = min(240000, max(500, waittimes))
        delay               : int = 5
        endtime             : Qt.QDateTime
        status              : int
        _isHomeDone         : int
        _isHomeAlarm        : int
        handler             : ModBusImplInterface = self.readhandler
        if not isinstance(handler, ModBusImplInterface):
            handler = self.new_handler
        if not handler.isAvailable:
            handler.ReConnected()
        if handler.isAvailable:
            endtime         = Qt.QDateTime.currentDateTime().addMSecs(waittime)
            while True:
                status = HardWareUnit.ReadUInt16(handler, self.Parameter.ReadOnlyRegister)
                if isinstance(status, int):
                    _isHomeDone     = AppBitUtils.get_bit(status, READONLY_AXIS_STATUS_REGISTER_3)
                    _isHomeAlarm    = AppBitUtils.get_bit(status, READONLY_AXIS_STATUS_REGISTER_4)
                    if Qt.QDateTime.currentDateTime() > endtime:
                        break
                    if _isHomeDone == 1:
                        break
                    if _isHomeAlarm == 1:
                        self.Reset(True, 300)
                        self.home()
                AppTimeLoop.processEvents(delay)
            isWrong = RECODE_SUCCEED if _isHomeDone == 1 else RECODE_FAILURE
        return isWrong

    
    def waitForMoving(self, waittimes: int) -> int:
        isWrong         : int = RECODE_FAILURE
        waittime        : int = min(120000, max(100, waittimes))
        delay           : int = 100
        endtime         : Qt.QDateTime
        status          : int
        _isMoving       : int
        _isMoveAlarm    : int
        handler: ModBusImplInterface = self.readhandler
        if not isinstance(handler, ModBusImplInterface):
            handler = self.new_handler
        if not handler.isAvailable:
            handler.ReConnected()
        if handler.isAvailable:
            endtime = Qt.QDateTime.currentDateTime().addMSecs(waittime)
            while True:
                status = HardWareUnit.ReadUInt16(handler, self.Parameter.ReadOnlyRegister)
                if isinstance(status, int):
                    _isMoving = AppBitUtils.get_bit(status, READONLY_AXIS_STATUS_REGISTER_5)
                    _isMoveAlarm = AppBitUtils.get_bit(status, READONLY_AXIS_STATUS_REGISTER_2)
                    if Qt.QDateTime.currentDateTime() > endtime:
                        break
                    if _isMoving == 1:
                        break
                    if _isMoveAlarm == 1:
                        break
                AppTimeLoop.processEvents(delay)
            isWrong = RECODE_SUCCEED if _isMoving == 1 else RECODE_FAILURE
        return isWrong

    
    def waitmoveComplete(self, position: float) -> int:
        isWrong         : int = RECODE_FAILURE
        waittimes       : int = 120000
        endtime         : Qt.QDateTime
        status          : int
        _position       : float = -1.0
        _isMoveDone     : int = 0
        _isMoveAlarm    : int
        handler: ModBusImplInterface = self.readhandler
        if not isinstance(handler, ModBusImplInterface):
            handler = self.new_handler
        if not handler.isAvailable:
            handler.ReConnected()
        if handler.isAvailable:
            endtime = Qt.QDateTime.currentDateTime().addMSecs(waittimes)
            while True:
                status = HardWareUnit.ReadUInt16(handler, self.Parameter.ReadOnlyRegister)
                if isinstance(status, int):
                    _isMoveDone = AppBitUtils.get_bit(status, READONLY_AXIS_STATUS_REGISTER_1)
                    if _isMoveDone == 1:
                        _position = HardWareUnit.ReadFloat(handler, self.Parameter.CurrentPosition)
                        if isinstance(_position, float) and Comparator(_position) == round(float(position), 4):
                            break
                    _isMoveAlarm = AppBitUtils.get_bit(status, READONLY_AXIS_STATUS_REGISTER_2)
                    if _isMoveAlarm == 1:
                        self.Reset(True)
                        self.setMoveTarget(position, True)
                        self.setMove(True)
                if Qt.QDateTime.currentDateTime() > endtime:
                    break
                AppTimeLoop.delay(5)
            isWrong = RECODE_SUCCEED if Comparator(_position) == position or _isMoveDone == 1 else RECODE_FAILURE
        return isWrong

    
    def waitForReadOnlyRegister(self, index: int, enable: bool = True, waittimes: int = 60000) -> int:
        result  : int = 0 if enable else 1
        delay   : int = 50
        maxmsec : int = min(max(300, waittimes), 120000)
        status  : int
        endtime : Qt.QDateTime
        handler: ModBusImplInterface = self.readhandler
        if not isinstance(handler, ModBusImplInterface):
            handler = self.new_handler
        if not handler.isAvailable:
            handler.ReConnected()
        if handler.isAvailable:
            if isinstance(handler, ModBusImplInterface) and handler.isAvailable:
                endtime = Qt.QDateTime.currentDateTime().addMSecs(maxmsec)
                while True:
                    status = HardWareUnit.ReadUInt16(handler, self.Parameter.ReadOnlyRegister)
                    if Qt.QDateTime.currentDateTime() > endtime:
                        break
                    if isinstance(status, int):
                        result = AppBitUtils.get_bit(status, index)
                        if result == enable:
                            break
                    AppTimeLoop.delay(delay)
        return result

    
    def waitForStatusRegister(self, index: int, enable: bool = True, waittimes: int = 60000) -> int:
        result  : int = 0 if enable else 1
        delay   : int = 50
        maxmsec : int = min(max(300, waittimes), 120000)
        status  : int
        endtime : Qt.QDateTime
        handler: ModBusImplInterface = self.readhandler
        if not isinstance(handler, ModBusImplInterface):
            handler = self.new_handler
        if not handler.isAvailable:
            handler.ReConnected()
        if handler.isAvailable:
            endtime = Qt.QDateTime.currentDateTime().addMSecs(maxmsec)
            while True:
                status = HardWareUnit.ReadUInt16(handler, self.Parameter.StatusRegister)
                if Qt.QDateTime.currentDateTime() > endtime:
                    break
                if isinstance(status, int):
                    result = AppBitUtils.get_bit(status, index)
                    if result == enable:
                        break
                AppTimeLoop.delay(delay)
        return result

    
    def isEnable(self) -> bool:
        handler: ModBusImplInterface = self.readhandler
        status: int = 0
        if not isinstance(handler, ModBusImplInterface):
            handler = self.new_handler
        if isinstance(handler, ModBusImplInterface):
            if not handler.isAvailable:
                handler.ReConnected()
            if handler.isAvailable:
                _status: int = HardWareUnit.ReadUInt16(handler, self.Parameter.StatusRegister)
                status = _status if isinstance(_status, int) else status
        return AppBitUtils.get_bit(status, READONLY_AXIS_STATUS_REGISTER_0) == 1

    
    def setEnable(self, enable: bool) -> int:
        isWrong: int = RECODE_FAILURE
        handler: ModBusImplInterface = self.readhandler
        if not isinstance(handler, ModBusImplInterface):
            handler = self.new_handler
        if isinstance(handler, ModBusImplInterface):
            if not handler.isAvailable:
                handler.ReConnected()
            if handler.isAvailable:
                status: int = AppBitUtils.set_bit(0, READONLY_AXIS_STATUS_REGISTER_0, True if isinstance(enable, (bool, int)) and enable else False)
                isWrong = HardWareUnit.SendUInt16(handler, self.Parameter.StatusRegister, status)
                self.waitForStatusRegister(READONLY_AXIS_STATUS_REGISTER_0, enable, 500)
        return isWrong

    
    def isPowerON(self) -> bool:
        handler: ModBusImplInterface = self.readhandler
        if not isinstance(handler, ModBusImplInterface):
            handler = self.new_handler
        if isinstance(handler, ModBusImplInterface):
            if not handler.isAvailable:
                handler.ReConnected()
            if handler.isAvailable:
                _status: bool = HardWareUnit.ReadBool(handler, self.Parameter.PowerRegister)
                return False if not isinstance(_status, bool) else _status
        return False

    
    def setPower(self, enable: bool) -> int:
        handler: ModBusImplInterface = self.handler
        if not isinstance(handler, ModBusImplInterface):
            handler = self.new_handler
        if isinstance(handler, ModBusImplInterface):
            if not handler.isAvailable:
                handler.ReConnected()
            if handler.isAvailable:
                return HardWareUnit.SendBool(handler, self.Parameter.PowerRegister, enable)
        return RECODE_FAILURE

    
    def Reset(self, enable: bool, delay: int = 300) -> int:
        isWrong: int = RECODE_FAILURE
        handler: ModBusImplInterface = self.handler
        if not isinstance(handler, ModBusImplInterface):
            handler = self.new_handler
        if isinstance(handler, ModBusImplInterface):
            if not handler.isAvailable:
                handler.ReConnected()
            if handler.isAvailable:
                status: int = AppBitUtils.set_bit(0, AXIS_STATUS_REGISTER_4, 1 if isinstance(enable, (bool, int)) and enable else 0)
                isWrong = HardWareUnit.SendUInt16(handler, self.Parameter.StatusRegister, status)
                self.waitForStatusRegister(AXIS_STATUS_REGISTER_4, not enable, delay)
        return isWrong

    
    def position(self) -> float:
        isWrong: int = RECODE_FAILURE
        position: float = None
        handler: ModBusImplInterface = self.readhandler
        if not isinstance(handler, ModBusImplInterface):
            handler = self.new_handler
        if isinstance(handler, ModBusImplInterface):
            if not handler.isAvailable:
                handler.ReConnected()
            if handler.isAvailable:
                _position = HardWareUnit.ReadFloat(handler, self.Parameter.CurrentPosition)
                if RECODE_SUCCEED == isWrong and isinstance(_position, (int, float)):
                    position = _position
        return position

    
    def getPosition(self) -> (int, float):
        isWrong: int = RECODE_FAILURE
        position: float = None
        handler: ModBusImplInterface = self.readhandler
        if not isinstance(handler, ModBusImplInterface):
            handler = self.new_handler
        if isinstance(handler, ModBusImplInterface):
            if not handler.isAvailable:
                handler.ReConnected()
            if handler.isAvailable:
                _position = HardWareUnit.ReadFloat(handler, self.Parameter.CurrentPosition)
                isWrong = RECODE_SUCCEED if isinstance(_position, float) else RECODE_FAILURE
                position = _position if isinstance(_position, float) else position
        return isWrong, position

    def get_position(self) -> (int, float):
        isWrong: int = RECODE_FAILURE
        position: float = None
        handler: ModBusImplInterface = self.readhandler
        if not isinstance(handler, ModBusImplInterface):
            handler = self.new_handler
        if isinstance(handler, ModBusImplInterface):
            if not handler.isAvailable:
                handler.ReConnected()
            if handler.isAvailable:
                _position = HardWareUnit.ReadFloat(handler, self.Parameter.CurrentPosition)
                isWrong = RECODE_SUCCEED if isinstance(_position, float) else RECODE_FAILURE
                position = _position if isinstance(_position, float) else position
        return isWrong, position

    def isEnabled(self) -> bool:
        handler: ModBusImplInterface = self.readhandler
        if not isinstance(handler, ModBusImplInterface):
            handler = self.new_handler
        if isinstance(handler, ModBusImplInterface):
            if not handler.isAvailable:
                handler.ReConnected()
            if handler.isAvailable:
                status: int = HardWareUnit.ReadUInt16(handler, self.Parameter.ReadOnlyRegister)
                return False if not isinstance(status, int) else AppBitUtils.get_bit(status, READONLY_AXIS_STATUS_REGISTER_0)
        return False

    
    def isMoveDone(self) -> bool:
        handler: ModBusImplInterface = self.readhandler
        if not isinstance(handler, ModBusImplInterface):
            handler = self.new_handler
        if isinstance(handler, ModBusImplInterface):
            if not handler.isAvailable:
                handler.ReConnected()
            if handler.isAvailable:
                status: int = HardWareUnit.ReadUInt16(handler, self.Parameter.ReadOnlyRegister)
                return False if not isinstance(status, int) else AppBitUtils.get_bit(status, READONLY_AXIS_STATUS_REGISTER_1)
        return False

    
    def isMoveAlarm(self) -> bool:
        handler: ModBusImplInterface = self.readhandler
        if not isinstance(handler, ModBusImplInterface):
            handler = self.new_handler
        if isinstance(handler, ModBusImplInterface):
            if not handler.isAvailable:
                handler.ReConnected()
            if handler.isAvailable:
                status: int = HardWareUnit.ReadUInt16(handler, self.Parameter.ReadOnlyRegister)
                return False if not isinstance(status, int) else AppBitUtils.get_bit(status,  READONLY_AXIS_STATUS_REGISTER_2)
        return False

    
    def isHomeDone(self) -> bool:
        handler: ModBusImplInterface = self.readhandler
        if not isinstance(handler, ModBusImplInterface):
            handler = self.new_handler
        if isinstance(handler, ModBusImplInterface):
            if not handler.isAvailable:
                handler.ReConnected()
            if handler.isAvailable:
                status: int = HardWareUnit.ReadUInt16(handler, self.Parameter.ReadOnlyRegister)
                return False if not isinstance(status, int) else AppBitUtils.get_bit(status,READONLY_AXIS_STATUS_REGISTER_3)
        return False

    
    def isHomeAlarm(self) -> bool:
        handler: ModBusImplInterface = self.readhandler
        if not isinstance(handler, ModBusImplInterface):
            handler = self.new_handler
        if isinstance(handler, ModBusImplInterface):
            if not handler.isAvailable:
                handler.ReConnected()
            if handler.isAvailable:
                status: int = HardWareUnit.ReadUInt16(handler, self.Parameter.ReadOnlyRegister)
                return False if not isinstance(status, int) else AppBitUtils.get_bit(status, READONLY_AXIS_STATUS_REGISTER_4)
        return False

    
    def isMoveStatus(self) -> bool:
        handler: ModBusImplInterface = self.readhandler
        if not isinstance(handler, ModBusImplInterface):
            handler = self.new_handler
        if isinstance(handler, ModBusImplInterface):
            if not handler.isAvailable:
                handler.ReConnected()
            if handler.isAvailable:
                status: int = HardWareUnit.ReadUInt16(handler, self.Parameter.ReadOnlyRegister)
                return False if not isinstance(status, int) else AppBitUtils.get_bit(status, READONLY_AXIS_STATUS_REGISTER_5)
        return False

    
    def isHome(self) -> bool:
        handler: ModBusImplInterface = self.readhandler
        if not isinstance(handler, ModBusImplInterface):
            handler = self.new_handler
        if isinstance(handler, ModBusImplInterface):
            if not handler.isAvailable:
                handler.ReConnected()
            if handler.isAvailable:
                status: int = HardWareUnit.ReadUInt16(handler, self.Parameter.StatusRegister)
                return False if not isinstance(status, int) else AppBitUtils.get_bit(status, AXIS_STATUS_REGISTER_0)
        return False

    
    def setHome(self, enable: bool) -> int:
        isWrong: int = RECODE_FAILURE
        status: int
        handler: ModBusImplInterface = self.handler
        if not isinstance(handler, ModBusImplInterface):
            handler = self.new_handler
        if isinstance(handler, ModBusImplInterface):
            if not handler.isAvailable:
                handler.ReConnected()
            if handler.isAvailable:
                status = AppBitUtils.set_bit(0, AXIS_STATUS_REGISTER_0, 1 if enable else 0)
                isWrong = HardWareUnit.SendUInt16(handler, self.Parameter.StatusRegister, status)
        return isWrong

    
    def isMove(self) -> bool:
        handler: ModBusImplInterface = self.readhandler
        if not isinstance(handler, ModBusImplInterface):
            handler = self.new_handler
        if isinstance(handler, ModBusImplInterface):
            if not handler.isAvailable:
                handler.ReConnected()
            if handler.isAvailable:
                status: int = HardWareUnit.ReadUInt16(handler, self.Parameter.StatusRegister)
                return False if not isinstance(status, int) else AppBitUtils.get_bit(status, AXIS_STATUS_REGISTER_1)
        return False

    
    def setMove(self, enable: bool, isDelay: bool = True) -> int:
        isWrong: int = RECODE_FAILURE
        status: int
        handler: ModBusImplInterface = self.send_handler()
        if not isinstance(handler, ModBusImplInterface):
            handler = self.new_handler
        if isinstance(handler, ModBusImplInterface):
            if not handler.isAvailable:
                handler.ReConnected()
            if handler.isAvailable:
                status = AppBitUtils.set_bit(0, AXIS_STATUS_REGISTER_1, 1 if enable else 0)
                isWrong = HardWareUnit.SendUInt16(handler, self.Parameter.StatusRegister, status)
        if RECODE_SUCCEED == isWrong and isDelay:
            AppTimeLoop.delay(2)

        return isWrong

    
    def setScanMoveEnable(self, enable: bool) -> int:
        isWrong : int = RECODE_FAILURE
        handler: ModBusImplInterface = self.handler
        if not isinstance(handler, ModBusImplInterface):
            handler = self.new_handler
        if isinstance(handler, ModBusImplInterface):
            if not handler.isAvailable:
                handler.ReConnected()
            if handler.isAvailable:
                status  : int   = AppBitUtils.set_bit(0, AXIS_STATUS_REGISTER_1, 1 if enable else 0)
                isWrong         = HardWareUnit.SendUInt16(handler, self.Parameter.StatusRegister, status)
        return isWrong

    
    def isForward(self) -> bool:
        handler: ModBusImplInterface = self.handler
        if not isinstance(handler, ModBusImplInterface):
            handler = self.new_handler
        if isinstance(handler, ModBusImplInterface):
            if not handler.isAvailable:
                handler.ReConnected()
            if handler.isAvailable:
                status: int = HardWareUnit.ReadUInt16(handler, self.Parameter.StatusRegister)
                return False if not isinstance(status, int) else AppBitUtils.get_bit(status, AXIS_STATUS_REGISTER_2)
        return False

    
    def setForward(self, enable: bool) -> int:
        isWrong: int = RECODE_FAILURE
        status: int
        handler: ModBusImplInterface = self.handler
        if not isinstance(handler, ModBusImplInterface):
            handler = self.new_handler
        if isinstance(handler, ModBusImplInterface):
            if not handler.isAvailable:
                handler.ReConnected()
            if handler.isAvailable:
                status = AppBitUtils.set_bit(0, AXIS_STATUS_REGISTER_2, 1 if enable else 0)
                isWrong = HardWareUnit.SendUInt16(handler, self.Parameter.StatusRegister, status)
        return isWrong

    
    def isBackward(self) -> bool:
        handler: ModBusImplInterface = self.readhandler
        if not isinstance(handler, ModBusImplInterface):
            handler = self.new_handler
        if isinstance(handler, ModBusImplInterface):
            if not handler.isAvailable:
                handler.ReConnected()
            if handler.isAvailable:
                status: int = HardWareUnit.ReadUInt16(handler, self.Parameter.StatusRegister)
                return False if not isinstance(status, int) else AppBitUtils.get_bit(status, AXIS_STATUS_REGISTER_3)
        return False

    
    def setBackward(self, enable: bool) -> int:
        isWrong: int = RECODE_FAILURE
        status: int
        handler: ModBusImplInterface = self.handler
        if not isinstance(handler, ModBusImplInterface):
            handler = self.new_handler
        if isinstance(handler, ModBusImplInterface):
            if not handler.isAvailable:
                handler.ReConnected()
            if handler.isAvailable:
                status = AppBitUtils.set_bit(0, AXIS_STATUS_REGISTER_3, 1 if enable else 0)
                isWrong = HardWareUnit.SendUInt16(handler, self.Parameter.StatusRegister, status)
        return isWrong

    
    def isReset(self) -> bool:
        handler: ModBusImplInterface = self.readhandler
        if not isinstance(handler, ModBusImplInterface):
            handler = self.new_handler
        if isinstance(handler, ModBusImplInterface):
            if not handler.isAvailable:
                handler.ReConnected()
            if handler.isAvailable:
                status: int = HardWareUnit.ReadUInt16(handler, self.Parameter.StatusRegister)
                return False if not isinstance(status, int) else AppBitUtils.get_bit(status, AXIS_STATUS_REGISTER_4)
        return False

    
    def setReset(self, enable: bool) -> int:
        isWrong: int = RECODE_FAILURE
        status: int
        handler: ModBusImplInterface = self.handler
        if not isinstance(handler, ModBusImplInterface):
            handler = self.new_handler
        if isinstance(handler, ModBusImplInterface):
            if not handler.isAvailable:
                handler.ReConnected()
            if handler.isAvailable:
                status = AppBitUtils.set_bit(0, AXIS_STATUS_REGISTER_4, 1 if enable else 0)
                isWrong = HardWareUnit.SendUInt16(handler, self.Parameter.StatusRegister, status)
        return isWrong

    
    def setMoveParameter(self, position: float, speed: float = None, acc: float = None, dec: float = None, isDelay: bool = False) -> int:
        isWrong: int = RECODE_FAILURE
        status: int

        handler: ModBusImplInterface
        handler = self.send_handler()
        if not isinstance(handler, ModBusImplInterface):
            handler = self.new_handler
        if isinstance(handler, ModBusImplInterface):
            if not handler.isAvailable:
                handler.ReConnected()
            if handler.isAvailable:
                status = AppBitUtils.set_bit(0, AXIS_STATUS_REGISTER_1, 0)
                HardWareUnit.SendUInt16(handler, self.Parameter.StatusRegister, status)
                AppTimeLoop.delay(2)
                MovePosition: float = float(round(position, 4))
                MoveVelocity: float = float(self.Parameter.MoveVelocity.Data) if not isinstance(speed  , (float, int)) else float(speed)
                Acceleration: float = float(self.Parameter.Acceleration.Data) if not isinstance(acc    , (float, int)) else float(acc  )
                Deceleration: float = float(self.Parameter.Deceleration.Data) if not isinstance(dec    , (float, int)) else float(dec  )
                values: list[float] = [MovePosition, round(MoveVelocity, 4), round(Acceleration, 4), round(Deceleration, 4)]
                isWrong = HardWareUnit.SendFloats(handler, self.Parameter.MovePosition, values)
                if RECODE_SUCCEED == isWrong and isDelay:
                    AppTimeLoop.delay(2)
        return isWrong

    def setMoveTarget(self, target: (int, float), isDelay: bool = True) -> int:
        isWrong: int = RECODE_FAILURE
        status: int
        handler: ModBusImplInterface
        handler = self.send_handler()
        if not isinstance(handler, ModBusImplInterface):
            handler = self.new_handler
        if isinstance(handler, ModBusImplInterface):
            if not handler.isAvailable:
                handler.ReConnected()
            if handler.isAvailable  and isinstance(target, (float, int)):
                isWrong = HardWareUnit.SendFloat(handler, self.Parameter.MovePosition, float(round(target, 4)))
        return isWrong

    def changedMoveParameter(self, speed: float = None, acc: float = None, dec: float = None, isDelay: bool = False) -> int:
        isWrong: int = RECODE_FAILURE
        status: int
        handler: ModBusImplInterface
        handler = self.send_handler()
        if not isinstance(handler, ModBusImplInterface):
            handler = self.new_handler
        if isinstance(handler, ModBusImplInterface):
            if not handler.isAvailable:
                handler.ReConnected()
            if handler.isAvailable:
                status = AppBitUtils.set_bit(0, AXIS_STATUS_REGISTER_1, 0)
                HardWareUnit.SendUInt16(handler, self.Parameter.StatusRegister, status)
                AppTimeLoop.delay(1)
                MoveVelocity: float = float(self.Parameter.MoveVelocity.Data) if not isinstance(speed  , (float, int)) else float(speed)
                Acceleration: float = float(self.Parameter.Acceleration.Data) if not isinstance(acc    , (float, int)) else float(acc  )
                Deceleration: float = float(self.Parameter.Deceleration.Data) if not isinstance(dec    , (float, int)) else float(dec  )


                values: list[float] = [round(MoveVelocity, 4), round(Acceleration, 4), round(Deceleration, 4)]
                isWrong = HardWareUnit.SendFloats(handler, self.Parameter.MoveVelocity, values)
                if RECODE_SUCCEED == isWrong and isDelay:
                    AppTimeLoop.delay(2)
        return isWrong


    def changedJopParameter(self, speed: float = None, acc: float = None, dec: float = None, isDelay: bool = False) -> int:
        isWrong: int = RECODE_FAILURE
        status: int
        handler: ModBusImplInterface
        handler = self.send_handler()
        if not isinstance(handler, ModBusImplInterface):
            handler = self.new_handler
        if isinstance(handler, ModBusImplInterface):
            if not handler.isAvailable:
                handler.ReConnected()
            if handler.isAvailable:
                status = AppBitUtils.set_bit(0, AXIS_STATUS_REGISTER_1, 0)
                HardWareUnit.SendUInt16(handler, self.Parameter.StatusRegister, status)
                AppTimeLoop.delay(1)
                MoveVelocity: float = float(self.Parameter.JOPVelocity      .Data) if not isinstance(speed  , (float, int)) else float(speed)
                Acceleration: float = float(self.Parameter.JOPAcceleration  .Data) if not isinstance(acc    , (float, int)) else float(acc  )
                Deceleration: float = float(self.Parameter.JOPDeceleration  .Data) if not isinstance(dec    , (float, int)) else float(dec  )
                values: list[float] = [round(MoveVelocity, 4), round(Acceleration, 4), round(Deceleration, 4)]
                isWrong = HardWareUnit.SendFloats(handler, self.Parameter.JOPVelocity, values)
                if RECODE_SUCCEED == isWrong and isDelay:
                    AppTimeLoop.delay(2)



        return isWrong

    def setScanMove(self, position: float) -> int:
        isWrong = RECODE_FAILURE
        handler: ModBusImplInterface = self.send_handler()
        if not isinstance(handler, ModBusImplInterface):
            handler = self.new_handler
        if isinstance(handler, ModBusImplInterface):
            if not handler.isAvailable:
                handler.ReConnected()
            if handler.isAvailable and  isinstance(position, (int, float)):
                isWrong = HardWareUnit.SendFloat(handler, self.Parameter.MovePosition, float(round(position, 4)))

        return isWrong


    def send_handler(self) -> ModBusImplInterface:
        handler: ModBusImplInterface
        if AxisLevel.isScan(self.level):
            handler = self.scan_handler
        elif AxisLevel.isSlow(self.level):
            handler = self.slow_handler
        elif AxisLevel.isDropOil(self.level):
            handler = self.drop_handler
        elif AxisLevel.isAxisH(self.level):
            handler = self.hook_handler
        else:
            handler = self.handler
        return handler

    @property
    def handler(self) -> ModBusImplInterface:
        handler: ModBusImplInterface = None
        if self.isValid:
            handler = self.manager.handle
        return handler

    @property
    def readhandler(self) -> ModBusImplInterface:
        handler: ModBusImplInterface = None
        if self.isValid:
            handler = self.manager.readhandler
        return handler
    @property
    def new_handler(self) -> ModBusImplInterface:
        handler: ModBusImplInterface = None
        from AppCore.AppImpls.ModBusImpl import ModBusImpl
        if self.isValid:
            handler = self.manager.new_handler
        else:
            handler = ModBusImpl(self.parameter)
        return handler
    @property
    def detectorhandler(self) -> ModBusImplInterface:
        handler: ModBusImplInterface = None
        if self.isValid:
            handler = self.manager.detectorhandler
        return handler

    @property
    def slow_handler(self) -> ModBusImplInterface:
        handler: ModBusImplInterface = None
        if self.isValid:
            handler = self.manager.slow_handler
        return handler

    @property
    def scan_handler(self) -> ModBusImplInterface:
        handler: ModBusImplInterface = None
        if self.isValid:
            handler = self.manager.scan_handler
        return handler

    @property
    def drop_handler(self) -> ModBusImplInterface:
        handler: ModBusImplInterface = None
        if self.isValid:
            handler = self.manager.drop_handler
        return handler

    @property
    def hook_handler(self) -> ModBusImplInterface:
        handler: ModBusImplInterface = None
        if self.isValid:
            handler = self.manager.hook_handler
        return handler