/**
 *
 * @author    seagle
 * @date      2025-4-20
 * @Description
 *   按PMC框架重写的BoatModule
 */
#include"TcPch.h"
#pragma hdrstop
#include"BoatModule.h"
#include"SC.h"
#include"string.h"
#include"pmc_types.h"
#include"debug.h"
#include "DEVICE.h"
#include "errcode.h"
#include "EV.h"
#include"IoSensor.h"
BoatModule* boatModule;


static char* describeBoatStatus(BoatStatus status) {
	static char buffer[10];
	switch (status.value) {
	case BoatStatusEnum::Idle:
		strcpy(buffer, "Idle");
		break;
	case BoatStatusEnum::Init:
		strcpy(buffer, "Init");
		break;
	case BoatStatusEnum::Error:
		strcpy(buffer, "Error");
		break;
	case BoatStatusEnum::Elevating:
		strcpy(buffer, "Elevating");
		break;
	case BoatStatusEnum::Moving:
		strcpy(buffer, "Moving");
		break;
	case BoatStatusEnum::Rotating:
		strcpy(buffer, "Rotating");
		break;
	default:
		sprintf(buffer, "%d", (int)status.value);
	}
	return buffer;
}
void BoatModule::initialize()
{

	boatElevator = (IoFurnaceMotor *)DEVICE->getDevice(MODULE_NAME, "BoatElevatorServo");
	boatRotation = (IoFurnaceMotor*)DEVICE->getDevice(MODULE_NAME, "BoatRotationServo");
	shutter = (IoShutter*)DEVICE->getDevice(MODULE_NAME, "Shutter");
	subscribe();
	this->status = BoatStatusEnum::Idle;
}

