#include "stdafx.h" #include "CommonFun.h" #include "V2COMBoxDevice.hpp" #include "DIOS.Dev.SyncBox.V2COM.h" #include "Helper.JSON.hpp" using namespace DIOS::Dev::Detail::SYNBOX; namespace nsSYN = DIOS::Dev::Detail::SYNBOX; static string tempErrorList = ""; const char cCmd_heartbeat[5] = {'E','C',0x0d ,0x0a ,0x00};// "EC 回车 换行"; //static string tempErrorlist; //----------------------------------------------------------------------------- // V2COMBoxDevice //----------------------------------------------------------------------------- nsSYN::V2COMBoxDevice::V2COMBoxDevice(std::shared_ptr center, nsSCF::SCF SCF, string configfile) { m_SCF = SCF; EventCenter = center; ResDataObject temp; temp.loadFile(configfile.c_str()); m_SYNConfig = temp["CONFIGURATION"]; m_SynBoxUnit.m_WS.reset(new WORKSTATIONMould("")); m_SynBoxUnit.m_CurrentExpNumber.reset(new CUREXPNUMMould(0, 0, 10000, 1)); m_SynBoxUnit.m_HandSwitchState.reset(new HANDSWITCHMould(0, 0, 10000, 1)); m_SynBoxUnit.m_GenSynState.reset(new GENSYNSTATEMould(0, 0, 10000, 1)); m_SynBoxUnit.m_GenExpectSynState.reset(new GENEXPECTSYNSTATEMould(0, 0, 10000, 1)); m_SynBoxUnit.m_TotalExpNumber.reset(new TOTALEXPNUMMould(0, 0, 10000, 1)); m_SynBoxUnit.m_DetectorState.reset(new DETECTORSTATUSMould(0, 0, 10000, 1)); m_SynBoxUnit.m_DetectorWindowState.reset(new XWINDOWSTATUSMould(AttrKey::XWINDOW_OFF, AttrKey::XWINDOW_OFF, AttrKey::XWINDOW_ON, 1)); m_SynBoxUnit.m_ExpMode.reset(new EXPMODEMould("")); //同步盒错误、告警信息 m_MSGUnit.reset(new nsDetail::MSGUnit(center, SyncConsoleUnitType)); m_DYNMap.m_MapChannelState["TB"] = 0; m_DYNMap.m_MapChannelState["WB"] = 0; m_DYNMap.m_MapChannelState["GT"] = 0; m_DYNMap.m_MapChannelState["GW"] = 0; m_DYNMap.m_MapChannelState["PT"] = 0; m_DYNMap.m_MapChannelState["PW"] = 0; m_DYNMap.m_MapChannelState["ER"] = 0; m_DYNMap.m_MapChannelState["RT"] = 0; m_DYNMap.m_MapChannelState["RW"] = 0; m_DYNMap.m_MapChannelState["OT"] = 0; m_DYNMap.m_MapChannelState["OW"] = 0; m_DYNMap.m_MapChannelState["PR"] = 0; m_DYNMap.m_MapChannelState["FT"] = 0; m_DYNMap.m_MapChannelState["FW"] = 0; m_DYNMap.m_MapChannelState["TT"] = 0; m_DYNMap.m_MapChannelState["TW"] = 0; m_pHardwareThread = nullptr; m_iHeartBeats = 0; m_bConnectFlag = true; m_bSetBaudOK = false; #if 1 //暂不启用断线检测 StartHardwareThread(); #endif } nsSYN::V2COMBoxDevice::~V2COMBoxDevice() { if (m_pHardwareThread != NULL) { TerminateThread(m_pHardwareThread, 0); m_pHardwareThread = NULL; } } void nsSYN::V2COMBoxDevice::ReConnect(string &errorList) { mLog::Info("Enter V2COMBox_reConnect"); m_SCF.Disconnect(); ResDataObject Connection = m_SYNConfig["connections"][0]; mLog::Info("Reconnections:{$} \n", Connection.encode()); auto erCode = m_SCF.Connect(Connection.encode(), &nsSYN::DynBoxDriver::callbackPackageProcess, SCF_PACKET_TRANSFER, 3000); if (erCode == SCF_ERR::SCF_SUCCEED) { FireErrorMessage(false, 1, "lost Connect"); m_bConnectFlag = true; mLog::Info("reconnect success"); mLog::Info("old errorlist:{$}", errorList.c_str()); errorList = ""; } else { mLog::Info("reconnect failed"); } } bool nsSYN::V2COMBoxDevice::StartHardwareThread() { mLog::Info("enter Start HardwareStatus Thread "); if (m_pHardwareThread == NULL) { DWORD m_HardwareStatusID; m_pHardwareThread = CreateThread(0, 0, HardwareStatusThread, this, 0, &m_HardwareStatusID); if (m_pHardwareThread == NULL) { mLog::Error("Start HardwareStatus Thread Failed"); return false; } } return true; } #if 1 DWORD nsSYN::V2COMBoxDevice::HardwareStatusThread(LPVOID pParam) { V2COMBoxDevice* pCurSyn = (V2COMBoxDevice*)pParam; if (pCurSyn == NULL) { return false; } mLog::Info("HardwareStatusThread start"); bool HeartBeatFlag = false; if(pCurSyn->m_SYNConfig.GetKeyCount("HeartBeatEnable")>0) HeartBeatFlag = (int)pCurSyn->m_SYNConfig["HeartBeatEnable"]; //pCurSyn->FireErrorMessage(false, 1, "lost Connect"); //pCurSyn->StopWindowRequest(); //pCurSyn->SetGenAECSignal(3); int iloopingFlag = 0; while (true) { if (HeartBeatFlag) //心跳检测 { //判断是否断连 if (!(pCurSyn->m_bConnectFlag)) { mLog::Info("V2COM: not Connect,try to reconnect \n"); pCurSyn->ReConnect(tempErrorList); Sleep(20000); continue; } Sleep(2000); pCurSyn->SendHeartBeat(); pCurSyn->m_iHeartBeats++; int tempHeartBeat = pCurSyn->m_iHeartBeats; if (tempHeartBeat > 10) //无返回信息认为连接断开 { pCurSyn->m_iHeartBeats = 0; pCurSyn->m_bConnectFlag = false; pCurSyn->FireErrorMessage(true, 1, "lost Connect"); tempErrorList = pCurSyn->m_MSGUnit->JSGet(); } } //定时查询CAN信息 Sleep(5000); pCurSyn->QueryInfo(); } mLog::Info("HardwareStatusThread stop"); return true; } #endif // 0 void nsSYN::V2COMBoxDevice::FireErrorMessage(const bool Act, const int Code, const char* ResInfo) { string ErrorCode("SYNBOX_ERR_"); ErrorCode += std::to_string(Code); int level = 0; if (Act) { mLog::Error("add {$}:{$}", ErrorCode.c_str(), ResInfo); m_MSGUnit->AddErrorMessage(ErrorCode.c_str(), level, ResInfo); } else { mLog::Error("del {$}:{$}", ErrorCode.c_str(), ResInfo); m_MSGUnit->DelErrorMessage(ErrorCode.c_str(), level, ResInfo); } } void nsSYN::V2COMBoxDevice::Register(Dispatch* Dispatch) { superGen::Register(Dispatch); Dispatch->Get.Push(m_MSGUnit->GetKey().c_str(), [this](std::string& out) { out = m_MSGUnit->JSGet(); return RET_STATUS::RET_SUCCEED; }); } nDev::RET_STATUS nsSYN::V2COMBoxDevice::SetWS(std::string value) { if (ResDYNConfig.GetFirstOf(value.c_str()) >= 0) { m_SynBoxUnit.m_WS->Update(value); m_strSYNMode = (string)ResDYNConfig[value.c_str()]; } else { m_strSYNMode = "SYN0"; } return RET_STATUS::RET_SUCCEED; } nDev::RET_STATUS nsSYN::V2COMBoxDevice::SetExpMode(std::string value) { m_SynBoxUnit.m_ExpMode->Update(value); mLog::Info("SetExpMode {$}", value.c_str()); return RET_STATUS::RET_SUCCEED; } nDev::RET_STATUS nsSYN::V2COMBoxDevice::SetGeneratortoSyncStatus(int state) { string strStateName = ""; int nstate = -1; mLog::Info(" SetGeneratortoSyncStatus :{$}", state); if (state == AttrKey::GENERATOR_FLU_OFF || state == AttrKey::GENERATOR_RAD_OFF)//如果是采集结束的消息,直接恢复同步盒状态 { ClearSignal(); } if (m_SynBoxUnit.m_GenSynState->Get() != state || state == AttrKey::GENERATOR_RAD_XRAYON || state == AttrKey::GENERATOR_RAD_XRAYOFF) { mLog::Info("switch :{$}", state); switch (state) { case AttrKey::GENERATOR_RAD_PREPARE: m_nCurrentExpTimes = 0; strStateName = "HANDSWITCHPREPREQUEST"; nstate = 1; m_nInExpState = true; m_wStartEXPTime = GetTickCount(); break; case AttrKey::GENERATOR_RAD_READY: m_nCurrentExpTimes = 0; strStateName = "HANDSWITCHREADYREQUEST"; nstate = 1; break; case AttrKey::GENERATOR_RAD_OFF: m_nCurrentExpTimes = 0; m_nExpTimes = -1; m_nInExpState = false; /*strStateName = "HANDSWITCHREADYREQUEST"; nstate = 0; ((DYNSyncBox*)GetDrvDPC())->SetSignal(strStateName.c_str(), state); Sleep(30); strStateName = "GENEXPREQUEST"; nstate = 0; ((DYNSyncBox*)GetDrvDPC())->SetSignal(strStateName.c_str(), state); Sleep(30); strStateName = "HANDSWITCHPREPREQUEST"; nstate = 0;*/ break; case AttrKey::GENERATOR_FLU_READY: m_nCurrentExpTimes = 0; strStateName = "HANDSWITCHPREPREQUEST"; nstate = 1; SetSignal(strStateName.c_str(), nstate); Sleep(30); strStateName = "HANDSWITCHREADYREQUEST"; nstate = 1; break; case AttrKey::GENERATOR_FLU_OFF: m_nCurrentExpTimes = 0; m_nExpTimes = -1; /*strStateName = "HANDSWITCHREADYREQUEST"; nstate = 0; ((DYNSyncBox*)GetDrvDPC())->SetSignal(strStateName.c_str(), nstate); Sleep(30); strStateName = "HANDSWITCHPREPREQUEST";*/ break; case AttrKey::GENERATOR_RAD_XRAYON: m_bINEEnable = true; strStateName = "GENEXPREQUEST"; nstate = 1; break; case AttrKey::GENERATOR_RAD_XRAYOFF: if (m_SynBoxUnit.m_ExpMode->JSGet() != "ContinueSerial") { strStateName = "GENEXPREQUEST"; nstate = 0; } break; default: strStateName = ""; nstate = -1; break; } if (state == AttrKey::GENERATOR_FLU_OFF || state == AttrKey::GENERATOR_RAD_OFF)//如果是采集结束的消息,直接恢复同步盒状态 { if (!m_bClear) { ClearSignal(); m_bClear = true; } m_SynBoxUnit.m_GenExpectSynState->Update(state); } else if (strStateName != "" && nstate >= 0) { m_bClear = false; SetSignal(strStateName.c_str(), nstate); m_SynBoxUnit.m_GenExpectSynState->Update(state); } } else { mLog::Error("switch :{$}, PreSetGeneratortoSyncStatus=false", state); } return RET_STATUS::RET_SUCCEED; } nDev::RET_STATUS nsSYN::V2COMBoxDevice::HWSend(char* strCommand, int nTimeOut) { if (!m_SCF) return RET_STATUS::RET_FAILED; mLog::Info("==OUT==: {$} ,len={$}\n", strCommand, strlen((char*)strCommand)); int retLength; m_SCF.Lock(msTimeOut_Lock) .SendPacket((char*)strCommand, strlen((char*)strCommand), nTimeOut, retLength); Sleep(nTimeOut); return RET_STATUS::RET_SUCCEED; } nDev::RET_STATUS nsSYN::V2COMBoxDevice::SetFilter(int filter) { BYTE data[16]; data[0] = 0x43; //C data[1] = 0x53; //S data[2] = 0x94; //ID:0x4A1 data[3] = 0x28; data[4] = 0x01; data[5] = 0x07; data[6] = filter; data[7] = 0x00; data[8] = 0x00; data[9] = 0x00; data[10] = 0x00; data[11] = 0x00; data[12] = 0x0D; data[13] = 0x0A; data[14] = 0x0; //不确定是否需要转0--->0x30 for (int i = 0; i <= 13; i++) { if (data[i] == 0) data[i] = 0x30; } HWSend((char*)data); } void nsSYN::V2COMBoxDevice::QueryInfo() { char data[20] = { 0 }; int nCmdSize; data[0] = 0x43; //C data[1] = 0x53; //S data[2] = 0x94; //ID:0x4A1 data[3] = 0x28; data[4] = 0x01; data[5] = 0x08; data[6] = 0x3F; data[7] = 0x3F; data[8] = 0x00; data[9] = 0x00; data[10] = 0x00; data[11] = 0x00; data[12] = 0x0D; data[13] = 0x0A; for (int i = 0; i <= 11; i++) { if (data[i] == 0) data[i] = 0x30; } data[14] = 0x0; HWSend((char*)data); } nDev::RET_STATUS nsSYN::V2COMBoxDevice::SetGrid(unsigned int GridType) { BYTE data[16]; data[0] = 0x43; //C data[1] = 0x53; //S data[2] = 0x94; //ID:0x4A1 data[3] = 0x28; data[4] = 0x01; data[5] = 0x04; data[6] = GridType; data[7] = 0x01; //振栅状态:1.图像IN;2.图像OUT;3.运动中.不知道如何处理 data[8] = 0x00; data[9] = 0x00; data[10] = 0x00; data[11] = 0x00; data[12] = 0x0D; data[13] = 0x0A; //不确定是否需要转0--->0x30 for (int i = 0; i <= 13; i++) { if (data[i] == 0) data[i] = 0x30; } data[14] = 0x0; HWSend((char*)data); } nDev::RET_STATUS nsSYN::V2COMBoxDevice::SetExpEnable() { return RET_STATUS::RET_SUCCEED; } nDev::RET_STATUS nsSYN::V2COMBoxDevice::SetExpDisable() { return RET_STATUS::RET_SUCCEED; } nDev::RET_STATUS nsSYN::V2COMBoxDevice::PrepareAcquisition() { return RET_STATUS::RET_SUCCEED; } nDev::RET_STATUS nsSYN::V2COMBoxDevice::StartWindowRequest() { if (m_nGenSynStateSignal == AttrKey::GENERATOR_RAD_READY) //add by wxx:解决OT1信号在 配置 及 工作流中重复发送的问题 { mLog::Info("send OT1 by workflows"); m_bINEEnable = true; string strStateName = "DETREACQREQUEST"; int state = 1; Sleep(1000); SetSignal(strStateName.c_str(), state); } else { mLog::Info("there is already send OT1 in this Exposure or not start Exposure yet"); } return RET_STATUS::RET_SUCCEED; } nDev::RET_STATUS nsSYN::V2COMBoxDevice::StopWindowRequest() { mLog::Info("send OT0 by workflows"); m_bINEEnable = false; string strStateName = "DETREACQREQUEST"; int state = 0; SetSignal(strStateName.c_str(), state); return RET_STATUS::RET_SUCCEED; } nDev::RET_STATUS nsSYN::V2COMBoxDevice::SetExposureTimes(int nNum) { m_nExpTimes = nNum; return RET_STATUS::RET_SUCCEED; } nDev::RET_STATUS nsSYN::V2COMBoxDevice::SetFrameRate(FLOAT frameRate) { SetPWM(frameRate); return RET_STATUS::RET_SUCCEED; } nDev::RET_STATUS nsSYN::V2COMBoxDevice::SetGenAECSignal(int signal) { mLog::Info("GENAECCONTROL:{$},AECMode:{$}", signal, m_bGenAECModeFlag); if (signal == 0) { m_bGenAECModeFlag = true; SetSignal("GENAECCONTROL", 0); //Preview模式控制AEC信号高 } else if(signal == 1) { if (m_bGenAECModeFlag) { m_bINEEnable = true; SetSignal("GENAECCONTROL", 1); //Preview模式控制AEC信号低 mLog::Info("send RT0 by Preview.workflows"); if (m_nGenSynStateSignal != AttrKey::GENERATOR_RAD_OFF) { m_nGenSynStateSignal = AttrKey::GENERATOR_RAD_READY; } mLog::Info("send RT0 by RAD.workflows GenSynState = {$}", m_nGenSynStateSignal); SetSignal("GENEXPREQUEST", 0); m_bINEEnable = false; } } else if (signal == 2) { if (m_bGenAECModeFlag) SetSignal("GENAECCONTROL", 0); //控制AEC信号高 } else if (signal == 3) { if (m_bGenAECModeFlag) { m_bGenAECModeFlag = false; SetSignal("GENAECCONTROL", 1); //控制AEC信号低 } m_bINEEnable = true; mLog::Info("send RT0 by RAD.workflows"); SetSignal("GENEXPREQUEST", 0); m_bINEEnable = false; } return RET_STATUS::RET_SUCCEED; } //----------------------------------------------------------------------------- // ProcessCmd //----------------------------------------------------------------------------- void nsSYN::V2COMBoxDevice::FireNotify(std::string key, std::string content) { EventCenter->OnNotify(1, key, content); } nDev::RET_STATUS nsSYN::V2COMBoxDevice::SetCollimatorDev(OemCollimator* dev) { if (dev) m_pCollDev.reset(dev); return RET_STATUS::RET_SUCCEED; } nDev::RET_STATUS nsSYN::V2COMBoxDevice::SetMechDev(OemMechanical* dev) { if (dev) m_pMechDev.reset(dev); return RET_STATUS::RET_SUCCEED; } //static bool DecodeFrame(const char* strFrame, int length); // 收到硬件的通知, 有包到达 // 按照设计, 仅当数据有变化时, 才发通知到上层, 因此里面有大量的 if (..) FireNotify (..) void nsSYN::V2COMBoxDevice::OnCallBack() { auto HWNotProcess = [](const char* value, int length) -> void { mLog::Info(" This commands didn't need to process!"); }; auto HWSignal = [this](const char* value, int length) -> void { assert(value && length>=3); char cChannelValue; cChannelValue = value[2]; //status : on /off string strChannel = ((string)value).substr(0, 2); bool bStatus = ChartoInt(cChannelValue); DealtheSignal(strChannel.c_str(), bStatus); }; auto HWCAN = [this](const char* value, int length) { char data_can[MAX_COMMAND_LEN] = { 0 }; for (int i = 0; i < length; i++) { if (value[i] == 0x30) data_can[i] = 0x0; else if (value[i] == 0x61) data_can[i] = 0x0a; else if (value[i] == 0x64) data_can[i] = 0x0d; else data_can[i] = value[i]; } string strcmd = data_can; string sCmdID = strcmd.substr(2, 2); DealReceiveData(data_can, length); }; arFrame.clear(); arFrame.push_back(tFrameMapping("EC", 2, HWNotProcess)); arFrame.push_back(tFrameMapping("CO", 2, HWNotProcess)); arFrame.push_back(tFrameMapping("GR", 2, HWCAN)); arFrame.push_back(tFrameMapping("CR", 2, HWCAN)); arFrame.push_back(tFrameMapping("TB", 2, HWSignal)); arFrame.push_back(tFrameMapping("WB", 2, HWSignal)); arFrame.push_back(tFrameMapping("GT", 2, HWSignal)); arFrame.push_back(tFrameMapping("GW", 2, HWSignal)); arFrame.push_back(tFrameMapping("PT", 2, HWSignal)); arFrame.push_back(tFrameMapping("PW", 2, HWSignal)); arFrame.push_back(tFrameMapping("ER", 2, HWSignal)); arFrame.push_back(tFrameMapping("RT", 2, HWSignal)); arFrame.push_back(tFrameMapping("RW", 2, HWSignal)); arFrame.push_back(tFrameMapping("OT", 2, HWSignal)); arFrame.push_back(tFrameMapping("OW", 2, HWSignal)); arFrame.push_back(tFrameMapping("PR", 2, HWSignal)); arFrame.push_back(tFrameMapping("FT", 2, HWSignal)); arFrame.push_back(tFrameMapping("FW", 2, HWSignal)); arFrame.push_back(tFrameMapping("TT", 2, HWSignal)); arFrame.push_back(tFrameMapping("TW", 2, HWSignal)); } void nsSYN::V2COMBoxDevice::DealReceiveData(char* data_can, int length_can_data) { char logbuf[200] = { 0 }; if(length_can_data>=14) { sprintf(logbuf, "%2X,%2X,%2X,%2X,%2X,%2X,%2X,%2X,%2X,%2X,%2X,%2X,%2X,%2X,length_can_data=%d", (BYTE)data_can[0], (BYTE)data_can[1], (BYTE)data_can[2], (BYTE)data_can[3], (BYTE)data_can[4], (BYTE)data_can[5], (BYTE)data_can[6], (BYTE)data_can[7], (BYTE)data_can[8], (BYTE)data_can[9], (BYTE)data_can[10], (BYTE)data_can[11], (BYTE)data_can[12], (BYTE)data_can[13], length_can_data); } if (length_can_data==5)//CO4 { //set baud ok. if (data_can[2]==0) { m_bSetBaudOK = true; } else { m_bSetBaudOK = false; } } if (length_can_data==4)//EC { //echo ok } mLog::Info("recv {$}.",logbuf); int idHigh = (unsigned char)(data_can[2]); int idLow = (unsigned char)(data_can[3]); if (idHigh == 0x80 && idLow == 0xA8)//0x405 { if (data_can[4] == 0 && data_can[5] == 1) { mLog::Info("recv 405 heart beat."); } if (data_can[4] == 1 && data_can[5] == 2) { //平板选择 int nPanelType = (BYTE)data_can[6]; //C arm ML0位,角度 int nML0Angle = (BYTE)data_can[7]; if (m_pMechDev) { m_pMechDev->UpdateMammo_MechAngle(100); } mLog::Info("recv 405 panelType and MLOangle ={$},{$}",nPanelType,nML0Angle); } if (data_can[4] == 1 && data_can[5] == 3) { //曝光模式:1-4(1-3为自动,4手动);6(48KV);8(校准) mLog::Info("recv 405 曝光模式"); } if (data_can[4] == 1 && data_can[5] == 4) { //1:ANRAN平板未准备好 //2:ANRAN平板准备好 int nPanelStatus = (BYTE)data_can[7]; mLog::Info("recv 405 ANRAN panel ready or not"); } } if (idHigh == 0x84 && idLow == 0xA8)//0x425 { if (data_can[4] == 1 && data_can[5] == 1) { //recv 425 heart mLog::Info("recv 425 heart beat."); } if (data_can[4] == 1 && data_can[5] == 3) { //recv 425 heart //压迫模式:普通压迫(01); 预压迫(10); 全压迫(11) 压迫器:自动释放(01); 手动释放(10) int nCompPressureMode = (BYTE)data_can[6]; if (m_pMechDev) { m_pMechDev->UpdateMammo_PressureState(nCompPressureMode); } //自动释放设定 int nCompPressureDEC = (BYTE)data_can[7]; if (m_pMechDev) { m_pMechDev->UpdateMammo_CompPressureDEC(nCompPressureDEC); } if (m_pMechDev) { m_pMechDev->UpdateMammo_Depress(nCompPressureDEC);//vmi doc文档中,DF0 DF1 也表示自动释放 } mLog::Info("recv 425 压迫模式{$},自动释放模式{$}",nCompPressureMode,nCompPressureDEC); } //filter if (data_can[4] == 1 && data_can[5] == 7) { //col滤过类型:1Mo,2Rh int nFilter = (BYTE)data_can[6]; if (m_pCollDev) { m_pCollDev->UpdateCollimatorFilter(nFilter); } if (m_pMechDev) { m_pMechDev->UpdateMammo_FT(nFilter); } mLog::Info("recv 425 fileter {$}",nFilter); } //angle if ((data_can[4] == 0 && data_can[5] == 6) || (data_can[4] == 0x30 && data_can[5] == 6)) { //C arm angle int angle = 0; int nSign = (BYTE)data_can[6]; if (nSign == 2) { angle = (BYTE)data_can[7] * -1; } else { angle = (BYTE)data_can[7]; } if (m_pCollDev) { m_pCollDev->UpdateCollimatorAngle(99); } mLog::Info("recv 425 CARM angle{$}",angle); } //grid mode if (data_can[4] == 1 && data_can[5] == 4) { int nGridMode = (BYTE)data_can[6]; if (nGridMode == 1) //此处更像是mag { //正常模式 } if (nGridMode == 0x10) { //放大模式 } if (m_pMechDev) { m_pMechDev->UpdateMammo_MAG(nGridMode); } int nGridStatus = (BYTE)data_can[7]; if (nGridStatus == 1) { //IN } if (nGridStatus == 2) { //OUT } if (nGridStatus == 3) { //RUNNING } if (m_pMechDev) { m_pMechDev->UpdateGrid(nGridStatus); } mLog::Info("recv 425 grid mode {$},gird status {$}",nGridMode,nGridStatus); } if (data_can[4] == 1 && data_can[5] == 5) { int nThickness = (BYTE)data_can[6]; int nPressValue = (BYTE)data_can[7]; //int nCompPressureMode = data_can[6]; if (m_pMechDev) { m_pMechDev->UpdateMammo_PressureState(nThickness);//note :thickness } if (m_pMechDev) { m_pMechDev->UpdateMammo_PressureValue(nPressValue); } mLog::Info("recv 425 thickness {$}, pressvalue {$}", nThickness, nPressValue); } if (data_can[4] == 1 && data_can[5] == 6) { int colHeight = (BYTE)data_can[6] * 256 + (BYTE)data_can[7]; int colWidth = (BYTE)data_can[8] * 256 + (BYTE)data_can[9]; if (m_pCollDev) { m_pCollDev->UpdateCollimatorXSize(colWidth); m_pCollDev->UpdateCollimatorYSize(colHeight); } mLog::Info("recv 425 : coll: x={$},y={$}",colWidth,colHeight); } if (data_can[4] == 1 && data_can[5] == 0x19) { //压迫板类型:1.大压迫板。2.小压迫板。3.放大摄影压迫板 int nPlateID = (BYTE)data_can[6]; std::string strPlateID = ""; if (m_pMechDev) { if (1 == nPlateID) { strPlateID = "1"; } else if (2 == nPlateID) { strPlateID = "2"; } else if (3 == nPlateID) { strPlateID = "3"; } m_pMechDev->UpdateMammo_CompressPaddle(strPlateID); } mLog::Info("recv 425 : 压迫板类型 {$}--[1.大压迫板。2.小压迫板。3.放大摄影压迫板]",nPlateID); } } } //不用了 int nsSYN::V2COMBoxDevice::DealReceiveData(string sCmdID, const char* pData, int Datalen) { if (strtol(("0x" + sCmdID).c_str(), NULL, 16) == 0x626) { string strCmd = pData; if (strtol(("0x" + strCmd.substr(0, 2)).c_str(), NULL, 16) == 0x14) { /*bool bUpdateSize = false, bUpdateFilter = false; if (strtol(("0x" + strCmd.substr(3, 1)).c_str(), NULL, 16) & 0x01) { m_nXSize = strtol(("0x" + strCmd.substr(4, 2)).c_str(), NULL, 16) + strtol(("0x" + strCmd.substr(6, 2)).c_str(), NULL, 16) * 256; bUpdateSize = true; m_nXSize = m_nXSize / 100; printf("m_nXSize = {$}", m_nXSize); } if (strtol(("0x" + strCmd.substr(3, 1)).c_str(), NULL, 16) & 0x02) { m_nYSize = strtol(("0x" + strCmd.substr(8, 2)).c_str(), NULL, 16) + strtol(("0x" + strCmd.substr(10, 2)).c_str(), NULL, 16) * 256; m_nYSize = m_nYSize / 100; bUpdateSize = true; printf("m_nYSize = {$}", m_nYSize); } if (strtol(("0x" + strCmd.substr(2, 1)).c_str(), NULL, 16) & 0x04) { m_nFilter = strtol(("0x" + strCmd.substr(12, 2)).c_str(), NULL, 16) + strtol(("0x" + strCmd.substr(14, 2)).c_str(), NULL, 16) * 256; bUpdateFilter = true; printf("m_nFilter = {$}", m_nFilter); } if (bUpdateSize) { CollimatorLogic::SetCollimatorSize(m_nXSize, m_nYSize); } if (bUpdateFilter) { CollimatorLogic::SetCollimatorFilter(m_nFilter); }*/ } } return 1; } int nsSYN::V2COMBoxDevice::DealtheSignal(const char* channel, int state) { string strchannel = channel; m_DYNMap.m_MapChannelState[strchannel] = state; if (ResDYNConfig.GetFirstOf(m_strSYNMode.c_str()) < 0) { mLog::Error("Didn't find SynMode : {$}", m_strSYNMode.c_str()); return -1; } if (ResDYNConfig[m_strSYNMode.c_str()].GetFirstOf(m_SynBoxUnit.m_ExpMode->JSGet().c_str()) < 0) { mLog::Error("Didn't find CurrentExamMode : {$}", m_SynBoxUnit.m_ExpMode->JSGet().c_str()); return -1; } int count = ResDYNConfig[m_strSYNMode.c_str()][m_SynBoxUnit.m_ExpMode->JSGet().c_str()]["INPUT"].size(); string strSignalName = ""; int nState = -1; mLog::Info("CurrentExamMode = {$}, strchannel = {$}", m_SynBoxUnit.m_ExpMode->JSGet().c_str(), strchannel.c_str()); for (int i = 0; i < count; i++) { string strKey = ResDYNConfig[m_strSYNMode.c_str()][m_SynBoxUnit.m_ExpMode->JSGet().c_str()]["INPUT"].GetKey(i); string confchannel = ResDYNConfig[m_strSYNMode.c_str()][m_SynBoxUnit.m_ExpMode->JSGet().c_str()]["INPUT"][strKey.c_str()]["CHANNEL"]; mLog::Info("strKey = {$}, confchannel = {$}", strKey.c_str(), confchannel.c_str()); if (confchannel == strchannel) { strSignalName = strKey; nState = state; if (strSignalName == "GENPREP") //add by wxx:解决OT1信号在 配置 及 工作流中重复发送的问题 { if (state == 1) //ER1 { m_nGenSynStateSignal = AttrKey::GENERATOR_RAD_PREPARE; } else { m_nGenSynStateSignal = AttrKey::GENERATOR_RAD_OFF; SetGenAECSignal(3); } } else if (strSignalName == "GENREADY") { if (state == 1) //TB1 { m_nGenSynStateSignal = AttrKey::GENERATOR_RAD_READY; } else { if (m_nGenSynStateSignal != AttrKey::GENERATOR_RAD_OFF) { m_nGenSynStateSignal = AttrKey::GENERATOR_RAD_PREPARE; } } } else if (strSignalName == "XWINDOWSTATUS") { if (state == 1) { if (m_nGenSynStateSignal == AttrKey::GENERATOR_RAD_READY) //发送OT1收到PT1 m_bINEEnable = true; } else //PT0 { if (m_nGenSynStateSignal != AttrKey::GENERATOR_RAD_OFF) { m_nGenSynStateSignal = AttrKey::GENERATOR_RAD_XRAYOFF; } } } mLog::Info("Signal Name = {$}, state = {$},GenSynState = {$}", strSignalName.c_str(), nState, m_nGenSynStateSignal); break; } } if (strSignalName != "" && nState >= 0) { NotifySignal(strSignalName.c_str(), nState); string strSetEnableSignal = (string)ResDYNConfig[m_strSYNMode.c_str()][m_SynBoxUnit.m_ExpMode->JSGet().c_str()]["INPUT"][strSignalName.c_str()]["SETENABLE"]; string strSetDisableSignal = (string)ResDYNConfig[m_strSYNMode.c_str()][m_SynBoxUnit.m_ExpMode->JSGet().c_str()]["INPUT"][strSignalName.c_str()]["SETDISABLE"]; if (nState == 1 && strSetEnableSignal != "") { if (strSetEnableSignal == "GENEXPREQUEST") //RT1 { m_nGenSynStateSignal = AttrKey::GENERATOR_RAD_XRAYON; } string strRelaySignal = ResDYNConfig[m_strSYNMode.c_str()][m_SynBoxUnit.m_ExpMode->JSGet().c_str()]["INPUT"][strSignalName.c_str()]["RELAY"]; if (strRelaySignal != "") { //strRelaySignal = strRelaySignal + "," + strSetEnableSignal; mLog::Info("Set Enable Relay_Signal = {$},GenSynState = {$}", strSetEnableSignal.c_str(), m_nGenSynStateSignal); SetSignal(strRelaySignal.c_str(), nState); } else { mLog::Info("Set Enable Signal = {$},GenSynState = {$}", strSetEnableSignal.c_str(), m_nGenSynStateSignal); SetSignal(strSetEnableSignal.c_str(), nState); } } else if (state == 0 && strSetDisableSignal != "") { if (strSetEnableSignal == "GENEXPREQUEST") //RT0 { if (m_nGenSynStateSignal != AttrKey::GENERATOR_RAD_OFF) { m_nGenSynStateSignal = AttrKey::GENERATOR_RAD_READY; } } string strRelaySignal = ResDYNConfig[m_strSYNMode.c_str()][m_SynBoxUnit.m_ExpMode->JSGet().c_str()]["INPUT"][strSignalName.c_str()]["RELAY"]; if (strRelaySignal != "") { //strRelaySignal = strRelaySignal + "," + strSetDisableSignal; mLog::Info("Set Disable Relay_Signal = {$},GenSynState = {$}", strSetDisableSignal.c_str(), m_nGenSynStateSignal); SetSignal(strRelaySignal.c_str(), state); } else { mLog::Info("Set Disable Signal = {$},GenSynState = {$}", strSetDisableSignal.c_str(), m_nGenSynStateSignal); SetSignal(strSetDisableSignal.c_str(), state); } if (strSignalName == "GENEXPREQUEST") //RT0,add by wxx:解决OT1信号在 配置 及 工作流中重复发送的问题 { m_bINEEnable = false; } } } return 2; } int nsSYN::V2COMBoxDevice::NotifySignal(const char* name, int state) { string strname = name; mLog::Info("Send Notify : Name = {$}, State = {$}", name, state); if (strname == "HANDSWITCHPREP") { if (state) { m_SynBoxUnit.m_HandSwitchState->Update(1); FireNotify(m_SynBoxUnit.m_HandSwitchState->GetKey(), m_SynBoxUnit.m_HandSwitchState->JSGet()); } else { m_SynBoxUnit.m_HandSwitchState->Update(0); FireNotify(m_SynBoxUnit.m_HandSwitchState->GetKey(), m_SynBoxUnit.m_HandSwitchState->JSGet()); } } else if (strname == "HANDSWITCHREADY") { if (state) { m_SynBoxUnit.m_HandSwitchState->Update(2); FireNotify(m_SynBoxUnit.m_HandSwitchState->GetKey(), m_SynBoxUnit.m_HandSwitchState->JSGet()); } else { m_SynBoxUnit.m_HandSwitchState->Update(0); FireNotify(m_SynBoxUnit.m_HandSwitchState->GetKey(), m_SynBoxUnit.m_HandSwitchState->JSGet()); } } #if 0//change by wxx:for 迈科龙乳腺机项目 探测器状态应由发生器自行更新 else if (strname == "XWINDOWSTATUS") { if (state) { m_SynBoxUnit.m_DetectorWindowState->Update(AttrKey::XWINDOW_ON); FireNotify(m_SynBoxUnit.m_DetectorWindowState->GetKey(), m_SynBoxUnit.m_DetectorWindowState->JSGet()); } else { m_SynBoxUnit.m_DetectorWindowState->Update(AttrKey::XWINDOW_OFF); FireNotify(m_SynBoxUnit.m_DetectorWindowState->GetKey(), m_SynBoxUnit.m_DetectorWindowState->JSGet()); } } #endif //change by wxx:for 迈科龙乳腺机项目 发生器状态应由发生器自行更新 #if 0 else if (strname == "GENPREP") { if (state) { m_SynBoxUnit.m_GenSynState->Update(AttrKey::GENERATOR_RAD_PREPARE); FireNotify(m_SynBoxUnit.m_GenSynState->GetKey(), m_SynBoxUnit.m_GenSynState->JSGet()); } else { m_SynBoxUnit.m_GenSynState->Update(AttrKey::GENERATOR_RAD_OFF); FireNotify(m_SynBoxUnit.m_GenExpectSynState->GetKey(), m_SynBoxUnit.m_GenExpectSynState->JSGet()); } } else if (strname == "GENREADY") { if (state) { m_SynBoxUnit.m_GenSynState->Update(AttrKey::GENERATOR_RAD_READY); FireNotify(m_SynBoxUnit.m_GenSynState->GetKey(), m_SynBoxUnit.m_GenSynState->JSGet()); } else { //m_pSynGen->ExpectToSyncStatus(GENERATOR_RAD_EXPECT_OFF); m_SynBoxUnit.m_GenSynState->Update(AttrKey::GENERATOR_RAD_OFF); FireNotify(m_SynBoxUnit.m_GenSynState->GetKey(), m_SynBoxUnit.m_GenSynState->JSGet()); } } else if (strname == "GENEXPSTATUS") { if (state) { m_SynBoxUnit.m_GenSynState->Update(AttrKey::GENERATOR_RAD_XRAYON); FireNotify(m_SynBoxUnit.m_GenSynState->GetKey(), m_SynBoxUnit.m_GenSynState->JSGet()); m_nCurrentExpTimes++; } else { m_SynBoxUnit.m_GenSynState->Update(AttrKey::GENERATOR_RAD_XRAYOFF); FireNotify(m_SynBoxUnit.m_GenSynState->GetKey(), m_SynBoxUnit.m_GenSynState->JSGet()); } } #endif return 2; } int nsSYN::V2COMBoxDevice::SetSignal(const char* name, int state) { string strtemp = name; string strName = strtemp; std::size_t oldPos = 0; std::size_t findPos = strtemp.find(","); while (findPos != string::npos) //change by wxx:原截取字符串操作有问题 { strName = strtemp.substr(oldPos, findPos - oldPos); if (ResDYNConfig.GetFirstOf(m_strSYNMode.c_str()) < 0) { mLog::Error("Didn't find SynMode : {$}", m_strSYNMode.c_str()); return -1; } if (ResDYNConfig[m_strSYNMode.c_str()].GetFirstOf(m_SynBoxUnit.m_ExpMode->JSGet().c_str()) < 0) { mLog::Error("Set Signal {$}, state {$} ", name, state); mLog::Error("Didn't find m_SynBoxUnit.m_ExpMode->JSGet() : {$}", m_SynBoxUnit.m_ExpMode->JSGet().c_str()); return -1; } string strChannel = ResDYNConfig[m_strSYNMode.c_str()][m_SynBoxUnit.m_ExpMode->JSGet().c_str()]["OUTPUT"][strName.c_str()]["CHANNEL"]; if (strChannel != "") { if (strName == "GENEXPREQUEST") { if (m_bINEEnable) { //m_nCurrentExpTimes++; if (m_nExpTimes > 0 && m_nCurrentExpTimes > m_nExpTimes) { mLog::Warn("m_nExpTimes has been enough in this sequence! m_nExpTimes={$},m_nCurrentExpTimes={$}", m_nExpTimes, m_nCurrentExpTimes); return true; } } else { mLog::Warn("Generator didn't ready or detector didn't startAcq, So can't send INE to generator!"); return true; } } mLog::Info("Set Signal {$}, state {$} ", strName, state); SendBySCF(strChannel.c_str(), state); //Sleep(10); } if (findPos != strtemp.length()) { oldPos = findPos + 1; findPos = strtemp.find(",", oldPos); if (findPos == string::npos) { strName = strtemp.substr(oldPos, strtemp.length() - oldPos); break; } } else { break; } } //strName = strtemp; if (ResDYNConfig.GetFirstOf(m_strSYNMode.c_str()) < 0) { mLog::Error("Didn't find SynMode : {$}", m_strSYNMode.c_str()); return -1; } if (ResDYNConfig[m_strSYNMode.c_str()].GetFirstOf(m_SynBoxUnit.m_ExpMode->JSGet().c_str()) < 0) { mLog::Error("Set Signal {$}, state {$} ", name, state); mLog::Error("Didn't find CurrentExamMode : {$}", m_SynBoxUnit.m_ExpMode->JSGet().c_str()); return -1; } string strChannel = ResDYNConfig[m_strSYNMode.c_str()][m_SynBoxUnit.m_ExpMode->JSGet().c_str()]["OUTPUT"][strName.c_str()]["CHANNEL"]; if (strChannel != "") { if (strName == "GENEXPREQUEST") { if (m_bINEEnable) { //m_nCurrentExpTimes++; if (m_nExpTimes > 0 && m_nCurrentExpTimes > m_nExpTimes) { mLog::Warn("m_nExpTimes has been enough in this sequence! m_nExpTimes={$},m_nCurrentExpTimes={$}", m_nExpTimes, m_nCurrentExpTimes); return true; } } else { mLog::Warn("Generator didn't ready or detector didn't startAcq, So can't send INE to generator!"); return true; } } mLog::Info("Set Signal {$}, state {$} ", name, state); SendBySCF(strChannel.c_str(), state); return 1; } return -1; } void nsSYN::V2COMBoxDevice::ClearSignal() { if (ResDYNConfig.GetFirstOf(m_strSYNMode.c_str()) < 0) { mLog::Error("Didn't find SynMode : {$}", m_strSYNMode.c_str()); return; } if (ResDYNConfig[m_strSYNMode.c_str()].GetFirstOf(m_SynBoxUnit.m_ExpMode->JSGet().c_str()) < 0) { mLog::Error("Didn't find CurrentExamMode : {$}", m_SynBoxUnit.m_ExpMode->JSGet().c_str()); return; } int nsize = ResDYNConfig[m_strSYNMode.c_str()][m_SynBoxUnit.m_ExpMode->JSGet().c_str()]["OUTPUT"].size(); for (int i = 0; i < nsize; i++) { string strChannel = ResDYNConfig[m_strSYNMode.c_str()][m_SynBoxUnit.m_ExpMode->JSGet().c_str()]["OUTPUT"][i]["CHANNEL"]; string name = ResDYNConfig[m_strSYNMode.c_str()][m_SynBoxUnit.m_ExpMode->JSGet().c_str()]["OUTPUT"].GetKey(i); mLog::Info("Clear Name :{$},CurrentExamMode ={$}", name.c_str(), m_SynBoxUnit.m_ExpMode->JSGet().c_str()); if (strChannel != "" && "FRAMERATE" != name) { mLog::Info("Clear Signal {$} ", strChannel); SendBySCF(strChannel.c_str(), false); Sleep(10); } } return; } int nsSYN::V2COMBoxDevice::SetPWM(float fpps) { return -1; } nDev::RET_STATUS nsSYN::V2COMBoxDevice::SendBySCF(const char* chChannelID, bool bStatus) { int nTimeout = 100; char cCmd[MAX_COMMAND_LEN] = { 0 }; cCmd[0] = chChannelID[0]; cCmd[1] = chChannelID[1]; if (bStatus) cCmd[2] = '1'; else cCmd[2] = '0'; int nSize = 3; FormatCmd(cCmd, nSize); string strLog; CmdtoString(cCmd, nSize, strLog); mLog::Info("[Send:{$}]", cCmd); if (!m_SCF) { mLog::Error("SCF is NULL"); return RET_STATUS::RET_FAILED; } mLog::Info("==OUT==: {$} ", cCmd); int ret = 0; m_SCF.Lock(msTimeOut_Lock) .SendPacket(cCmd, nSize, nTimeout, ret); Sleep(nTimeout); return RET_STATUS::RET_SUCCEED; } void nsSYN::V2COMBoxDevice::SendHeartBeat() { int nTimeout = 100; int ret = 0; mLog::Info("==OUT==: heartbeat{$} ", cCmd_heartbeat); m_SCF.Lock(msTimeOut_Lock) .SendPacket(cCmd_heartbeat, 4, nTimeout, ret); Sleep(nTimeout); } void nsSYN::V2COMBoxDevice::DealtheHB(const char* channel, int state) { m_iHeartBeats = 0; }