Files

365 lines
11 KiB
C++

#include "PrinterStateManager.h"
#include <QDebug>
#include "LogInfo.h"
PrinterStateManager* PrinterStateManager::s_instance = nullptr;
PrinterStateManager* PrinterStateManager::instance()
{
if (!s_instance) {
s_instance = new PrinterStateManager();
}
return s_instance;
}
PrinterStateManager::PrinterStateManager()
{
initTransitions();
m_currentState = PrinterState::IDLE;
initTimer();
}
PrinterStateManager::~PrinterStateManager()
{
if (m_updateUITimer) {
m_updateUITimer->stop();
m_updateUITimer->deleteLater();
m_updateUITimer = NULL;
}
if (m_sysPara) {
m_sysPara = NULL;
}
}
QString PrinterStateManager::stateName() const
{
switch (m_currentState) {
case PrinterState::IDLE: return "空闲";
case PrinterState::SELF_CHECK: return "自检完成";
case PrinterState::READY: return "就绪";
case PrinterState::PRINTING: return "打印中";
case PrinterState::STOPPING: return "停止中";
case PrinterState::ERROR: return "故障";
case PrinterState::POWER_OFF: return "关机中";
default: return "未知";
}
}
// ============ 初始化状态(开机时调用一次) ============
void PrinterStateManager::initFromSysPara()
{
setState(PrinterState::IDLE, "Init from sysPara");
}
// ============ 状态转移表 ============
void PrinterStateManager::initTransitions()
{
m_transitions = {
// 开机流程
{PrinterState::IDLE, PrinterEvent::PowerOn,
PrinterState::SELF_CHECK, "IDLE → SELF_CHECK", nullptr},
{PrinterState::SELF_CHECK, PrinterEvent::SelfCheckDone,
PrinterState::READY, "SELF_CHECK → READY",
[this]() -> bool { return guardReclaimTankOpen(); }},
{PrinterState::SELF_CHECK, PrinterEvent::SelfCheckFailed,
PrinterState::ERROR, "SELF_CHECK → ERROR", nullptr},
// 注意,逆清洗和关回收槽时,需要把状态重新切换回自检
{PrinterState::READY, PrinterEvent::ReSelfCheck,
PrinterState::SELF_CHECK, "READY → SELF_CHECK", nullptr},
// 打印流程
{PrinterState::READY, PrinterEvent::StartPrint,
PrinterState::PRINTING, "READY → PRINTING",
[this]() -> bool { return guardCanStartPrint(); }},
{PrinterState::PRINTING, PrinterEvent::StopPrint,
PrinterState::STOPPING, "PRINTING → STOPPING", nullptr},
{PrinterState::STOPPING, PrinterEvent::StopComplete,
PrinterState::READY, "STOPPING → READY", nullptr},
// 错误处理
{PrinterState::READY, PrinterEvent::ErrorOccurred,
PrinterState::ERROR, "READY → ERROR", nullptr},
{PrinterState::PRINTING, PrinterEvent::ErrorOccurred,
PrinterState::ERROR, "PRINTING → ERROR", nullptr},
{PrinterState::STOPPING, PrinterEvent::ErrorOccurred,
PrinterState::ERROR, "STOPPING → ERROR", nullptr},
{PrinterState::ERROR, PrinterEvent::ErrorCleared,
PrinterState::READY, "ERROR → READY", nullptr},
// 关机
{PrinterState::READY, PrinterEvent::PowerOff,
PrinterState::POWER_OFF, "READY → POWER_OFF", nullptr},
{PrinterState::PRINTING, PrinterEvent::PowerOff,
PrinterState::POWER_OFF, "PRINTING → POWER_OFF", nullptr},
{PrinterState::STOPPING, PrinterEvent::PowerOff,
PrinterState::POWER_OFF, "STOPPING → POWER_OFF", nullptr},
{PrinterState::ERROR, PrinterEvent::PowerOff,
PrinterState::POWER_OFF, "ERROR → POWER_OFF", nullptr},
{PrinterState::POWER_OFF, PrinterEvent::PowerOffDone,
PrinterState::IDLE, "POWER_OFF → IDLE", nullptr},
};
}
// ============ 查找转移 ============
PrinterStateManager::Transition* PrinterStateManager::findTransition(PrinterEvent event)
{
for (Transition& trans : m_transitions) {
if (trans.fromState == m_currentState && trans.event == event) {
return &trans;
}
}
return nullptr;
}
// ============ 请求切换状态(外部唯一接口) ============
void PrinterStateManager::requestTransition(PrinterEvent event)
{
LogInfo::setRunStatusText(QString("Transition %1:%2")
.arg(stateName())
.arg(m_sysPara->status.reclaimTankstatus));
Transition* trans = findTransition(event);
if (!trans) {
qDebug() << "Invalid transition, ignored";
return;
}
// 检查守卫条件
if (trans->guard) {
bool result = trans->guard();
if (!result) {
qDebug() << "Guard condition failed for:" << trans->description;
return;
}
}
// 执行状态切换(内部管理)
setState(trans->toState, trans->description);
}
void PrinterStateManager::checkReadyState()
{
// 自检完成后,随时检查能否进入READY状态
if (m_currentState == PrinterState::SELF_CHECK) {
if (m_sysPara) {
// 现在还有个压力稳定期,期间也不能切换状态
if (m_sysPara->status.airPushing) {
return;
}
switch (m_sysPara->status.reclaimTankstatus) {
case 5:
emit sig_updateReclaimStatus();
// 检测压力波动 -10~10,检测 3 秒,相位故障 检测3秒,总时长不超过60秒
if (!isState(PrinterState::READY)) {
if (m_canReadyTimer) m_canReadyTimer->start();
}
break;
default:
// 回收槽状态变化后就更新一次
if (lastState != m_sysPara->status.reclaimTankstatus
&& m_sysPara->status.reclaimTankstatus != 0) {
if (m_updateUITimer && !m_updateUITimer->isActive()) {
m_updateUITimer->start();
}
lastState = m_sysPara->status.reclaimTankstatus;
emit sig_updateReclaimStatus();
}
break;
}
}
}
}
// ============ 内部状态切换 ============
void PrinterStateManager::setState(PrinterState newState, const QString& reason)
{
if (m_currentState == newState) {
return;
}
m_previousState = m_currentState;
m_currentState = newState;
qDebug() << "State changed:" << stateName() << "Reason:" << reason;
if (m_updateUITimer && !m_updateUITimer->isActive()) {
m_updateUITimer->start();
}
// 发送信号通知外部
emit sig_stateChanged(newState, m_previousState, reason);
emit sig_updateReclaimStatus();
}
// ============ 辅助函数 ============
QString PrinterStateManager::stateNameFromEnum(PrinterState state) const
{
switch (state) {
case PrinterState::IDLE: return "IDLE";
case PrinterState::SELF_CHECK: return "SELF_CHECK";
case PrinterState::READY: return "READY";
case PrinterState::PRINTING: return "PRINTING";
case PrinterState::STOPPING: return "STOPPING";
case PrinterState::ERROR: return "ERROR";
case PrinterState::POWER_OFF: return "POWER_OFF";
default: return "UNKNOWN";
}
}
// ============ 守卫条件函数 ============
bool PrinterStateManager::guardReclaimTankOpen()
{
if (!m_sysPara) return false;
// 开完成和关完成后,回收槽状态会变成0
return m_sysPara->status.reclainTankReachEnd || (m_sysPara->status.reclaimTankstatus == 5);
}
bool PrinterStateManager::guardInkSwintOpen()
{
if (!m_sysPara) return false;
return !(m_sysPara->status.statWarn & WARN_STATUS_INK_SWINT);
}
bool PrinterStateManager::guardNoError()
{
if (!m_sysPara) return false;
return m_sysPara->status.statWarn == 0;
}
bool PrinterStateManager::guardNoInkWarn()
{
if (!m_sysPara) return false;
return !(m_sysPara->status.statWarn & WARN_STATUS_INK_WARN);
}
bool PrinterStateManager::guardNoSolventWarn()
{
if (!m_sysPara) return false;
return !(m_sysPara->status.statWarn & WARN_STATUS_SOLV_WARN);
}
bool PrinterStateManager::guardSelfCheckDone()
{
if (!m_sysPara) return false;
return m_sysPara->status.selfCheckDone;
}
bool PrinterStateManager::guardCanStartPrint()
{
if (!m_sysPara) return false;
// 自检完成,开回收槽,开墨线,无异常报错
return guardReclaimTankOpen() && guardInkSwintOpen() &&
guardNoError() && guardSelfCheckDone();
}
void PrinterStateManager::initTimer()
{
if (m_updateUITimer == NULL) {
m_updateUITimer = new QTimer();
connect(m_updateUITimer, &QTimer::timeout, this,
&PrinterStateManager::slt_timeoutUI);
m_updateUITimer->setInterval(50);
m_updateUITimer->setSingleShot(true);
}
if (m_canReadyTimer == NULL) {
m_canReadyTimer = new QTimer();
connect(m_canReadyTimer, &QTimer::timeout, this,
&PrinterStateManager::slt_timeoutReady);
m_canReadyTimer->setInterval(500);
}
}
void PrinterStateManager::slt_timeoutUI()
{
if (m_sysPara) {
LogInfo::setRunStatusText(QString("slt_timeout ENTER:%1--state:%2")
.arg(stateName())
.arg(m_sysPara->status.reclaimTankstatus));
switch (m_sysPara->status.reclaimTankstatus) {
case 0:
emit sig_updateReclaimStatus();
break;
case 1: // 开
emit sig_enableOpenTank(false);
emit sig_enableCloseTank(true);
break;
case 2: // 关
emit sig_enableOpenTank(true);
emit sig_enableCloseTank(false);
break;
case 3:
case 4:
break;
case 5: // 开完成
emit sig_enableOpenTank(false);
emit sig_enableCloseTank(true);
break;
case 6: // 6关完成
emit sig_enableOpenTank(true);
emit sig_enableCloseTank(false);
break;
case 0x10: // 故障
emit sig_enableStartPrint(false);
emit sig_enableStopPrint(false);
emit sig_enableOpenTank(false);
emit sig_enableCloseTank(true);
break;
case 0x11: // 卡住,关闭
default:
break;
}
}
// STATE
switch (m_currentState) {
case PrinterState::SELF_CHECK:
emit sig_enableStartPrint(false);
emit sig_enableStopPrint(false);
break;
// 需要确认开完成时,状态是否一定是READY,然后避免重复操作 TODO
case PrinterState::READY:
emit sig_enableStartPrint(true);
emit sig_enableStopPrint(true);
break;
default:
break;
}
// 避免发出太多信号
if (m_updateUITimer) m_updateUITimer->stop();
}
static short allTimes = 0;
static short checkTimes = 0;
void PrinterStateManager::slt_timeoutReady()
{
allTimes++; //3s(checkTimes=6)一个周期,不超过60秒
if (allTimes > 120) {
if (m_canReadyTimer) m_canReadyTimer->stop();
allTimes = 0;
checkTimes = 0;
emit sig_closeTank();
emit sig_infoMsg(tr("相位故障,回收喷嘴"));
}
emit sig_infoMsg(tr("检查相位中..."));
// 检查相位,如果有一个错误,就重新开始累计
if (m_sysPara->status.lastPhaseFault) { checkTimes = 0; }
// 累计6次(3秒)后,再进入READY状态
if (checkTimes++ > 5){
if (m_canReadyTimer) m_canReadyTimer->stop();
checkTimes = 0;
setState(PrinterState::READY, "READY");
emit sig_infoMsg(tr("检查完毕"));
}
}