void BoatModule::subscribe()
{
	/*
	* boatload / boatcap2
	* 执行序列:
	*  CheckPrepareMove 立刻
	*  AutoShutterOpen
	*  CheckPrepareMove  等待interlock满足
	*  SetBoatZAxisMove
	*/
#pragma region boatload
	char cmd[MAX_NAME_LEN];
	sprintf(cmd, "%s.SetBoatMotion.boatload",MODULE_NAME);
	auto opNode=OP->subscribe(cmd);
	//第一个CheckPrepareMove
	auto subOp=opNode->addChild("CheckPrepareMove");
	
	subOp->addExec([]()->OperatorStatusEnum {
		OP->current->setTimes( 0, 0, 0, 0);
		//检查一下状态
		if (boatModule->status!=BoatStatusEnum::Idle && boatModule->status!=BoatStatusEnum::Rotating) {
			char* err = EV->parseErrCode(ALARM_BOAT_STATUS, "status=%s;",   describeBoatStatus(boatModule->status));
			strcpy(OP->alarmText, err);
			return OperatorStatusEnum::ALARM;
		}
		//检查interlock
		if (boatModule->checkPrepareMove()) {
			
			
			return OperatorStatusEnum::SUCCESS;
			
		}
		else {
			return OperatorStatusEnum::ALARM;
		}
		});
	//AutoShutterOpen
	subOp = opNode->addChild("AutoShutterOpen");
	subOp->addExec([]()->OperatorStatusEnum {
		OP->current->setTimes( 0, 0, 0, boatModule->shutter->scMotionTimeout);
		boatModule->autoShutterOpen(TRUE);
		return OperatorStatusEnum::RUNNING;
		
		});
	subOp->addCheck([]()->OperatorStatusEnum {
		
		if (boatModule->checkAutoShutterOpen(TRUE)) {
			return OperatorStatusEnum::SUCCESS;
		}
		else {
			if (OP->current->isTimeout.value) {
				char* err = EV->parseErrCode(ALARM_SHUTTER, "status=open;");
				strcpy(OP->alarmText, err);
				return OperatorStatusEnum::ALARM;
			}
			else {
				return OperatorStatusEnum::RUNNING;
			}
		}
		
		});
	//第二个checkPrepareMove，等2秒
	subOp = opNode->addChild("CheckPrepareMove");
	
	subOp->addExec([]()->OperatorStatusEnum {
		OP->current->setTimes( 0, 0, 0, 2000);
		return OperatorStatusEnum::RUNNING;
		});
	subOp->addCheck([]()->OperatorStatusEnum {
		//检查interlock
		if (boatModule->checkPrepareMove()) {
			return OperatorStatusEnum::SUCCESS;
		}
		else {
			if (OP->current->isTimeout.value) {
				return OperatorStatusEnum::ALARM;
			}
			else {
				return OperatorStatusEnum::RUNNING;
			}
			
		}
		});
	//SetBoatZAxisMove
	subOp = opNode->addChild("SetBoatZAxisMove");
	subOp->addExec([]()->OperatorStatusEnum {
		OP->current->setTimes( 0, 0, 0, boatModule->boatElevator->scMotionTimeout);
		boatModule->setBoatZAxisMove(SERVO_MOVE_POSITION(1));//CAP2
		return OperatorStatusEnum::RUNNING;
		});
	subOp->addCheck([]()->OperatorStatusEnum {
		OperatorStatusEnum ret = boatModule->checkBoatZAxisMove(SERVO_MOVE_POSITION(1));
		if (ret==OperatorStatusEnum::SUCCESS) {
			if (boatModule->status == BoatStatusEnum::Elevating) {
				boatModule->status = BoatStatusEnum::Idle;
			}
			else if (boatModule->status == BoatStatusEnum::Moving) {
				boatModule->status = BoatStatusEnum::Rotating;
			}
			return OperatorStatusEnum::SUCCESS;
		}
		else if (ret == OperatorStatusEnum::ALARM) {
			return OperatorStatusEnum::ALARM;
		}else {
			if (OP->current->isTimeout.value) {
				char* err = EV->parseErrCode(ALARM_BOAT_TIMEOUT, "move=elevating;");
				strcpy(OP->alarmText, err);
				return OperatorStatusEnum::ALARM;
			}
			else {
				return OperatorStatusEnum::RUNNING;
			}

		}
		
		});
	subOp->addAlarmCallback([]()->OperatorStatusEnum {
		boatModule->stopElevating();
		OP->alarm();
		return OperatorStatusEnum::ALARM;
		});
#pragma endregion
#pragma region boatunload
	sprintf(cmd, "%s.SetBoatMotion.boatunload", MODULE_NAME);
	opNode = OP->subscribe(cmd);
	//第一个CheckPrepareMove
	subOp = opNode->addChild("CheckPrepareMove");
	
	subOp->addExec([]()->OperatorStatusEnum {
		OP->current->setTimes( 0, 0, 0, 0);
		//检查一下状态
		if (boatModule->status != BoatStatusEnum::Idle && boatModule->status != BoatStatusEnum::Rotating) {
			char* err = EV->parseErrCode(ALARM_BOAT_STATUS, "status=%s;", describeBoatStatus(boatModule->status));
			strcpy(OP->alarmText, err);
			return OperatorStatusEnum::ALARM;
		}
		//检查interlock
		if (boatModule->checkPrepareMove()) {


			return OperatorStatusEnum::SUCCESS;

		}
		else {
			return OperatorStatusEnum::ALARM;
		}
		});
	//AutoShutterOpen
	subOp = opNode->addChild("AutoShutterOpen");
	subOp->addExec([]()->OperatorStatusEnum {
		OP->current->setTimes( 0, 0, 0, boatModule->shutter->scMotionTimeout);
		boatModule->autoShutterOpen(TRUE);
		return OperatorStatusEnum::RUNNING;

		});
	subOp->addCheck([]()->OperatorStatusEnum {

		if (boatModule->checkAutoShutterOpen(TRUE)) {
			return OperatorStatusEnum::SUCCESS;
		}
		else {
			if (OP->current->isTimeout.value) {
				char* err = EV->parseErrCode(ALARM_SHUTTER, "status=open;");
				strcpy(OP->alarmText, err);
				return OperatorStatusEnum::ALARM;
			}
			else {
				return OperatorStatusEnum::RUNNING;
			}
		}

		});
	//第二个checkPrepareMove，等2秒
	subOp = opNode->addChild("CheckPrepareMove");
	
	subOp->addExec([]()->OperatorStatusEnum {
		OP->current->setTimes( 0, 0, 0, 2000);
		return OperatorStatusEnum::RUNNING;
		});
	subOp->addCheck([]()->OperatorStatusEnum {
		//检查interlock
		if (boatModule->checkPrepareMove()) {
			return OperatorStatusEnum::SUCCESS;
		}
		else {
			if (OP->current->isTimeout.value) {

				return OperatorStatusEnum::ALARM;
			}
			else {
				return OperatorStatusEnum::RUNNING;
			}

		}
		});
	//SetBoatZAxisMove
	subOp = opNode->addChild("SetBoatZAxisMove");
	subOp->addExec([]()->OperatorStatusEnum {
		OP->current->setTimes( 0, 0, 0, boatModule->boatElevator->scMotionTimeout);
		boatModule->setBoatZAxisMove(SERVO_MOVE_POSITION(3));//HOME
		return OperatorStatusEnum::RUNNING;
		});
	subOp->addCheck([]()->OperatorStatusEnum {
		OperatorStatusEnum ret = boatModule->checkBoatZAxisMove(SERVO_MOVE_POSITION(3));
		if (ret == OperatorStatusEnum::SUCCESS) {
			if (boatModule->status == BoatStatusEnum::Elevating) {
				boatModule->status = BoatStatusEnum::Idle;
			}
			else if (boatModule->status == BoatStatusEnum::Moving) {
				boatModule->status = BoatStatusEnum::Rotating;
			}
			return OperatorStatusEnum::SUCCESS;
		}
		else if (ret == OperatorStatusEnum::ALARM) {
			return OperatorStatusEnum::ALARM;
		}
		else {
			if (OP->current->isTimeout.value) {
				char* err = EV->parseErrCode(ALARM_BOAT_TIMEOUT, "move=elevating;");
				strcpy(OP->alarmText, err);
				return OperatorStatusEnum::ALARM;
			}
			else {
				return OperatorStatusEnum::RUNNING;
			}

		}

		});
	subOp->addAlarmCallback([]()->OperatorStatusEnum {
		boatModule->stopElevating();
		OP->alarm();
		return OperatorStatusEnum::ALARM;
		});
	//AutoShutterOpen（CLOSE)
	subOp = opNode->addChild("AutoShutterOpen");
	subOp->addExec([]()->OperatorStatusEnum {
		OP->current->setTimes( 0, 0, 0, boatModule->shutter->scMotionTimeout);
		boatModule->autoShutterOpen(FALSE);
		return OperatorStatusEnum::RUNNING;

		});
	subOp->addCheck([]()->OperatorStatusEnum {

		if (boatModule->checkAutoShutterOpen(FALSE)) {
			return OperatorStatusEnum::SUCCESS;
		}
		else {
			if (OP->current->isTimeout.value) {
				char* err = EV->parseErrCode(ALARM_SHUTTER, "status=close;");
				strcpy(OP->alarmText, err);
				return OperatorStatusEnum::ALARM;
			}
			else {
				return OperatorStatusEnum::RUNNING;
			}
		}

		});
#pragma endregion
#pragma region boatrotate
	sprintf(cmd, "%s.SetBoatMotion.boatrotate", MODULE_NAME);
	opNode = OP->subscribe(cmd);
	//SetBoatRAxisMove
	subOp = opNode->addChild("SetBoatRAxisMove");
	subOp->addExec([]()->OperatorStatusEnum {
		OP->current->setTimes( 0, 0, 0, boatModule->boatRotation->scMotionTimeout);
		boatModule->setBoatRAxisMove(BoatRotateDirection::CCW);
		return OperatorStatusEnum::RUNNING;
		});
	subOp->addCheck([]()->OperatorStatusEnum {
		OperatorStatusEnum ret = boatModule->checkBoatRAxisMove(BoatRotateDirection::CCW);
		if (ret == OperatorStatusEnum::SUCCESS) {
			
			return OperatorStatusEnum::SUCCESS;
		}
		else if (ret == OperatorStatusEnum::ALARM) {
			return OperatorStatusEnum::ALARM;
		}
		else {
			if (OP->current->isTimeout.value) {
				char* err = EV->parseErrCode(ALARM_BOAT_TIMEOUT, "move=rotating;");
				strcpy(OP->alarmText, err);
				return OperatorStatusEnum::ALARM;
			}
			else {
				return OperatorStatusEnum::RUNNING;
			}

		}

		});
	subOp->addAlarmCallback([]()->OperatorStatusEnum {
		boatModule->stopRotating();
		OP->alarm();
		return OperatorStatusEnum::ALARM;
		});
	
#pragma endregion
#pragma region boatstoprotate
	sprintf(cmd, "%s.SetBoatMotion.boatstoprotate", MODULE_NAME);
	opNode = OP->subscribe(cmd);
	//SetBoatRAxisMove
	subOp = opNode->addChild("SetBoatRAxisMoveStop");
	subOp->addExec([]()->OperatorStatusEnum {
		OP->current->setTimes( 0, 0, 0, boatModule->boatRotation->scMotionTimeout);
		boatModule->stopRotating();
		return OperatorStatusEnum::RUNNING;
		});
	subOp->addCheck([]()->OperatorStatusEnum {
		
		if (boatModule->status==BoatStatusEnum::Idle|| boatModule->status == BoatStatusEnum::Elevating) {

			return OperatorStatusEnum::SUCCESS;
		}else {
			if (OP->current->isTimeout.value) {
				char* err = EV->parseErrCode(ALARM_BOAT_TIMEOUT, "move=stoprotating;");
				strcpy(OP->alarmText, err);
				return OperatorStatusEnum::ALARM;
			}
			else {
				return OperatorStatusEnum::RUNNING;
			}

		}

		});
	

#pragma endregion
#pragma region stop(include-axis)
	sprintf(cmd, "%s.SetBoatMotion.stop(include-axis)", MODULE_NAME);
	opNode = OP->subscribe(cmd);
	//SetBoatRAxisMoveStop
	subOp = opNode->addChild("SetBoatRAxisMoveStop");
	subOp->addExec([]()->OperatorStatusEnum {
		OP->current->setTimes( 0, 0, 0, boatModule->boatRotation->scMotionTimeout);
		boatModule->stopRotating();
		return OperatorStatusEnum::RUNNING;
		});
	subOp->addCheck([]()->OperatorStatusEnum {

		if (boatModule->status == BoatStatusEnum::Idle || boatModule->status == BoatStatusEnum::Elevating) {

			return OperatorStatusEnum::SUCCESS;
		}
		else {
			if (OP->current->isTimeout.value) {
				char* err = EV->parseErrCode(ALARM_BOAT_TIMEOUT, "move=stoprotating;");
				strcpy(OP->alarmText, err);
				return OperatorStatusEnum::ALARM;
			}
			else {
				return OperatorStatusEnum::RUNNING;
			}

		}

		});
	//SetBoatZAxisMoveStop
	subOp = opNode->addChild("SetBoatZAxisMoveStop");
	subOp->addExec([]()->OperatorStatusEnum {
		OP->current->setTimes( 0, 0, 0, boatModule->boatElevator->scMotionTimeout);
		boatModule->stopElevating();
		return OperatorStatusEnum::RUNNING;
		});
	subOp->addCheck([]()->OperatorStatusEnum {

		if (boatModule->status == BoatStatusEnum::Idle || boatModule->status == BoatStatusEnum::Rotating) {

			return OperatorStatusEnum::SUCCESS;
		}
		else {
			if (OP->current->isTimeout.value) {
				char* err = EV->parseErrCode(ALARM_BOAT_TIMEOUT, "move=stopelevating;");
				strcpy(OP->alarmText, err);
				return OperatorStatusEnum::ALARM;
			}
			else {
				return OperatorStatusEnum::RUNNING;
			}

		}

		});
#pragma endregion
}




