DIOS.Dev.Mech.OTCStitch.cpp 60 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886
  1. #include "stdafx.h"
  2. #include <assert.h>
  3. #include "Helper.JSON.hpp"
  4. #include "DIOS.Dev.Mech.OTCStitch.hpp"
  5. using namespace DIOS::Dev;
  6. using namespace DIOS::Dev::Detail::MECH;
  7. namespace nsMech = DIOS::Dev::Detail::MECH;
  8. //关闭无关警告
  9. #pragma warning (disable:4244) // warning C4244: “初始化”: 从“double”转换到“float”,可能丢失数据
  10. #pragma warning (disable:4305) // warning C4305: “参数”: 从“double”到“float”截断
  11. #pragma warning (disable:4267) // warning C4267 : “初始化”: 从“size_t”转换到“int”,可能丢失数据
  12. #pragma warning (disable:4805) // warning C4805: “!=”: 在操作中将类型“bool”与类型“int”混合不安全
  13. //设置相关常量
  14. #define OTCStitch_TIMEOUTVALUE 100
  15. #define OTCStitch_LoopDefHBTime 1000
  16. #define OTCStitch_LoopExpHBTime 500
  17. static const int msTimeOut_Lock = 200; //通讯接口锁定时间
  18. #define OTCStitch_Com_NormalLen 150
  19. #define OTCStitch_STX 0x02
  20. #define OTCStitch_NAK 0x15
  21. #define OTCStitch_ETX 0x03
  22. Log4CPP::Logger* mLog::gLogger = nullptr;
  23. //-----------------------------------------------------------------------------
  24. // OTCStitchDevice
  25. //-----------------------------------------------------------------------------
  26. struct tFrameMapping
  27. {
  28. static const int MaxLen = 5; // 前缀不能超超过 5 个字符 !
  29. using cbFun = std::function <void(const char*, int)>;
  30. char strHead[MaxLen];
  31. int NbOfCharOfHead;
  32. cbFun fun;
  33. tFrameMapping(char* str, int len, cbFun f)
  34. {
  35. assert(len < MaxLen); //len最大只能是4
  36. for (int i = 0; i < len; i++)
  37. strHead[i] = str[i];
  38. NbOfCharOfHead = len;
  39. fun = f;
  40. }
  41. };
  42. static std::list <tFrameMapping> arFrame;
  43. static bool DecodeFrame(const char* strFrame, int length)
  44. {
  45. auto pr = [strFrame, length](const tFrameMapping& Item)
  46. {
  47. for (int i = 0; i < Item.NbOfCharOfHead; i++)
  48. {
  49. if (strFrame[i] != Item.strHead[i])
  50. {
  51. return false;
  52. }
  53. }
  54. return true;
  55. };
  56. auto found = std::find_if(arFrame.begin(), arFrame.end(), pr);//此处pr,是上面定义的 lambda表达式,用来在list中找到对于的包头。
  57. if (found == arFrame.end())
  58. {
  59. return false;
  60. }
  61. const auto& Item = *found;
  62. auto pc = strFrame;
  63. char data[100] = { 0 };
  64. memcpy(data, strFrame + Item.NbOfCharOfHead, length - Item.NbOfCharOfHead);
  65. Item.fun(data, length - Item.NbOfCharOfHead);//第二个参数 不重要
  66. return true;
  67. }
  68. nsMech::OTCStitchDevice::OTCStitchDevice(std::shared_ptr <IOEventCenter> center, nsSCF::SCF SCF, string configfile /*= ""*/):super(center, SCF)
  69. {
  70. string version;
  71. if (GetVersion(version, hMyModule))
  72. mLog::Info("\n===============log begin : version:{$} ===================\n", version.c_str());
  73. else
  74. mLog::Info("\n===============log begin : version:0.0.0.0 ===================\n");
  75. ResDataObject Conftemp;
  76. if (!configfile.empty())
  77. {
  78. Conftemp.loadFile(configfile.c_str());
  79. m_GenConfig = Conftemp["CONFIGURATION"];
  80. TransJsonText(m_GenConfig);
  81. }
  82. //m_MECHUnit.m_ViewID.reset(new VIEWIDMould(0, 0, 10, 1));
  83. //m_MECHUnit.m_GridState.reset(new GRIDSTATEMould(AttrKey::Grid_Noinformation, AttrKey::Grid_Noinformation, AttrKey::Grid_OUT_CHANGE, 1));
  84. //m_MECHUnit.m_GridType.reset(new GRIDTYPEMould(AttrKey::Grid_No, AttrKey::Grid_No, AttrKey::Grid_1500, 1));
  85. //m_MECHUnit.m_GridOrientation.reset(new GRIDORIENTATIONMould(AttrKey::Grid_Vertical, AttrKey::Grid_Vertical, AttrKey::Grid_Horizontal, 1));
  86. //m_MECHUnit.m_TID.reset(new TIDMould(0, 0, 10000, 1));
  87. //m_MECHUnit.m_SOD.reset(new SODMould(0, 0, 10000, 1));
  88. //m_MECHUnit.m_ENTRANCE.reset(new ENTRANCEMould(0, 0, 10000, 1));
  89. m_strcurrentcmd = "";
  90. m_bStitchingInProgress = false;
  91. m_nCurrentImage = 0;
  92. m_nImageCount = 0;
  93. m_MECHUnit.m_StitchingState.reset(new StitchingStateMould(AttrKey::STITCHSTATE_INIT, AttrKey::STITCHSTATE_ERR, AttrKey::STITCHSTATE_RESTART, 1));
  94. m_MECHUnit.m_KV.reset(new KVMould(0.0, 40.0, 120.0, 1.0));
  95. m_MECHUnit.m_MA.reset(new MAMould(0.0, 1.0, 1000.0, 0.1));
  96. m_MECHUnit.m_MS.reset(new MSMould(0.0, 1.0, 10000.0, 0.01));
  97. m_MECHUnit.m_MAS.reset(new MASMould(0.0, 0.5, 1000.0, 0.01));
  98. m_MECHUnit.m_Techmode.reset(new TECHMODEMould(AttrKey::TECHMODE_NOAEC_3P, AttrKey::TECHMODE_NOAEC_3P, AttrKey::TECHMODE_AEC_MAS_MA, 1));
  99. m_MECHUnit.m_WS.reset(new WORKSTATIONMould(1, 0, 5, 1));
  100. m_MECHUnit.m_Focus.reset(new FOCUSMould(AttrKey::FOCUS_TYPE::FOCUS_LARGE, AttrKey::FOCUS_SMALL, AttrKey::FOCUS_LARGE, 1));
  101. m_MECHUnit.m_AECField.reset(new AECFIELDMould(0, 0, 111, 1));
  102. //stitching parameter
  103. m_MECHUnit.m_StitchHeight.reset(new StitchHeightMould(0, 0, 1000, 1));
  104. m_MECHUnit.m_StitchLength.reset(new StitchLengthMould(0, 0, 1000, 1));
  105. m_MECHUnit.m_StitchOverLap.reset(new StitchOverLapMould(0, 0, 1000, 1));
  106. m_MECHUnit.m_SID.reset(new SIDMould(0, 0, 10000, 1));
  107. m_MECHUnit.m_StitchPID.reset(new StitchPIDMould(0, 0, 1000, 1));
  108. m_MECHUnit.m_StitchDirection.reset(new StitchDirectionMould(AttrKey::STITCHDIR_TopToBottom, AttrKey::STITCHDIR_TopToBottom, AttrKey::STITCHDIR_RightToLeft, 1));
  109. m_MECHUnit.m_StitchType.reset(new StitchTypeMould(AttrKey::STITCHTYPE_AutomaticTranslation, AttrKey::STITCHTYPE_AutomaticTranslation, AttrKey::STITCHTYPE_ManualAngle, 1));
  110. m_MECHUnit.m_StitchStepLength.reset(new StitchStepLengthMould(0, 0, 1000, 1));
  111. //normal parameter
  112. m_MECHUnit.m_FID.reset(new FIDMould(0, 0, 10000, 1));
  113. m_MECHUnit.m_TubeAngle.reset(new TubeAngleMould(0, -180, 180, 1));
  114. m_MECHUnit.m_FPDPosition.reset(new FPDPositionMould(0, 0, 100, 1));
  115. m_MECHUnit.m_PatientSize.reset(new PATIENTSIZEMould(0, 0, 10, 1));
  116. m_MECHUnit.m_PostionNumber.reset(new POSITIONNUMBERMould(0, 0, 10000, 1));
  117. m_Collimator.fHeight = 0;
  118. m_Collimator.fWidth = 0;
  119. m_MSGUnit.reset(new nsDetail::MSGUnit(center, MechUnitType));
  120. Delivermodule.InitSendModle(this ,&ProcessClientData, WriteLog);
  121. Delivermodule.SetPriority(1, false, 150, false); //type=1时,需要等ACK
  122. if (m_GenConfig.GetKeyCount("ConvertFlag") > 0)
  123. m_ConvertFlag = (int)m_GenConfig["ConvertFlag"];
  124. else
  125. m_ConvertFlag = 0;
  126. if (m_GenConfig.GetKeyCount("OTCType") > 0)
  127. m_strOTCType = (string)m_GenConfig["OTCType"];
  128. else
  129. m_strOTCType = "";
  130. //配置响应操作对照表
  131. OnCallBack();
  132. //将机架可以对外提供的指令注册集进行补充
  133. Register();
  134. /*2023 new add:表示初始化完成。*/
  135. string strcommand = "INI";
  136. FormatCommand(strcommand);
  137. Delivermodule.ProcessCommand(strcommand, 1);
  138. }
  139. nsMech::OTCStitchDevice::~OTCStitchDevice()
  140. {
  141. //关闭之前,发送退出指令至机架
  142. mLog::Debug("Send EXIT");
  143. string strcommand = "GEX";
  144. FormatCommand(strcommand);
  145. Delivermodule.ProcessCommand(strcommand, 1);
  146. mLog::Debug(strcommand.c_str());
  147. Sleep(200);
  148. Delivermodule.EixtSendModle();
  149. mLog::Info("\n===============log end ===================\n");
  150. }
  151. std::string OTCStitchDevice::GetGUID() const
  152. {
  153. mLog::Debug("\n===============GetGUID : {$} ===================\n", MechUnitType);
  154. return MechUnitType;
  155. }
  156. void nsMech::OTCStitchDevice::Register()
  157. {
  158. auto Disp = &Dispatch;
  159. superMech::RegisterStitchingControl(Disp);
  160. Disp->Get.Push(m_MSGUnit->GetKey().c_str(), [this](std::string& out) { out = m_MSGUnit->JSGet(); return RET_STATUS::RET_SUCCEED; });
  161. }
  162. int nsMech::OTCStitchDevice::FormatCommand(string& command)
  163. {
  164. mLog::Debug("FormatCommand:str[{$}]", command.c_str());
  165. int size = command.length();
  166. if (size == 0) //发送命令字节为0
  167. {
  168. return -1;
  169. }
  170. int checknum = 0;
  171. for (int i = 0; i < size; i++)
  172. {
  173. checknum += command[i];
  174. }
  175. checknum = checknum + (0x02) + (0x03);
  176. char xorResult = checknum & 0xFF;
  177. command = char(OTCStitch_STX) + command;
  178. command += char(OTCStitch_ETX);
  179. command += (char)(xorResult);
  180. return static_cast<int>(command.length());
  181. }
  182. int nsMech::OTCStitchDevice::FormatCommand(string inuputcommand, char* poutputcommand)
  183. {
  184. mLog::Debug("FormatCommand:char[{$}]", inuputcommand.c_str());
  185. int size = inuputcommand.length();// command.GetLength();
  186. if (size == 0) //发送命令字节为0
  187. {
  188. return -1;
  189. }
  190. int checknum = 0;
  191. for (int i = 0; i < size; i++)
  192. {
  193. checknum += inuputcommand[i];
  194. }
  195. checknum = checknum + (OTCStitch_STX)+(OTCStitch_ETX);
  196. char xorResult = checknum & 0xFF;
  197. poutputcommand[0] = OTCStitch_STX;
  198. for (int i = 1; i < size + 1; i++)
  199. {
  200. poutputcommand[i] = inuputcommand[i - 1];
  201. }
  202. poutputcommand[size + 1] = 3;
  203. poutputcommand[size + 2] = xorResult;
  204. //return static_cast<int>(strlen(command));
  205. return size + 3;
  206. }
  207. void nsMech::OTCStitchDevice::FireNotify(std::string key, std::string content)
  208. {
  209. EventCenter->OnNotify(1, key, content);
  210. }
  211. void nsMech::OTCStitchDevice::FireNotify(std::string key, int content)
  212. {
  213. std::string str = std::format("{:d}", content);
  214. m_EventCenter->OnNotify(1, key, str);
  215. }
  216. void nsMech::OTCStitchDevice::FireErrorMessage(const bool Act, const int Code, const char* ResInfo)
  217. {
  218. string ErrorCode("OTC_ERR_");
  219. ErrorCode += std::to_string(Code);
  220. int level = OTC_MG_REGULATION_LEVEL::REG_ERRO;
  221. if (Act)
  222. {
  223. mLog::Error("add {$}:{$}", ErrorCode.c_str(), ResInfo);
  224. m_MSGUnit->AddErrorMessage(ErrorCode.c_str(), level, ResInfo);
  225. }
  226. else
  227. {
  228. mLog::Error("del {$}:{$}", ErrorCode.c_str(), ResInfo);
  229. m_MSGUnit->DelErrorMessage(ErrorCode.c_str(), level, ResInfo);
  230. }
  231. }
  232. void nsMech::OTCStitchDevice::FireWarnMessage(const bool Act, const int Code, const char* ResInfo)
  233. {
  234. string ErrorCode("OTC_WAR_");
  235. ErrorCode += std::to_string(Code);
  236. int level = OTC_MG_REGULATION_LEVEL::REG_WARN;
  237. if (Act)
  238. {
  239. mLog::Error("add {$}:{$}", ErrorCode.c_str(), ResInfo);
  240. m_MSGUnit->AddWarnMessage(ErrorCode.c_str(), level, ResInfo);
  241. }
  242. else
  243. {
  244. mLog::Error("del {$}:{$}", ErrorCode.c_str(), ResInfo);
  245. m_MSGUnit->DelWarnMessage(ErrorCode.c_str(), level, ResInfo);
  246. }
  247. }
  248. void __stdcall nsMech::OTCStitchDevice::ProcessClientData(const char* pData, unsigned long nDataLength, void* lparam)
  249. {
  250. nsMech::OTCStitchDevice* h = (nsMech::OTCStitchDevice*)lparam;
  251. mLog::Debug("==OUT==: [{$}]", pData);
  252. if (h->m_SCF)
  253. {
  254. //此处有一个bug,当校验和是零的时候,转为string,会截断。相当于少发送一位数据。所以此处需要判断,并主动添加。
  255. //0x03结尾的,并且不是0303的(因为0303)很可能时正常数据。很大可能缺少结尾。故主动添加
  256. string strData(pData);
  257. if (pData[nDataLength - 1] == 0x03 && pData[nDataLength - 2] != 0x03)
  258. {
  259. strData[nDataLength] = 0;
  260. nDataLength += 1;
  261. mLog::Debug("==OUT==:jk++:xoresult is zero,so add zero at the end.");
  262. }
  263. int retLength;
  264. h->m_SCF.Lock(msTimeOut_Lock)
  265. .SendPacket(strData.c_str(), strData.length(), OTCStitch_TIMEOUTVALUE, retLength);
  266. Sleep(OTCStitch_TIMEOUTVALUE);
  267. }
  268. }
  269. void __stdcall nsMech::OTCStitchDevice::WriteLog(const char* pData, nsSerialGPM::LOG_V2_LEVEL level)
  270. {
  271. switch (level)
  272. {
  273. case 0:
  274. case 1:
  275. mLog::Error(pData);
  276. break;
  277. case 2:
  278. mLog::Warn(pData);
  279. break;
  280. case 3:
  281. mLog::Info(pData);
  282. break;
  283. default:
  284. break;
  285. }
  286. }
  287. void OTCStitchDevice::OnCallBack()
  288. {
  289. mLog::Info("Enter OnCallBack");
  290. auto HWNotProcess = [](const char* value, int length) -> void
  291. {
  292. mLog::Warn(" This commands didn't need to process!");
  293. };
  294. auto HWUCS = [this](const char* value, int length) -> void
  295. {
  296. //assert(value && length >= 3);
  297. int ret = atoi(value);
  298. if (ret)
  299. {
  300. m_bStitchingInProgress = false;
  301. mLog::Debug("Stitch cancle");
  302. if(m_MECHUnit.m_StitchingState->Update(AttrKey::STITCHSTATE_CANCEL))
  303. FireNotify(AttrKey::STITCHINGSTATE, m_MECHUnit.m_StitchingState->JSGet());
  304. }
  305. else
  306. {
  307. //是否通知上层报错
  308. mLog::Debug("Stitch cancle failed");
  309. if (m_MECHUnit.m_StitchingState->Update(AttrKey::STITCHSTATE_ERR))
  310. FireNotify(AttrKey::STITCHINGSTATE, m_MECHUnit.m_StitchingState->JSGet());
  311. }
  312. };
  313. auto HWUER = [this](const char* value, int length) -> void
  314. {
  315. //assert(value && length >= 3);
  316. int errorcode = atoi(value);
  317. FireErrorMessage(true, errorcode, "unknown");
  318. if (m_MECHUnit.m_StitchingState->Update(AttrKey::STITCHSTATE_ERR))
  319. FireNotify(AttrKey::STITCHINGSTATE, m_MECHUnit.m_StitchingState->JSGet());
  320. };
  321. auto HWUEX = [this](const char* value, int length) -> void
  322. {
  323. //assert(value && length >= 3);
  324. int ret = atoi(value);
  325. if (ret)
  326. {
  327. mLog::Debug("Extra image number");
  328. }
  329. else
  330. {
  331. //是否通知上层报错
  332. mLog::Debug("Extra image number failed");
  333. }
  334. };
  335. auto HWUSA = [this](const char* value, int length) -> void
  336. {
  337. //assert(value && length >= 3);
  338. mLog::Debug("accept this image");
  339. if (m_MECHUnit.m_StitchingState->Update(AttrKey::STITCHSTATE_Accept_Image))
  340. FireNotify(AttrKey::STITCHINGSTATE, m_MECHUnit.m_StitchingState->JSGet());
  341. };
  342. auto HWUSC = [this](const char* value, int length) -> void
  343. {
  344. //assert(value && length >= 3);
  345. m_nCurrentImage = atoi(value);
  346. mLog::Debug("Current image is [{$}],Total image is [{$}]", m_nCurrentImage, m_nImageCount);
  347. FireNotify(AttrKey::CURRENTIMAGENUMBER, m_nCurrentImage);
  348. //if (m_nCurrentImage == m_nImageCount)
  349. //{
  350. // mLog::Debug("Total image is [{$}]", m_nImageCount);
  351. // //EndStitching();
  352. //}
  353. };
  354. auto HWUSD = [this](const char* value, int length) -> void
  355. {
  356. //assert(value && length >= 3);
  357. if (UP_TO_DOWN == m_MECHUnit.m_StitchDirection->Get())
  358. {
  359. m_MECHUnit.m_StitchDirection->Update(AttrKey::STITCHDIR_TopToBottom);
  360. }
  361. else if (DOWN_TO_UP == m_MECHUnit.m_StitchDirection->Get())
  362. {
  363. if(m_MECHUnit.m_StitchDirection->Update(AttrKey::STITCHDIR_BottomToTop))
  364. FireNotify(AttrKey::STITCHDIRECTION, m_MECHUnit.m_StitchDirection->JSGet());
  365. }
  366. else
  367. {
  368. //default
  369. if (m_MECHUnit.m_StitchDirection->Update(AttrKey::STITCHDIR_TopToBottom))
  370. FireNotify(AttrKey::STITCHDIRECTION, m_MECHUnit.m_StitchDirection->JSGet());
  371. }
  372. mLog::Debug("stitch direction is[{$}]", m_MECHUnit.m_StitchDirection->Get());
  373. };
  374. auto HWUSE = [this](const char* value, int length) -> void
  375. {
  376. //assert(value && length >= 3);
  377. m_bStitchingInProgress = false;
  378. mLog::Debug("stitch end");
  379. if (m_MECHUnit.m_StitchingState->Update(AttrKey::STITCHSTATE_END))
  380. FireNotify(AttrKey::STITCHINGSTATE, m_MECHUnit.m_StitchingState->JSGet());
  381. };
  382. auto HWUSJ = [this](const char* value, int length) -> void
  383. {
  384. //assert(value && length >= 3);
  385. mLog::Debug("reject this image");
  386. if (m_MECHUnit.m_StitchingState->Update(AttrKey::STITCHSTATE_Reject_Image))
  387. FireNotify(AttrKey::STITCHINGSTATE, m_MECHUnit.m_StitchingState->JSGet());
  388. };
  389. auto HWUSR = [this](const char* value, int length) -> void
  390. {
  391. //assert(value && length >= 3);
  392. mLog::Debug("stitch resart");
  393. if (m_MECHUnit.m_StitchingState->Update(AttrKey::STITCHSTATE_RESTART))
  394. FireNotify(AttrKey::STITCHINGSTATE, m_MECHUnit.m_StitchingState->JSGet());
  395. };
  396. auto HWUSM = [this](const char* value, int length) -> void
  397. {
  398. //assert(value && length >= 3);
  399. mLog::Debug("stitch moving");
  400. if (m_MECHUnit.m_StitchingState->Update(AttrKey::STITCHSTATE_MOVING))
  401. FireNotify(AttrKey::STITCHINGSTATE, m_MECHUnit.m_StitchingState->JSGet());
  402. };
  403. auto HWUSN = [this](const char* value, int length) -> void
  404. {
  405. //assert(value && length >= 3);
  406. m_nImageCount = atoi(value);
  407. mLog::Debug("Total image is [{$}]", m_nImageCount);
  408. FireNotify(AttrKey::TOTALIMAGECOUNT, m_nImageCount);
  409. };
  410. auto HWUSP = [this](const char* value, int length) -> void
  411. {
  412. //assert(value && length >= 3);
  413. string strReadString = std::format("{:s}", value);
  414. m_nImageCount = atoi(strReadString.substr(0, 2).c_str());
  415. //m_nCurrentImage = 1;
  416. mLog::Debug("stitch setup");
  417. //if (m_MECHUnit.m_StitchingState->Update(AttrKey::STITCHSTATE_STANDBY))
  418. // FireNotify(AttrKey::STITCHINGSTATE, m_MECHUnit.m_StitchingState->JSGet());
  419. };
  420. auto HWUSS = [this](const char* value, int length) -> void
  421. {
  422. //assert(value && length >= 3);
  423. mLog::Debug("stitch start");
  424. if (m_MECHUnit.m_StitchingState->Update(AttrKey::STITCHSTATE_START))
  425. FireNotify(AttrKey::STITCHINGSTATE, m_MECHUnit.m_StitchingState->JSGet());
  426. };
  427. auto HWUST = [this](const char* value, int length) -> void
  428. {
  429. //assert(value && length >= 3);
  430. int nTemp = atoi(value);
  431. switch (nTemp)
  432. {
  433. case 1://Stitch Start
  434. {
  435. if (m_bStitchingInProgress == false)
  436. {
  437. m_bStitchingInProgress = true;
  438. }
  439. mLog::Debug("StitchingState:[{$}]->STITCHSTATE_START", m_MECHUnit.m_StitchingState->Get());
  440. if (m_MECHUnit.m_StitchingState->Update(AttrKey::STITCHSTATE_START))
  441. FireNotify(AttrKey::STITCHINGSTATE, m_MECHUnit.m_StitchingState->JSGet());
  442. break;
  443. }
  444. case 2://Stitch need to move
  445. {
  446. if (m_bStitchingInProgress)
  447. {
  448. mLog::Debug("StitchingState:[{$}]->STITCHSTATE_NEED_MOVE", m_MECHUnit.m_StitchingState->Get());
  449. if (m_MECHUnit.m_StitchingState->Update(AttrKey::STITCHSTATE_NEED_MOVE))
  450. FireNotify(AttrKey::STITCHINGSTATE, m_MECHUnit.m_StitchingState->JSGet());
  451. if (m_nCurrentImage == m_nImageCount)
  452. {
  453. EndStitching();
  454. }
  455. }
  456. break;
  457. }
  458. case 3://Moving
  459. {
  460. if (m_bStitchingInProgress)
  461. {
  462. mLog::Debug("StitchingState:[{$}]->STITCHSTATE_MOVING", m_MECHUnit.m_StitchingState->Get());
  463. if (m_MECHUnit.m_StitchingState->Update(AttrKey::STITCHSTATE_MOVING))
  464. FireNotify(AttrKey::STITCHINGSTATE, m_MECHUnit.m_StitchingState->JSGet());
  465. if (m_nCurrentImage == 1)
  466. {
  467. mLog::Debug("First image, Moving to init position");
  468. }
  469. else
  470. {
  471. mLog::Debug("Moving to next position");
  472. }
  473. }
  474. break;
  475. }
  476. case 4://Stitch Ready for exposure
  477. {
  478. if (m_bStitchingInProgress)
  479. {
  480. mLog::Debug("StitchingState:[{$}]->STITCHSTATE_READY", m_MECHUnit.m_StitchingState->Get());
  481. if (m_MECHUnit.m_StitchingState->Update(AttrKey::STITCHSTATE_READY))
  482. FireNotify(AttrKey::STITCHINGSTATE, m_MECHUnit.m_StitchingState->JSGet());
  483. mLog::Debug("Ready for exposure");
  484. }
  485. break;
  486. }
  487. case 5://Stitch End
  488. {
  489. if (m_bStitchingInProgress)
  490. {
  491. m_bStitchingInProgress = false;
  492. mLog::Debug("StitchingState:[{$}]->STITCHSTATE_END", m_MECHUnit.m_StitchingState->Get());
  493. if (m_MECHUnit.m_StitchingState->Update(AttrKey::STITCHSTATE_END))
  494. FireNotify(AttrKey::STITCHINGSTATE, m_MECHUnit.m_StitchingState->JSGet());
  495. }
  496. break;
  497. }
  498. case 6://Setup Parameter receive
  499. {
  500. if (m_bStitchingInProgress == false)
  501. {
  502. m_bStitchingInProgress = true;
  503. }
  504. mLog::Debug("StitchingState:[{$}]->STITCHSTATE_INIT", m_MECHUnit.m_StitchingState->Get());
  505. if (m_MECHUnit.m_StitchingState->Update(AttrKey::STITCHSTATE_INIT))
  506. FireNotify(AttrKey::STITCHINGSTATE, m_MECHUnit.m_StitchingState->JSGet());
  507. break;
  508. }
  509. case 7://Setup stitch ok
  510. {
  511. if (m_bStitchingInProgress == false)
  512. {
  513. m_bStitchingInProgress = true;
  514. }
  515. mLog::Debug("StitchingState:[{$}]->STITCHSTATE_STANDBY", m_MECHUnit.m_StitchingState->Get());
  516. if (m_MECHUnit.m_StitchingState->Update(AttrKey::STITCHSTATE_STANDBY))
  517. FireNotify(AttrKey::STITCHINGSTATE, m_MECHUnit.m_StitchingState->JSGet());
  518. break;
  519. }
  520. case 8://Setup stitch fail
  521. {
  522. mLog::Debug("StitchingState:[{$}]->STITCHSTATE_ERR", m_MECHUnit.m_StitchingState->Get());
  523. if (m_MECHUnit.m_StitchingState->Update(AttrKey::STITCHSTATE_ERR))
  524. FireNotify(AttrKey::STITCHINGSTATE, m_MECHUnit.m_StitchingState->JSGet());
  525. mLog::Debug("Setup stitch fail");
  526. break;
  527. }
  528. case 9://Reach to the initial position
  529. {
  530. if (m_bStitchingInProgress)
  531. {
  532. mLog::Debug("StitchingState:[{$}]->STITCHSTATE_REACH_INIT", m_MECHUnit.m_StitchingState->Get());
  533. if (m_MECHUnit.m_StitchingState->Update(AttrKey::STITCHSTATE_REACH_INIT))
  534. FireNotify(AttrKey::STITCHINGSTATE, m_MECHUnit.m_StitchingState->JSGet());
  535. mLog::Debug("Reach to the initial position");
  536. }
  537. break;
  538. }
  539. case 10://Reach to the next position
  540. {
  541. if (m_bStitchingInProgress)
  542. {
  543. mLog::Debug("StitchingState:[{$}]->STITCHSTATE_REACH_NEXT", m_MECHUnit.m_StitchingState->Get());
  544. if (m_MECHUnit.m_StitchingState->Update(AttrKey::STITCHSTATE_REACH_NEXT))
  545. FireNotify(AttrKey::STITCHINGSTATE, m_MECHUnit.m_StitchingState->JSGet());
  546. mLog::Debug("Reach to the next position");
  547. }
  548. break;
  549. }
  550. case 11://Reach to the Extra position
  551. {
  552. if (m_bStitchingInProgress)
  553. {
  554. mLog::Debug("StitchingState:[{$}]->STITCHSTATE_REACH_EXTRA", m_MECHUnit.m_StitchingState->Get());
  555. if (m_MECHUnit.m_StitchingState->Update(AttrKey::STITCHSTATE_REACH_EXTRA))
  556. FireNotify(AttrKey::STITCHINGSTATE, m_MECHUnit.m_StitchingState->JSGet());
  557. mLog::Debug("Reach to the Extra position");
  558. }
  559. break;
  560. }
  561. }
  562. };
  563. auto HWUWN = [this](const char* value, int length) -> void
  564. {
  565. //assert(value && length >= 3);
  566. int warncode = atoi(value);
  567. FireWarnMessage(true, warncode, "unknown");
  568. };
  569. auto HWSID = [this](const char* value, int length) -> void
  570. {
  571. //assert(value && length >= 3);
  572. int nSID = atoi(value);
  573. if (m_MECHUnit.m_SID->Get() != nSID)
  574. {
  575. mLog::Debug("SID:[{$}]->[{$}]", m_MECHUnit.m_SID->Get(), nSID);
  576. if(m_MECHUnit.m_SID->Update(nSID))
  577. FireNotify(AttrKey::SID, m_MECHUnit.m_SID->JSGet());
  578. }
  579. else
  580. {
  581. //do nothing.
  582. }
  583. };
  584. auto HWTAG = [this](const char* value, int length) -> void//球管角度
  585. {
  586. //assert(value && length >= 3);
  587. int nTubeAngle = atoi(value);
  588. mLog::Debug("TubeAngle:[{$}]->[{$}]", m_MECHUnit.m_TubeAngle->Get(), nTubeAngle);
  589. if(m_MECHUnit.m_TubeAngle->Update(nTubeAngle))
  590. FireNotify(AttrKey::TUBEANGLE, m_MECHUnit.m_TubeAngle->JSGet());
  591. };
  592. auto HWGPP = [this](const char* value, int length) -> void//位置码
  593. {
  594. //assert(value && length >= 3);
  595. int nPositionCode = atoi(value);
  596. mLog::Debug("PositionNumber:[{$}]->[{$}]", m_MECHUnit.m_PostionNumber->Get(), nPositionCode);
  597. m_MECHUnit.m_PostionNumber->Update(nPositionCode);
  598. FireNotify(AttrKey::POSITIONNUMBER, m_MECHUnit.m_PostionNumber->JSGet());
  599. };
  600. auto HWFID = [this](const char* value, int length) -> void//床台到地面的距离
  601. {
  602. //assert(value && length >= 3);
  603. int nFID = atoi(value);
  604. mLog::Debug("FID:[{$}]->[{$}]", m_MECHUnit.m_FID->Get(), nFID);
  605. m_MECHUnit.m_FID->Update(nFID);
  606. FireNotify(AttrKey::FID, m_MECHUnit.m_FID->JSGet());
  607. };
  608. auto HWDTP = [this](const char* value, int length) -> void//探测器位置
  609. {
  610. //assert(value && length >= 3);
  611. int nDtPosition = atoi(value);
  612. mLog::Debug("FPDPosition:[{$}]->[{$}]", m_MECHUnit.m_FPDPosition->Get(), nDtPosition);
  613. m_MECHUnit.m_FPDPosition->Update(nDtPosition);
  614. FireNotify(AttrKey::FPDPOSITION, m_MECHUnit.m_FPDPosition->JSGet());
  615. };
  616. auto HWGKV = [this](const char* value, int length) -> void//KV
  617. {
  618. //assert(value && length >= 3);
  619. string strReadString = std::format("{:s}", value);
  620. if (strReadString.substr(0, 1) == "+")
  621. {
  622. mLog::Debug("KV:+");
  623. }
  624. else if (strReadString.substr(0, 1) == "-")
  625. {
  626. mLog::Debug("KV:-");
  627. }
  628. else
  629. {
  630. int temp = atoi(value);
  631. mLog::Debug("KV:[{$}]->[{$}]", m_MECHUnit.m_KV->Get(),temp);
  632. m_MECHUnit.m_KV->Update(temp);
  633. }
  634. };
  635. auto HWGMA = [this](const char* value, int length) -> void//MA
  636. {
  637. //assert(value && length >= 3);
  638. string strReadString = std::format("{:s}", value);
  639. if (strReadString.substr(0, 1) == "+")
  640. {
  641. mLog::Debug("MA:+");
  642. }
  643. else if (strReadString.substr(0, 1) == "-")
  644. {
  645. mLog::Debug("MA:-");
  646. }
  647. else
  648. {
  649. int temp = atoi(value);
  650. float ftemp = (float)temp / 100;
  651. mLog::Debug("MA:[{$}]->[{$}]", m_MECHUnit.m_MA->Get(), ftemp);
  652. m_MECHUnit.m_MA->Update(ftemp);
  653. }
  654. };
  655. auto HWGMS = [this](const char* value, int length) -> void//MS
  656. {
  657. //assert(value && length >= 3);
  658. string strReadString = std::format("{:s}", value);
  659. if (strReadString.substr(0, 1) == "+")
  660. {
  661. mLog::Debug("MS:+");
  662. }
  663. else if (strReadString.substr(0, 1) == "-")
  664. {
  665. mLog::Debug("MS:-");
  666. }
  667. else
  668. {
  669. int temp = atoi(value);
  670. float ftemp = (float)temp / 10;
  671. mLog::Debug("MS:[{$}]->[{$}]", m_MECHUnit.m_MS->Get(), ftemp);
  672. m_MECHUnit.m_MS->Update(ftemp);
  673. }
  674. };
  675. auto HWGMX = [this](const char* value, int length) -> void//MAS
  676. {
  677. //assert(value && length >= 3);
  678. string strReadString = std::format("{:s}", value);
  679. if (strReadString.substr(0, 1) == "+")
  680. {
  681. mLog::Debug("MAS:+");
  682. }
  683. else if (strReadString.substr(0, 1) == "-")
  684. {
  685. mLog::Debug("MAS:-");
  686. }
  687. else
  688. {
  689. int temp = atoi(value);
  690. float ftemp = (float)temp / 100;
  691. mLog::Debug("MAS:[{$}]->[{$}]", m_MECHUnit.m_MAS->Get(), ftemp);
  692. m_MECHUnit.m_MAS->Update(ftemp);
  693. }
  694. };
  695. auto HWGFI = [this](const char* value, int length) -> void//AEC filed
  696. {
  697. //assert(value && length >= 3);
  698. int temp = atoi(value);
  699. mLog::Debug("AEC filed:[{$}]->[{$}]", m_MECHUnit.m_AECField->Get(), temp);
  700. m_MECHUnit.m_AECField->Update(temp);
  701. };
  702. auto HWGFO = [this](const char* value, int length) -> void//FO
  703. {
  704. //assert(value && length >= 3);
  705. int temp = atoi(value);
  706. mLog::Debug("Focus:[{$}]->[{$}]", m_MECHUnit.m_Focus->Get(), temp);
  707. m_MECHUnit.m_Focus->Update(temp);
  708. };
  709. auto HWGWS = [this](const char* value, int length) -> void//work station
  710. {
  711. //assert(value && length >= 3);
  712. int temp = atoi(value);
  713. mLog::Debug("work station:[{$}]->[{$}]", m_MECHUnit.m_WS->Get(), temp);
  714. m_MECHUnit.m_WS->Update(temp);
  715. };
  716. auto HWGET = [this](const char* value, int length) -> void//tech mode
  717. {
  718. //assert(value && length >= 3);
  719. int temp = atoi(value);
  720. mLog::Debug("tech mode:[{$}]->[{$}]", m_MECHUnit.m_Techmode->Get(), temp);
  721. m_MECHUnit.m_Techmode->Update(temp);
  722. };
  723. auto HWGFN = [this](const char* value, int length) -> void//AEC density
  724. {
  725. //assert(value && length >= 3);
  726. int temp = atoi(value);
  727. mLog::Debug("AEC density:[{$}]->[{$}]", m_MECHUnit.m_AECDensity->Get(), temp);
  728. m_MECHUnit.m_AECDensity->Update(temp);
  729. };
  730. auto HWGCL = [this](const char* value, int length) -> void
  731. {
  732. //assert(value && length >= 3);
  733. string strReadString = std::format("{:s}", value);
  734. int nHeight = atoi(strReadString.substr(0, 3).c_str());
  735. int nWidth = atoi(strReadString.substr(3, 3).c_str());
  736. mLog::Debug("Collimator:Height[{$}]->[{$}],Width[{$}]->[{$}]", m_Collimator.fHeight, nHeight, m_Collimator.fWidth, nWidth);
  737. m_Collimator.fHeight = nHeight;
  738. m_Collimator.fWidth = nWidth;
  739. FireNotify("XSize", m_Collimator.fHeight);
  740. FireNotify("YSize", m_Collimator.fWidth);
  741. };
  742. auto HWGPS = [this](const char* value, int length) -> void
  743. {
  744. //assert(value && length >= 3);
  745. /*
  746. if (strPSize.MakeUpper() == "SMALL")
  747. {
  748. strPS = "2";
  749. }
  750. else if (strPSize.MakeUpper() == "MEDIUM")
  751. {
  752. strPS = "3";
  753. }
  754. else if (strPSize.MakeUpper() == "LARGE")
  755. {
  756. strPS = "4";
  757. }
  758. else if (strPSize.MakeUpper() == "PAEDIATRIC")
  759. {
  760. strPS = "1";
  761. }
  762. */
  763. int temp = atoi(value);
  764. mLog::Debug("PatientSize:[{$}]->[{$}]", m_MECHUnit.m_PatientSize->Get(), temp);
  765. if(m_MECHUnit.m_PatientSize->Update(temp))
  766. FireNotify(AttrKey::PATIENTSIZE, m_MECHUnit.m_PatientSize->JSGet());
  767. };
  768. // 有部分前缀是包含关系, 长的包含短的, 因此长的在前面, 短的在后面
  769. // Device 是个短寿命对象, 而 arFrame 是静态变量 !!!
  770. // 因此, 在添加到 arFrame 之前, 务必先清零 !!!
  771. arFrame.clear();
  772. arFrame.push_back(tFrameMapping("NULL", 4, HWNotProcess));
  773. arFrame.push_back(tFrameMapping("UCS", 3, HWUCS));
  774. arFrame.push_back(tFrameMapping("UER", 3, HWUER));
  775. arFrame.push_back(tFrameMapping("UEX", 3, HWUEX));
  776. arFrame.push_back(tFrameMapping("USA", 3, HWUSA));
  777. arFrame.push_back(tFrameMapping("USC", 3, HWUSC));
  778. arFrame.push_back(tFrameMapping("USD", 3, HWUSD));
  779. arFrame.push_back(tFrameMapping("USE", 3, HWUSE));
  780. arFrame.push_back(tFrameMapping("USJ", 3, HWUSJ));
  781. arFrame.push_back(tFrameMapping("USR", 3, HWUSR));
  782. arFrame.push_back(tFrameMapping("USM", 3, HWUSM));
  783. arFrame.push_back(tFrameMapping("USN", 3, HWUSN));
  784. arFrame.push_back(tFrameMapping("USP", 3, HWUSP));
  785. arFrame.push_back(tFrameMapping("USS", 3, HWUSS));
  786. arFrame.push_back(tFrameMapping("UST", 3, HWUST));
  787. arFrame.push_back(tFrameMapping("UWN", 3, HWUWN));
  788. arFrame.push_back(tFrameMapping("SID", 3, HWSID));
  789. arFrame.push_back(tFrameMapping("TAG", 3, HWTAG));
  790. arFrame.push_back(tFrameMapping("GPP", 3, HWGPP));
  791. arFrame.push_back(tFrameMapping("FID", 3, HWFID));
  792. arFrame.push_back(tFrameMapping("DTP", 3, HWDTP));
  793. arFrame.push_back(tFrameMapping("GKV", 3, HWGKV));
  794. arFrame.push_back(tFrameMapping("GMA", 3, HWGMA));
  795. arFrame.push_back(tFrameMapping("GMS", 3, HWGMS));
  796. arFrame.push_back(tFrameMapping("GMX", 3, HWGMX));
  797. arFrame.push_back(tFrameMapping("GFI", 3, HWGFI));
  798. arFrame.push_back(tFrameMapping("GFO", 3, HWGFO));
  799. arFrame.push_back(tFrameMapping("GWS", 3, HWGWS));
  800. arFrame.push_back(tFrameMapping("GET", 3, HWGET));
  801. arFrame.push_back(tFrameMapping("GFN", 3, HWGFN));
  802. arFrame.push_back(tFrameMapping("GCL", 3, HWGCL));
  803. arFrame.push_back(tFrameMapping("GPS", 3, HWGPS));
  804. }
  805. void nsMech::OTCStitchDevice::Convert(const char* strIn, string& strOut, int sourceCodepage, int targetCodepage)
  806. {
  807. int len = lstrlen(strIn);
  808. int unicodeLen = MultiByteToWideChar(sourceCodepage, 0, strIn, -1, NULL, 0);
  809. wchar_t* pUnicode;
  810. pUnicode = new wchar_t[unicodeLen + 1];
  811. memset(pUnicode, 0, (unicodeLen + 1) * sizeof(wchar_t));
  812. MultiByteToWideChar(sourceCodepage, 0, strIn, -1, (LPWSTR)pUnicode, unicodeLen);
  813. BYTE* pTargetData = NULL;
  814. int targetLen = WideCharToMultiByte(targetCodepage, 0, (LPWSTR)pUnicode, -1, (char*)pTargetData, 0, NULL, NULL);
  815. pTargetData = new BYTE[targetLen + 1];
  816. memset(pTargetData, 0, targetLen + 1);
  817. WideCharToMultiByte(targetCodepage, 0, (LPWSTR)pUnicode, -1, (char*)pTargetData, targetLen, NULL, NULL);
  818. strOut = std::format("{:s}", (char*)pTargetData);
  819. delete pUnicode;
  820. delete pTargetData;
  821. }
  822. RET_STATUS nsMech::OTCStitchDevice::SetPatientInfo(ResDataObject& pParam) //注册完病人信息后调用
  823. {
  824. mLog::Debug("Enter SetPatientInfo");
  825. //m_sPATIENTInfo = sPATIENT;
  826. string strcommand{""};
  827. string strPName{ "" };
  828. if (m_ConvertFlag != 1)
  829. {
  830. Convert(m_sPATIENTInfo.strPatientName.c_str(), strPName, CP_ACP, CP_UTF8);
  831. }
  832. else
  833. {
  834. strPName = m_sPATIENTInfo.strPatientName;
  835. mLog::Debug("m_ConvertFlag = 1, don't do any code switch");
  836. }
  837. if (strPName == "")
  838. {
  839. strPName = " ";
  840. }
  841. mLog::Debug("PatientName[{$}]", strPName.c_str());
  842. strcommand = std::format("PIN{:s}", strPName.c_str());
  843. FormatCommand(strcommand);
  844. Delivermodule.ProcessCommand(strcommand, 1);
  845. string strSex = m_sPATIENTInfo.strSex.substr(0, 1);
  846. transform(strSex.begin(), strSex.end(), strSex.begin(), ::toupper);
  847. if (strSex == "")
  848. {
  849. strSex = " ";
  850. }
  851. mLog::Debug("Sex[{$}]", strSex.c_str());
  852. string strAge{ "" };
  853. int age = 0;
  854. if (m_sPATIENTInfo.strAge.find('D',0) != string::npos)
  855. {
  856. age = atoi(m_sPATIENTInfo.strAge.c_str()) / 365;
  857. }
  858. else if (m_sPATIENTInfo.strAge.find('M',0) != string::npos)
  859. {
  860. age = atoi(m_sPATIENTInfo.strAge.c_str()) / 12;
  861. }
  862. else
  863. {
  864. age = atoi(m_sPATIENTInfo.strAge.c_str());
  865. }
  866. strAge = std::format("{:03d}", age);
  867. if (strAge == "")
  868. {
  869. strAge = " ";
  870. }
  871. mLog::Debug("Age[{$}]", strAge.c_str());
  872. string strPSize = m_sPATIENTInfo.strPatientSize; //Large\Medium\Small\Paediatric
  873. string strPS = "3";
  874. transform(strPSize.begin(), strPSize.end(), strPSize.begin(), ::toupper);
  875. if (strPSize == "SMALL")
  876. {
  877. strPS = "2";
  878. }
  879. else if (strPSize == "MEDIUM")
  880. {
  881. strPS = "3";
  882. }
  883. else if (strPSize == "LARGE")
  884. {
  885. strPS = "4";
  886. }
  887. else if (strPSize == "PAEDIATRIC")
  888. {
  889. strPS = "1";
  890. }
  891. if (strPS == "")
  892. {
  893. strPS = " ";
  894. }
  895. mLog::Debug("PatientSize[{$}]", strPS.c_str());
  896. strcommand = std::format("PIF{:s}{:s}{:s}", strSex.c_str(), strPS.c_str(), strAge.c_str());
  897. FormatCommand(strcommand);
  898. Delivermodule.ProcessCommand(strcommand, 1);
  899. string strPID = m_sPATIENTInfo.strPatientID;
  900. if (strPID == "")
  901. {
  902. strPID = " ";
  903. }
  904. mLog::Debug("PatientID[{$}]", strPID.c_str());
  905. strcommand = std::format("PID{:s}", strPID.c_str());
  906. FormatCommand(strcommand);
  907. Delivermodule.ProcessCommand(strcommand, 1);
  908. string strViewDescription{ "" };
  909. if (m_ConvertFlag != 1)
  910. {
  911. Convert(m_sPATIENTInfo.strStudyDescription.c_str(), strViewDescription, CP_ACP, CP_UTF8);
  912. }
  913. else
  914. {
  915. strViewDescription = m_sPATIENTInfo.strStudyDescription;
  916. }
  917. if (strViewDescription == "")
  918. {
  919. strViewDescription = " ";
  920. }
  921. mLog::Debug("StudyDescription[{$}]", strViewDescription.c_str());
  922. strcommand = std::format("PSD{:s}", strViewDescription.c_str());
  923. FormatCommand(strcommand);
  924. Delivermodule.ProcessCommand(strcommand, 1);
  925. return RET_STATUS::RET_SUCCEED;
  926. }
  927. RET_STATUS nsMech::OTCStitchDevice::SetViewInfo(ResDataObject& pParam) //假设2个体位View
  928. {
  929. mLog::Debug("Enter SetViewInfo:ListSize");
  930. m_tempProcedureViewList.clear();
  931. //m_tempProcedureViewList = tempProcedureViewList;
  932. string strcommand;
  933. strcommand = std::format("VLC{:03d}", m_tempProcedureViewList.size());
  934. FormatCommand(strcommand);
  935. Delivermodule.ProcessCommand(strcommand, 1);
  936. string strViewDescription;
  937. for (int i = 0; i < m_tempProcedureViewList.size(); i++)
  938. {
  939. //mLog::Debug("ViewDescription[{$}]", m_tempProcedureViewList[i].strViewDescription);
  940. strViewDescription.clear();
  941. if (m_ConvertFlag != 1)
  942. {
  943. Convert(m_tempProcedureViewList[i].strViewDescription.c_str(), strViewDescription, CP_ACP, CP_UTF8);
  944. }
  945. else
  946. {
  947. strViewDescription = m_tempProcedureViewList[i].strViewDescription;
  948. mLog::Debug("Reserved2 = 1, don't do any code switch");
  949. }
  950. mLog::Debug("ViewDescription[{$}]", strViewDescription.c_str());
  951. strcommand = std::format("VLD{:03d}{:s}", i, strViewDescription.c_str());
  952. FormatCommand(strcommand);
  953. Delivermodule.ProcessCommand(strcommand, 1);
  954. }
  955. return RET_STATUS::RET_SUCCEED;
  956. }
  957. RET_STATUS nsMech::OTCStitchDevice::SetStudyInfo(ResDataObject& pParam)
  958. {
  959. mLog::Debug("Enter SetStudyInfo");
  960. return RET_STATUS::RET_SUCCEED;
  961. }
  962. RET_STATUS nsMech::OTCStitchDevice::SetSID(float value)
  963. {
  964. mLog::Debug("Enter SetSID[{$}]", value);
  965. string strcommand = std::format("SID{:03d}", value);
  966. FormatCommand(strcommand);
  967. Delivermodule.ProcessCommand(strcommand, 1);
  968. return RET_STATUS::RET_SUCCEED;
  969. }
  970. RET_STATUS nsMech::OTCStitchDevice::BeginStitching()
  971. {
  972. mLog::Debug("Enter BeginStitching");
  973. string strcommand = "USS";
  974. FormatCommand(strcommand);
  975. Delivermodule.ProcessCommand(strcommand, 0);
  976. return RET_STATUS::RET_SUCCEED;
  977. }
  978. RET_STATUS nsMech::OTCStitchDevice::EndStitching()
  979. {
  980. mLog::Debug("Enter EndStitching");
  981. string strcommand = "USE";
  982. FormatCommand(strcommand);
  983. Delivermodule.ProcessCommand(strcommand, 0);
  984. return RET_STATUS::RET_SUCCEED;
  985. }
  986. RET_STATUS nsMech::OTCStitchDevice::SetupStitching(string& value)
  987. {
  988. ResDataObject json;
  989. json.decode(value.c_str());
  990. int nInitHeight = atoi(((string)json[AttrKey::STITCHHEIGHT]).c_str());
  991. int nTargetLength = atoi(((string)json[AttrKey::STITCHLENGTH]).c_str());
  992. int nOverlap = atoi(((string)json[AttrKey::STITCHOVERLAP]).c_str());
  993. int nSID = atoi(((string)json[AttrKey::SID]).c_str());
  994. int nPID = atoi(((string)json[AttrKey::STITCHPID]).c_str());
  995. int nDirection = atoi(((string)json[AttrKey::STITCHDIRECTION]).c_str());
  996. int nStitchType = atoi(((string)json[AttrKey::STITCHTYPE]).c_str());
  997. mLog::Debug("Enter SetupStitching:[InitHeight:{$},TotalLength:{$},Overlap:{$},SID:{$},TID:{$},Direction:{$},StitchType:{$}]",
  998. nInitHeight, nTargetLength, nOverlap, nSID, nPID, nDirection, nStitchType);
  999. if (nInitHeight <= 0 || nTargetLength <= 0 || nOverlap <= 0 || nSID <= 0)
  1000. {
  1001. return RET_STATUS::RET_FAILED;
  1002. }
  1003. if (nDirection)//up down, now just support two direction
  1004. {
  1005. nDirection = 1;
  1006. }
  1007. else
  1008. {
  1009. nDirection = 2;//down up
  1010. }
  1011. m_MECHUnit.m_StitchDirection->Update(nDirection);
  1012. if (nStitchType == 0)
  1013. {
  1014. nStitchType = 0;//line
  1015. }
  1016. else
  1017. {
  1018. nStitchType = 1;// Angle
  1019. }
  1020. m_MECHUnit.m_StitchType->Update(nStitchType);
  1021. int nStitchingLength = nTargetLength;//length for stitching
  1022. int nTID = 10;
  1023. int nStitchingStepLength = 43 * (nSID - nTID) / nSID - nOverlap;
  1024. m_MECHUnit.m_StitchHeight->Update(nInitHeight);
  1025. m_MECHUnit.m_StitchLength->Update(nStitchingLength);
  1026. m_MECHUnit.m_StitchOverLap->Update(nOverlap);
  1027. m_MECHUnit.m_StitchStepLength->Update(nStitchingStepLength);
  1028. mLog::Debug("StitchingStepLength[{$}]cm, StitchingLength[{$}]cm", nStitchingStepLength, nStitchingLength);
  1029. m_nImageCount = nStitchingLength / nStitchingStepLength;
  1030. if (m_nImageCount < 2)
  1031. {
  1032. m_nImageCount = 2;
  1033. mLog::Debug("The image count is not correct");
  1034. }
  1035. else if (m_nImageCount > 4)
  1036. {
  1037. m_nImageCount = 4;
  1038. mLog::Debug("The image count is not correct");
  1039. }
  1040. FireNotify(AttrKey::TOTALIMAGECOUNT, m_nImageCount);
  1041. m_nCurrentImage = 0;
  1042. FireNotify(AttrKey::CURRENTIMAGENUMBER, m_nCurrentImage);
  1043. mLog::Debug("Image index[{$}], total images[{$}]", m_nCurrentImage, m_nImageCount);
  1044. string strcommand = "";
  1045. strcommand = std::format("USP{:02d}{:02d}{:d}{:02d}{:03d}{:03d}{:03d}", m_nImageCount, nDirection, nStitchType, nOverlap, nInitHeight, nSID, nTargetLength);
  1046. FormatCommand(strcommand);
  1047. Delivermodule.ProcessCommand(strcommand, 0);
  1048. //strcommand="SS";
  1049. //FormatCommand(strcommand);
  1050. //ProcessCommand(strcommand,0);
  1051. return RET_STATUS::RET_SUCCEED;
  1052. }
  1053. RET_STATUS nsMech::OTCStitchDevice::AcceptStitchingImage()
  1054. {
  1055. mLog::Debug("Enter AcceptStitchingImage");
  1056. string strcommand = "USA";
  1057. FormatCommand(strcommand);
  1058. Delivermodule.ProcessCommand(strcommand, 1);
  1059. if (m_nImageCount == m_nCurrentImage)
  1060. CompleteStitching();
  1061. return RET_STATUS::RET_SUCCEED;
  1062. }
  1063. RET_STATUS nsMech::OTCStitchDevice::RejectStitchingImage()
  1064. {
  1065. mLog::Debug("Enter RejectStitchingImage");
  1066. string strcommand = "USJ";
  1067. FormatCommand(strcommand);
  1068. Delivermodule.ProcessCommand(strcommand, 0);
  1069. return RET_STATUS::RET_SUCCEED;
  1070. }
  1071. RET_STATUS nsMech::OTCStitchDevice::CancelStitching()
  1072. {
  1073. mLog::Debug("Enter CancelStitching");
  1074. if (m_bStitchingInProgress)
  1075. {
  1076. string strcommand = "UCS";
  1077. FormatCommand(strcommand);
  1078. Delivermodule.ProcessCommand(strcommand, 0);
  1079. }
  1080. return RET_STATUS::RET_SUCCEED;
  1081. }
  1082. RET_STATUS nsMech::OTCStitchDevice::CompleteStitching()
  1083. {
  1084. mLog::Debug("Enter CompleteStitching");
  1085. if (m_bStitchingInProgress)
  1086. {
  1087. string strcommand = "USE";
  1088. FormatCommand(strcommand);
  1089. Delivermodule.ProcessCommand(strcommand, 0);
  1090. }
  1091. return RET_STATUS::RET_SUCCEED;
  1092. }
  1093. RET_STATUS nsMech::OTCStitchDevice::NewExtraView()
  1094. {
  1095. mLog::Debug("Enter NewExtraView");
  1096. string strcommand = "UEX";
  1097. FormatCommand(strcommand);
  1098. Delivermodule.ProcessCommand(strcommand, 0);
  1099. return RET_STATUS::RET_SUCCEED;
  1100. }
  1101. RET_STATUS nsMech::OTCStitchDevice::RepeatStitching()
  1102. {
  1103. mLog::Debug("Enter RepeatStitching");
  1104. if (m_bStitchingInProgress)//如果还没有取消或者结束拼接,则先取消拼接再重新开始
  1105. CancelStitching();
  1106. string strcommand = "USR";
  1107. FormatCommand(strcommand);
  1108. Delivermodule.ProcessCommand(strcommand, 0);
  1109. return RET_STATUS::RET_SUCCEED;
  1110. }
  1111. RET_STATUS nsMech::OTCStitchDevice::SetAutoPosiitonNo(int nPN)
  1112. {
  1113. mLog::Debug("Enter SetAutoPosiitonNo[{$}]", nPN);
  1114. string strcommand = std::format("GPP{:03d}", nPN);
  1115. FormatCommand(strcommand);
  1116. Delivermodule.ProcessCommand(strcommand, 1);
  1117. return RET_STATUS::RET_SUCCEED;
  1118. }
  1119. RET_STATUS nsMech::OTCStitchDevice::SetExpEnable(bool nExpEnabled)
  1120. {
  1121. mLog::Debug("Enter SetExpEnable[{$}]", nExpEnabled);
  1122. string strcommand = std::format("PRX{:d}", nExpEnabled);
  1123. FormatCommand(strcommand);
  1124. //add by wxx for DEL at 20231026:解决DEL拼接时系统不ready但机架一直使能
  1125. Delivermodule.ProcessCommand(strcommand,1);
  1126. return RET_STATUS::RET_SUCCEED;
  1127. }
  1128. RET_STATUS nsMech::OTCStitchDevice::SetKV(int nKV)
  1129. {
  1130. mLog::Debug("Enter SetKV[{$}]", nKV);
  1131. string strcommand = std::format("GKV{:03d}", nKV);
  1132. FormatCommand(strcommand);
  1133. Delivermodule.ProcessCommand(strcommand, 1);
  1134. //m_nKV = nKV;
  1135. return RET_STATUS::RET_SUCCEED;
  1136. }
  1137. RET_STATUS nsMech::OTCStitchDevice::SetMA(float fMA)
  1138. {
  1139. mLog::Debug("Enter SetMA[{$}]", fMA);
  1140. int temp = fMA * 100;
  1141. string strcommand = std::format("GMA{:06d}", temp);
  1142. FormatCommand(strcommand);
  1143. Delivermodule.ProcessCommand(strcommand, 1);
  1144. //m_fMA = fMA;
  1145. return RET_STATUS::RET_SUCCEED;
  1146. }
  1147. RET_STATUS nsMech::OTCStitchDevice::SetMS(float fMS)
  1148. {
  1149. mLog::Debug("Enter SetMS[{$}]", fMS);
  1150. int temp = fMS * 10;
  1151. string strcommand = std::format("GMS{:06d}", temp);
  1152. FormatCommand(strcommand);
  1153. Delivermodule.ProcessCommand(strcommand, 1);
  1154. //m_fMS = fMS;
  1155. return RET_STATUS::RET_SUCCEED;
  1156. }
  1157. RET_STATUS nsMech::OTCStitchDevice::SetMAS(float fMAS)
  1158. {
  1159. mLog::Debug("Enter SetMAS[{$}]", fMAS);
  1160. int temp = fMAS * 100;
  1161. string strcommand = std::format("GMX{:06d}", temp);
  1162. FormatCommand(strcommand);
  1163. Delivermodule.ProcessCommand(strcommand, 1);
  1164. //m_fMAS = fMAS;
  1165. return RET_STATUS::RET_SUCCEED;
  1166. }
  1167. RET_STATUS nsMech::OTCStitchDevice::SetWS(int nWS)
  1168. {
  1169. mLog::Debug("Enter SetWS[{$}]", nWS);
  1170. if (nWS != m_MECHUnit.m_WS->Get())
  1171. {
  1172. string strcommand = std::format("GWS{:01d}", nWS);
  1173. FormatCommand(strcommand);
  1174. Delivermodule.ProcessCommand(strcommand, 1);
  1175. //m_nWS = nWS; //第一次会设置,第二次,就会跳过。除非发生了变化。
  1176. //此处有一个问题,因为ws 没有了返回值,我一旦设置,就认为成功。所以我把该值上传. 记不得当初是怎么跟他们协商的了。
  1177. }
  1178. return RET_STATUS::RET_SUCCEED;
  1179. }
  1180. RET_STATUS nsMech::OTCStitchDevice::SetFO(int nFO)
  1181. {
  1182. mLog::Debug("Enter SetFO[{$}]", nFO);
  1183. string strcommand = std::format("GFO{:01d}", nFO);
  1184. FormatCommand(strcommand);
  1185. Delivermodule.ProcessCommand(strcommand, 1);
  1186. //m_nFO = nFO;
  1187. return RET_STATUS::RET_SUCCEED;
  1188. }
  1189. RET_STATUS nsMech::OTCStitchDevice::SetTechMode(int nET)
  1190. {
  1191. mLog::Debug("Enter SetTechMode[{$}]", nET);
  1192. if (nET < 0 || nET>2)
  1193. {
  1194. return RET_STATUS::RET_SUCCEED;
  1195. }
  1196. string strcommand = std::format("GET{:01d}", nET);
  1197. FormatCommand(strcommand);
  1198. Delivermodule.ProcessCommand(strcommand, 1);
  1199. //m_nET = nET;
  1200. return RET_STATUS::RET_SUCCEED;
  1201. }
  1202. RET_STATUS nsMech::OTCStitchDevice::SetAECField(int nAECFieldSel)
  1203. {
  1204. mLog::Debug("Enter SetAECField[{$}]", nAECFieldSel);
  1205. string strcommand = std::format("GFI{:03d}", nAECFieldSel);
  1206. FormatCommand(strcommand);
  1207. Delivermodule.ProcessCommand(strcommand, 1);
  1208. //m_nAECField = nAECFieldSel;
  1209. return RET_STATUS::RET_SUCCEED;
  1210. }
  1211. RET_STATUS nsMech::OTCStitchDevice::SetDensity(float fAECDensity)
  1212. {
  1213. mLog::Debug("Enter SetDensity[{$}]", fAECDensity);
  1214. if (fAECDensity != m_MECHUnit.m_AECDensity->Get())
  1215. {
  1216. int temp = fAECDensity;
  1217. int a, b;
  1218. if (temp < 0)
  1219. {
  1220. a = 0;
  1221. }
  1222. else
  1223. {
  1224. a = 1;
  1225. }
  1226. b = abs(temp);
  1227. string strcommand = std::format("GFN{:01d}{:01d}", a, b);
  1228. FormatCommand(strcommand);
  1229. Delivermodule.ProcessCommand(strcommand, 1);
  1230. //m_nAECDensity = temp;
  1231. }
  1232. return RET_STATUS::RET_SUCCEED;
  1233. }
  1234. RET_STATUS nsMech::OTCStitchDevice::SetCollimator(ECOM_COLLIMATOR_INFO& curCollimator)
  1235. {
  1236. float fWidth = curCollimator.fWidth;
  1237. float fHeight = curCollimator.fHeight;
  1238. mLog::Debug("SetCollimator:Width[{$}],Height[{$}]", fWidth, fHeight);
  1239. string strcommand = std::format("GCL{:03d}{:03d}", (int)fHeight, (int)fWidth);
  1240. FormatCommand(strcommand);
  1241. Delivermodule.ProcessCommand(strcommand, 1);
  1242. return RET_STATUS::RET_SUCCEED;
  1243. }
  1244. RET_STATUS nsMech::OTCStitchDevice::SetFilter(int nFilter)
  1245. {
  1246. mLog::Debug("Enter SetFilter[{$}]", nFilter);
  1247. string strcommand = std::format("GFL{:03d}", nFilter);
  1248. FormatCommand(strcommand);
  1249. Delivermodule.ProcessCommand(strcommand, 1);
  1250. return RET_STATUS::RET_SUCCEED;
  1251. }
  1252. //-----------------------------------------------------------------------------
  1253. // OTCStitchDriver
  1254. //-----------------------------------------------------------------------------
  1255. nsMech::OTCStitchDriver::OTCStitchDriver()
  1256. {
  1257. m_bDemoInitDataFlag = false;
  1258. m_pDriGenDev = nullptr;
  1259. m_pAttribute.reset(new ResDataObject());
  1260. m_pDescription.reset(new ResDataObject());
  1261. }
  1262. nsMech::OTCStitchDriver::~OTCStitchDriver()
  1263. {
  1264. }
  1265. auto nsMech::OTCStitchDriver::CreateDevice(int index) -> std::unique_ptr <IODevice>
  1266. {
  1267. mLog::Debug("Enter CreateDevice[{$}]", index);
  1268. if (index == 0)
  1269. {
  1270. m_pDriGenDev = new OTCStitchDevice(EventCenter, m_SCF, m_ConfigFileName);
  1271. auto dev = std::unique_ptr<IODevice>(new IODevice(m_pDriGenDev));
  1272. return dev;
  1273. }
  1274. unique_ptr <IODevice> dev;
  1275. return dev;
  1276. }
  1277. void nsMech::OTCStitchDriver::FireNotify(int code, std::string key, std::string content)
  1278. {
  1279. mLog::Debug("Enter FireNotify");
  1280. EventCenter->OnNotify(code, key, content);
  1281. }
  1282. void nsMech::OTCStitchDriver::Prepare()
  1283. {
  1284. string strLogPath = GetProcessDirectory() + R"(\OEMDrivers\Mechanical\Conf\Log4CPP.Config.MECH.xml)";
  1285. //Log4CPP::ThreadContext::Map::Set("LogFileName", "Mech.OTCStitch");
  1286. Log4CPP::GlobalContext::Map::Set(ECOM::Utility::Hash("LogFileName"), "Mech.OTCStitch");
  1287. auto rc = Log4CPP::LogManager::LoadConfigFile(strLogPath.c_str());
  1288. mLog::gLogger = Log4CPP::LogManager::GetLogger("Mech.OTCStitch");
  1289. m_SCFDllName = GetConnectDLL(m_ConfigFileName);
  1290. super::Prepare();
  1291. }
  1292. bool nsMech::OTCStitchDriver::Connect()
  1293. {
  1294. mLog::Debug("Enter Connect");
  1295. ResDataObject Connection = GetConnectParam(m_ConfigFileName);
  1296. mLog::Info("connections:{$} \n", Connection.encode());
  1297. auto erCode = m_SCF.Connect(Connection.encode(), &nsMech::OTCStitchDriver::callbackPackageProcess, SCF_PACKET_TRANSFER, 3000);
  1298. if (erCode != SCF_ERR::SCF_SUCCEED)
  1299. return erCode;
  1300. auto rc = super::Connect();
  1301. if (!rc) return 0;
  1302. return SCF_ERR::SCF_SUCCEED;
  1303. }
  1304. void nsMech::OTCStitchDriver::Disconnect()
  1305. {
  1306. mLog::Debug("Enter Disconnect");
  1307. super::Disconnect();
  1308. m_SCF.Disconnect();
  1309. }
  1310. bool nsMech::OTCStitchDriver::isConnected() const
  1311. {
  1312. return super::isConnected();
  1313. }
  1314. std::string nsMech::OTCStitchDriver::DriverProbe()
  1315. {
  1316. printf("line= %d,%s %s\n", __LINE__, __FUNCTION__, m_ConfigFileName.c_str());
  1317. ResDataObject r_config, HardwareInfo;
  1318. if (r_config.loadFile(m_ConfigFileName.c_str()))
  1319. {
  1320. HardwareInfo.add("MajorID", r_config["CONFIGURATION"]["MajorID"]);
  1321. HardwareInfo.add("MinorID", r_config["CONFIGURATION"]["MinorID"]);
  1322. HardwareInfo.add("VendorID", r_config["CONFIGURATION"]["VendorID"]);
  1323. HardwareInfo.add("ProductID", r_config["CONFIGURATION"]["ProductID"]);
  1324. HardwareInfo.add("SerialID", r_config["CONFIGURATION"]["SerialID"]);
  1325. }
  1326. else
  1327. {
  1328. HardwareInfo.add("MajorID", "Machine");
  1329. HardwareInfo.add("MinorID", "Dr");
  1330. HardwareInfo.add("VendorID", "ECOM");
  1331. HardwareInfo.add("ProductID", "HF");
  1332. HardwareInfo.add("SerialID", "1234");
  1333. }
  1334. string ret = HardwareInfo.encode();
  1335. printf("line= %d,%s %s\n", __LINE__, __FUNCTION__, m_ConfigFileName.c_str());
  1336. return ret;
  1337. }
  1338. bool nsMech::OTCStitchDriver::GetDeviceConfig(std::string& Cfg)
  1339. {
  1340. Cfg = m_DeviceConfigSend.encode();
  1341. printf("GetDeviceConfig over , %s", Cfg.c_str());
  1342. return true;
  1343. }
  1344. bool nsMech::OTCStitchDriver::SetDeviceConfig(std::string Cfg)
  1345. {
  1346. printf("\n--Func-- SetDeviceConfig %s\n", Cfg.c_str());
  1347. ResDataObject DeviceConfig;
  1348. DeviceConfig.decode(Cfg.c_str());
  1349. ResDataObject DescriptionTempEx;
  1350. DescriptionTempEx = DeviceConfig["DeviceConfig"]["Attribute"];
  1351. //mLog::Debug("Attribute:{$}", DescriptionTempEx.encode());
  1352. bool bSaveFile = false; //true:重新保存配置文件
  1353. string strAccess = "";
  1354. for (int i = 0; i < DescriptionTempEx.size(); i++)
  1355. {
  1356. string strKey = DescriptionTempEx.GetKey(i);
  1357. ////mLog::Info("{$}", strKey.c_str());
  1358. printf("%s\n", strKey.c_str());
  1359. try
  1360. {
  1361. if (m_pAttribute->GetFirstOf(strKey.c_str()) >= 0)
  1362. {
  1363. strAccess = (string)(*m_pDescription)[strKey.c_str()]["Access"];
  1364. if ("RW" == strAccess)
  1365. {
  1366. //修改对应配置,在其他单元的配置项要同时调用其修改函数修改真实值
  1367. //1. 修改内存中的值,用于给上层发消息
  1368. (*m_pAttribute)[strKey.c_str()] = DescriptionTempEx[i];
  1369. //2. 拿到Innerkey
  1370. int nConfigInfoCount = (int)m_Configurations["ConfigToolInfo"].GetKeyCount("AttributeInfo");
  1371. ////mLog::Info("nConfigInfoCount {$}", nConfigInfoCount);
  1372. string strTemp = ""; //存储AttributeKey
  1373. for (int nInfoIndex = 0; nInfoIndex < nConfigInfoCount; nInfoIndex++)
  1374. {
  1375. strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeKey"];
  1376. if (strTemp == strKey)
  1377. {
  1378. strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["InnerKey"];
  1379. break;
  1380. }
  1381. }
  1382. //3. 修改配置文件中的值
  1383. if (SetDeviceConfigValue(m_Configurations, strTemp.c_str(), 1, DescriptionTempEx[i]))
  1384. {
  1385. //mLog::Debug("SetDeviceConfigValue over");
  1386. bSaveFile = true;
  1387. }
  1388. }
  1389. else
  1390. {
  1391. ////mLog::Info("{$} is not a RW configuration item", strKey.c_str());
  1392. }
  1393. }
  1394. else
  1395. {
  1396. ////mLog::Info("without this attribute {$}", strKey.c_str());
  1397. }
  1398. }
  1399. catch (ResDataObjectExption& e)
  1400. {
  1401. printf("\nSetDriverConfig crashed: %s\n", e.what());
  1402. //mLog::Error("SetDriverConfig crashed: {$}", e.what());
  1403. return false;
  1404. }
  1405. }
  1406. if (bSaveFile)
  1407. {
  1408. //3. 重新保存配置文件
  1409. SaveConfigFile(true);
  1410. }
  1411. return true;
  1412. }
  1413. bool nsMech::OTCStitchDriver::SaveConfigFile(bool bSendNotify)
  1414. {
  1415. m_ConfigAll["CONFIGURATION"] = m_Configurations;
  1416. bool bRt = m_ConfigAll.SaveFile(m_ConfigFileName.c_str());
  1417. ////mLog::Info("SaveConfigFile over {$}", bRt);
  1418. return true;
  1419. }
  1420. bool nsMech::OTCStitchDriver::GetDeviceConfigValue(ResDataObject config, const char* pInnerKey, int nPathID, string& strValue)
  1421. {
  1422. printf("line= %d,%s,pInnerKey=%s,nPathID=%d\n", __LINE__, __FUNCTION__, pInnerKey, nPathID);
  1423. strValue = "";
  1424. string strTemp = pInnerKey;
  1425. if (1 == nPathID) //从DriverConfig路径下每个DPC自己的配置文件读取
  1426. {
  1427. int pos = 0;
  1428. ResDataObject resTemp = config;
  1429. while ((pos = strTemp.find_first_of(',')) != string::npos)
  1430. {
  1431. string Key = strTemp.substr(0, pos);
  1432. string TempValue = resTemp[Key.c_str()].encode();
  1433. //printf("-TempValue=== %s\n", TempValue.c_str());
  1434. resTemp.clear();
  1435. resTemp.decode(TempValue.c_str());
  1436. strTemp = strTemp.substr(pos + 1, strTemp.length() - pos - 1);
  1437. //printf("-************--%s\n", strTemp.c_str());
  1438. }
  1439. if (strTemp != "")
  1440. {
  1441. strValue = (string)resTemp[strTemp.c_str()];
  1442. }
  1443. else
  1444. {
  1445. strValue = (string)resTemp;
  1446. }
  1447. }
  1448. //printf("------------%s\n", strValue.c_str());
  1449. return true;
  1450. }
  1451. bool nsMech::OTCStitchDriver::SetDeviceConfigValue(ResDataObject& config, const char* pInnerKey, int nPathID, const char* szValue)
  1452. {
  1453. string strTemp = pInnerKey;
  1454. //mLog::Debug("Begin to change {$} item value to {$}", pInnerKey, szValue);
  1455. printf("\n Begin to change {%s} item value to {%s}\n", pInnerKey, szValue);
  1456. if (1 == nPathID) //从DriverConfig路径下每个DPC自己的配置文件读取
  1457. {
  1458. try {
  1459. int pos = 0;
  1460. ResDataObject* resTemp = &config;
  1461. while ((pos = strTemp.find_first_of(',')) != string::npos)
  1462. {
  1463. string Key = strTemp.substr(0, pos);
  1464. resTemp = &(*resTemp)[Key.c_str()];
  1465. strTemp = strTemp.substr(pos + 1, strTemp.length() - pos - 1);
  1466. }
  1467. if (strTemp != "")
  1468. {
  1469. (*resTemp)[strTemp.c_str()] = szValue;
  1470. }
  1471. else
  1472. {
  1473. *resTemp = szValue;
  1474. }
  1475. }
  1476. catch (ResDataObjectExption& e)
  1477. {
  1478. //mLog::Error("SetDriverConfigvalue crashed: {$}", e.what());
  1479. return false;
  1480. }
  1481. }
  1482. return true;
  1483. }
  1484. std::string nsMech::OTCStitchDriver::GetResource()
  1485. {
  1486. ResDataObject r_config, temp;
  1487. if (!temp.loadFile(m_ConfigFileName.c_str()))
  1488. {
  1489. return "";
  1490. }
  1491. m_ConfigAll = temp;
  1492. r_config = temp["CONFIGURATION"];
  1493. m_Configurations = r_config;
  1494. ResDataObject DescriptionTemp;
  1495. ResDataObject DescriptionSend;
  1496. ResDataObject m_DescriptionSend;
  1497. ResDataObject ListTemp;
  1498. string strTemp = ""; //用于读取字符串配置信息
  1499. string strIndex = ""; //用于读取配置信息中的List项
  1500. int nTemp = -1; //用于读取整型配置信息
  1501. char sstream[10] = { 0 }; //用于转换值
  1502. string strValue = ""; //用于存储配置的值
  1503. string strType = ""; //用于存储配置的类型 int/float/string...
  1504. try
  1505. {
  1506. //便利ConfigToolInfo 中 所有的AttributeInfo 属性段
  1507. int nConfigInfoCount = (int)m_Configurations["ConfigToolInfo"].GetKeyCount("AttributeInfo");
  1508. m_pAttribute->clear();
  1509. m_pDescription->clear();
  1510. for (int nInfoIndex = 0; nInfoIndex < nConfigInfoCount; nInfoIndex++)
  1511. {
  1512. DescriptionTemp.clear();
  1513. DescriptionSend.clear();
  1514. ListTemp.clear();
  1515. //AttributeType
  1516. strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeDescripition"]["Type"];
  1517. DescriptionTemp.add(ConfKey::DiosType, strTemp.c_str());//DiosGeneratorAttribute
  1518. DescriptionSend.add(ConfKey::DiosType, strTemp.c_str());//DiosGeneratorAttribute
  1519. strType = strTemp; //记录配置项的类型
  1520. //AttributeKey
  1521. //1. 根据AttributeType,内部key和配置路径,拿到当前的真实值
  1522. strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["InnerKey"];
  1523. nTemp = (int)m_Configurations["ConfigToolInfo"][nInfoIndex]["PathID"];
  1524. GetDeviceConfigValue(r_config, strTemp.c_str(), nTemp, strValue); //得到strValue的值
  1525. //2. 赋值
  1526. strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeKey"];
  1527. if ("int" == strType)
  1528. {
  1529. (*m_pAttribute).add(strTemp.c_str(), atoi(strValue.c_str()));
  1530. }
  1531. else if ("float" == strType)
  1532. {
  1533. (*m_pAttribute).add(strTemp.c_str(), atoi(strValue.c_str()));
  1534. }
  1535. else //其它先按string类型处理
  1536. {
  1537. (*m_pAttribute).add(strTemp.c_str(), strValue.c_str());
  1538. }
  1539. //AttributeAccess
  1540. strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeDescripition"]["Access"];
  1541. DescriptionTemp.add(ConfKey::DiosAccess, strTemp.c_str());
  1542. DescriptionSend.add(ConfKey::DiosAccess, strTemp.c_str());
  1543. //AttributeRangeMin
  1544. //strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeDescripition"]["RangeMin"];
  1545. //if (strTemp != "") //不需要的配置项为空
  1546. //{
  1547. // DescriptionTemp.add(ConfKey::DiosRangeMin, strTemp.c_str());
  1548. //}
  1549. ////AttributeRangeMax
  1550. //strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeDescripition"]["RangeMax"];
  1551. //if (strTemp != "") //不需要的配置项为空
  1552. //{
  1553. // DescriptionTemp.add(ConfKey::DiosRangeMax, strTemp.c_str());
  1554. //}
  1555. //AttributeList
  1556. nTemp = m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeDescripition"]["ListNum"];
  1557. if (nTemp > 0) //ListNum不大于0时说明不需要list配置
  1558. {
  1559. for (int nListIndex = 0; nListIndex < nTemp; nListIndex++)
  1560. {
  1561. strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeDescripition"]["ListInfo"][nListIndex];
  1562. auto temKey = std::to_string(nListIndex);
  1563. ListTemp.add(temKey.c_str(), strTemp.c_str());
  1564. }
  1565. DescriptionTemp.add(ConfKey::DiosList, ListTemp);
  1566. DescriptionSend.add(ConfKey::DiosList, ListTemp.encode());
  1567. }
  1568. //AttributeRequired
  1569. strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeDescripition"]["Required"];
  1570. DescriptionTemp.add(ConfKey::DiosRequired, strTemp.c_str());
  1571. DescriptionSend.add(ConfKey::DiosRequired, strTemp.c_str());
  1572. //AttributeDefaultValue
  1573. strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeDescripition"]["DefaultValue"];
  1574. if (strTemp != "") //不需要的配置项为空
  1575. {
  1576. DescriptionTemp.add(ConfKey::DiosDefaultValue, strTemp.c_str());
  1577. DescriptionSend.add(ConfKey::DiosDefaultValue, strTemp.c_str());
  1578. }
  1579. strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeKey"];
  1580. (*m_pDescription).add(strTemp.c_str(), DescriptionTemp);
  1581. m_DescriptionSend.add(strTemp.c_str(), DescriptionSend.encode());
  1582. }
  1583. }
  1584. catch (ResDataObjectExption& e)
  1585. {
  1586. //mLog::Error("Get config error: {$}", e.what());
  1587. return "";
  1588. }
  1589. ResDataObject resDeviceResource;
  1590. resDeviceResource.add(ConfKey::DiosAttribute, (*m_pAttribute));
  1591. resDeviceResource.add(ConfKey::DiosDescription, (*m_pDescription));
  1592. ResDataObject DescriptionTempEx;
  1593. DescriptionTempEx.add(ConfKey::DiosConfig, resDeviceResource);
  1594. m_DeviceConfig.clear();
  1595. m_DeviceConfig = DescriptionTempEx;
  1596. //mLog::Debug("local ************* get resource over {$}", DescriptionTempEx.encode());
  1597. printf("local ************* get resource over %s \n", DescriptionTempEx.encode());
  1598. resDeviceResource.clear();
  1599. resDeviceResource.add(ConfKey::DiosAttribute, (*m_pAttribute));
  1600. resDeviceResource.add(ConfKey::DiosDescription, m_DescriptionSend);
  1601. DescriptionTempEx.clear();
  1602. DescriptionTempEx.add(ConfKey::DiosConfig, resDeviceResource);
  1603. m_DeviceConfigSend.clear();
  1604. m_DeviceConfigSend = DescriptionTempEx;
  1605. string res = m_DeviceConfigSend.encode();
  1606. //mLog::Debug("get resource over {$}", DescriptionTempEx.encode());
  1607. printf("************* get resource over %s \n", DescriptionTempEx.encode());
  1608. return res;
  1609. }
  1610. std::string nsMech::OTCStitchDriver::DeviceProbe()
  1611. {
  1612. ResDataObject r_config, HardwareInfo;
  1613. if (r_config.loadFile(m_ConfigFileName.c_str()))
  1614. {
  1615. HardwareInfo.add("MajorID", r_config["CONFIGURATION"]["MajorID"]);
  1616. HardwareInfo.add("MinorID", r_config["CONFIGURATION"]["MinorID"]);
  1617. HardwareInfo.add("VendorID", r_config["CONFIGURATION"]["VendorID"]);
  1618. HardwareInfo.add("ProductID", r_config["CONFIGURATION"]["ProductID"]);
  1619. HardwareInfo.add("SerialID", r_config["CONFIGURATION"]["SerialID"]);
  1620. }
  1621. else
  1622. {
  1623. HardwareInfo.add("MajorID", "Machine");
  1624. HardwareInfo.add("MinorID", "Dr");
  1625. HardwareInfo.add("VendorID", "ECOM");
  1626. HardwareInfo.add("ProductID", "HF");
  1627. HardwareInfo.add("SerialID", "1234");
  1628. }
  1629. string ret = HardwareInfo.encode();
  1630. return ret;
  1631. }
  1632. void nsMech::OTCStitchDriver::Dequeue(const char* Packet, DWORD Length)
  1633. {
  1634. DecodeFrame(Packet, Length);
  1635. }
  1636. PACKET_RET nsMech::OTCStitchDriver::callbackPackageProcess(const char* RecData, DWORD nLength, DWORD& PacketLength)
  1637. {
  1638. #if 0
  1639. if (nLength > 1)
  1640. {
  1641. mLog::Error("receive data_len[{$}]", nLength);
  1642. for (int i = 0; i < nLength; i++)
  1643. {
  1644. if (i != nLength - 1)
  1645. {
  1646. mLog::Error("receive data[{$}][{$}]", i, RecData[i]);
  1647. }
  1648. else
  1649. {
  1650. mLog::Error("receive data[{$}][{$}]", i, RecData[i]);
  1651. }
  1652. }
  1653. }
  1654. #endif
  1655. bool bHasHead = false;
  1656. if (nLength < 1)
  1657. {
  1658. PacketLength = 0;
  1659. //printf("nLength too small, nLength==%d \n", nLength);
  1660. mLog::Error("nLength too small, nLength=={$}", nLength);
  1661. return PACKET_USELESS;
  1662. }
  1663. else if (nLength > OTCStitch_Com_NormalLen)
  1664. {
  1665. PacketLength = nLength;
  1666. //printf("nLength too big, nLength==%d \n", nLength);
  1667. mLog::Error("nLength too big, nLength=={$}", nLength);
  1668. return PACKET_USELESS;
  1669. }
  1670. for (DWORD i = 0; i < nLength; i++)
  1671. {
  1672. //寻找包头
  1673. if (RecData[i] == OTCStitch_STX && RecData[i] == OTCStitch_NAK)
  1674. {
  1675. if (i != 0) //包头之前的数据格式不对,全部扔掉
  1676. {
  1677. PacketLength = i;
  1678. char strtemp[OTCStitch_Com_NormalLen] = { 0 };
  1679. memcpy(strtemp, RecData, PacketLength);
  1680. //printf("==IN unknown format data ==:[%s],UselessDataLength=%d,TotalLength=%d\n", strtemp, PacketLength, nLength);
  1681. mLog::Error("\n==IN unknown format data ==:[{$}],UselessDataLength={$},TotalLength={$}", strtemp, PacketLength, nLength);
  1682. return PACKET_USELESS;
  1683. }
  1684. else
  1685. {
  1686. bHasHead = true;
  1687. }
  1688. }
  1689. //寻找包尾
  1690. if (RecData[i] == OTCStitch_ETX)
  1691. {
  1692. if (bHasHead)
  1693. {
  1694. if (i >= 4) //正常指令(不包含校验位)
  1695. {
  1696. if (i + 2 > nLength)
  1697. {
  1698. PacketLength = nLength;
  1699. }
  1700. else
  1701. {
  1702. PacketLength = i + 2; //+2 because ETX + Checksum
  1703. }
  1704. char strtemp[OTCStitch_Com_NormalLen] = { 0 };
  1705. memcpy(strtemp, RecData + 1, i - 1); //只有数据,+1 排除 STX ,-1 排除 ETX。
  1706. //printf("==IN==:[%s]\n", strtemp);
  1707. //if (!((strtemp[0] == '9' && strtemp[1] == '9') || (strtemp[0] == '7' && strtemp[1] == '7')))
  1708. mLog::Info("==IN==:[{$}]", strtemp);
  1709. return PACKET_ISPACKET;
  1710. }
  1711. else //空指令
  1712. {
  1713. PacketLength = i + 1;
  1714. char strtemp[OTCStitch_Com_NormalLen] = { 0 };
  1715. memcpy(strtemp, RecData, PacketLength); //空数据,格式正确但无有效命令。
  1716. //printf("==IN uselss data==:[%s]\n", strtemp);
  1717. mLog::Error("==IN uselss data==:[{$}]", strtemp);
  1718. return PACKET_USELESS;
  1719. }
  1720. }
  1721. else //有包尾但无包头
  1722. {
  1723. PacketLength = i + 1;
  1724. char strtemp[OTCStitch_Com_NormalLen] = { 0 };
  1725. memcpy(strtemp, RecData, PacketLength);
  1726. //printf("==IN no head data ==:[%s],NoHeadDataLength=%d,TotalLength=%d\n", strtemp, PacketLength, nLength);
  1727. mLog::Error("==IN no head data ==:[{$}],NoHeadDataLength={$},TotalLength={$}", strtemp, PacketLength, nLength);
  1728. return PACKET_USELESS;
  1729. }
  1730. }
  1731. }
  1732. if (bHasHead)
  1733. {
  1734. PacketLength = 0;
  1735. }
  1736. return PACKET_NOPACKET;
  1737. }
  1738. static nsMech::OTCStitchDriver gIODriver;
  1739. extern "C" DIOS::Dev::IODriver * __cdecl GetIODriver() // 返回静态对象的引用, 调用者不能删除 !
  1740. {
  1741. return &gIODriver;
  1742. }
  1743. extern "C" DIOS::Dev::IODriver * __cdecl CreateIODriver() // 返回新对象, 调用者必须自行删除此对象 !
  1744. {
  1745. return new nsMech::OTCStitchDriver();
  1746. }