// CCOS.Dev.GEN.SINO.cpp : 定义 DLL 应用程序的导出函数。 // #include "stdafx.h" #include #include using namespace std::placeholders; //#include "logger.temp.h" #include "CCOS.Dev.Generator.SINO.h" #include "Helper.JSON.hpp" using namespace CCOS::Dev::Detail::Generator; namespace nsGEN = CCOS::Dev::Detail::Generator; //关闭无关警告 #pragma warning (disable:4244) // warning C4244: “初始化”: 从“double”转换到“float”,可能丢失数据 #pragma warning (disable:4305) // warning C4305: “参数”: 从“double”到“float”截断 #pragma warning (disable:4267) // warning C4267 : “初始化”: 从“size_t”转换到“int”,可能丢失数据 #pragma warning (disable:4805) // warning C4805: “!=”: 在操作中将类型“bool”与类型“int”混合不安全 //设置对应通信接口库 #ifdef _WIN64 #ifdef _DEBUG static const auto COM_SCFDllName = "Ccos.Dev.SerialSCFX64D.dll"; #else static const auto COM_SCFDllName = "Ccos.Dev.SerialSCFX64.dll"; #endif #endif #ifdef _WIN64 #ifdef _DEBUG static const auto TCP_SCFDllName = "Ccos.Dev.TcpipSCFX64D.dll"; #else static const auto TCP_SCFDllName = "Ccos.Dev.TcpipSCFX64.dll"; #endif #endif /* #数据命令格式 字节编号 数据 数据含义 备注 1 STX 帧头 WS(程序)的帧头为:0xA5,MU(设备)的帧头为:0xCF 2 TYPE 数据类型 0x00: 主动发出的数据,0x01: 反馈数据,表示收到命令并反馈数据 3 ID 命令ID(CMD) 4 LEN 数据总长度(LEN) 5~n DATA… 参数数据 n+1 CRC 异或取反校验(CRC) n+2 ETX 帧尾 WS的帧尾为:0x5A,MU的帧尾为:0xFC #应答命令格式 字节编号 数据 数据含义 备注 1 STX 帧头 WS的帧头为:0xA5,MU的帧头为:0xCF 2 TYPE 数据类型 0x02: 应答命令 3 ID 命令ID(CMD) 4 LEN 数据总长度(LEN) 5 Stauts 状态 0x00: 数据成功接收并设置, 0x01: 数据不正确,未成功设置 6 CRC 异或取反校验(CRC) 7 ETX 帧尾 WS的帧尾为:0x5A, MU的帧尾为:0xFC */ //设置相关常量 static const int msTimeOut_Lock = 500; Log4CPP::Logger* mLog::gLogger = nullptr; //指令操作关联结构 struct tFrameMapping { static const int MaxLen = 5; //前缀不能超超过5个字符 using cbFun = std::function ; char strHead[MaxLen]; int NbOfCharOfHead; cbFun fun; tFrameMapping(char* str, int len, cbFun f) { assert(len < MaxLen); //len最大只能是4 for (int i = 0; i < len; i++) //给strHead赋值 strHead[i] = str[i]; NbOfCharOfHead = len + 1; fun = f; } tFrameMapping(char str, cbFun f) { strHead[0] = str; NbOfCharOfHead = 1; fun = f; } }; //响应操作对照表 static std::list arFrame; //生成命令校验和:异或取反校验为除帧尾外前面所有数据的异或取反校验 char ComputeCheckSum(char* cmdData, int size) { UINT8 Checksum = 0x00; for (int i = 0; i < size-2; i++) { Checksum ^= cmdData[i]; //异或 } Checksum = (~Checksum) & 0xff;; //取非 return Checksum; } //查找响应操作对照表执行对应操作 static bool DecodeFrame(const char* strFrame, int length) { auto pr = [strFrame, length](const tFrameMapping& Item) { //mLog::Debug("DecodeFrame[{$}][{$}]", (UINT8)strFrame[2], (UINT8)Item.strHead[0]); for (int i = 0; i < Item.NbOfCharOfHead; i++) { if ((UINT8)strFrame[i+2] != (UINT8)Item.strHead[i]) { return false; } } return true; }; auto found = std::find_if(arFrame.begin(), arFrame.end(), pr);//此处pr用来在arFrame中找到对于的包头 if (found == arFrame.end()) { return false; } const auto& Item = *found; auto pc = strFrame; char data[SINO_Com_NormalLen] = { 0 }; //memcpy(data, strFrame + Item.NbOfCharOfHead + 3, length - Item.NbOfCharOfHead - 3); memcpy(data, strFrame, length); data[3] = length; Item.fun(data, length - Item.NbOfCharOfHead);//第二个参数 不重要 if ((UINT8)strFrame[1] != (UINT8)SINO_TYPE_CONFIRM) { arFrame.begin()->fun(data, length - Item.NbOfCharOfHead);//统一响应操作 } return true; } //----------------------------------------------------------------------------- // SINODevice //----------------------------------------------------------------------------- //暂无取固定值的使用要求 float g_MA_List[] = { 8, 10, 12.5, 16, 20, 25, 32, 40, 50, 64, 80, 100, 125, 160, 200, 250, 320, 400, 500, 640 }; float g_MS_List[] = { 1, 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 25, 32, 40, 50, 64, 80, 100, 125, 160, 200, 250, 320, 400, 500, 640, 800, 1000, 1250, 1600, 2000, 2500, 3200, 4000, 5000, 6400, 8000, 10000 }; float g_MAS_List[] = { 1, 1.25, 1.6, 2, 2.5, 3.2, 4, 5, 6.4, 8, 10, 12.5, 16, 20, 25, 32, 40, 50, 64, 80, 100, 125, 160, 200, 250, 320, 400, 500, 640, 800, 1000 }; int g_AECFIELD_List[] = { 1, 10, 100, 11, 101, 111 }; int nsGEN::SINODevice::m_iLoopTime = 1000; nsGEN::SINODevice::SINODevice(std::shared_ptr center, nsSCF::SCF SCF, string configfile) : super(center, SCF) { assert(EventCenter); //其余属性初始化 ResDataObject temp; temp.loadFile(configfile.c_str()); m_GenConfig = temp["CONFIGURATION"]; TransJsonText(m_GenConfig); m_pHardwareStatusThread = NULL; m_bExpEnable = false; m_iHeartBeats = 0; m_bConnectFlag = true; m_pMechDev = nullptr; m_pCollDev = nullptr; string version; if(GetVersion(version,m_GenConfig)) mLog::Info("\n===============log begin : version:{$} ===================\n", version.c_str()); else mLog::Info("\n===============log begin : version:0.0.0.0 ===================\n"); //设置发生器属性集合各个值的范围及精度 m_DoseUnit.m_KV.reset(new KVMould(10.0, 10.0, 35.0, 1.0)); m_DoseUnit.m_MA.reset(new MAMould(1.0, 0.0, 200.0, 0.1)); m_DoseUnit.m_MS.reset(new MSMould(20.0, 20.0, 12000.0, 0.01)); m_DoseUnit.m_MAS.reset(new MASMould(10.0, 10.0, 600.0, 1.0)); m_DoseUnit.m_Techmode.reset(new TECHMODEMould(AttrKey::TECHMODE_TYPE::TECHMODE_NOAEC_2P, AttrKey::TECHMODE_NOAEC_3P, AttrKey::TECHMODE_AEC_2P, 1)); m_DoseUnit.m_WS.reset(new WORKSTATIONMould(1, 0, 5, 1)); m_DoseUnit.m_Focus.reset(new FOCUSMould(AttrKey::FOCUS_TYPE::FOCUS_LARGE, AttrKey::FOCUS_SMALL, AttrKey::FOCUS_LARGE, 1)); m_DoseUnit.m_AECField.reset(new AECFIELDMould(0, 0, 111, 1)); m_DoseUnit.m_AECFilm.reset(new AECFILMMould(0, 0, 2, 1)); m_DoseUnit.m_AECDensity.reset(new AECDENSITYMould(0, -4, 4, 1)); m_DoseUnit.m_HE.reset(new TUBEHEATMould(0, 0, 100, 1)); m_DoseUnit.m_GenSynState.reset(new GENSYNSTATEMould(AttrKey::GENERATOR_RAD_OFF, AttrKey::GENERATOR_SYNC_ERR, AttrKey::GENERATOR_SYNC_MAX, 1)); m_DoseUnit.m_GenState.reset(new GENSTATEMould(0, SINO_STATUS_PowerOn, SINO_STATUS_Error, 1)); m_DoseUnit.m_GenTotalExpNumber.reset(new TOTALEXPNUMMould(0, 0, 9999, 1)); m_DoseUnit.m_GenTotalAcqTimes.reset(new TOTALACQTIMESMould(0, 0, 9999, 1)); m_DoseUnit.m_GenTubeCoolWaitTimes.reset(new TUBECOOLTIMEMould(0, 0, 9999, 1)); m_DoseUnit.m_GenTubeOverLoadNumber.reset(new TUBEOVERLOADNUMMould(0, 0, 9999, 1)); m_DoseUnit.m_GenCurrentExpNumber.reset(new CUREXPNUMMould(0, 0, 9999, 1)); m_DoseUnit.m_ExpMode.reset(new EXPMODEMould(AttrKey::EXPMODE_TYPE::Single)); m_DoseUnit.m_FrameRate.reset(new FRAMERATEMould(0, 0, 16, 1)); m_DoseUnit.m_FLMode.reset(new FLUModeMould(AttrKey::GENERATOR_FLUMode::GENERATOR_FLMODE_NOTFLU)); m_DoseUnit.m_BatteryChargeState.reset(new BATTERYCHARGSTATEMould(0, 0, 1, 1)); //m_DoseUnit.m_EXAMMode.reset(new EXAMMODEMould(EXAMMODE_TYPE::MANUAL)); //实际曝光参数值 m_DoseUnit.m_PostKV.reset(new POSTKVMould(0.0, 0.0, 40.0, 1.0)); m_DoseUnit.m_PostMA.reset(new POSTMAMould(0.0, 0.0, 200.0, 0.1)); m_DoseUnit.m_PostMS.reset(new POSTMSMould(0.0, 20.0, 12000.0, 0.01)); m_DoseUnit.m_PostMAS.reset(new POSTMASMould(0.0, 0.0, 600.0, 0.01)); //发生器告警及错误消息 m_MSGUnit.reset(new nsDetail::MSGUnit(center, nsGEN::GeneratorUnitType)); //配置响应操作对照表 供发生器回传的数据触发相应的操作 OnCallBack(); //将发生器可以对外提供的指令注册集进行补充 Register(); //重置发生器 Reset(); Sleep(500); //以下进行默认设置,需要注意默认值是否正确 //刷新数据 RefreshData(); //启动硬件转状态查询进程 StartHardwareStatusThread(); } nsGEN::SINODevice::~SINODevice() { mLog::Info("\n===============log end ===================\n"); //ReleaseLogger(); if (m_pHardwareStatusThread != NULL) { DWORD dwExitCode = 0; GetExitCodeThread(m_pHardwareStatusThread, &dwExitCode); if (STILL_ACTIVE != dwExitCode) { TerminateThread(m_pHardwareStatusThread, 0); } m_pHardwareStatusThread = NULL; } //m_pMechDev.reset(); } std::string nsGEN::SINODevice::GetGUID() const { mLog::Info("===============GetGUID : {$} ===================\n", GeneratorUnitType); return GeneratorUnitType; } void nsGEN::SINODevice::Register() { auto Disp = &Dispatch; superGen::Register(Disp); superGen::RegisterRAD(Disp); superGen::RegisterAEC(Disp); superGen::RegisterExpEnable(Disp); superGen::RegisterGeneratortoSyncStatus(Disp); Disp->Get.Push(m_MSGUnit->GetKey().c_str(), [this](std::string& out) { out = m_MSGUnit->JSGet(); return RET_STATUS::RET_SUCCEED; }); auto fun_Clear_DAP = [this](auto a, auto&) { return Clear_DAP(); }; Disp->Action.Push("Clear_DAP", fun_Clear_DAP); auto fun_GetValue_DAP = [this](auto a, auto& b) { float value = 0; RET_STATUS ret = GetValue_DAP(value); b = ToJSON(value); return ret; }; Disp->Action.Push("GetValue_DAP", fun_GetValue_DAP); #if 0 auto fun_StartMove = [this](auto a,auto& b) { return StartMove(); }; Disp->Action.Push("StartMove", fun_StartMove); auto fun_EndMove = [this](auto a, auto& b) { return EndMove(); }; Disp->Action.Push("EndMove", fun_EndMove); #endif // 0 } RET_STATUS nsGEN::SINODevice::SetAPRMaMmo(int nKV, float fMAS, int nFO, int nET) { mLog::Debug("SetAPRMaMmo:nKV[{$}],MAS[{$}],FO[{$}],ET[{$}] ", nKV, fMAS, nFO, nET); SINOCommand strCmd(SINO_ExpoParam, SINO_TYPE_SEND,11); strCmd.SetAt(5, nKV); int nmAs = (int)fMAS; char nmAs_Low = nmAs & (0xFF); strCmd.SetAt(6, nmAs_Low); char nmAs_High = nmAs >> 8; strCmd.SetAt(7, nmAs_High); if(1) strCmd.SetAt(8, EM_Focus_Large); else strCmd.SetAt(8, EM_Focus_Small); if (nET == AttrKey::TECHMODE_TYPE::TECHMODE_AEC_1P || nET == AttrKey::TECHMODE_TYPE::TECHMODE_NOAEC_3P || nET == AttrKey::TECHMODE_TYPE::TECHMODE_AEC_3P) { mLog::Error("SetAPRMaMmo:can not set TECHMODE[{$}] \n", nET); } else { if (nET == AttrKey::TECHMODE_TYPE::TECHMODE_NOAEC_2P) { strCmd.SetAt(9, EM_EXPMode_MAN); } if (nET == AttrKey::TECHMODE_TYPE::TECHMODE_AEC_2P) { strCmd.SetAt(9, EM_EXPMode_AEC); } } return HWSend(strCmd); } RET_STATUS nsGEN::SINODevice::IncKV() { if (!m_DoseUnit.m_KV->CanInc()) return RET_STATUS::RET_SUCCEED; float oldKV= m_DoseUnit.m_KV->Get(); oldKV++; return SetAPRMaMmo(oldKV, m_DoseUnit.m_MAS->Get(), m_DoseUnit.m_Focus->Get(), m_DoseUnit.m_Techmode->Get()); } RET_STATUS nsGEN::SINODevice::DecKV() { if (!m_DoseUnit.m_KV->CanDec()) return RET_STATUS::RET_SUCCEED; float oldKV = m_DoseUnit.m_KV->Get(); oldKV--; return SetAPRMaMmo(oldKV, m_DoseUnit.m_MAS->Get(), m_DoseUnit.m_Focus->Get(), m_DoseUnit.m_Techmode->Get()); } RET_STATUS nsGEN::SINODevice::SetKV(float value) { if (!m_DoseUnit.m_KV->Verify(value)) return RET_STATUS::RET_SUCCEED; return SetAPRMaMmo(value, m_DoseUnit.m_MAS->Get(), m_DoseUnit.m_Focus->Get(), m_DoseUnit.m_Techmode->Get()); } RET_STATUS nsGEN::SINODevice::IncMAS() { if (!m_DoseUnit.m_MAS->CanInc()) return RET_STATUS::RET_SUCCEED; float oldMAS = m_DoseUnit.m_MAS->Get(); oldMAS++; return SetAPRMaMmo(m_DoseUnit.m_KV->Get(), oldMAS, m_DoseUnit.m_Focus->Get(), m_DoseUnit.m_Techmode->Get()); } RET_STATUS nsGEN::SINODevice::DecMAS() { if (!m_DoseUnit.m_MAS->CanDec()) return RET_STATUS::RET_SUCCEED; float oldMAS = m_DoseUnit.m_MAS->Get(); oldMAS--; return SetAPRMaMmo(m_DoseUnit.m_KV->Get(), oldMAS, m_DoseUnit.m_Focus->Get(), m_DoseUnit.m_Techmode->Get()); } RET_STATUS nsGEN::SINODevice::SetMAS(float value) { if (!m_DoseUnit.m_MAS->Verify(value)) return RET_STATUS::RET_SUCCEED; return SetAPRMaMmo(m_DoseUnit.m_KV->Get(), value, m_DoseUnit.m_Focus->Get(), m_DoseUnit.m_Techmode->Get()); } RET_STATUS nsGEN::SINODevice::SetTechmode(int value) { if (!m_DoseUnit.m_Techmode->Verify(value)) return RET_STATUS::RET_SUCCEED; mLog::Info("SetTechmode [{$}] \n", value); if (value == AttrKey::TECHMODE_TYPE::TECHMODE_NOAEC_2P || value == AttrKey::TECHMODE_TYPE::TECHMODE_AEC_2P) { return SetAPRMaMmo(m_DoseUnit.m_KV->Get(), m_DoseUnit.m_MAS->Get(), m_DoseUnit.m_Focus->Get(), value); } else { mLog::Error("SetTechmode:unknown mode[{$}] \n", value); } return RET_STATUS::RET_SUCCEED; } RET_STATUS nsGEN::SINODevice::SetEXAMMode(std::string value) { //上层给我设置exam mode。(manual semi atuo)对应(NoAEC2Point AEC2Point AEC2Point) mLog::Info("Enter setexammode func value = {$}\n", value); if (value == AttrKey::EXAMMODE_TYPE::MANUAL) { if (m_DoseUnit.m_Techmode->Get() != AttrKey::TECHMODE_TYPE::TECHMODE_NOAEC_2P) { SetTechmode(1); } } else if (value == AttrKey::EXAMMODE_TYPE::SEMIAUTO) { if (m_DoseUnit.m_Techmode->Get() != AttrKey::TECHMODE_TYPE::TECHMODE_AEC_2P) { SetTechmode(3); } } else if (value == AttrKey::EXAMMODE_TYPE::AUTOMATIC) { if (m_DoseUnit.m_Techmode->Get() != AttrKey::TECHMODE_TYPE::TECHMODE_AEC_2P) { SetTechmode(3); } } return RET_STATUS::RET_SUCCEED; } RET_STATUS nsGEN::SINODevice::SetFocus(int value) { if (!m_DoseUnit.m_Focus->Verify(value)) return RET_STATUS::RET_SUCCEED; return SetAPRMaMmo(m_DoseUnit.m_KV->Get(), m_DoseUnit.m_MAS->Get(), value, m_DoseUnit.m_Techmode->Get()); } RET_STATUS nsGEN::SINODevice::SetAECDensity(int value) //发生器无此设置 { if (!m_DoseUnit.m_AECDensity->Verify(value)) return RET_STATUS::RET_SUCCEED; #if 0 if (m_DoseUnit.m_Techmode->Get() == AttrKey::TECHMODE_TYPE::TECHMODE_NOAEC_3P || m_DoseUnit.m_Techmode->Get() == AttrKey::TECHMODE_TYPE::TECHMODE_NOAEC_2P) { mLog::Info("Techmode is not AEC, Cannot set Density \n"); return RET_STATUS::RET_FAILED; } #endif // 0 m_DoseUnit.m_AECDensity->Update(value); return RET_STATUS::RET_SUCCEED; } RET_STATUS nsGEN::SINODevice::SetAECField(int value) //发生器无此设置 { if (!m_DoseUnit.m_AECField->Verify(value)) return RET_STATUS::RET_SUCCEED; #if 0 if (m_DoseUnit.m_Techmode->Get() == AttrKey::TECHMODE_TYPE::TECHMODE_NOAEC_3P || m_DoseUnit.m_Techmode->Get() == AttrKey::TECHMODE_TYPE::TECHMODE_NOAEC_2P) { mLog::Info("Techmode is not AEC, Cannot set Field \n"); return RET_STATUS::RET_FAILED; } #endif // 0 m_DoseUnit.m_AECField->Update(value); return RET_STATUS::RET_SUCCEED; } RET_STATUS nsGEN::SINODevice::SetAECFilm(int value) //发生器无此设置 { if (!m_DoseUnit.m_AECFilm->Verify(value)) return RET_STATUS::RET_SUCCEED; #if 0 if (m_DoseUnit.m_Techmode->Get() == AttrKey::TECHMODE_TYPE::TECHMODE_NOAEC_3P || m_DoseUnit.m_Techmode->Get() == AttrKey::TECHMODE_TYPE::TECHMODE_NOAEC_2P) { mLog::Info("Techmode is not AEC, Cannot set Film \n"); return RET_STATUS::RET_FAILED; } #endif // 0 m_DoseUnit.m_AECFilm->Update(value); return RET_STATUS::RET_SUCCEED; } RET_STATUS nsGEN::SINODevice::SetWS(const string value) //发生器无此设置 { mLog::Info("Enter SetWS {$}", value); int tempws = 0; if (value == "Table") tempws = (int)m_GenConfig["WSTable"]; else if (value == "Wall") tempws = (int)m_GenConfig["WSWall"]; else if (value == "Direct") tempws = (int)m_GenConfig["WSConventional"]; else if (value == "Free") tempws = (int)m_GenConfig["WSFree"]; else if (value == "Tomo") tempws = (int)m_GenConfig["WSTomo"]; m_DoseUnit.m_WS->Update(tempws); return RET_STATUS::RET_SUCCEED; } RET_STATUS nsGEN::SINODevice::SetAPR(const _tAPRArgs& t) { mLog::Info("APR:KV={$},MA={$},MS={$},MAS={$},Focus={$},Techmode={$},WS={$},AECDensity={$},AECField={$},AECFilm={$}",t.fKV, t.fMA, t.fMS, t.fMAS, t.nFocus, t.nTechmode, t.nWS, t.nAECDensity, t.nAECField, t.nAECFilm); if (!m_DoseUnit.m_KV->Verify(t.fKV)) { mLog::Error("SetAPR:KV Out of bounds[{$}] \n", t.fKV); } else if (!m_DoseUnit.m_MA->Verify(t.fMA)) { mLog::Error("SetAPR:MA Out of bounds[{$}] \n", t.fMA); } else if (!m_DoseUnit.m_MS->Verify(t.fMS)) { mLog::Error("SetAPR:MS Out of bounds[{$}] \n", t.fMS); } else if (!m_DoseUnit.m_MAS->Verify(t.fMAS)) { mLog::Error("SetAPR:MAS Out of bounds[{$}] \n", t.fMAS); } else if (!m_DoseUnit.m_Focus->Verify(t.nFocus)) { mLog::Error("SetAPR:Focus Out of bounds[{$}] \n", t.nFocus); } else { SetAPRMaMmo(t.fKV, t.fMAS, t.nFocus, t.nTechmode); } m_DoseUnit.m_WS->Update(t.nWS); SetAECDensity(t.nAECDensity); SetAECField(t.nAECField); SetAECFilm(t.nAECFilm); return RET_STATUS::RET_SUCCEED; } RET_STATUS nsGEN::SINODevice::QueryHE(int& value) //实际为主动上报 { //value = m_DoseUnit.m_HE->Get(); return RET_STATUS::RET_SUCCEED; } RET_STATUS nsGEN::SINODevice::RefreshData() //发生器无此设置 { mLog::Debug("RefreshData: get System power on status \n"); SINOCommand strCmd(SINO_ComInquiry, SINO_TYPE_SEND, 7); strCmd.SetAt(5, EM_ComInquiry_PowerOn); return HWSend(strCmd); } RET_STATUS nsGEN::SINODevice::SetExpEnable() { SINOCommand strCmd(SINO_DataQuery, SINO_TYPE_SEND, 7); strCmd.SetAt(5, EM_Query_READY); return HWSend(strCmd); } RET_STATUS nsGEN::SINODevice::SetExpDisable() { SINOCommand strCmd(SINO_DataQuery, SINO_TYPE_SEND, 7); strCmd.SetAt(5, EM_Query_NOREADY); return HWSend(strCmd); } RET_STATUS nsGEN::SINODevice::QueryPostKV(float& value) //实际为主动上报 { if (m_DoseUnit.m_PostKV->Get() > 0) { value = m_DoseUnit.m_PostKV->Get(); } return RET_STATUS::RET_SUCCEED; } RET_STATUS nsGEN::SINODevice::QueryPostMA(float& value) //实际为主动上报 { if (m_DoseUnit.m_PostMA->Get() > 0) { value = m_DoseUnit.m_PostMA->Get(); } return RET_STATUS::RET_SUCCEED; } RET_STATUS nsGEN::SINODevice::QueryPostMS(float& value) //实际为主动上报 { if (m_DoseUnit.m_PostMS->Get() > 0) { value = m_DoseUnit.m_PostMS->Get(); } return RET_STATUS::RET_SUCCEED; } RET_STATUS nsGEN::SINODevice::QueryPostMAS(float& value) //实际为主动上报 { if (m_DoseUnit.m_PostMAS->Get() > 0) { value = m_DoseUnit.m_PostMAS->Get(); } return RET_STATUS::RET_SUCCEED; } RET_STATUS nsGEN::SINODevice::IncMA() { return RET_STATUS::RET_SUCCEED; } RET_STATUS nsGEN::SINODevice::DecMA() { return RET_STATUS::RET_SUCCEED; } RET_STATUS nsGEN::SINODevice::SetMA(float value) { return RET_STATUS::RET_SUCCEED; } RET_STATUS nsGEN::SINODevice::IncMS() { return RET_STATUS::RET_SUCCEED; } RET_STATUS nsGEN::SINODevice::DecMS() { return RET_STATUS::RET_SUCCEED; } RET_STATUS nsGEN::SINODevice::SetMS(float value) { return RET_STATUS::RET_SUCCEED; } RET_STATUS nsGEN::SINODevice::Clear_DAP() //发生器无此设置 { return RET_STATUS::RET_SUCCEED; } RET_STATUS nsGEN::SINODevice::GetValue_DAP(float& value) //发生器无此设置 { //value = m_DAP->Get(); return RET_STATUS::RET_SUCCEED; } RET_STATUS nsGEN::SINODevice::StartMove() //发生器无此设置 { return RET_STATUS::RET_SUCCEED; } RET_STATUS nsGEN::SINODevice::EndMove() //发生器无此设置 { return RET_STATUS::RET_SUCCEED; } RET_STATUS nsGEN::SINODevice::SetGenSynState(int value) //仅供Demo测试 { m_DoseUnit.m_GenSynState->Update(value); FireNotify(m_DoseUnit.m_GenSynState->GetKey(), m_DoseUnit.m_GenSynState->JSGet()); return RET_STATUS::RET_SUCCEED; //发生器的所有状态只能主动查询,设备不会主动上报,所以可能无法软同步 } RET_STATUS nsGEN::SINODevice::SetGenState(int value) //发生器无此设置 { return RET_STATUS::RET_SUCCEED; } RET_STATUS nsGEN::SINODevice::SetExpMode(std::string value) //发生器无此设置 { mLog::Info("Enter SetExpMode...{$} \n",value); m_DoseUnit.m_ExpMode->Update(value); return RET_STATUS::RET_SUCCEED; } RET_STATUS nsGEN::SINODevice::SetFLFMode(std::string value) //发生器无此设置 { return RET_STATUS::RET_SUCCEED; } RET_STATUS nsGEN::SINODevice::SetFrameRate(FLOAT frameRate) //发生器无此设置 { m_DoseUnit.m_FrameRate->Update(frameRate); return RET_STATUS::RET_SUCCEED; } RET_STATUS nsGEN::SINODevice::SetRPS(int rps) //发生器无此设置 { return RET_STATUS::RET_SUCCEED; } //为了将gen和其他设备关联,能相互调用接口 RET_STATUS nsGEN::SINODevice::SetGrid(int nGridType) { mLog::Debug("Enter SetGrid[{$}]", nGridType); if (m_pMechDev) m_pMechDev->UpdateGrid(0); return RET_STATUS::RET_SUCCEED; } RET_STATUS nsGEN::SINODevice::SetFilter(int nFilterType) { if (m_pMechDev) { m_pMechDev->UpdateMammo_FT(nFilterType); } if (m_pCollDev) { m_pCollDev->UpdateCollimatorFilter(nFilterType); } SINOCommand strCmd(SINO_DataQuery, SINO_TYPE_SEND, 7); strCmd.SetAt(5, EM_Query_STATUS); return HWSend(strCmd); } RET_STATUS nsGEN::SINODevice::SetAutoTracking(int nAutoTracking) { mLog::Debug("Enter SetAutoTracking[{$}]", nAutoTracking); if (m_pMechDev) m_pMechDev->UpdateMammo_Depress(nAutoTracking); SINOCommand strCmd(SINO_Compressor, SINO_TYPE_SEND, 11); strCmd.SetAt(9, nAutoTracking); return HWSend(strCmd); } RET_STATUS nsGEN::SINODevice::GetTomoResults(ResDataObject& resultAngle, ResDataObject& resultHeight) { mLog::Debug("Enter GetTomoResults"); return RET_STATUS::RET_SUCCEED; } RET_STATUS nsGEN::SINODevice::SetMechDev(OemMechanical* dev) { if (dev) m_pMechDev.reset(dev); return RET_STATUS::RET_SUCCEED; } RET_STATUS nsGEN::SINODevice::SetCollimatorDev(OemCollimator* dev) { if (dev) m_pCollDev.reset(dev); return RET_STATUS::RET_SUCCEED; } RET_STATUS nsGEN::SINODevice::SetCollimatorSize(int xsize, int ysize) { if (m_pCollDev) { m_pCollDev->UpdateCollimatorXSize(xsize); m_pCollDev->UpdateCollimatorYSize(ysize); } return RET_STATUS::RET_SUCCEED; } RET_STATUS nsGEN::SINODevice::SetCollimatorLight(WORD pParams) { //此处应该发送指令给GEN,并且该指令可以控制 coll 的LED return RET_STATUS::RET_SUCCEED; } RET_STATUS nsGEN::SINODevice::Reset() { mLog::Debug("clear all errors \n"); int level = 0; m_MSGUnit->DelErrorMessage("0", level, "clear all errors"); SINOCommand strCmd(SINO_SystemWarning, SINO_TYPE_SEND, 7); strCmd.SetAt(5, EM_SysWarn018); return HWSend(strCmd); } RET_STATUS nsGEN::SINODevice::HWSend(SINOCommand& strCommand, int nTimeOut) { std::unique_lock uqeConnectFlag(mtxConnectFlag); if (!m_bConnectFlag) { mLog::Error("==OUT==: not Connect,[{$}] send failed \n", strCommand.Get_Hex_Log()); //uqeConnectFlag.unlock(); return RET_STATUS::RET_FAILED; } uqeConnectFlag.unlock(); if (!m_SCF) return RET_STATUS::RET_FAILED; strCommand.SetCRC(ComputeCheckSum); mLog::Info("==OUT==: [{$}] \n", strCommand.Get_Hex_Log()); int retLength; m_SCF.Lock(msTimeOut_Lock) .SendPacket(strCommand, strCommand[3], nTimeOut, retLength); Sleep(nTimeOut); return RET_STATUS::RET_SUCCEED; } //----------------------------------------------------------------------------- // ProcessCmd //----------------------------------------------------------------------------- void nsGEN::SINODevice::FireNotify(std::string key, std::string content) { EventCenter->OnNotify(1, key, content); } void nsGEN::SINODevice::FireErrorMessage(const bool Act, const int Code, const char* ResInfo) { char ErrorCode[20] = {0}; sprintf_s(ErrorCode, "SINO_ERR_%03d", Code); int level = SINO_REGULATION_LEVEL::REG_ERRO; if (Act) { mLog::Error("add {$}:{$}", ErrorCode, ResInfo); m_MSGUnit->AddErrorMessage(ErrorCode, level, ResInfo); } else { mLog::Error("del {$}:{$}", ErrorCode, ResInfo); m_MSGUnit->DelErrorMessage(ErrorCode, level, ResInfo); } } void nsGEN::SINODevice::FireWarnMessage(const bool Act, const int Code, const char* ResInfo) { char ErrorCode[20] = { 0 }; sprintf_s(ErrorCode, "SINO_WAR_%03d", Code); int level = SINO_REGULATION_LEVEL::REG_WARN; if (Act) { mLog::Error("add {$}:{$}", ErrorCode, ResInfo); m_MSGUnit->AddWarnMessage(ErrorCode, level, ResInfo); } else { mLog::Error("del {$}:{$}", ErrorCode, ResInfo); m_MSGUnit->DelWarnMessage(ErrorCode, level, ResInfo); } } void nsGEN::SINODevice::OnCallBack() { //无 操作 auto HWNotProcess = [this](const char* value, int length) -> void { mLog::Info("\n This commands didn't need to process!"); }; //响应操作 auto CallbackACK = [this](const char* value, int length) -> void { if (value[2] == SINO_SystemStatus) { SINOCommand strCmd(value[2], SINO_TYPE_CONFIRM, 6); HWSend(strCmd); } else { SINOCommand strCmd(value[2], SINO_TYPE_CONFIRM, 7); strCmd.SetAt(5, SINO_CONFIRM_OK); HWSend(strCmd); } }; //命令模式:用于正常操作 auto CallbackExpoParam = [this](const char* value, int length) -> void { #if 0 SINOCommand ExposureParam(value); //KV int nKV = ExposureParam.GetAt(5); mLog::Debug("get CurrtSetKV [{$}]", nKV); m_DoseUnit.m_KV->Update(nKV); FireNotify(AttrKey::KV, m_DoseUnit.m_KV->JSGet()); //MAS float fMAS = 0; if (ExposureParam.GetAt(7) == 0xFF) { fMAS = ExposureParam.GetAt(6); } else { fMAS = (ExposureParam.GetAt(7) << 8) + ExposureParam.GetAt(6); } mLog::Debug("get CurrtSetMS [{$}]", fMAS); m_DoseUnit.m_MAS->Update(fMAS); FireNotify(AttrKey::MAS, m_DoseUnit.m_MAS->JSGet()); //Focus int nFO = 0; switch (ExposureParam.GetAt(8)) { case EM_Focus_Large: mLog::Debug("get CurrtFocus [Small]"); nFO = AttrKey::FOCUS_TYPE::FOCUS_LARGE; break; case EM_Focus_Small: mLog::Debug("get CurrtFocus [Large]"); nFO = AttrKey::FOCUS_TYPE::FOCUS_SMALL; break; default: mLog::Debug("==CallbackExposureParam==: Get other Focus value!"); break; } if (m_DoseUnit.m_Focus->Update(nFO)) FireNotify(AttrKey::FOCUS, m_DoseUnit.m_Focus->JSGet()); //Techmode int nET = 0; switch (ExposureParam.GetAt(9)) { case EM_EXPMode_MAN: nET = AttrKey::TECHMODE_TYPE::TECHMODE_NOAEC_2P; m_DoseUnit.m_Techmode->Update(AttrKey::TECHMODE_TYPE::TECHMODE_NOAEC_2P); break; case EM_EXPMode_AEC: nET = AttrKey::TECHMODE_TYPE::TECHMODE_AEC_2P; m_DoseUnit.m_Techmode->Update(AttrKey::TECHMODE_TYPE::TECHMODE_AEC_2P); break; case EM_EXPMode_Opdose: nET = AttrKey::TECHMODE_TYPE::TECHMODE_AEC_2P; m_DoseUnit.m_Techmode->Update(AttrKey::TECHMODE_TYPE::TECHMODE_AEC_2P); break; default: mLog::Debug("==CallbackExposureParam==: Get other Techmode value!"); break; } FireNotify(AttrKey::TECHMODE, m_DoseUnit.m_Techmode->JSGet()); mLog::Debug("==CallbackExposureParam==: KV: [{$}], MAS:[{$}], Focus: [{$}], TechMode: [{$}]", nKV, fMAS, nFO, nET); #else SINOCommand strCmd(SINO_DataQuery, SINO_TYPE_SEND, 7); strCmd.SetAt(5, EM_Query_STATUS); HWSend(strCmd); #endif }; auto CallbackPosition = [this](const char* value, int length) -> void { SINOCommand Position(value); float fAngle = 0, fHeight = 0; //Angle if (Position.GetAt(6) == 0xFF) { fAngle = (float)(Position.GetAt(5)) / 10.0f; } else { fAngle = (float)((Position.GetAt(6) << 8) + Position.GetAt(5)) / 10.0f; } fAngle = 180 - fAngle; if (m_pMechDev) m_pMechDev->UpdateMammo_MechAngle(fAngle); //Height if (Position.GetAt(8) == 0xFF) { fHeight = Position.GetAt(7); } else { fHeight = (Position.GetAt(8) << 8) + Position.GetAt(7); } if (m_pMechDev) m_pMechDev->UpdateMammo_MechHeight(fHeight); mLog::Debug("==CallbackPosition==: Angle:[{$}], Height:[{$}]", fAngle, fHeight); }; auto CallbackCompressor = [this](const char* value, int length) -> void { SINOCommand Compressor(value); float fPressure = 0; int nBreastThickness = 0, nPaddle_Type = 0, nDe_comp = 0; //BreastThickness if (Compressor.GetAt(6) == 0xFF) { nBreastThickness = Compressor.GetAt(5); } else { nBreastThickness = (Compressor.GetAt(6) << 8) + Compressor.GetAt(5); } if (m_pMechDev) m_pMechDev->UpdateMammo_PressureState(nBreastThickness); //pressure if (Compressor.GetAt(7) == 0xFF) { fPressure = 0; } else { fPressure = Compressor.GetAt(7); } if (m_pMechDev) m_pMechDev->UpdateMammo_PressureValue(fPressure); //Paddle Type if (Compressor.GetAt(8) == 0xFF) { nPaddle_Type = 0; } else { nPaddle_Type = Compressor.GetAt(8); } //De-comp if (Compressor.GetAt(9) == 0xFF) { nDe_comp = 0; } else { nDe_comp = Compressor.GetAt(9); } if (m_pMechDev) m_pMechDev->UpdateMammo_Depress(nDe_comp); mLog::Debug("==CallbackCompressor==: BreastThickness: [{$}], Pressure:[{$}] N,Paddle_Type:[{$}],De_comp:[{$}]", nBreastThickness, fPressure, nPaddle_Type, nDe_comp); }; auto CallbackCollimator = [this](const char* value, int length) -> void { SINOCommand Collimator(value); //Filter int nFilter = 0; if (Collimator.GetAt(5) == 0xFF) { nFilter = EM_Mo_Filtration; } else { nFilter = Collimator.GetAt(5); } if(m_pMechDev) m_pMechDev->UpdateMammo_FT(nFilter); mLog::Debug("==CallbackCollimator==: filter: [{$}]", nFilter); }; auto CallbackExposureParam = [this](const char* value, int length) -> void { SINOCommand ExposureParam(value); //KV int nKV = ExposureParam.GetAt(5); mLog::Debug("get CurrtSetKV [{$}]", nKV); m_DoseUnit.m_KV->Update(nKV); FireNotify(AttrKey::KV, m_DoseUnit.m_KV->JSGet()); //MAS float fMAS = 0; if (ExposureParam.GetAt(7) == 0xFF) { fMAS = ExposureParam.GetAt(6); } else { fMAS = (ExposureParam.GetAt(7) << 8) + ExposureParam.GetAt(6); } mLog::Debug("get CurrtSetMS [{$}]", fMAS); m_DoseUnit.m_MAS->Update(fMAS); FireNotify(AttrKey::MAS, m_DoseUnit.m_MAS->JSGet()); //Focus int nFO = 0; switch (ExposureParam.GetAt(8)) { case EM_Focus_Large: mLog::Debug("get CurrtFocus [Small]"); nFO = AttrKey::FOCUS_TYPE::FOCUS_LARGE; break; case EM_Focus_Small: mLog::Debug("get CurrtFocus [Large]"); nFO = AttrKey::FOCUS_TYPE::FOCUS_SMALL; break; default: mLog::Debug("==CallbackExposureParam==: Get other Focus value!"); break; } if (m_DoseUnit.m_Focus->Update(nFO)) FireNotify(AttrKey::FOCUS, m_DoseUnit.m_Focus->JSGet()); //Techmode int nET = 0; switch (ExposureParam.GetAt(9)) { case EM_EXPMode_MAN: nET = AttrKey::TECHMODE_TYPE::TECHMODE_NOAEC_2P; m_DoseUnit.m_Techmode->Update(AttrKey::TECHMODE_TYPE::TECHMODE_NOAEC_2P); break; case EM_EXPMode_AEC: nET = AttrKey::TECHMODE_TYPE::TECHMODE_AEC_2P; m_DoseUnit.m_Techmode->Update(AttrKey::TECHMODE_TYPE::TECHMODE_AEC_2P); break; case EM_EXPMode_Opdose: nET = AttrKey::TECHMODE_TYPE::TECHMODE_AEC_2P; m_DoseUnit.m_Techmode->Update(AttrKey::TECHMODE_TYPE::TECHMODE_AEC_2P); break; default: mLog::Debug("==CallbackExposureParam==: Get other Techmode value!"); break; } FireNotify(AttrKey::TECHMODE, m_DoseUnit.m_Techmode->JSGet()); mLog::Debug("==CallbackExposureParam==: KV: [{$}], MAS:[{$}], Focus: [{$}], TechMode: [{$}]", nKV, fMAS, nFO, nET); }; auto CallbackHu = [this](const char* value, int length) -> void { SINOCommand HU(value); //TubeHeat status int nHUStatus = HU.GetAt(5); string HUCode("SINO_HU_"); HUCode += std::to_string(nHUStatus); //TubeHeat percent value int nTubeHeat = 0; if (HU.GetAt(6) == 0xFF) { nTubeHeat = 0; } else { nTubeHeat = HU.GetAt(6); } m_DoseUnit.m_HE->Update(nTubeHeat); FireNotify(m_DoseUnit.m_HE->GetKey(), m_DoseUnit.m_HE->JSGet()); mLog::Debug("==CallbackHu==: HUStatus: [{$}],HU: [{$}]", HUCode, nTubeHeat); }; auto CallbackQueryStatus = [this](const char* value, int length) -> void { #if 1 SINOCommand QueryStatus(value); //KV int nKV = QueryStatus.GetAt(5); mLog::Debug("get CurrtSetKV [{$}]", nKV); m_DoseUnit.m_KV->Update(nKV); FireNotify(AttrKey::KV, m_DoseUnit.m_KV->JSGet()); //MAS float fMAS = 0; if (QueryStatus.GetAt(7) == 0xFF) { fMAS = QueryStatus.GetAt(6); } else { fMAS = (QueryStatus.GetAt(7) << 8) + QueryStatus.GetAt(6); } mLog::Debug("get CurrtSetMS [{$}]", fMAS); m_DoseUnit.m_MAS->Update(fMAS); FireNotify(AttrKey::MAS, m_DoseUnit.m_MAS->JSGet()); //Focus int nFO = 0; switch (QueryStatus.GetAt(8)) { case EM_Focus_Large: mLog::Debug("get CurrtFocus [Small]"); nFO = AttrKey::FOCUS_TYPE::FOCUS_LARGE; break; case EM_Focus_Small: mLog::Debug("get CurrtFocus [Large]"); nFO = AttrKey::FOCUS_TYPE::FOCUS_SMALL; break; default: mLog::Debug("==CallbackQueryStatus==: Get other Focus value!"); break; } if (m_DoseUnit.m_Focus->Update(nFO)) FireNotify(AttrKey::FOCUS, m_DoseUnit.m_Focus->JSGet()); //Techmode int nET = 0; switch (QueryStatus.GetAt(9)) { case EM_EXPMode_MAN: nET = AttrKey::TECHMODE_TYPE::TECHMODE_NOAEC_2P; m_DoseUnit.m_Techmode->Update(AttrKey::TECHMODE_TYPE::TECHMODE_NOAEC_2P); break; case EM_EXPMode_AEC: nET = AttrKey::TECHMODE_TYPE::TECHMODE_AEC_2P; m_DoseUnit.m_Techmode->Update(AttrKey::TECHMODE_TYPE::TECHMODE_AEC_2P); break; case EM_EXPMode_Opdose: nET = AttrKey::TECHMODE_TYPE::TECHMODE_AEC_2P; m_DoseUnit.m_Techmode->Update(AttrKey::TECHMODE_TYPE::TECHMODE_AEC_2P); break; default: mLog::Debug("==CallbackQueryStatus==: Get other Techmode value!"); break; } FireNotify(AttrKey::TECHMODE, m_DoseUnit.m_Techmode->JSGet()); //AGD float fAGD = 0; if (QueryStatus.GetAt(11) == 0xFF) { fAGD = QueryStatus.GetAt(10); } else { fAGD = (QueryStatus.GetAt(11) << 8) + QueryStatus.GetAt(10); } if (m_pMechDev) { m_pMechDev->UpdateMammo_AGD(fAGD); } //Filter int nFilter = 0; if (QueryStatus.GetAt(12) == 0xFF) { nFilter = EM_Mo_Filtration; } else { nFilter = QueryStatus.GetAt(12); } if (m_pMechDev) m_pMechDev->UpdateMammo_FT(nFilter); //BreastThickness int nBreastThickness = 0; if (QueryStatus.GetAt(14) == 0xFF) { nBreastThickness = QueryStatus.GetAt(13); } else { nBreastThickness = (QueryStatus.GetAt(14) << 8) + QueryStatus.GetAt(13); } if (m_pMechDev) m_pMechDev->UpdateMammo_PressureState(nBreastThickness); //pressure float fPressure = 0; if (QueryStatus.GetAt(15) == 0xFF) { fPressure = 0; } else { fPressure = QueryStatus.GetAt(15); } if (m_pMechDev) m_pMechDev->UpdateMammo_PressureValue(fPressure); //Paddle Type int nPaddle_Type = 0; if (QueryStatus.GetAt(16) == 0xFF) { nPaddle_Type = 0; } else { nPaddle_Type = QueryStatus.GetAt(16); } //Angle float fAngle = 0; if (QueryStatus.GetAt(18) == 0xFF) { fAngle = (float)(QueryStatus.GetAt(17)) / 10.0f; } else { fAngle = (float)((QueryStatus.GetAt(18) << 8) + QueryStatus.GetAt(17)) / 10.0f; } fAngle = 180 - fAngle; if (m_pMechDev) m_pMechDev->UpdateMammo_MechAngle(fAngle); //Height float fHeight = 0; if (QueryStatus.GetAt(20) == 0xFF) { fHeight = QueryStatus.GetAt(7); } else { fHeight = (QueryStatus.GetAt(20) << 8) + QueryStatus.GetAt(19); } if (m_pMechDev) m_pMechDev->UpdateMammo_MechHeight(fHeight); mLog::Debug("==CallbackQueryStatus==: KV: [{$}],MAS: [{$}],Techmode:[{$}],AGD:[{$}],Filter:[{$}],Thickness:[{$}],Pressure:[{$}],Paddle_Type:[{$}],Angle:[{$}],Height:[{$}]", nKV, fMAS, nET, fAGD, nFilter, nBreastThickness, fPressure, nPaddle_Type, fAngle, fHeight); #endif }; auto CallbackPostExposure = [this](const char* value, int length) -> void { SINOCommand PostExposure(value); //KV int nKV = PostExposure.GetAt(5); mLog::Debug("get CurrtSetKV [{$}]", nKV); m_DoseUnit.m_PostKV->Update(nKV); FireNotify(AttrKey::POSTKV, m_DoseUnit.m_PostKV->JSGet()); //MAS float fMAS = 0; if (PostExposure.GetAt(7) == 0xFF) { fMAS = PostExposure.GetAt(6); } else { fMAS = (PostExposure.GetAt(7) << 8) + PostExposure.GetAt(6); } mLog::Debug("get CurrtSetMS [{$}]", fMAS); m_DoseUnit.m_PostMAS->Update(fMAS); FireNotify(AttrKey::POSTMAS, m_DoseUnit.m_PostMAS->JSGet()); //Focus int nFO = 0; switch (PostExposure.GetAt(8)) { case EM_Focus_Large: mLog::Debug("get CurrtFocus [Small]"); nFO = AttrKey::FOCUS_TYPE::FOCUS_LARGE; break; case EM_Focus_Small: mLog::Debug("get CurrtFocus [Large]"); nFO = AttrKey::FOCUS_TYPE::FOCUS_SMALL; break; default: mLog::Debug("==CallbackPostExposure==: Get other Focus value!"); break; } if (m_DoseUnit.m_Focus->Update(nFO)) FireNotify(AttrKey::FOCUS, m_DoseUnit.m_Focus->JSGet()); //Techmode int nET = 0; switch (PostExposure.GetAt(9)) { case EM_EXPMode_MAN: nET = AttrKey::TECHMODE_TYPE::TECHMODE_NOAEC_2P; m_DoseUnit.m_Techmode->Update(AttrKey::TECHMODE_TYPE::TECHMODE_NOAEC_2P); break; case EM_EXPMode_AEC: nET = AttrKey::TECHMODE_TYPE::TECHMODE_AEC_2P; m_DoseUnit.m_Techmode->Update(AttrKey::TECHMODE_TYPE::TECHMODE_AEC_2P); break; case EM_EXPMode_Opdose: nET = AttrKey::TECHMODE_TYPE::TECHMODE_AEC_2P; m_DoseUnit.m_Techmode->Update(AttrKey::TECHMODE_TYPE::TECHMODE_AEC_2P); break; default: mLog::Debug("==CallbackPostExposure==: Get other Techmode value!"); break; } FireNotify(AttrKey::TECHMODE, m_DoseUnit.m_Techmode->JSGet()); //AGD float fAGD = 0; if (PostExposure.GetAt(11) == 0xFF) { fAGD = PostExposure.GetAt(10); } else { fAGD = (PostExposure.GetAt(11) << 8) + PostExposure.GetAt(10); } if (m_pMechDev) { m_pMechDev->UpdateMammo_AGD(fAGD); } //Filter int nFilter = 0; if (PostExposure.GetAt(12) == 0xFF) { nFilter = EM_Mo_Filtration; } else { nFilter = PostExposure.GetAt(12); } if (m_pMechDev) m_pMechDev->UpdateMammo_FT(nFilter); //BreastThickness int nBreastThickness = 0; if (PostExposure.GetAt(14) == 0xFF) { nBreastThickness = PostExposure.GetAt(13); } else { nBreastThickness = (PostExposure.GetAt(14) << 8) + PostExposure.GetAt(13); } if (m_pMechDev) m_pMechDev->UpdateMammo_PressureState(nBreastThickness); //pressure float fPressure = 0; if (PostExposure.GetAt(15) == 0xFF) { fPressure = 0; } else { fPressure = PostExposure.GetAt(15); } if (m_pMechDev) m_pMechDev->UpdateMammo_PressureValue(fPressure); //Paddle Type int nPaddle_Type = 0; if (PostExposure.GetAt(16) == 0xFF) { nPaddle_Type = 0; } else { nPaddle_Type = PostExposure.GetAt(16); } //Angle float fAngle = 0; if (PostExposure.GetAt(18) == 0xFF) { fAngle = (float)(PostExposure.GetAt(17)) / 10.0f; } else { fAngle = (float)((PostExposure.GetAt(18) << 8) + PostExposure.GetAt(17)) / 10.0f; } fAngle = 180 - fAngle; if (m_pMechDev) m_pMechDev->UpdateMammo_MechAngle(fAngle); //Height float fHeight = 0; if (PostExposure.GetAt(20) == 0xFF) { fHeight = PostExposure.GetAt(7); } else { fHeight = (PostExposure.GetAt(20) << 8) + PostExposure.GetAt(19); } if (m_pMechDev) m_pMechDev->UpdateMammo_MechHeight(fHeight); mLog::Debug("==CallbackPostExposure==: KV: [{$}],MAS: [{$}],Techmode:[{$}],AGD:[{$}],Filter:[{$}],Thickness:[{$}],Pressure:[{$}],Paddle_Type:[{$}],Angle:[{$}],Height:[{$}]", nKV, fMAS,nET, fAGD, nFilter, nBreastThickness, fPressure, nPaddle_Type, fAngle, fHeight); }; auto CallbackSystemStatus = [this](const char* value, int length) -> void { SINOCommand SystemStatus(value); int nStatus = SystemStatus.GetAt(5); mLog::Debug("==CallbackSystemStatus==: MU system Status: [{$}]", nStatus); switch ((UINT8)nStatus) { case (UINT8)EM_SysStatus001: //C臂正在做旋转运动 mLog::Debug("C-arm is undergoing rotational motion"); break; case (UINT8)EM_SysStatus002: //C臂旋转运动停止 mLog::Debug("C-arm rotation stop"); break; case (UINT8)EM_SysStatus003: //C臂正在做升降运动 mLog::Debug("C-arm is in lifting motion"); break; case (UINT8)EM_SysStatus004: //C臂升降运动停止 mLog::Debug("C-arm lifting movement stops"); break; case (UINT8)EM_SysStatus005: //急停开关按下 mLog::Debug("Emergency stop switch pressed"); break; case (UINT8)EM_SysStatus006: //急停开关弹起 mLog::Debug("Emergency stop switch pops up"); break; case (UINT8)EM_SysStatus016: //压迫器正在做升降运动 mLog::Debug("Compressor is in lifting motion"); break; case (UINT8)EM_SysStatus017: //压迫器升降运动停止 mLog::Debug("Compressor lifting movement stopped"); break; case (UINT8)EM_SysStatus018: //达到最佳压力停止 mLog::Debug("Reaching optimal pressure stop"); break; case (UINT8)EM_SysStatus019: //解除达到最佳压力停止 mLog::Debug("Release to reach optimal pressure stop"); break; case (UINT8)EM_SysStatus020: //压迫器上升 mLog::Debug("Compressor ascending"); break; case (UINT8)EM_SysStatus021: //压迫器下降 mLog::Debug("Compressor descent"); break; case (UINT8)EM_SysStatus022: //压迫器停止 mLog::Debug("Compressor stop"); break; case (UINT8)EM_SysStatus032: //准直器滤过正在切换 mLog::Debug("Collimator filter is switching"); break; case (UINT8)EM_SysStatus033: //准直器滤过切换完毕 mLog::Debug("Collimator filter switching completed"); break; case (UINT8)EM_SysStatus034: //准直器摄野范围正在调整 mLog::Debug("Collimator field range is being adjusted"); break; case (UINT8)EM_SysStatus035: //准直器摄野范围调整完毕 mLog::Debug("Collimator field range adjustment completed"); break; case (UINT8)EM_SysStatus036: //摄野灯点亮 mLog::Debug("Camera light on"); break; case (UINT8)EM_SysStatus037: //摄野灯熄灭 mLog::Debug("Camera light off"); break; case (UINT8)EM_SysStatus064: //允许曝光板开启曝光功能 mLog::Debug("Allow exposure board to activate exposure function"); break; case (UINT8)EM_SysStatus065: //禁止曝光板开启曝光功能 mLog::Debug("Prohibit exposure board to activate exposure function"); break; case (UINT8)EM_SysStatus066: //采集工作站启动曝光按钮 mLog::Debug("Start exposure button on the collection workstation"); break; case (UINT8)EM_SysStatus067: //曝光手闸按下 mLog::Debug("PR1 : Exposure handbrake pressed"); //mLog::Debug("Request Status_4:RAD_OFF(PR0) -> RAD_PREPARE(PR1)"); if (m_DoseUnit.m_GenSynState->Update(nsGEN::AttrKey::GENERATOR_RAD_PREPARE)) FireNotify(m_DoseUnit.m_GenSynState->GetKey(), m_DoseUnit.m_GenSynState->JSGet()); break; case (UINT8)EM_SysStatus068: //系统曝光预热状态 mLog::Debug("PR2 : System exposure preheating status"); //mLog::Debug("Request Status_13:PREPARE or XRAYOFF(PR1 or XR0) -> RAD_READY(PR2)"); if (m_DoseUnit.m_GenSynState->Update(nsGEN::AttrKey::GENERATOR_RAD_READY)) FireNotify(m_DoseUnit.m_GenSynState->GetKey(), m_DoseUnit.m_GenSynState->JSGet()); break; case (UINT8)EM_SysStatus070: //滤线栅同步命令(预留) mLog::Debug("Filter grid synchronization command"); break; case (UINT8)EM_SysStatus071: //AEC/Opdose模式开启高压预曝光 mLog::Debug("Pre - XR1 : AEC/Opdose mode high-pressure pre exposure begin"); //mLog::Debug("Request Status_1:RAD_READY(PR2) -> X-Ray On(XR1)"); if (m_DoseUnit.m_GenSynState->Update(nsGEN::AttrKey::GENERATOR_RAD_XRAYON)) FireNotify(m_DoseUnit.m_GenSynState->GetKey(), m_DoseUnit.m_GenSynState->JSGet()); mLog::Debug("Request Status_1:GENSTATE {$} -> STATUS_EXP", m_DoseUnit.m_GenState->JSGet()); m_DoseUnit.m_GenState->Update(nsGEN::AttrKey::GENERATOR_STATUS_EXP); FireNotify(AttrKey::GENSTATE, m_DoseUnit.m_GenState->JSGet()); break; case (UINT8)EM_SysStatus073: //AEC/Opdose模式高压预曝光结束 mLog::Debug("Pre - XR0 : AEC/Opdose mode enables high-pressure pre exposure end"); //mLog::Debug("Request Status_1:X-Ray On(XR1) -> Off(XR0)"); if (m_DoseUnit.m_GenSynState->Update(nsGEN::AttrKey::GENERATOR_RAD_XRAYOFF)) FireNotify(m_DoseUnit.m_GenSynState->GetKey(), m_DoseUnit.m_GenSynState->JSGet()); mLog::Debug("Request Status_1:GENSTATE {$} -> STATUS_STANDBY", m_DoseUnit.m_GenState->JSGet()); m_DoseUnit.m_GenState->Update(nsGEN::AttrKey::GENERATOR_STATUS_STANDBY); FireNotify(AttrKey::GENSTATE, m_DoseUnit.m_GenState->JSGet()); break; case (UINT8)EM_SysStatus075: //开启高压,系统开始正常曝光 mLog::Debug("XR1 : the system starts normal exposure"); //mLog::Debug("Request Status_1:RAD_READY(PR2) -> X-Ray On(XR1)"); if (m_DoseUnit.m_GenSynState->Update(nsGEN::AttrKey::GENERATOR_RAD_XRAYON)) FireNotify(m_DoseUnit.m_GenSynState->GetKey(), m_DoseUnit.m_GenSynState->JSGet()); mLog::Debug("Request Status_1:GENSTATE {$} -> STATUS_EXP", m_DoseUnit.m_GenState->JSGet()); m_DoseUnit.m_GenState->Update(nsGEN::AttrKey::GENERATOR_STATUS_EXP); FireNotify(AttrKey::GENSTATE, m_DoseUnit.m_GenState->JSGet()); break; case (UINT8)EM_SysStatus077: //曝光进程中断 mLog::Debug("XR0 : Exposure process interrupted"); //mLog::Debug("Request Status_1:X-Ray On(XR1) -> Off(XR0)"); if (m_DoseUnit.m_GenSynState->Update(nsGEN::AttrKey::GENERATOR_RAD_XRAYOFF)) FireNotify(m_DoseUnit.m_GenSynState->GetKey(), m_DoseUnit.m_GenSynState->JSGet()); mLog::Debug("Request Status_1:GENSTATE {$} -> STATUS_STANDBY", m_DoseUnit.m_GenState->JSGet()); m_DoseUnit.m_GenState->Update(nsGEN::AttrKey::GENERATOR_STATUS_STANDBY); FireNotify(AttrKey::GENSTATE, m_DoseUnit.m_GenState->JSGet()); break; case (UINT8)EM_SysStatus078: //曝光完成开始冷却 mLog::Debug("PR0 : Start cooling after exposure is completed"); //mLog::Debug("Request Status_4:GEN is not in Prep state(PR0)"); if (m_DoseUnit.m_GenSynState->Update(nsGEN::AttrKey::GENERATOR_RAD_OFF)) FireNotify(m_DoseUnit.m_GenSynState->GetKey(), m_DoseUnit.m_GenSynState->JSGet()); mLog::Debug("Request Fault Status:GENSTATE {$} -> STATUS_SLEEP", m_DoseUnit.m_GenState->JSGet()); m_DoseUnit.m_GenState->Update(nsGEN::AttrKey::GENERATOR_STATUS_SLEEP); FireNotify(AttrKey::GENSTATE, m_DoseUnit.m_GenState->JSGet()); break; case (UINT8)EM_SysStatus079: //系统冷却完成 mLog::Debug("System cooling completed"); mLog::Debug("Request Status_1:GENSTATE {$} -> STATUS_STANDBY", m_DoseUnit.m_GenState->JSGet()); m_DoseUnit.m_GenState->Update(nsGEN::AttrKey::GENERATOR_STATUS_STANDBY); FireNotify(AttrKey::GENSTATE, m_DoseUnit.m_GenState->JSGet()); break; case (UINT8)EM_SysStatus080: //屏蔽房间门处于闭合状态 mLog::Debug("The shielded room door is in a closed state"); break; case (UINT8)EM_SysStatus081: //屏蔽房间门处于敞开状态 mLog::Debug("The shielded room door is in a opened state"); break; case (UINT8)EM_SysStatus160: //MU初始化中 mLog::Debug("MU initialization in progress"); mLog::Debug("Request Status_1:GENSTATE {$} -> STATUS_INIT", m_DoseUnit.m_GenState->JSGet()); m_DoseUnit.m_GenState->Update(nsGEN::AttrKey::GENERATOR_STATUS_INIT); FireNotify(AttrKey::GENSTATE, m_DoseUnit.m_GenState->JSGet()); break; case (UINT8)EM_SysStatus161: //MU初始化完成 mLog::Debug("MU initialization completed"); mLog::Debug("Request Status_1:GENSTATE {$} -> STATUS_STANDBY", m_DoseUnit.m_GenState->JSGet()); m_DoseUnit.m_GenState->Update(nsGEN::AttrKey::GENERATOR_STATUS_STANDBY); FireNotify(AttrKey::GENSTATE, m_DoseUnit.m_GenState->JSGet()); break; case (UINT8)EM_SysStatus162: //MU各个状态 READY,可以进行曝光 mLog::Debug("MU in various states READY, can be exposed"); mLog::Debug("Request Status_1:GENSTATE {$} -> STATUS_STANDBY", m_DoseUnit.m_GenState->JSGet()); m_DoseUnit.m_GenState->Update(nsGEN::AttrKey::GENERATOR_STATUS_STANDBY); FireNotify(AttrKey::GENSTATE, m_DoseUnit.m_GenState->JSGet()); break; case (UINT8)EM_SysStatus163: //MU 各状态NOT READY,不可以进行曝光 mLog::Debug("MU in various states not READY, can not be exposed"); mLog::Debug("Request Fault Status:GENSTATE {$} -> STATUS_ERROR", m_DoseUnit.m_GenState->JSGet()); m_DoseUnit.m_GenState->Update(nsGEN::AttrKey::GENERATOR_STATUS_ERROR); FireNotify(AttrKey::GENSTATE, m_DoseUnit.m_GenState->JSGet()); break; default: mLog::Error("==CallbackSystemStatus==: unKnown status: [{$}]", nStatus); } }; auto CallbackSystemWarn = [this](const char* value, int length) -> void { SINOCommand SystemWarn(value); int nCode = SystemWarn.GetAt(5); mLog::Debug("==CallbackSystemWarn==: MU system Wraning: [{$}]", nCode); switch ((UINT8)nCode) { case (UINT8)EM_SysWarn001: //球管温度过高报警 case (UINT8)EM_SysWarn002: //高压发生器高压输出未允许报警 case (UINT8)EM_SysWarn003: //球管高速启动故障报警 case (UINT8)EM_SysWarn004: //高压发生器产生高压电弧故障报警 case (UINT8)EM_SysWarn005: //无效曝光参数设置导致高压输出大于5KW报警 case (UINT8)EM_SysWarn006: //AEC曝光控制超时报警 case (UINT8)EM_SysWarn007: //高压发生器反馈的mAs超出设置值报警 case (UINT8)EM_SysWarn008: //曝光周期中间歇时间未完成就进行曝光报警 case (UINT8)EM_SysWarn009: //高压发生器输出KV大于42765V且时间超过1ms报警 case (UINT8)EM_SysWarn010: //高压发生器输出mA大于213.828 mA且时间超过100ms报警 case (UINT8)EM_SysWarn011: //高压发生器输出KV或mA大于设置值的%25导致报警 case (UINT8)EM_SysWarn012: //高压发生器反馈球管灯丝开路报警 case (UINT8)EM_SysWarn013: //高压发生器反馈球管过流报警 case (UINT8)EM_SysWarn014: //高压发生器AD/DC输入电压过低报警 FireErrorMessage(true, nCode, "SINO using error"); break; case (UINT8)EM_SysWarn015: //高压发生器强制超出曝光任务周期报警 case (UINT8)EM_SysWarn016: //高压发生器管电压、管电流检测报警 case (UINT8)EM_SysWarn017: //高压发生器强制恢复过压异常报警 case (UINT8)EM_SysWarn018: //解除高压发生器报警 FireErrorMessage(false, 0, "SINO using warn"); break; case (UINT8)EM_SysWarn019: //曝光按钮短路或者未释放报警 FireErrorMessage(true, nCode, "SINO handswitch short circuit error"); break; case (UINT8)EM_SysWarn020: //解除手闸短路报警命令 FireErrorMessage(false, EM_SysWarn019, "SINO handswitch short circuit error"); break; case (UINT8)EM_SysWarn021: //曝光没有到设定时间提前松开手闸报警 FireErrorMessage(true, nCode, "SINO handswitch early release error"); break; case (UINT8)EM_SysWarn022: //消除提前松开手闸报警 FireErrorMessage(false, EM_SysWarn021, "SINO handswitch early release error"); break; case (UINT8)EM_SysWarn023: //自动测试模式时,检测到没有短接跳线报警 FireErrorMessage(true, nCode, "SINO automatic testing short circuit error"); break; case (UINT8)EM_SysWarn024: //解除自动测试跳线帽未短接报警 FireErrorMessage(false, EM_SysWarn023, "SINO automatic testing short circuit error"); break; case (UINT8)EM_SysWarn025: //曝光时,未收到运动板发来的滤线栅抖动信号 case (UINT8)EM_SysWarn032: //高压通信超时 case (UINT8)EM_SysWarn048: //运动控制板自检不通过报警 FireErrorMessage(true, nCode, "SINO Sports board error"); break; case (UINT8)EM_SysWarn049: //解除运动控制板自检不通过报警 FireErrorMessage(false, EM_SysWarn048, "SINO Sports board error"); break; case (UINT8)EM_SysWarn052: //运动控制板存储器读写数据失败报警 FireErrorMessage(true, nCode, "SINO Sports board Memory read/write data failure error"); break; case (UINT8)EM_SysWarn054: //解除运动控制板存储器读写数据失败报警 FireErrorMessage(false, EM_SysWarn052, "SINO Sports board Memory read/write data failure error"); break; case (UINT8)EM_SysWarn055: //急停开关按下时,运动控制键被按下报警 FireErrorMessage(true, nCode, "SINO Sports board Key pressed error"); break; case (UINT8)EM_SysWarn056: //解除急停开关按下时,运动控制键被按下错误 FireErrorMessage(false, EM_SysWarn055, "SINO Sports board Key pressed error"); break; case (UINT8)EM_SysWarn057: //脚踏开关自检未完成时被踩下报警 FireErrorMessage(true, nCode, "SINO footwitch Stepped down error"); break; case (UINT8)EM_SysWarn058: //解除脚踏开关自检未完成时被踩下报警 FireErrorMessage(false, EM_SysWarn057, "SINO footwitch Stepped down error"); break; case (UINT8)EM_SysWarn059: //旋转运动二次限位保护开关触发报警 FireErrorMessage(true, nCode, "SINO Rotational board second limit Trigger touch off error"); break; case (UINT8)EM_SysWarn060: //旋转运动二次限位保护开关触发报警解除 FireErrorMessage(false, EM_SysWarn059, "SINO Rotational board second limit Trigger touch off error"); break; case (UINT8)EM_SysWarn061: //C臂旋转方向控制引脚失效报警 FireErrorMessage(true, nCode, "SINO C-arm rotation direction control pin failure error"); break; case (UINT8)EM_SysWarn062: //解除C臂旋转方向控制引脚失效报警 FireErrorMessage(false, EM_SysWarn061, "SINO C-arm rotation direction control pin failure error"); break; case (UINT8)EM_SysWarn063: //C臂旋转或者升降按键在自检未完成时按下报警 FireErrorMessage(true, nCode, "SINO C-arm rotation button pressed error"); break; case (UINT8)EM_SysWarn064: //解除C臂旋转或者升降按键在自检未完成时按下报警 FireErrorMessage(false, EM_SysWarn063, "SINO C-arm rotation button pressed error"); break; case (UINT8)EM_SysWarn065: //C臂旋转电机驱动器报警 FireErrorMessage(true, nCode, "SINO C-arm rotation motor driver error"); break; case (UINT8)EM_SysWarn066: //解除C臂旋转电机驱动器报警 FireErrorMessage(false, EM_SysWarn065, "SINO C-arm rotation motor driver error"); break; case (UINT8)EM_SysWarn067: //C臂电机位置超差报警 FireErrorMessage(true, nCode, "SINO C-arm motor position out of tolerance error"); break; case (UINT8)EM_SysWarn068: //解除C臂电机位置超差报警 FireErrorMessage(false, EM_SysWarn067, "SINO C-arm motor position out of tolerance error"); break; case (UINT8)EM_SysWarn069: //升降运动二次限位保护开关触发报警 FireErrorMessage(true, nCode, "SINO lifting board second limit Trigger touch off error"); break; case (UINT8)EM_SysWarn070: //升降运动二次限位保护开关触发报警解除 FireErrorMessage(false, EM_SysWarn069, "SINO lifting board second limitTrigger touch off error"); break; case (UINT8)EM_SysWarn071: //升降电机方向控制引脚失效报警 FireErrorMessage(true, nCode, "SINO Lift motor direction control pin failure error"); break; case (UINT8)EM_SysWarn072: //解除升降电机方向控制引脚失效报警 FireErrorMessage(false, EM_SysWarn071, "SINO Lift motor direction control pin failure error"); break; case (UINT8)EM_SysWarn073: //机架升降电机驱动器报警 FireErrorMessage(true, nCode, "SINO Rack lifting motor driver error"); break; case (UINT8)EM_SysWarn074: //解除机架升降电机驱动器报警 FireErrorMessage(false, EM_SysWarn073, "SINO Rack lifting motor driver error"); break; case (UINT8)EM_SysWarn075: //升降电机位置超差报警 FireErrorMessage(true, nCode, "SINO Lift motor position out of tolerance error"); break; case (UINT8)EM_SysWarn076: //解除升降电机位置超差报警 FireErrorMessage(false, EM_SysWarn075, "SINO Lift motor position out of tolerance error"); break; case (UINT8)EM_SysWarn077: //角度校准板失效报警 FireErrorMessage(true, nCode, "SINO Angle calibration board failure error"); break; case (UINT8)EM_SysWarn078: //解除角度校准板失效报警 FireErrorMessage(false, EM_SysWarn077, "SINO Angle calibration board failure error"); break; case (UINT8)EM_SysWarn096: //压迫器运动二次限位保护开关触发 FireErrorMessage(true, nCode, "SINO Compressor board second limit Trigger touch off error"); break; case (UINT8)EM_SysWarn097: //压迫器运动二次限位保护开关触发解除 FireErrorMessage(false, EM_SysWarn096, "SINO Compressor board second limit Trigger touch off error"); break; case (UINT8)EM_SysWarn098: //压迫器方向控制引脚失效 FireErrorMessage(true, nCode, "SINO Compressor direction control pin failure error"); break; case (UINT8)EM_SysWarn099: //解除压迫器方向控制引脚失效 FireErrorMessage(false, EM_SysWarn098, "SINO Compressor direction control pin failure error"); break; case (UINT8)EM_SysWarn100: //压迫器升降电机驱动器报警 FireErrorMessage(true, nCode, "SINO Compressor lifting motor driver error"); break; case (UINT8)EM_SysWarn101: //解除压迫器升降电机驱动器报警 FireErrorMessage(false, EM_SysWarn100, "SINO Compressor lifting motor driver error"); break; case (UINT8)EM_SysWarn102: //开机检测到压力报错 FireErrorMessage(true, nCode, "SINO Pressure detected during startup error"); break; case (UINT8)EM_SysWarn103: //解除开机检测到压力报错 FireErrorMessage(false, EM_SysWarn102, "SINO Pressure detected during startup error"); break; case (UINT8)EM_SysWarn104: //压力传感器故障报警Pressure Sensor ERROR FireErrorMessage(true, nCode, "SINO pressure sensor failure error"); break; case (UINT8)EM_SysWarn105: //解除压力传感器故障报警 FireErrorMessage(false, EM_SysWarn104, "SINO pressure sensor failure error"); break; case (UINT8)EM_SysWarn106: //压迫器电机位置超差报警 FireErrorMessage(true, nCode, "SINO Compressor motor position out of tolerance error"); break; case (UINT8)EM_SysWarn107: //解除压迫器电机位置超差报警 FireErrorMessage(false, EM_SysWarn106, "SINO Compressor motor position out of tolerance error"); break; case (UINT8)EM_SysWarn108: //压迫器高度过低时插入放大架报警 FireErrorMessage(true, nCode, "SINO Insert amplifier when compressor is too low error"); break; case (UINT8)EM_SysWarn109: //解除压迫器高度过低时插入放大架报警 FireErrorMessage(false, EM_SysWarn108, "SINO Insert amplifier when compressor is too low error"); break; case (UINT8)EM_SysWarn110: //远端压迫器自动释放按钮被开机时按下报警 FireErrorMessage(true, nCode, "SINO Press remote compressor automatic release button when turned on error"); break; case (UINT8)EM_SysWarn111: //解除远端压迫器自动释放按钮被开机时按下报警 FireErrorMessage(false, EM_SysWarn110, "SINO Press remote compressor automatic release button when turned on error"); break; case (UINT8)EM_SysWarn112: //压力超限报警 FireErrorMessage(true, nCode, "SINO Pressure exceeding limit error"); break; case (UINT8)EM_SysWarn113: //解除压力超限报警 FireErrorMessage(false, EM_SysWarn112, "SINO Pressure exceeding limit error"); break; case (UINT8)EM_SysWarn128: //滤线栅控制电路错误 FireErrorMessage(true, nCode, "SINO Filter grid control circuit error"); break; case (UINT8)EM_SysWarn129: //解除滤线栅电路错误 FireErrorMessage(false, EM_SysWarn128, "SINO Filter grid control circuit error"); break; case (UINT8)EM_SysWarn152: //准直器滤片切换超时报警 FireErrorMessage(true, nCode, "SINO Collimator filter switching timeout error"); break; case (UINT8)EM_SysWarn153: //解除准直器滤片切换超时报警 FireErrorMessage(false, EM_SysWarn152, "SINO Collimator filter switching timeout error"); break; case (UINT8)EM_SysWarn154: //准直器摄野调节超时报警 FireErrorMessage(true, nCode, "SINO Collimator field adjustment timeout error"); break; case (UINT8)EM_SysWarn155: //解除准直器摄野调节超时报警 FireErrorMessage(false, EM_SysWarn154, "SINO Collimator field adjustment timeout error"); break; case (UINT8)EM_SysWarn156: //准直器存储器读数据错误报警 FireErrorMessage(true, nCode, "SINO Collimator memory read data error error"); break; case (UINT8)EM_SysWarn157: //解除准直器存储器读数据错误报警 FireErrorMessage(false, EM_SysWarn156, "SINO Collimator memory read data error error"); break; case (UINT8)EM_SysWarn161: //曝光控制板通信异常 case (UINT8)EM_SysWarn162: //压迫器控制板通信异常 case (UINT8)EM_SysWarn163: //准直器控制板通信异常 case (UINT8)EM_SysWarn165: //底座显示板通信异常 case (UINT8)EM_SysWarn166: //远端控制盒通信异常 FireErrorMessage(true, nCode, "SINO Abnormal communication error"); break; case (UINT8)EM_SysWarn168: //解除通信报警 FireErrorMessage(false, 0, "SINO Abnormal communication error"); break; default: mLog::Error("==CallbackSystemWarn==: unKnown Wraning: [{$}]", nCode); } }; auto CommunicationInquiry = [this](const char* value, int length) -> void { SINOCommand ComInquiry(value); int nStatus = ComInquiry.GetAt(5); if (nStatus == EM_ComInquiry_PowerOn) { mLog::Debug("Request Status_1:GENSTATE {$} -> STATUS_STANDBY", m_DoseUnit.m_GenState->JSGet()); m_DoseUnit.m_GenState->Update(nsGEN::AttrKey::GENERATOR_STATUS_STANDBY); FireNotify(AttrKey::GENSTATE, m_DoseUnit.m_GenState->JSGet()); } else if(nStatus == EM_ComInquiry_handshake) { std::unique_lock uqeHeartBeat(mtxHeartBeats); //心跳包统计清空 m_iHeartBeats = 0; uqeHeartBeat.unlock(); } mLog::Debug("==CommunicationInquiry==: status[{$}]", nStatus); }; //服务模式:用于修改并读取非通用值, 不是正常操作的一部分.仅用于系统测试和设备维修 //暂不使用 arFrame.clear(); //命令模式:用于正常操作 arFrame.push_back(tFrameMapping("ACK",3, CallbackACK)); arFrame.push_back(tFrameMapping(SINO_ExpoParam, CallbackExpoParam)); arFrame.push_back(tFrameMapping(SINO_RackPosition,CallbackPosition)); arFrame.push_back(tFrameMapping(SINO_Compressor, CallbackCompressor)); arFrame.push_back(tFrameMapping(SINO_Collimator, CallbackCollimator)); arFrame.push_back(tFrameMapping(SINO_ExpoParam, CallbackExposureParam)); arFrame.push_back(tFrameMapping(SINO_TubeHeat, CallbackHu)); arFrame.push_back(tFrameMapping(SINO_DataFeedback, CallbackQueryStatus)); arFrame.push_back(tFrameMapping(SINO_PostFeedback, CallbackPostExposure)); arFrame.push_back(tFrameMapping(SINO_SystemStatus, CallbackSystemStatus)); arFrame.push_back(tFrameMapping(SINO_SystemWarning, CallbackSystemWarn)); arFrame.push_back(tFrameMapping(SINO_ComInquiry, CommunicationInquiry)); //服务模式:用于修改并读取非通用值, 不是正常操作的一部分.仅用于系统测试和设备维修,暂不添加 } void nsGEN::SINODevice::ReConnect() { mLog::Info("enter reconnect"); m_SCF.Disconnect(); ResDataObject Connection = m_GenConfig["connections"][0]; mLog::Info("Reconnections:{$} \n", Connection.encode()); auto erCode = m_SCF.Connect(Connection.encode(), &nsGEN::SINODriver::callbackPackageProcess, SCF_PACKET_TRANSFER, 3000); if (erCode == SCF_ERR::SCF_SUCCEED) { FireErrorMessage(false, 1, "lost Connect"); std::unique_lock uqeConnectFlag(mtxConnectFlag); m_bConnectFlag = true; uqeConnectFlag.unlock(); mLog::Info("reconnect success"); } else { mLog::Info("reconnect failed"); } } bool nsGEN::SINODevice::StartHardwareStatusThread() { mLog::Info("enter Start HardwareStatus Thread "); if (m_pHardwareStatusThread == NULL) { DWORD m_HardwareStatusID; m_pHardwareStatusThread = CreateThread(0, 0, HardwareStatusThread, this, 0, &m_HardwareStatusID); if (m_pHardwareStatusThread == NULL) { mLog::Error("Start HardwareStatus Thread Failed"); return false; } } return true; } DWORD nsGEN::SINODevice::HardwareStatusThread(LPVOID pParam) { SINODevice* pCurGen = (SINODevice*)pParam; if (pCurGen == NULL) { return false; } mLog::Info("HardwareStatusThread start"); int iloopingFlag = 0; if ((int)pCurGen->m_GenConfig["loopEnable"] >= 1) { iloopingFlag = (int)pCurGen->m_GenConfig["loopEnable"]; } if ((int)pCurGen->m_GenConfig["loopTime"] >= 100) { pCurGen->m_iLoopTime = (int)pCurGen->m_GenConfig["loopTime"]; } mLog::Info("loopEnable = {$},loopTime = {$}", iloopingFlag, pCurGen->m_iLoopTime); int currtTime = pCurGen->m_iLoopTime; SINOCommand strHBCmd(SINO_ComInquiry, SINO_TYPE_SEND, 7); strHBCmd.SetAt(5, EM_ComInquiry_handshake); pCurGen->HWSend(strHBCmd); Sleep(currtTime); while (iloopingFlag == 1) { std::unique_lock uqeConnectFlag(pCurGen->mtxConnectFlag); //判断是否断连 if (!(pCurGen->m_bConnectFlag)) { uqeConnectFlag.unlock(); mLog::Info("SINOGEN: not Connect,try to reconnect \n"); pCurGen->FireErrorMessage(true, 1, "lost Connect"); pCurGen->ReConnect(); Sleep(20000); continue; } uqeConnectFlag.unlock(); std::unique_lock uqeTime(pCurGen->mtxTime); //读取循环时间 mLog::Debug("currtloopTime = {$}", pCurGen->m_iLoopTime); currtTime = pCurGen->m_iLoopTime; uqeTime.unlock(); Sleep(currtTime); pCurGen->HWSend(strHBCmd); //轮询发生器相关数据信息 std::unique_lock uqeHeartBeat(pCurGen->mtxHeartBeats); //心跳包统计加1 pCurGen->m_iHeartBeats++; int tempHeartBeat = pCurGen->m_iHeartBeats; uqeHeartBeat.unlock(); if (tempHeartBeat > 10) //无返回信息认为连接断开 { uqeHeartBeat.lock(); pCurGen->m_iHeartBeats = 0; uqeHeartBeat.unlock(); mLog::Info("SINOGEN: lost Connect \n"); uqeConnectFlag.lock(); pCurGen->m_bConnectFlag = false; uqeConnectFlag.unlock(); } } mLog::Info("HardwareStatusThread stop"); return true; } //----------------------------------------------------------------------------- // SINODriver //----------------------------------------------------------------------------- nsGEN::SINODriver::SINODriver() { m_pAttribute.reset(new ResDataObject()); m_pDescription.reset(new ResDataObject()); m_pDriGenDev = nullptr; m_pDriMechDev = nullptr; m_pDriCollDev = nullptr; } nsGEN::SINODriver::~SINODriver() { mLog::Close(); mLog::gLogger = nullptr; if (m_pDriGenDev) { delete m_pDriGenDev; m_pDriGenDev = nullptr; } if (m_pDriMechDev) { delete m_pDriMechDev; m_pDriMechDev = nullptr; } if (m_pDriCollDev) { delete m_pDriCollDev; m_pDriCollDev = nullptr; } } void nsGEN::SINODriver::Prepare() { ResDataObject r_config; if (r_config.loadFile(m_ConfigFileName.c_str())) { if ((int)r_config["CONFIGURATION"]["logEnable"] == 1) { string strLogPath = GetProcessDirectory() + R"(\OEMDrivers\Generator\Conf\Log4CPP.Config.GEN.xml)"; //Log4CPP::ThreadContext::Map::Set("LogFileName", "GEN.SINO"); Log4CPP::GlobalContext::Map::Set(ECOM::Utility::Hash("LogFileName"), "GEN.SINO"); auto rc = Log4CPP::LogManager::LoadConfigFile(strLogPath.c_str()); mLog::gLogger = Log4CPP::LogManager::GetLogger("GEN.SINO"); } m_SCFDllName = GetConnectDLL(m_ConfigFileName); } super::Prepare(); } std::string nsGEN::SINODriver::DriverProbe() { ResDataObject r_config, HardwareInfo; if (r_config.loadFile(m_ConfigFileName.c_str())) { HardwareInfo.add("MajorID", r_config["CONFIGURATION"]["MajorID"]); HardwareInfo.add("MinorID", r_config["CONFIGURATION"]["MinorID"]); HardwareInfo.add("VendorID", r_config["CONFIGURATION"]["VendorID"]); HardwareInfo.add("ProductID", r_config["CONFIGURATION"]["ProductID"]); HardwareInfo.add("SerialID", r_config["CONFIGURATION"]["SerialID"]); } else { HardwareInfo.add("MajorID", "Generator"); HardwareInfo.add("MinorID", "Dr"); HardwareInfo.add("VendorID", "SINO"); HardwareInfo.add("ProductID", "HF"); HardwareInfo.add("SerialID", "Drv"); } string ret = HardwareInfo.encode(); return ret; } bool DATA_ACTION nsGEN::SINODriver::Connect() { ResDataObject Connection = GetConnectParam(m_ConfigFileName); mLog::Info("connections:{$} \n", Connection.encode()); auto erCode = m_SCF.Connect(Connection.encode(), &nsGEN::SINODriver::callbackPackageProcess, SCF_PACKET_TRANSFER, 3000); if (erCode != SCF_ERR::SCF_SUCCEED) return false; auto rc = super::Connect(); if (!rc) return false; //return (erCode == SCF_ERR::SCF_SUCCEED); return true; } auto nsGEN::SINODriver::CreateDevice(int index) -> std::unique_ptr { mLog::Info("Enter CreateDevice, index={$}", index); if (!m_SCF.isConnected()) { mLog::Warn("CreateDevice:not Connected"); return nullptr; } if (index == 0) { m_pDriGenDev = new SINODevice(EventCenter, m_SCF, m_ConfigFileName); auto dev = std::unique_ptr(new IODevice(m_pDriGenDev)); return dev; } else if (index == 1) { mLog::Info("Enter CreateDevice Mechanical"); m_pDriMechDev = new OemMechanical(std::shared_ptr(new IOEventCenter()), 0, 1, 2, 31, 32, 33, 34, 35, 36, 4, 5); auto dev = std::unique_ptr (new IODevice(m_pDriMechDev)); m_pDriMechDev->SetCtrlDev(m_pDriGenDev); m_pDriGenDev->SetMechDev(m_pDriMechDev); mLog::Info("Leave CreateDevice Mechanical"); return dev; } else if (index == 2) { mLog::Info("Enter CreateDevice Collimator"); m_pDriCollDev = new OemCollimator(std::shared_ptr(new IOEventCenter()), 40, 50, 6, 7, 8, 1); auto dev = std::unique_ptr (new IODevice(m_pDriCollDev)); m_pDriCollDev->SetCtrlDev(m_pDriGenDev); m_pDriGenDev->SetCollimatorDev(m_pDriCollDev); mLog::Info("Leave CreateDevice Collimator"); return dev; } } void nsGEN::SINODriver::FireNotify(int code, std::string key, std::string content) { EventCenter->OnNotify(code, key, content); } bool nsGEN::SINODriver::isConnected() const { return super::isConnected(); } std::string nsGEN::SINODriver::GetResource() { ResDataObject r_config, temp; if (!temp.loadFile(m_ConfigFileName.c_str())) { return ""; } m_ConfigAll = temp; r_config = temp["CONFIGURATION"]; m_Configurations = r_config; ResDataObject DescriptionTemp; ResDataObject DescriptionSend; ResDataObject m_DescriptionSend; ResDataObject ListTemp; string strTemp = ""; //用于读取字符串配置信息 string strIndex = ""; //用于读取配置信息中的List项 int nTemp = -1; //用于读取整型配置信息 char sstream[10] = { 0 }; //用于转换值 string strValue = ""; //用于存储配置的值 string strType = ""; //用于存储配置的类型 int/float/string... /*** * 1. 通过循环,将所有配置项写到pDeviceConfig * 2. 记录配置项的内部key以及配置类型,类型对应了不同配置文件路径,用于读写真实值 ***/ try { //便利ConfigToolInfo 中 所有的AttributeInfo 属性段 int nConfigInfoCount = (int)m_Configurations["ConfigToolInfo"].GetKeyCount("AttributeInfo"); m_pAttribute->clear(); m_pDescription->clear(); for (int nInfoIndex = 0; nInfoIndex < nConfigInfoCount; nInfoIndex++) { DescriptionTemp.clear(); DescriptionSend.clear(); ListTemp.clear(); //AttributeType strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeDescripition"]["Type"]; DescriptionTemp.add(ConfKey::CcosType, strTemp.c_str());//CcosGeneratorAttribute DescriptionSend.add(ConfKey::CcosType, strTemp.c_str());//CcosGeneratorAttribute strType = strTemp; //记录配置项的类型 //AttributeKey //1. 根据AttributeType,内部key和配置路径,拿到当前的真实值 strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["InnerKey"]; nTemp = (int)m_Configurations["ConfigToolInfo"][nInfoIndex]["PathID"]; GetDeviceConfigValue(r_config, strTemp.c_str(), nTemp, strValue); //得到strValue的值 //printf("********************************innerkey=%s --strValue = %s\n", strTemp.c_str(), strValue.c_str()); //2. 赋值 strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeKey"]; if ("int" == strType) { (*m_pAttribute).add(strTemp.c_str(), atoi(strValue.c_str())); } else if ("float" == strType) { (*m_pAttribute).add(strTemp.c_str(), atoi(strValue.c_str())); } else //其它先按string类型处理 { (*m_pAttribute).add(strTemp.c_str(), strValue.c_str()); } //printf("********************************outkey =%s --strValue = %s\n", strTemp.c_str(), strValue.c_str()); //AttributeAccess strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeDescripition"]["Access"]; DescriptionTemp.add(ConfKey::CcosAccess, strTemp.c_str()); DescriptionSend.add(ConfKey::CcosAccess, strTemp.c_str()); /* //AttributeRangeMin strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeDescripition"]["RangeMin"]; if (strTemp != "") //不需要的配置项为空 { DescriptionTemp.add(ConfKey::CcosRangeMin, strTemp.c_str()); } //AttributeRangeMax strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeDescripition"]["RangeMax"]; if (strTemp != "") //不需要的配置项为空 { DescriptionTemp.add(ConfKey::CcosRangeMax, strTemp.c_str()); } */ //AttributeList nTemp = m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeDescripition"]["ListNum"]; if (nTemp > 0) //ListNum不大于0时说明不需要list配置 { for (int nListIndex = 0; nListIndex < nTemp; nListIndex++) { strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeDescripition"]["ListInfo"][nListIndex]; auto temKey = std::to_string(nListIndex); ListTemp.add(temKey.c_str(), strTemp.c_str()); } DescriptionTemp.add(ConfKey::CcosList, ListTemp); DescriptionSend.add(ConfKey::CcosList, ListTemp.encode()); } //AttributeRequired strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeDescripition"]["Required"]; DescriptionTemp.add(ConfKey::CcosRequired, strTemp.c_str()); DescriptionSend.add(ConfKey::CcosRequired, strTemp.c_str()); //AttributeDefaultValue strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeDescripition"]["DefaultValue"]; if (strTemp != "") //不需要的配置项为空 { DescriptionTemp.add(ConfKey::CcosDefaultValue, strTemp.c_str()); DescriptionSend.add(ConfKey::CcosDefaultValue, strTemp.c_str()); } strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeKey"]; (*m_pDescription).add(strTemp.c_str(), DescriptionTemp); m_DescriptionSend.add(strTemp.c_str(), DescriptionSend.encode()); } } catch (ResDataObjectExption& e) { mLog::Error("Get config error: {$}", e.what()); return ""; } ResDataObject resDeviceResource; resDeviceResource.add(ConfKey::CcosGeneratorAttribute, (*m_pAttribute)); resDeviceResource.add(ConfKey::CcosGeneratorDescription, (*m_pDescription)); ResDataObject DescriptionTempEx; DescriptionTempEx.add(ConfKey::CcosGeneratorConfig, resDeviceResource); m_DeviceConfig.clear(); m_DeviceConfig = DescriptionTempEx; //mLog::Debug("local ************* get resource over {$}", DescriptionTempEx.encode()); //printf("local ************* get resource over %s \n", DescriptionTempEx.encode()); resDeviceResource.clear(); resDeviceResource.add(ConfKey::CcosGeneratorAttribute, (*m_pAttribute)); resDeviceResource.add(ConfKey::CcosGeneratorDescription, m_DescriptionSend); DescriptionTempEx.clear(); DescriptionTempEx.add(ConfKey::CcosGeneratorConfig, resDeviceResource); m_DeviceConfigSend.clear(); m_DeviceConfigSend = DescriptionTempEx; string res = m_DeviceConfigSend.encode(); //printf("%s", res.c_str()); //mLog::Debug("get resource over {$}", DescriptionTempEx.encode()); //printf("************* get resource over %s \n", DescriptionTempEx.encode()); return res; } std::string nsGEN::SINODriver::DeviceProbe() { ResDataObject r_config, HardwareInfo; if (r_config.loadFile(m_ConfigFileName.c_str())) { HardwareInfo.add("MajorID", r_config["CONFIGURATION"]["MajorID"]); HardwareInfo.add("MinorID", r_config["CONFIGURATION"]["MinorID"]); HardwareInfo.add("VendorID", r_config["CONFIGURATION"]["VendorID"]); HardwareInfo.add("ProductID", r_config["CONFIGURATION"]["ProductID"]); HardwareInfo.add("SerialID", r_config["CONFIGURATION"]["SerialID"]); } else { HardwareInfo.add("MajorID", "Generator"); HardwareInfo.add("MinorID", "Dr"); HardwareInfo.add("VendorID", "SINO"); HardwareInfo.add("ProductID", "HF"); HardwareInfo.add("SerialID", "Dev"); } string ret = HardwareInfo.encode(); return ret; } void nsGEN::SINODriver::Disconnect() { super::Disconnect(); m_SCF.Disconnect(); mLog::Close(); mLog::gLogger = nullptr; } void nsGEN::SINODriver::Dequeue(const char* Packet, DWORD Length) { DecodeFrame(Packet, Length); } PACKET_RET nsGEN::SINODriver::callbackPackageProcess(const char* RecData, DWORD nLength, DWORD& PacketLength) { #if 0 if (nLength > 1) { mLog::Error("receive data_len[{$}]", nLength); for (int i = 0; i < nLength; i++) { mLog::Debug("receive data[{$}][{$:x2}]", i, RecData[i]); } } #endif bool bHasHead = false; int iComdLengh = 7; if (nLength < 7) { PacketLength = 0; //printf("nLength too small, nLength==%d \n", nLength); mLog::Error("nLength too small, nLength=={$}", nLength); return PACKET_USELESS; } for (DWORD i = 0; i < nLength; i++) { //寻找包头 if ((UINT8)RecData[i]== SINO_WS_STX || (UINT8)RecData[i] == SINO_MU_STX) { if (i!=0) //包头之前的数据格式不对,全部扔掉 { SINOCommand strtemp(RecData); if (bHasHead) { if (i >= iComdLengh - 1) //正常指令 { mLog::Warn("==IN two head data ==:[{$}],UselessDataLength={$},TotalLength={$} \n", strtemp.Get_Hex_Log(), PacketLength, nLength); PacketLength = i + 1; return PACKET_ISPACKET; } } else { PacketLength = i; //char strtemp[SINO_Com_NormalLen] = { 0 }; //memcpy(strtemp, RecData, SINO_Com_NormalLen - 1); mLog::Error("==IN unknown format data ==:[{$}],UselessDataLength={$},TotalLength={$} \n", strtemp.Get_Hex_Log(), PacketLength, nLength); return PACKET_USELESS; } } else { bHasHead = true; } } if (bHasHead && i == 3) { iComdLengh = RecData[i]; } //寻找包尾 if ((UINT8)RecData[i] == SINO_WS_ETX || (UINT8)RecData[i] == SINO_MU_ETX) { if(bHasHead) { if (i >= iComdLengh-1) //正常指令 { PacketLength = i + 1; //+1 because ETX SINOCommand strtemp(RecData, i + 1); //全部数据 mLog::Info("==IN==:[{$}] \n", strtemp.Get_Hex_Log()); return PACKET_ISPACKET; } } else //有包尾但无包头 { PacketLength = i + 1; //char strtemp[SINO_Com_NormalLen] = { 0 }; //memcpy(strtemp, RecData, SINO_Com_NormalLen - 1); SINOCommand strtemp(RecData); mLog::Error("==IN no head data ==:[{$}],NoHeadDataLength={$},TotalLength={$} \n", strtemp.Get_Hex_Log(), PacketLength, nLength); return PACKET_USELESS; } } } if (bHasHead && nLength < SINO_Com_NormalLen) { PacketLength = 0; } if (nLength > SINO_Com_NormalLen) { PacketLength = nLength; mLog::Error("nLength too big, nLength=={$}", nLength); return PACKET_USELESS; } return PACKET_NOPACKET; } bool nsGEN::SINODriver::GetDeviceConfig(std::string& Cfg) { Cfg = m_DeviceConfigSend.encode(); printf("GetDeviceConfig over , %s", Cfg.c_str()); return true; } bool nsGEN::SINODriver::SetDeviceConfig(std::string Cfg) { mLog::Info("--Func-- SetDeviceConfig {$}\n", Cfg.c_str()); printf("\n--Func-- SetDeviceConfig %s\n", Cfg.c_str()); ResDataObject DeviceConfig; DeviceConfig.decode(Cfg.c_str()); ResDataObject DescriptionTempEx; DescriptionTempEx = DeviceConfig["DeviceConfig"]["Attribute"]; mLog::Debug("Attribute:{$}", DescriptionTempEx.encode()); bool bSaveFile = false; //true:重新保存配置文件 string strAccess = ""; for (int i = 0; i < DescriptionTempEx.size(); i++) { string strKey = DescriptionTempEx.GetKey(i); mLog::Info("{$}", strKey.c_str()); printf("%s\n", strKey.c_str()); try { if (m_pAttribute->GetFirstOf(strKey.c_str()) >= 0) { strAccess = (string)(*m_pDescription)[strKey.c_str()]["Access"]; if ("RW" == strAccess) { //修改对应配置,在其他单元的配置项要同时调用其修改函数修改真实值 //1. 修改内存中的值,用于给上层发消息 (*m_pAttribute)[strKey.c_str()] = DescriptionTempEx[i]; //2. 拿到Innerkey int nConfigInfoCount = (int)m_Configurations["ConfigToolInfo"].GetKeyCount("AttributeInfo"); mLog::Info("nConfigInfoCount {$}", nConfigInfoCount); string strTemp = ""; //存储AttributeKey for (int nInfoIndex = 0; nInfoIndex < nConfigInfoCount; nInfoIndex++) { strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeKey"]; if (strTemp == strKey) { strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["InnerKey"]; break; } } //3. 修改配置文件中的值 if (SetDeviceConfigValue(m_Configurations, strTemp.c_str(), 1, DescriptionTempEx[i])) { mLog::Debug("SetDeviceConfigValue over"); bSaveFile = true; } } else { mLog::Info("{$} is not a RW configuration item", strKey.c_str()); } } else { mLog::Info("without this attribute {$}", strKey.c_str()); } } catch (ResDataObjectExption& e) { printf("\nSetDriverConfig crashed: %s\n", e.what()); mLog::Error("SetDriverConfig crashed: {$}", e.what()); return false; } } if (bSaveFile) { //3. 重新保存配置文件 SaveConfigFile(true); } return true; } bool nsGEN::SINODriver::SaveConfigFile(bool bSendNotify) { m_ConfigAll["CONFIGURATION"] = m_Configurations; bool bRt = m_ConfigAll.SaveFile(m_ConfigFileName.c_str()); mLog::Info("SaveConfigFile over {$}", bRt); return true; } bool nsGEN::SINODriver::GetDeviceConfigValue(ResDataObject config, const char* pInnerKey, int nPathID, string& strValue) { strValue = ""; //return true;//暂时不需要 string strTemp = pInnerKey; if (1 == nPathID) //从DriverConfig路径下每个DPC自己的配置文件读取 { int pos = 0; ResDataObject resTemp = config; while ((pos = strTemp.find_first_of(',')) != string::npos) { string Key = strTemp.substr(0, pos); string TempValue = resTemp[Key.c_str()].encode(); // printf("-TempValue=== %s", TempValue.c_str()); resTemp.clear(); resTemp.decode(TempValue.c_str()); strTemp = strTemp.substr(pos + 1, strTemp.length() - pos - 1); //printf("-************--%s", strTemp.c_str()); } if (strTemp != "") { strValue = (string)resTemp[strTemp.c_str()]; } else { strValue = (string)resTemp; } } //printf("------------%s", strValue.c_str()); return true; } bool nsGEN::SINODriver::SetDeviceConfigValue(ResDataObject& config, const char* pInnerKey, int nPathID, const char* szValue) { //return true;//暂时不需要 string strTemp = pInnerKey; mLog::Debug("Begin to change {$} item value to {$}", pInnerKey, szValue); printf("\nbbbbbbbbbbbbbbBegin to change {%s} item value to {%s}\n", pInnerKey, szValue); if (1 == nPathID) //从DriverConfig路径下每个DPC自己的配置文件读取 { try { int pos = 0; ResDataObject* resTemp = &config; while ((pos = strTemp.find_first_of(',')) != string::npos) { string Key = strTemp.substr(0, pos); resTemp = &(*resTemp)[Key.c_str()]; strTemp = strTemp.substr(pos + 1, strTemp.length() - pos - 1); } if (strTemp != "") { //if ((strTemp.compare("WSTable") == 0) || // (strTemp.compare("WSWall") == 0) || // (strTemp.compare("WSFree") == 0) || // (strTemp.compare("WSTomo") == 0) || // (strTemp.compare("WSConventional") == 0) // ) //{ // int sum = (*szValue) + 1; // (*resTemp)[strTemp.c_str()] = (char*)(&sum); //} //else // (*resTemp)[strTemp.c_str()] = szValue; (*resTemp)[strTemp.c_str()] = szValue; } else { *resTemp = szValue; } } catch (ResDataObjectExption& e) { mLog::Error("SetDriverConfigvalue crashed: {$}", e.what()); return false; } } return true; } //----------------------------------------------------------------------------- // GetIODriver & CreateIODriver //----------------------------------------------------------------------------- static nsGEN::SINODriver gIODriver; extern "C" CCOS::Dev::IODriver * __cdecl GetIODriver() // 返回静态对象的引用, 调用者不能删除 ! { return &gIODriver; } extern "C" CCOS::Dev::IODriver * __cdecl CreateIODriver() // 返回新对象, 调用者必须自行删除此对象 ! { return new nsGEN::SINODriver(); }