//往下是OP处理的公共函数

PMCBOOL BoatModule::checkPrepareMove()
{
	
	if (IoSensor::poSensorVAC1->di.isEmpty|| !IoSensor::poSensorVAC1->di.getBoolValue() ) {
		char* err = EV->parseErrCode(ALARM_DO_ILK, "reason=VAC1[%d];", IoSensor::poSensorVAC1->di.getBoolValue());
		strcpy(OP->alarmText, err);
		return FALSE;
	}
	if (IoSensor::poSensorVAC2->di.isEmpty || !IoSensor::poSensorVAC2->di.getBoolValue()) {
		char* err = EV->parseErrCode(ALARM_DO_ILK, "reason=VAC2[%d];", IoSensor::poSensorVAC2->di.getBoolValue());
		strcpy(OP->alarmText, err);
		return FALSE;
	}
	if (IoSensor::poSensorVAC3->di.isEmpty || !IoSensor::poSensorVAC3->di.getBoolValue()) {
		char* err = EV->parseErrCode(ALARM_DO_ILK, "reason=VAC3[%d];", IoSensor::poSensorVAC3->di.getBoolValue());
		strcpy(OP->alarmText, err);
		return FALSE;
	}
	if (IoSensor::poSensorRaxisaircylinderretractposition->di.isEmpty || !IoSensor::poSensorRaxisaircylinderretractposition->di.getBoolValue()) {
		char* err = EV->parseErrCode(ALARM_DO_ILK, "reason=Raxisaircylinderretractposition[%d];", IoSensor::poSensorRaxisaircylinderretractposition->di.getBoolValue());
		strcpy(OP->alarmText, err);
		return FALSE;
	}
	if (IoSensor::poSensorBoatUnloadInterlock->di.isEmpty || !IoSensor::poSensorBoatUnloadInterlock->di.getBoolValue()) {
		char* err = EV->parseErrCode(ALARM_DO_ILK, "reason=BoatUnloadInterlock[%d];", IoSensor::poSensorBoatUnloadInterlock->di.getBoolValue());
		strcpy(OP->alarmText, err);
		return FALSE;
	}
	return TRUE;
}

