#include "DeviceManager.h" #include #include #include #include #include #include #include #include #include #include #include "appvals/AppGlobalValues.h" #include "json/ScanJson.h" #include "json/jsonobject.h" #include "event/EventCenter.h" #include "db/SQLHelper.h" #include "InfoReceiveWorker.h" #include "DmsSyncAction.h" #include "DmsAsyncAction.h" #include "dms_mq.h" #include "recon/ReconManager.h" #include "dialogs/MultyMessageDialog.h" #include "UsctStateManager.h" #include "utilities/ScanProcessSequence.h" #include "utilities/AlarmHelper.h" #include "log/LogManager.h" #define TRIGGER_EVENT EventCenter::Default()->triggerEvent #define THROW_ERROR(errormsg)\ TRIGGER_EVENT(GUIEvents::GUIErrorRaise, nullptr, (QObject*)&errormsg); namespace { const int PREVIEW_IMAGE_WH = 140; const unsigned int GET_TEMPERATURE_TIME = 60000; const int CHECK_RECON_CONNECTION_TIME = 30000; const int SHUT_DOWN_TIMEOUT = 180000;//3 minitues const int PUMP_TIMEOUT = 3000;//3 seconds const int GETDMSVERSION_TIMEOUT = 5000; const int EFFECTIVE_POSITION_RADIUS = 125; const int EFFECTIVE_POSITION_Z_START = 150; const int EFFECTIVE_POSITION_Z_END = 225; const QString DEFAULT_DMS_START_FAILED = "Dms start failed."; QJsonObject toJsonObject(const QString& aJsonString) { QJsonDocument jsonDoc = QJsonDocument::fromJson(aJsonString.toUtf8()); if(!jsonDoc.isNull() && jsonDoc.isObject()) { return jsonDoc.object(); } return QJsonObject(); } } const char* getStatusString(DeviceStatus aStatus) { switch (aStatus) { case DeviceStatus::Scanning: return "SCANNING"; case DeviceStatus::Rready: return "Ready"; case DeviceStatus::Busy: return "BUSY"; case DeviceStatus::Error: return "ERROR"; case DeviceStatus::Unkonw: return "Unkonw"; default: return nullptr; } } QString getFullScanJson(QObject* obj) { QString* msg = (QString*)obj; QJsonDocument patientInfo = QJsonDocument::fromJson(msg->toUtf8()); QJsonObject fullJson; fullJson["Patient Info"] = patientInfo.object()["Patient Info"]; fullJson["mode"] = "0"; fullJson["active report"] = "0"; return QString::fromUtf8(QJsonDocument(fullJson).toJson(QJsonDocument::Compact)); } void DeviceManager::initDevice() { mReconTransferPath = JsonObject::Instance()->getReconTransferPath(); dmsmq_init(0); // empty scan connect(EventCenter::Default(), &EventCenter::RequestEmptyScan, [=](QObject* sender, QObject* detail) { startScan(getFullScanJson(detail), true); }); // Patient scan connect(EventCenter::Default(), &EventCenter::RequestPatientScan, [=](QObject* sender, QObject* detail) { startScan(getFullScanJson(detail)); }); // stop connect(EventCenter::Default(), &EventCenter::RequestFullScanStop,this, &DeviceManager::stopFullScan); connect(EventCenter::Default(), &EventCenter::RequestPreviewStop,this, &DeviceManager::stopPreviewScan); // preview connect(EventCenter::Default(), &EventCenter::RequestPreviewScan,this, &DeviceManager::startPreview); //shutdown connect(EventCenter::Default(), &EventCenter::RequestShutdown, this, &DeviceManager::shutdownDms); //Drainage connect(EventCenter::Default(), &EventCenter::RequestDrainage, this, [this](QObject* sender, QObject* detail) { controlDrainage(*(QString*)detail); }); //AutoLocate connect(EventCenter::Default(), &EventCenter::StartScanProcess, this, &DeviceManager::startScanProcess); connect(EventCenter::Default(), &EventCenter::StopScanProcess, this, &DeviceManager::stopScanProcess); //Sync action mGetDeviceStatusAction = new DmsSyncAction(USRV_SCAN, ACT_SCAN_STATUS, this, "responseGetDeviceStatus(const QString&)", this); mFullScanAction = new DmsSyncAction(USRV_SCAN, ACT_SCAN_FULLSCAN, this, "responseFullScan(const QString&)", this); mStopScanAction = new DmsSyncAction(USRV_SCAN, ACT_SCAN_STOP, this, "responseStopScan(const QString&)", this); mPreviewScanAction = new DmsSyncAction(USRV_SCAN, ACT_SCAN_PREVIEW, this, "responsePreviewScan(const QString&)", this); mTransferAction = new DmsSyncAction(USRV_XFR, ACT_XFR_START, this, "responseTransfer(const QString&)", this); mGetTransferProgressAction = new DmsSyncAction(USRV_XFR, ACT_XFR_PROGRESS_PASSIVE, this, "responseGetTransferProgress(const QString&)", this); mCEScanAction = new DmsSyncAction(USRV_SCAN, ACT_SCAN_CE, this, "responseCEScan(const QString&)", this); mGetCEStatusAction = new DmsSyncAction(USRV_SCAN, ACT_SCAN_CE_STATUS, this, "responseGetCEStatus(const QString&)", this); mSetSimulatorModeAction = new DmsSyncAction(USRV_SCAN, ACT_SCAN_SIMULATOR, this, "responseSetSimulatorMode(const QString&)", this); mSetHeartBeatAction = new DmsSyncAction(USRV_INFOCFG, ACT_IFCFG_HBCFG, this, "responseSetHeartBeat(const QString&)", this); mCheckInitStatusAction = new DmsSyncAction(USRV_INFOCFG, ACT_IFCFG_INIT_STATUS, this, "responseCheckInitStatus(const QString&)", this); mStartAutoLocateAction = new DmsSyncAction(USRV_CONTROL, ACT_CTL_MOTION_START, this, "responseStartAutoLocate(const QString&)", this); mStopAutoLocateAction = new DmsSyncAction(USRV_CONTROL, ACT_CTL_MOTION_STOP, this, "responseStopAutoLocate(const QString&)", this); mCheckDataQualityAction = new DmsSyncAction(USRV_SCAN, ACT_SCAN_IMGQUALITI, this, "responseCheckDataQuality(const QString&)", this); //Async action mGetScanProgressAction = new DmsAsyncAction(USRV_SCAN, ACT_SCAN_PROGRESS_PASSIVE, this,"responseGetScanProgress(const QString&)", this); mGetDeviceTemperatureAction = new DmsAsyncAction(USRV_SCAN, ACT_SCAN_TEMP, this, "responseGetDeviceTemperature(const QString&)", this); mStopTransferAction = new DmsAsyncAction(USRV_XFR, ACT_XFR_STOP, this, "responseStopTransfer(const QString&)", this); mShutDownAction = new DmsAsyncAction(USRV_CONTROL, ACT_CTL_PWRDOWN, this, "responseShutDown(const QString&)", this); mShutDownAction->setTimeoutInterval(SHUT_DOWN_TIMEOUT); mPumpControlAction = new DmsAsyncAction(USRV_CONTROL, ACT_CTL_PUMP, this, "responsePumpControl(const QString&)", this); mPumpControlAction->setTimeoutInterval(PUMP_TIMEOUT); mGetAutoLocatePositionAction = new DmsAsyncAction(USRV_CONTROL, ACT_CTL_MOTION_POSITION, this, "responseGetAutoLocatePosition(const QString&)", this); mGetSoftwareVersionAction = new DmsAsyncAction(USRV_INFOCFG, ACT_IFCFG_VERINFO, this,"responseGetSoftwareVersion(const QString&)", this); mGetSoftwareVersionAction->setTimeoutInterval(GETDMSVERSION_TIMEOUT); mEmergencyResetAction = new DmsAsyncAction(USRV_CONTROL, ACT_CTL_EMG_RESET, this,"responseEmergencyButtonReset(const QString&)", this); connect(mGetSoftwareVersionAction, &DmsAsyncAction::timeout, [this]() { emit getDmsVersionResponsed("DMS Version Fetch Error"); }); connect(mPumpControlAction, &DmsAsyncAction::timeout, [this]() { this->processPumpResult("{\"code\":-1}"); }); connect(mGetScanProgressAction, &DmsAsyncAction::timeout, this, &DeviceManager::scanTimeout); connect(mShutDownAction, &DmsAsyncAction::timeout, this, &DeviceManager::shutdownDmsFailed); connect(mGetAutoLocatePositionAction, &DmsAsyncAction::timeout, [this]() { if(mGetAutoLocatePositionTimer != -1) { this->killTimer(mGetAutoLocatePositionTimer); mGetAutoLocatePositionTimer = -1; } TRIGGER_EVENT(StopScanProcess, nullptr, nullptr); QString errorMessage = tr("DMS connection error"); THROW_ERROR(errorMessage) }); //dmsInfoReceiverThread mDmsInfoReceiveThread = new QThread(this); mInfoReceiveWorker = new InfoReceiveWorker(nullptr); mInfoReceiveWorker->moveToThread(mDmsInfoReceiveThread); connect(mDmsInfoReceiveThread, &QThread::started, mInfoReceiveWorker, &InfoReceiveWorker::startListen); connect(mDmsInfoReceiveThread, &QThread::finished, mInfoReceiveWorker, &InfoReceiveWorker::deleteLater); connect(mInfoReceiveWorker, &InfoReceiveWorker::infoReceived, this, &DeviceManager::processReceiveDMSInfoResult); mDmsInfoReceiveThread->start(); //reconHttpThread mReconHttpThread = new QThread(this); QTimer* reconConnectionTimer = new QTimer(this); ReconManager::getInstance()->moveToThread(mReconHttpThread); connect(EventCenter::Default(), &EventCenter::LoginSuccess, [reconConnectionTimer, this]() { emit checkReconConnection(); if(!reconConnectionTimer->isActive()) { reconConnectionTimer->start(CHECK_RECON_CONNECTION_TIME); } }); connect(ReconManager::getInstance(), &ReconManager::reconStateResponsed, UsctStateManager::getInstance(), &UsctStateManager::updateReconState); connect(this, &DeviceManager::checkReconConnection, ReconManager::getInstance(), &ReconManager::checkReconConnection); connect(reconConnectionTimer, &QTimer::timeout, this, &DeviceManager::prepareCheckReconConnection); connect(this, &DeviceManager::createEmptyScanToRecon, ReconManager::getInstance(), &ReconManager::createEmptyScan); connect(this, &DeviceManager::createScanToRecon, ReconManager::getInstance(), &ReconManager::createScan); connect(ReconManager::getInstance(), &ReconManager::createScanResponsed, this, &DeviceManager::processReconCreateScan); connect(ReconManager::getInstance(), &ReconManager::createEmptyScanResponsed, this, &DeviceManager::processReconCreateEmptyScan); connect(this, &DeviceManager::queryScanStatusToRecon, ReconManager::getInstance(), &ReconManager::queryReconStatus); connect(ReconManager::getInstance(), &ReconManager::queryReconStateResponsed, this, &DeviceManager::processReconQueryScanState); connect(ReconManager::getInstance(), &ReconManager::restartCreatReconRecord, this, &DeviceManager::startCreateReconRecord); connect(ReconManager::getInstance(), &ReconManager::checkReconConnectionResponsed, this, &DeviceManager::updateReconConnectionState); mReconHttpThread->start(); mTemperatureTimer = startTimer(GET_TEMPERATURE_TIME); //init dms status--------------------make a function future if(JsonObject::Instance()->isDmsSimulator()) { //set simulator mSetSimulatorModeAction->setSendData("{ \"code\":0, \"info\":\"1\"}"); mSetSimulatorModeAction->execute(); } mSetHeartBeatAction->setSendData("{ \"code\":0, \"info\":\"0\"}"); mSetHeartBeatAction->execute(); mSoftwareVersion = "DMS Version Loading"; mGetSoftwareVersionAction->execute(); mCheckInitStatusTimer = startTimer(500); } void DeviceManager::initGUI(bool aIsInitSucceed) { if(!AppGlobalValues::DBconnected().toBool()) { emitErrorCallback(tr("Fail to connect to DB!Reboot device to try!")); emit initializeFinished(); return; } if(aIsInitSucceed) { if(getDeviceStatus() != DeviceStatus::Rready) { mStopScanAction->execute(); } if(!getCEStatus() && startCEScan()) { mIsInitializing = true; mScanProgressTimer = startTimer(500); } else { emit initializeProgress("33"); QThread::msleep(500); emit initializeProgress("66"); QThread::msleep(500); emit initializeProgress("100"); emit initializeFinished(); } } else { UsctStateManager::getInstance()->setState(DmsState, false); QString msg = tr("Initialize Failed."); THROW_ERROR(msg); emit initializeProgress("33"); QThread::msleep(500); emit initializeProgress("66"); QThread::msleep(500); emit initializeProgress("100"); emit initializeFinished(); } initEmptyScanMeasurementID(); //process expired patient list QDate date = QDate::currentDate().addDays(-JsonObject::Instance()->getPatientListExpireDays()); SQLHelper::exec(QString("DELETE FROM Patient WHERE AddDate <= %1").arg(date.toString("yyyy-MM-dd"))); //process expired scan list date = QDate::currentDate().addDays(-JsonObject::Instance()->getScanListExpireDays()); SQLHelper::exec(QString("DELETE FROM Scan WHERE ScanDateTime <= \"%1\"").arg(date.toString("yyyy-MM-dd"))); } void DeviceManager::processInitializeProgress(const QString& aProgress) { if(!mIsInitializing) { return; } QJsonObject jsonObj = toJsonObject(aProgress); int code = jsonObj["code"].toInt(); QString msg = jsonObj["info"].toString(); switch (code) { case 1: //emit initializeProgress(msg); break; case 2: emit initializeProgress(msg); break; case 3: prepareFinishInitialize(); emit initializeFinished(); break; case -1: prepareFinishInitialize(); THROW_ERROR(msg); break; default: break; } } bool DeviceManager::hasValidEmptyScan() { return !mCurrentEmptyMeasurementID.isEmpty(); } void DeviceManager::startScan(const QString& json, bool empty) { DeviceStatus inf = getDeviceStatus(); if(inf == DeviceStatus::Unkonw) { return; } if (inf != DeviceStatus::Rready) { QString errMsg(empty ? tr("Device is not ready, start empty scan operation failed!") : tr("Device is not ready, start scan operation failed!")); THROW_ERROR(errMsg); TRIGGER_EVENT(StopScanProcess, nullptr, nullptr); return; } AppGlobalValues::setEmptyScanFlag(empty); if (startFullScan(json)) { QString msg = "Start scan..."; TRIGGER_EVENT(GUIEvents::InvokeOperationStart, nullptr, (QObject*)&msg); mIsScanning = true; mIsEmptyScan = empty; QJsonObject patientInfo = QJsonDocument::fromJson(json.toUtf8()).object()["Patient Info"].toObject(); mCurrentPatientID = patientInfo["PatientID"].toString(); mCurrentAccessionNumber = patientInfo["AccessionNumber"].toString(); mCurrentPatientName = patientInfo["PatientName"].toString(); mCurrentLaterality = patientInfo["Laterality"].toString(); mCurrentOperatorName = patientInfo["OperatorName"].toString(); mCurrentMPPSUID = patientInfo["MPPSUID"].toString(); mCurrentModality = patientInfo["Modality"].toString(); mCurrentStudyUID = patientInfo["StudyUID"].toString(); mScanProgressTimer = startTimer(500); } } void DeviceManager::processScanProgress(const QString& aProgress) { if(mIsScanning == false) { return; } QJsonObject jsonObj = toJsonObject(aProgress); if(!jsonObj.contains("code") || !jsonObj.contains("info")) { prepareFinishScan(false); return; } int code = jsonObj["code"].toInt(); QString msg = jsonObj["info"].toString(); switch (code) { case 1: { QVariant var(tr("progress:%1%").arg(msg)); TRIGGER_EVENT(InvokeOperationProgress, nullptr, (QObject *) &var); break; } case 2: { QVariant var; if(mIsEmptyScan) { var = QVariant(tr("progress:%1%").arg(msg)); } else { ScanProcessSequence::getInstance()->fullScanDataExport(); var = QVariant(tr("Patient can leave.\nprogress:%1%").arg(msg)); } TRIGGER_EVENT(InvokeOperationProgress, nullptr, (QObject *) &var); break; } case 3: { QVariant var( tr("Data quality assessment in progress\nprogress:99%")); TRIGGER_EVENT(InvokeOperationProgress, nullptr, (QObject *) &var); break; } case 4: checkDataQuality(); break; default: prepareFinishScan(false, msg); break; } } void DeviceManager::prepareFinishScan(bool isNormalFinish, const QString& aReason) { if(!mIsScanning) { return; } if(mScanProgressTimer != -1) { killTimer(mScanProgressTimer); mScanProgressTimer = -1; } mIsScanning = false; QString message = aReason; QObject* var = message.isEmpty() ? nullptr : (QObject*)&message; bool isCompleteNotify = JsonObject::Instance()->getCompleteNotify(); if(!isNormalFinish) { if(!mIsEmptyScan) { TRIGGER_EVENT(StopScanProcess, nullptr, nullptr); } TRIGGER_EVENT(InvokeOperationEnd, nullptr, var); return; } if(mIsEmptyScan) { insertEmptyScanRecord(); TRIGGER_EVENT(EmptyScanFinished, nullptr, nullptr); } else { insertScanRecord(); } startTransfer(); if(isCompleteNotify) { QString msg = ScanProcessSequence::getInstance()->getScanPositionSize() == 2 ? tr("Scan completed! Please prepare for the next scan. \nAfter lying down, click the confirm button" "to start scanning on the next side.") : tr("Scan completed!") ; TRIGGER_EVENT(InvokeOperationEnd, nullptr, (QObject *)&msg); } else { TRIGGER_EVENT(InvokeOperationEnd, nullptr, var); } if(!mIsEmptyScan) { ScanProcessSequence::getInstance()->popPosition(); startAutoLocate(); } } void DeviceManager::prepareFinishInitialize() { mIsInitializing = false; if(mScanProgressTimer != -1) { killTimer(mScanProgressTimer); mScanProgressTimer = -1; } } void DeviceManager::stopFullScan() { // DeviceStatus inf = getDeviceStatus(); // if (inf != DeviceStatus::Scanning) // { // return; // } DmsSyncActionResult result = mStopScanAction->execute(); if(!result.mIsSucessful) { prepareFinishScan(false, ""); THROW_ERROR(result.mData); return; } prepareFinishScan(false, ""); } void DeviceManager::stopPreviewScan() { DeviceStatus inf = getDeviceStatus(); if (inf == DeviceStatus::Unkonw) { return; } DmsSyncActionResult result = mStopScanAction->execute(); if(!result.mIsSucessful) { THROW_ERROR(result.mData); return; } TRIGGER_EVENT(ResponseStopPreview, nullptr, nullptr); mIsPreviewing = false; AppGlobalValues::setInProcessing(false); } void DeviceManager::close() { } void DeviceManager::processPreviewData(const QString& aPreviewData) { if(!mIsPreviewing) { return; } QJsonObject jsonObj = toJsonObject(aPreviewData); if(!jsonObj.contains("code") || jsonObj["code"].toInt() != 0) { return; } QString path = jsonObj["info"].toString(); QFile file(path); if (!file.open(QIODevice::ReadOnly)) { qDebug() << "Preview file path error. Path : " + path; return; } QByteArray data = file.readAll(); QByteArray bytes = QByteArray::fromRawData(data, PREVIEW_IMAGE_WH * PREVIEW_IMAGE_WH); TRIGGER_EVENT(ResponsePreviewData, nullptr, (QObject *) (&bytes)); } void DeviceManager::startPreview() { DeviceStatus status = getDeviceStatus(); if(status == DeviceStatus::Unkonw) { emit startPreviewScanResult(false); return; } if (status != DeviceStatus::Rready) { emit startPreviewScanResult(false); QString msg(status != DeviceStatus::Rready ? "Can't start preview,Device is not ready!" : "Start preview operation fail!"); THROW_ERROR(msg); return; } DmsSyncActionResult result = mPreviewScanAction->execute(); if(!result.mIsSucessful) { emit startPreviewScanResult(false); THROW_ERROR(result.mData); return; } QJsonObject jsonObj = toJsonObject(result.mData); if(!jsonObj.contains("code") || jsonObj["code"].toInt() !=0) { emit startPreviewScanResult(false); QString msg = jsonObj.contains("info") ? jsonObj["info"].toString() : DEFAULT_DMS_START_FAILED; THROW_ERROR(msg); return; } AppGlobalValues::setInProcessing(true); mIsPreviewing = true; emit startPreviewScanResult(true); TRIGGER_EVENT(ResponsePreview, nullptr, nullptr); } void DeviceManager::checkInitStatus() { DmsSyncActionResult result = mCheckInitStatusAction->execute(); if(!result.mIsSucessful) { if(mCheckInitStatusTimer != -1) { killTimer(mCheckInitStatusTimer); mCheckInitStatusTimer = -1; } initGUI(false); return; } QJsonObject jsonObj = toJsonObject(result.mData); if(jsonObj["code"].toInt() == 1) { if(mCheckInitStatusTimer != -1) { killTimer(mCheckInitStatusTimer); mCheckInitStatusTimer = -1; } initGUI(true); } else if(jsonObj["code"].toInt() == 2) { if(mCheckInitStatusTimer != -1) { killTimer(mCheckInitStatusTimer); mCheckInitStatusTimer = -1; } initGUI(false); } } void DeviceManager::timerEvent(QTimerEvent* event) { if(event->timerId() == mScanProgressTimer) { getScanProcess(); return QObject::timerEvent(event); } if(event->timerId() == mGetAutoLocatePositionTimer) { getAutoLocatePosition(); return QObject::timerEvent(event); } if(event->timerId() == mCheckInitStatusTimer) { checkInitStatus(); return QObject::timerEvent(event); } if (event->timerId() == mTemperatureTimer) { getDeviceTemperature(); return QObject::timerEvent(event); } } void DeviceManager::emitErrorCallback(const QString& msg) { emit raiseGlobalError(msg); } void DeviceManager::emitInfoCallback(const QString& aMessage,const unsigned int aInfoType) { emit raiseGlobalInfo(QPair(aMessage,aInfoType)); } QString DeviceManager::getSoftwareVersion() { return mSoftwareVersion; } void DeviceManager::processReceiveDMSInfoResult(int aServerID, int aActionID, const QString& aContents) { qDebug()<<"processReceiveDMSInfoResult " < GUI : %1-%2, Message:%3").arg(aServerID).arg(aActionID).arg(aContents)); switch(aServerID) { case USRV_SCAN : switch(aActionID) { case ACT_SCAN_STATUS : emit responseGetDeviceStatus(aContents); break; case ACT_SCAN_FULLSCAN : emit responseFullScan(aContents); break; case ACT_SCAN_PREVIEW: emit responsePreviewScan(aContents); break; case ACT_SCAN_TEMP : emit responseGetDeviceTemperature(aContents); processDeviceTemperature(aContents); break; case ACT_SCAN_PROGRESS_PASSIVE : emit responseGetScanProgress(aContents); if(mIsInitializing) { processInitializeProgress(aContents); } else { processScanProgress(aContents); } break; case ACT_SCAN_PRESIG: processPreviewData(aContents); break; case ACT_SCAN_STOP : emit responseStopScan(aContents); break; case ACT_SCAN_CE : emit responseCEScan(aContents); break; case ACT_SCAN_CE_STATUS : emit responseGetCEStatus(aContents); break; case ACT_SCAN_SIMULATOR: emit responseSetSimulatorMode(aContents); break; case ACT_SCAN_IMGQUALITI: emit responseCheckDataQuality(aContents); default: break; } break; case USRV_LOGALARM : switch (aActionID) { case ACT_LOGALM_RPT : processAlarm(aContents); break; default: break; } break; case USRV_XFR : switch(aActionID) { case ACT_XFR_START : emit responseTransfer(aContents); break; case ACT_XFR_STOP : emit responseStopTransfer(aContents); break; case ACT_XFR_PROGRESS_PASSIVE : emit responseGetTransferProgress(aContents); break; case ACT_XFR_PROGRESS_ACTIVE : processTransferProgress(aContents); break; } break; case USRV_INFOCFG: switch(aActionID) { case ACT_IFCFG_VERINFO : emit responseGetSoftwareVersion(aContents); processGetSoftwareVersion(aContents); break; case ACT_IFCFG_HBCFG : emit responseSetHeartBeat(aContents); break; case ACT_IFCFG_INIT_STATUS : emit responseCheckInitStatus(aContents); break; } break; case USRV_CONTROL: switch(aActionID) { case ACT_CTL_PUMP: emit responsePumpControl(aContents); processPumpResult(aContents); break; case ACT_CTL_PWRDOWN: emit responseShutDown(aContents); processShutDownDms(aContents); break; case ACT_CTL_MOTION_START: emit responseStartAutoLocate(aContents); break; case ACT_CTL_MOTION_STOP: emit responseStopAutoLocate(aContents); break; case ACT_CTL_MOTION_POSITION: emit responseGetAutoLocatePosition(aContents); processAutoLocatePosition(aContents); break; case ACT_CTL_EMG_RESET: processEmergencyButtonReset(aContents); break; } break; default: break; } } void DeviceManager::processAlarm(const QString& aAlarm) { QJsonObject jsonObj = toJsonObject(aAlarm); int alarmCode = jsonObj["code"].toInt(); QString alarm = tr("Error: ") + QString::number(alarmCode) + AlarmHelper::getAlarmString(alarmCode); qDebug()<<"processAlarm : "<= 400 && alarmCode < 500) { switch (alarmCode) { case 492://left emergency button pushed prepareFinishScan(false,""); emit emergencyButtonPushed(true, false); return; case 494://right emergency button pushed prepareFinishScan(false,""); emit emergencyButtonPushed(false, false); return; default: break; } if(mIsScanning) { prepareFinishScan(false, alarm); } else { THROW_ERROR(alarm); } } else if(alarmCode >= 500 && alarmCode < 600) { emitInfoCallback(alarm, MessageLevel::Warning); } else if(alarmCode >= 600 && alarmCode < 700) { emitInfoCallback(alarm, MessageLevel::Info); } } void DeviceManager::processGetSoftwareVersion(const QString& aSoftwareVersion) { QJsonObject jsonObj = toJsonObject(aSoftwareVersion); if(jsonObj["code"].toInt() != 0) { mSoftwareVersion = "DMS Version Fetch Error"; } mSoftwareVersion = jsonObj["info"].toString(); emit getDmsVersionResponsed(mSoftwareVersion); } void DeviceManager::scanTimeout() { prepareFinishScan(false, tr("DMS connection error")); } DeviceStatus DeviceManager::getDeviceStatus() { DmsSyncActionResult result = mGetDeviceStatusAction->execute(); if(!result.mIsSucessful) { QString message = tr("DMS connection error"); THROW_ERROR(message); return DeviceStatus::Unkonw; } QJsonObject jsonObj = toJsonObject(result.mData); if(!jsonObj.contains("code") || jsonObj["code"].toInt() != 0) { return DeviceStatus::Error; } int status = jsonObj["info"].toString().toInt(); switch (status) { case 0 : return DeviceStatus::Busy; case 1 : return DeviceStatus::Rready; case 2 : return DeviceStatus::Scanning; case 3 : return DeviceStatus::Error; default: return DeviceStatus::Error; } } bool DeviceManager::startFullScan(const QString& aPatientInfo) { mFullScanAction->setSendData(aPatientInfo); DmsSyncActionResult result = mFullScanAction->execute(); if(!result.mIsSucessful) { QString message = tr("Start scan failed. Reason:time out."); THROW_ERROR(message); LOG_SYS_OPERATION("Start full scan failed. " + message); TRIGGER_EVENT(StopScanProcess, nullptr, nullptr); return false; } QJsonObject jsonObj = toJsonObject(result.mData); int code = jsonObj["code"].toInt(); if(code != 0) { QString msg = tr("Start scan failed. Reason:%1").arg(jsonObj["info"].toString()) + AlarmHelper::getAlarmString(code); LOG_SYS_OPERATION("Start full scan failed. " + msg); THROW_ERROR(msg); TRIGGER_EVENT(StopScanProcess, nullptr, nullptr); return false; } mCurrentScanMeasurementID = jsonObj["measurement id"].toString(); return true; } bool DeviceManager::startCEScan() { DmsSyncActionResult result = mCEScanAction->execute(); if(!result.mIsSucessful) { QString message = tr("Initialize Failed."); THROW_ERROR(message); return false; } QJsonObject jsonObj = toJsonObject(result.mData); if(jsonObj.contains("code") && jsonObj["code"].toInt() != 0) { QString msg = tr("Initialize Failed."); THROW_ERROR(msg); msg = tr("Start CE Scan Failed."); EventCenter::Default()->triggerEvent(WarningMessageRaise, nullptr, (QObject*)&msg); return false; } return true; } void DeviceManager::getDeviceTemperature() { mGetDeviceTemperatureAction->execute(); } void DeviceManager::processDeviceTemperature(const QString& aResponseTemperature) { QJsonObject jsonObj = toJsonObject(aResponseTemperature); if(jsonObj["code"].toInt() != 0) { return; } QString temp = jsonObj["info"].toString(); TRIGGER_EVENT(GUIEvents::ResponseDeviceTemperature, nullptr, (QObject *) &temp); } void DeviceManager::getScanProcess() { mGetScanProgressAction->execute(); } void DeviceManager::shutdownDms() { if(mIsTransfering) { QString msg = tr("Data is currently being transmitted, please shut down later."); THROW_ERROR(msg); return; } if(!mShutDownAction->execute()) { QString msg = tr("Shut down failed, please push emergency button to shutdown."); THROW_ERROR(msg); return; } AppGlobalValues::setInProcessing(true); emit shutdownDmsSended(); } void DeviceManager::processShutDownDms(const QString& aResponse) { QJsonObject jsonObj = toJsonObject(aResponse); if(jsonObj.contains("code") && jsonObj["code"].toInt() == 0) { shutdownOperationSystem(); return; } AppGlobalValues::setInProcessing(false); emit shutdownDmsFailed(); } void DeviceManager::shutdownOperationSystem() { qDebug()<< "shut down OS"; QProcess::startDetached("shutdown", QStringList() << "-h" << "now"); } void DeviceManager::insertEmptyScanRecord() { QString sql = QString("INSERT INTO EScan (ScanID, ScanDateTime, State) VALUES ('%1','%2',%3)") .arg(mCurrentScanMeasurementID) .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")) .arg(0); if(!SQLHelper::exec(sql)) { QString msg = "DB Error. G401"; THROW_ERROR(msg); return; } mCurrentEmptyMeasurementID = mCurrentScanMeasurementID; } void DeviceManager::insertScanRecord() { QString sql = QString("INSERT INTO Scan (ScanID, ReferenceID, PatientID, AccessionNumber, PatientName, ScanDateTime, Laterality, OperatorName, State, StudyUID, Modality, MPPSUID) VALUES ('%1','%2','%3','%4','%5','%6','%7','%8', %9, '%10', '%11', '%12')") .arg(mCurrentScanMeasurementID) .arg(mCurrentEmptyMeasurementID) .arg(mCurrentPatientID) .arg(mCurrentAccessionNumber) .arg(mCurrentPatientName) .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")) .arg(mCurrentLaterality) .arg(mCurrentOperatorName) .arg(0) .arg(mCurrentStudyUID) .arg(mCurrentModality) .arg(mCurrentMPPSUID); if(!SQLHelper::exec(sql)) { QString msg = "DB Error. G401"; THROW_ERROR(msg); } } void DeviceManager::startTransfer() { if(mIsTransfering) { return; } QString sql = "SELECT ScanID FROM %1 WHERE State<200 ORDER BY ScanDateTime ASC LIMIT 1"; QString table = "EScan"; QVariant sqlResult = SQLHelper::queryValue(sql.arg(table)); mIsTransferEmptyScan = true; if(sqlResult.isNull()) { mIsTransferEmptyScan = false; table = "Scan"; sqlResult = SQLHelper::queryValue(sql.arg(table)); if(sqlResult.isNull()) { return; } } QString scanID = sqlResult.toString(); auto host = JsonObject::Instance()->getServer(JsonObject::RECON); mTransferAction->setSendData("{\"MD5\":1, \"dst\":\"" + host.ae + "@" + host.ip +":" + mReconTransferPath + "\", \"src\":\"" + scanID + "\",\"delete\":1,\"active report\":0}"); DmsSyncActionResult result = mTransferAction->execute(); if(!result.mIsSucessful) { QString msg = tr("Scan data transfer failed."); emitInfoCallback(msg, MessageLevel::Error); return; } QJsonObject jsonObj = toJsonObject(result.mData); int code = jsonObj["code"].toInt(); if(code != 0) { mStopTransferAction->execute(); QString msg = tr("Scan data transfer failed."); emitInfoCallback(msg, MessageLevel::Error); return; } mIsTransfering = true; mCurrentTransferMeasurementID = scanID; mCurrentTransferPatientID = mIsTransferEmptyScan ? "" : SQLHelper::queryValue(QString("SELECT PatientID FROM %1 WHERE ScanID = '%2'").arg(table).arg(scanID)).toString(); sql = QString("UPDATE %1 set State = 100 where ScanID = '%2'") .arg(mIsTransferEmptyScan ? "EScan" : "Scan") .arg(mCurrentTransferMeasurementID); if(!SQLHelper::exec(sql)) { QString msg = "DB Error. Code:G501"; emitInfoCallback(msg, MessageLevel::Error); } else { updateTransferState(); } } void DeviceManager::processTransferProgress(const QString& aProgress) { if(!mIsTransfering) { return; } QJsonObject jsonObj = toJsonObject(aProgress); int code = jsonObj["code"].toInt(); QString msg = jsonObj["info"].toString(); switch (code) { case 1: { break; } case 2: { QString sql = QString("UPDATE %1 set State = 200 where ScanID = '%2'") .arg(mIsTransferEmptyScan ? "EScan" : "Scan") .arg(mCurrentTransferMeasurementID); mIsTransfering = false; mTransferProgress = 0; mCurrentTransferMeasurementID.clear(); if(!SQLHelper::exec(sql)) { QString msg = "DB Error. Code:G502"; emitInfoCallback(msg, MessageLevel::Error); break; } emitInfoCallback(tr("Scan data transfer Succeeded!"), MessageLevel::Sucess); updateTransferState(); if(ReconManager::getInstance()->isConnected()) { startCreateReconRecord(); } startTransfer(); break; } default: QString sql = QString("UPDATE %1 set State = 104 where ScanID = '%2'") .arg(mIsTransferEmptyScan ? "EScan" : "Scan") .arg(mCurrentTransferMeasurementID); mIsTransfering = false; mTransferProgress = 0; mCurrentTransferMeasurementID.clear(); if(!SQLHelper::exec(sql)) { QString msg = "DB Error. Code:G503"; emitInfoCallback(msg, MessageLevel::Error); break; } QString message = tr("Scan data transfer failed."); emitInfoCallback(message, MessageLevel::Error); updateTransferState(); break; } } void DeviceManager::processReconCreateEmptyScan(bool aResult, const QString& aScanID, const QString& aMessage, bool aIsConnectSucceed) { if(aResult) { UsctStateManager::getInstance()->setEmptyScanUpdateFlag(false); QString sql = QString("UPDATE EScan set State = 300 where ScanID = '%1'").arg(aScanID); if(!SQLHelper::exec(sql)) { QString msg = "DB Error. Code:G504"; emitInfoCallback(msg, MessageLevel::Error); } EventCenter::Default()->triggerEvent(EmptyScanDataStateUpdated, nullptr, nullptr); return; } emitInfoCallback(tr("Create empty scan data failed"), MessageLevel::Error); QString sql = QString("UPDATE EScan set State = %1 where ScanID = '%2'").arg(aIsConnectSucceed ? "304" : "204").arg(aScanID); if(!SQLHelper::exec(sql)) { QString msg = "DB Error. Code:G505"; emitInfoCallback(msg, MessageLevel::Error); } EventCenter::Default()->triggerEvent(EmptyScanDataStateUpdated, nullptr, nullptr); } void DeviceManager::processReconCreateScan(bool aResult, const QString& aScanID, const QString& aMessage, bool aIsConnectSucceed) { if(aResult) { QString sql = QString("UPDATE Scan set State = 300 where ScanID = '%1'").arg(aScanID); if(!SQLHelper::exec(sql)) { QString msg = "DB Error. Code:G504"; emitInfoCallback(msg, MessageLevel::Error); } return; } emitInfoCallback(tr("Create scan data failed"), MessageLevel::Error); QString sql = QString("UPDATE Scan set State = %1 where ScanID = '%2'").arg(aIsConnectSucceed ? "304" : "204").arg(aScanID); if(!SQLHelper::exec(sql)) { QString msg = "DB Error. Code:G505"; emitInfoCallback(msg, MessageLevel::Error); } } void DeviceManager::processReconQueryScanState(bool aResult, const QVariant& aState) { if(!aResult) { emitInfoCallback(aState.toString(), MessageLevel::Error); return; } QMap states = aState.value>(); for(auto itor= states.constBegin(); itor != states.constEnd(); ++itor) { QString sql = QString("UPDATE Scan set State = %1 where ScanID = '%2'").arg(itor.value()).arg(itor.key()); if(!SQLHelper::exec(sql)) { QString msg = "DB Error. Code:G506"; emitInfoCallback(msg, MessageLevel::Error); } } emit updateReconStateFinished(); } void DeviceManager::startCreateReconRecord() { QString sql = "SELECT ScanID FROM EScan WHERE State < 300 And State >= 200 ORDER BY ScanDateTime ASC"; auto result = SQLHelper::queryValues(sql); for (const QVariant &variant : result) { QString scanid = variant.value>()[0].toString(); emit createEmptyScanToRecon(scanid, mReconTransferPath + "/" + scanid); } sql = "SELECT ScanID, ReferenceID, PatientID, AccessionNumber, StudyUID, MPPSUID FROM Scan WHERE State < 300 And State >= 200 ORDER BY ScanDateTime ASC"; result = SQLHelper::queryValues(sql); for (const QVariant &variant : result) { QList record = variant.value>(); QString scanID = record[0].toString(); QString referenceID = record[1].toString(); QString patientID = record[2].toString(); QString AccessionNumber = record[3].toString(); QString studyUID = record[4].toString(); QString mppsUID = record[5].toString(); emit createScanToRecon(scanID, mppsUID, referenceID, mReconTransferPath + "/" + scanID); } startTransfer(); } void DeviceManager::initEmptyScanMeasurementID() { QString sql = "SELECT ScanID FROM EScan ORDER BY ScanDateTime DESC LIMIT 1"; mCurrentEmptyMeasurementID = SQLHelper::queryValue(sql).toString(); } void DeviceManager::updateReconState() { if(!ReconManager::getInstance()->isConnected()) { emitInfoCallback(tr("Recon disconnected."), MessageLevel::Error); return; } QString sql = "SELECT ScanID FROM Scan WHERE State < 999 And State >= 300 And State != 304"; auto result = SQLHelper::queryValues(sql); QStringList scanIDs; for (const QVariant &variant : result) { scanIDs << variant.value>()[0].toString(); } if(scanIDs.isEmpty()) { emit updateReconStateFinished(); return; } emit queryScanStatusToRecon(scanIDs); } bool DeviceManager::updateTransferProgress() { if(!mIsTransfering) { return false; } mTransferProgress = 0; auto result = mGetTransferProgressAction->execute(); QJsonObject jsonObj = toJsonObject(result.mData); if(jsonObj["code"].toInt() == 1 ) { mTransferProgress = jsonObj["info"].toString().toInt(); return true; } return false; } void DeviceManager::updateTransferState() { if(mIsTransferEmptyScan) { EventCenter::Default()->triggerEvent(EmptyScanDataStateUpdated, nullptr, nullptr); } else { emit transferStatusUpdated(); } } int DeviceManager::getTransferProgress() { return mTransferProgress; } bool DeviceManager::getCEStatus() { auto result = mGetCEStatusAction->execute(); if(result.mIsSucessful) { QJsonObject jsonObj = toJsonObject(result.mData); if(jsonObj["code"].toInt() == 0 ) { if(jsonObj["info"].toString().toInt() == 0) { return false; } } } return true; } void DeviceManager::controlDrainage(const QString& aCode) { mPumpControlAction->setSendData(QString("{\"valve\":%1}").arg(aCode)); if(!mPumpControlAction->execute()) { emit startPumpControlResult(false); QString msg = tr("Open pump failed."); THROW_ERROR(msg); } } void DeviceManager::processPumpResult(const QString& aResponse) { QJsonObject jsonObj = toJsonObject(aResponse); if(jsonObj["code"].toInt() == 0 ) { emit startPumpControlResult(true); return; } emit startPumpControlResult(false); QString msg = tr("Open pump failed."); THROW_ERROR(msg); } void DeviceManager::updateReconConnectionState(bool aIsConnected) { EventCenter::Default()->triggerEvent(ReconConnectionUpdated, nullptr, (QObject*)&aIsConnected); } void DeviceManager::startScanProcess() { LOG_SYS_OPERATION("Start scan process."); if( !JsonObject::Instance()->getScanCanWithoutRecon() && (!UsctStateManager::getInstance()->getState(ReconConnectionState) || !UsctStateManager::getInstance()->getState(ReconState) || !UsctStateManager::getInstance()->getState(ReconDBState))) { QString errorMessage = tr("Recon error, can't start scan process"); LOG_SYS_OPERATION(errorMessage) TRIGGER_EVENT(StopScanProcess, nullptr, nullptr); THROW_ERROR(errorMessage); return; } AppGlobalValues::setInProcessing(true); mIsScanning = true; startAutoLocate(); } void DeviceManager::stopScanProcess() { AppGlobalValues::setInProcessing(false); mIsScanning = false; LOG_SYS_OPERATION("Stop scan process.") stopAutoLocate(); } bool DeviceManager::startAutoLocate() { if(ScanProcessSequence::getInstance()->getScanPositionSize() == 0) { TRIGGER_EVENT(StopScanProcess, nullptr, nullptr); return false; } auto result = mStartAutoLocateAction->execute(); if(result.mIsSucessful) { mIsAutoLocating = true; QJsonObject jsonObj = toJsonObject(result.mData); if(jsonObj["code"].toInt() == 0 ) { emit startAutoLocateResult(true); mEffectivePositionCount = 0; mGetAutoLocatePositionTimer = startTimer(1000); return true; } } emit startAutoLocateResult(false); TRIGGER_EVENT(StopScanProcess, nullptr, nullptr); QString errorMessage = tr("Start auto locate failed") + AlarmHelper::getAlarmString(toJsonObject(result.mData)["info"].toInt()); THROW_ERROR(errorMessage) LOG_SYS_OPERATION("Start auto locate failed.") return false; } void DeviceManager::stopAutoLocate() { if(mIsAutoLocating) { mStopAutoLocateAction->execute(); mIsAutoLocating = false; } if(mGetAutoLocatePositionTimer != -1) { killTimer(mGetAutoLocatePositionTimer); mGetAutoLocatePositionTimer = -1; } } void DeviceManager::getAutoLocatePosition() { mGetAutoLocatePositionAction->execute(); } void DeviceManager::processAutoLocatePosition(const QString& aProgress) { QJsonObject jsonObj = toJsonObject(aProgress); int code = jsonObj["code"].toInt(); int x = jsonObj["x"].toInt(); int y = jsonObj["y"].toInt(); int z = jsonObj["z"].toInt(); if(code == 0) { if(qSqrt(x*x + y*y) EFFECTIVE_POSITION_Z_START && z< EFFECTIVE_POSITION_Z_END) { if(++mEffectivePositionCount >= 5) { mEffectivePositionCount = 0; stopAutoLocate(); emit autolocatePositionEffective(); } } else { mEffectivePositionCount = 0;; } emit updateAutoLocatePosition(x, y, z); } else { TRIGGER_EVENT(StopScanProcess, nullptr, nullptr); QString errorMessage = tr("Start auto locate failed"); THROW_ERROR(errorMessage); } } void DeviceManager::checkDataQuality() { auto result = mCheckDataQualityAction->execute(); if(result.mIsSucessful) { QJsonObject jsonObj = toJsonObject(result.mData); if(jsonObj["qualities"].toInt() == 1 ) { LOG_SYS_OPERATION("Check data quality succeed. Data quality is good.") prepareFinishScan(true); return; } else { LOG_SYS_OPERATION("Check data quality succeed. Data quality is bad.") QString errorMessage = tr("The data quality is low, please restart the data scan.") + jsonObj["info"].toString(); prepareFinishScan(false, errorMessage); TRIGGER_EVENT(StopScanProcess, nullptr, nullptr); return; } } QString errorMessage = tr("DMS connection error"); prepareFinishScan(false, errorMessage); TRIGGER_EVENT(StopScanProcess, nullptr, nullptr); LOG_SYS_OPERATION("Check data quality failed. " + errorMessage) return; } void DeviceManager::prepareCheckReconConnection() { if(AppGlobalValues::InProcessing().toBool()) { return; } emit checkReconConnection(); } void DeviceManager::processEmergencyButtonReset(const QString& aResponse) { QJsonObject jsonObj = toJsonObject(aResponse); int code = jsonObj["code"].toInt(); if(code == -1) { QString errorMessage = tr("Device reset failed, please contact maintenance person"); THROW_ERROR(errorMessage); } if(jsonObj["info"].toString() == "left" ) { emit emergencyButtonPushed(true, true); return; } if(jsonObj["info"].toString() == "right" ) { emit emergencyButtonPushed(false, true); return; } } void DeviceManager::prepareEmergencyReset() { mEmergencyResetAction->execute(); }