PMCBOOL BoatModule::autoShutterOpen(PMCBOOL shutterOpen)
{
	if (!boatModule->shutter->doOpen.isEmpty) {
		boatModule->shutter->doOpen.setBoolValue(shutterOpen);
	}
	if (!boatModule->shutter->doClose.isEmpty) {
		boatModule->shutter->doClose.setBoolValue(!shutterOpen);
	}
	return PMCBOOL();
}

PMCBOOL BoatModule::setBoatZAxisMove(int position)
{
	boatModule->boatElevator->aoTargetPosition.setFloatValue(position);
	boatModule->boatElevator->aoTargetSpeed.setDoubleValue(boatModule->boatElevator->scMoveSpeed);
	boatModule->boatElevator->doHome.setBoolValue(FALSE);
	boatModule->boatElevator->doInit.setBoolValue(FALSE);
	boatModule->boatElevator->doMove.setBoolValue(FALSE);
	boatModule->boatElevator->doStop.setBoolValue(FALSE);
	boatModule->boatElevator->doReset.setBoolValue(FALSE);
	boatModule->boatElevator->aoAcc.setDoubleValue(boatModule->boatElevator->scAcc);
	boatModule->boatElevator->aoDec.setDoubleValue(boatModule->boatElevator->scDec);
	boatModule->boatElevator->doServoOn.setBoolValue(TRUE); 
	if (boatModule->status == BoatStatusEnum::Idle) {
		boatModule->status = BoatStatusEnum::Elevating;
	}
	else if (boatModule->status == BoatStatusEnum::Rotating) {
		boatModule->status = BoatStatusEnum::Moving;

	}
	return TRUE;
}
PMCBOOL BoatModule::setBoatRAxisMove(BoatRotateDirection direction)
{
	boatModule->boatRotation->doHome.setBoolValue(FALSE);
	boatModule->boatRotation->doInit.setBoolValue(FALSE);
	boatModule->boatRotation->doMove.setBoolValue(FALSE);
	boatModule->boatRotation->doStop.setBoolValue(FALSE);
	boatModule->boatRotation->doReset.setBoolValue(FALSE);
	boatModule->boatRotation->doCCW.setBoolValue(direction==BoatRotateDirection::CCW?TRUE:FALSE);
	boatModule->boatRotation->doCW.setBoolValue(direction == BoatRotateDirection::CW ? TRUE : FALSE);
	boatModule->boatRotation->aoTargetSpeed.setDoubleValue(boatModule->boatRotation->scMoveSpeed);
	boatModule->boatRotation->aoAcc.setDoubleValue(boatModule->boatElevator->scAcc);
	boatModule->boatRotation->aoDec.setDoubleValue(boatModule->boatElevator->scDec);
	boatModule->boatRotation->doServoOn.setBoolValue(TRUE);
	if (boatModule->status == BoatStatusEnum::Idle) {
		boatModule->status = BoatStatusEnum::Rotating;
	}
	else if (boatModule->status == BoatStatusEnum::Elevating) {
		boatModule->status = BoatStatusEnum::Moving;

	}
	return TRUE;
}

OperatorStatusEnum BoatModule::checkBoatZAxisMove(int position)
{
	if (!boatModule->boatElevator->diMotorAlarm.isEmpty) {
		if (boatModule->boatElevator->diMotorAlarm.getBoolValue()) {
			char* err = EV->parseErrCode(ALARM_BOAT, "trigger=%s;", boatModule->boatElevator->diMotorAlarm.referName);
			strcpy(OP->alarmText, err);
			return OperatorStatusEnum::ALARM;
		}
	}
	if (!boatModule->boatElevator->diAlarm.isEmpty) {
		if (boatModule->boatElevator->diAlarm.getBoolValue()) {
			char* err = EV->parseErrCode(ALARM_BOAT, "trigger=%s;", boatModule->boatElevator->diAlarm.referName);
			strcpy(OP->alarmText, err);
			return OperatorStatusEnum::ALARM;
		}
	}
	if (!boatModule->boatElevator->diPosition1.isEmpty && position==1) {
		if (boatModule->boatElevator->diPosition1.getBoolValue()) {
			return OperatorStatusEnum::SUCCESS;
		}
	}
	if (!boatModule->boatElevator->diPosition2.isEmpty && position == 2) {
		if (boatModule->boatElevator->diPosition2.getBoolValue()) {
			return OperatorStatusEnum::SUCCESS;
		}
	}
	if (!boatModule->boatElevator->diPosition3.isEmpty && position == 3) {
		if (boatModule->boatElevator->diPosition3.getBoolValue()) {
			return OperatorStatusEnum::SUCCESS;
		}
	}
	return OperatorStatusEnum::RUNNING;
}

OperatorStatusEnum BoatModule::checkBoatRAxisMove(BoatRotateDirection direction)
{
	if (!boatModule->boatRotation->diMotorAlarm.isEmpty ) {
		if (boatModule->boatRotation->diMotorAlarm.getBoolValue() ) {
			char* err = EV->parseErrCode(ALARM_BOAT, "trigger=%s;", boatModule->boatRotation->diMotorAlarm.referName);
			strcpy(OP->alarmText, err);
			return OperatorStatusEnum::ALARM;
		}
	}
	if (!boatModule->boatRotation->diAlarm.isEmpty) {
		if (boatModule->boatRotation->diAlarm.getBoolValue()) {
			char* err = EV->parseErrCode(ALARM_BOAT, "trigger=%s;", boatModule->boatRotation->diAlarm.referName);
			strcpy(OP->alarmText, err);
			return OperatorStatusEnum::ALARM;
		}
	}
	
	return OperatorStatusEnum::SUCCESS;
}



void BoatModule::stopElevating(){
	boatModule->boatElevator->doHome.setBoolValue(FALSE);
	boatModule->boatElevator->doInit.setBoolValue(FALSE);
	boatModule->boatElevator->doMove.setBoolValue(FALSE);
	boatModule->boatElevator->doStop.setBoolValue(FALSE);
	boatModule->boatElevator->doReset.setBoolValue(FALSE);
	boatModule->boatElevator->doStop.setHoldValue(TRUE, [](DeviceAttribute* var) {
		boatModule->boatElevator->diMoving.waitBoolValue(FALSE, [](DeviceAttribute* var) {
				boatModule->boatElevator->doStop.setBoolValue(FALSE);
				boatModule->boatElevator->doServoOn.setBoolValue(FALSE);
				if (boatModule->status == BoatStatusEnum::Elevating) {
					boatModule->status = BoatStatusEnum::Idle;
				}
				else if (boatModule->status == BoatStatusEnum::Moving) {
					boatModule->status = BoatStatusEnum::Rotating;
				}
			}, boatModule->boatElevator->scMotionTimeout, [](DeviceAttribute* var) {	//等5秒收尾
				boatModule->boatElevator->doStop.setBoolValue(FALSE);
				boatModule->boatElevator->doServoOn.setBoolValue(FALSE);
				if (boatModule->status == BoatStatusEnum::Elevating) {
					boatModule->status = BoatStatusEnum::Idle;
				}
				else if (boatModule->status == BoatStatusEnum::Moving) {
					boatModule->status = BoatStatusEnum::Rotating;
				}
			});
		});

}
void BoatModule::stopRotating() {
	boatModule->boatRotation->doHome.setBoolValue(FALSE);
	boatModule->boatRotation->doInit.setBoolValue(FALSE);
	boatModule->boatRotation->doMove.setBoolValue(FALSE);
	boatModule->boatRotation->doStop.setBoolValue(FALSE);
	boatModule->boatRotation->doReset.setBoolValue(FALSE);
	boatModule->boatRotation->doStop.setHoldValue(TRUE, [](DeviceAttribute* var) {
		boatModule->boatRotation->diMoving.waitBoolValue(FALSE, [](DeviceAttribute* var) {
			boatModule->boatRotation->doStop.setBoolValue(FALSE);
			boatModule->boatRotation->doServoOn.setBoolValue(FALSE);
			if (boatModule->status == BoatStatusEnum::Rotating) {
				boatModule->status = BoatStatusEnum::Idle;
			}
			else if (boatModule->status == BoatStatusEnum::Moving) {
				boatModule->status = BoatStatusEnum::Elevating;
			}
			}, boatModule->boatElevator->scMotionTimeout, [](DeviceAttribute* var) {	//等5秒收尾
				boatModule->boatRotation->doStop.setBoolValue(FALSE);
				boatModule->boatRotation->doServoOn.setBoolValue(FALSE);
				if (boatModule->status == BoatStatusEnum::Rotating) {
					boatModule->status = BoatStatusEnum::Idle;
				}
				else if (boatModule->status == BoatStatusEnum::Moving) {
					boatModule->status = BoatStatusEnum::Elevating;
				}
			});
		});

}
PMCBOOL BoatModule::checkAutoShutterOpen(PMCBOOL shutterOpen)
{
	if (!boatModule->shutter->diOpen.isEmpty) {
		if (boatModule->shutter->diOpen.getBoolValue() != shutterOpen) {
			return FALSE;
		}
	}
	if (!boatModule->shutter->diClose.isEmpty) {
		if (boatModule->shutter->diClose.getBoolValue() != !shutterOpen) {
			return FALSE;
		}
	}
	return TRUE;
}
