CCOS.Dev.Generator.REMEDYST.cpp 83 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803
  1. // CCOS.Dev.GEN.REMEDYST.cpp : 定义 DLL 应用程序的导出函数。
  2. //
  3. #include <assert.h>
  4. #include <functional>
  5. #include <unordered_map>
  6. #include <fstream>
  7. #include <set>
  8. #include "LogicDevice.h"
  9. #include "CCOS.Dev.Generator.REMEDYST.h"
  10. #include "Helper.JSON.hpp"
  11. #include "LogLocalHelper.h"
  12. #include "Log4CPP.h"
  13. using namespace std::placeholders;
  14. using namespace CCOS::Dev::Detail::Generator;
  15. namespace nsGEN = CCOS::Dev::Detail::Generator;
  16. static const int msTimeOut_Lock = 500;
  17. // Linux 环境下的 SCF 库文件名
  18. static const auto COM_SCFDllName = "libSerialSCF.so";
  19. static const auto TCP_SCFDllName = "libTcpipSCF.so";
  20. // 定义 Sleep 宏(如果头文件中没有定义)
  21. #ifndef Sleep
  22. #define Sleep(ms) std::this_thread::sleep_for(std::chrono::milliseconds(ms))
  23. #endif
  24. //-----------------------------------------------------------------------------
  25. // REMEDYSTDevice
  26. //-----------------------------------------------------------------------------
  27. 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 };
  28. 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 };
  29. 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 };
  30. std::unordered_map<int, std::string> errorMessages = {
  31. {3, "Generator CPU EEPROM Data Checksum Error"},
  32. {4, "Generator CPU Real Time Clock error"},
  33. {5, "Main Contactor error"},
  34. {6, "Rotor Fault"},
  35. {7, "Filament Fault"},
  36. {9, "Beam_Cathode Fault"},
  37. {10, "Beam_Anode Fault"},
  38. {11, "Beam_INVA Fault"},
  39. {12, "Beam_INVB Fault"},
  40. {13, "Beam_KV Fault"},
  41. {14, "Beam_IR Fault"},
  42. {15, "Beam KV too low."},
  43. {16, "Beam kv unbalance"},
  44. {17, "Inverter is too hot"},
  45. {18, "Preparation Time-out Error"},
  46. {19, "Handle release time timed out"},
  47. {20, "No KV during exposure"},
  48. {21, "mA during exposure too high"},
  49. {22, "mA during exposure too low"},
  50. {23, "Manually Terminated Exposure"},
  51. {24, "AEC Back-up Timer - Exposure Terminated"},
  52. {25, "AEC MAS Exceeded - Exposure Terminated"},
  53. {27, "Anode Heat Limit"},
  54. {28, "Thermal Switch Interlock Error"},
  55. {29, "Door Interlock Error"},
  56. {31, "Bucky 1 Not Contact Error"},
  57. {33, "Bucky 2 Not Contact Error"},
  58. {34, "Prep Input active during Initialization Phase"},
  59. {35, "X-ray Input active during Initialization Phase"},
  60. {36, "Communication Error Console"},
  61. {37, "+12VDC Error"},
  62. {38, "-12VDC Error"},
  63. {43, "High Voltage Error - KV detected in non x-ray state"},
  64. {44, "Invalid Communication Message"},
  65. {45, "Communication Message Not Supported"},
  66. {46, "Communication Message Not Allowed"},
  67. {48, "Current reception is not enabled"},
  68. {49, "AEC channel is not enable in current reception"},
  69. {51, "AEC Feedback Error (No Feedback Signal Detected)"},
  70. {52, "High Small Focus Filament Current Error in Standby"},
  71. {53, "High Large Focus Filament Current Error in Standby"},
  72. {54, "AEC Reference out of range"},
  73. {55, "No Fields Selected in AEC mode"},
  74. {56, "No Tube Programmed"},
  75. {57, "AEC Stop signal in wrong state"},
  76. {60, "High KV Error"},
  77. {61, "Low KV Error"},
  78. {71, "Boost filament current error"},
  79. {72, "Preheat filament current error"},
  80. {73, "Film screen is invalid"},
  81. {74, "DC BUS voltage is too higher or too low"},
  82. {75, "Tube count data corrupt"},
  83. {82, "INV1 Error"},
  84. {83, "INV2 Error"},
  85. {84, "INV3 Error"},
  86. {100, "Calibration Error - Maximum mA Exceeded"},
  87. {101, "Calibration Error - Calibration Data Table Exceeded"},
  88. {102, "Calibration Error - Maximum Filament Current Exceeded"},
  89. {103, "Calibration Error - Manually Terminated"},
  90. {104, "Calibration Error - No mA"},
  91. {105, "Calibration Error - Minimum mA not calibrated"},
  92. {106, "Generator Limit, Selected Parameter Not calibrated"},
  93. {107, "pre-charge relay fault"},
  94. {108, "large filament set parameter is more than max. filament current"},
  95. {109, "small filament set parameter is more than max. filament current."},
  96. {200, "Anode Warning Level Exceeded"},
  97. {202, "Generator KW Limit"},
  98. {203, "Generator KV Limit"},
  99. {204, "Generator MA Limit"},
  100. {205, "Generator MS Limit"},
  101. {206, "Generator MAS Limit"},
  102. {207, "Tube KW Limit"},
  103. {208, "Tube KV Limit"},
  104. {209, "Tube MA Limit"},
  105. {210, "Tube MAS Limit"},
  106. {212, "Generator AEC Density Limit"},
  107. {213, "Invalid Communication Parameter"},
  108. {214, "Housing Heat Warning2 "}
  109. };
  110. static const std::set<int> specialErrorValues = { 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 20, 28, 29, 34, 35, 37, 38 };
  111. int g_AECFIELD_List[] = { 1, 10, 100, 11, 101, 111 };
  112. std::vector <float> gf_MA_List = { 8, 10, 12.5, 16, 20, 25, 32, 40, 50, 64, 80, 100, 125, 160, 200, 250, 320, 400, 500, 640 };
  113. atomic<int> nsGEN::REMEDYSTDevice::m_iLoopTime = REMEDYST_LoopDefTime;
  114. atomic<bool> nsGEN::REMEDYSTDevice::m_bExtraFlag = false;
  115. nsGEN::REMEDYSTDevice::REMEDYSTDevice(std::shared_ptr <IOEventCenter> center, std::shared_ptr<SCFWrapper> SCF, string configfile)
  116. : super(center)
  117. , superGen()
  118. , m_SCF(SCF)
  119. {
  120. FINFO("========================================");
  121. FINFO("REMEDYSTDevice Constructor Starting...");
  122. FINFO("Version: 0.0.1");
  123. FINFO("Config file: {$}", configfile.c_str());
  124. FINFO("========================================");
  125. assert(EventCenter);
  126. FINFO("Initializing dose unit moulds...");
  127. m_DoseUnit.m_KV.reset(new KVMould(0.0, 40.0, 120.0, 1.0));
  128. m_DoseUnit.m_MA.reset(new MAMould(0.0, 10.0, 1000.0, 0.1));
  129. m_DoseUnit.m_MS.reset(new MSMould(0.0, 1.0, 6300.0, 0.01));
  130. m_DoseUnit.m_MAS.reset(new MASMould(0.0, 0.1, 1000.0, 0.01));
  131. m_DoseUnit.m_Techmode.reset(new TECHMODEMould(0, 0, 2, 1));
  132. m_DoseUnit.m_WS.reset(new WORKSTATIONMould(1, 0, 5, 1));
  133. m_DoseUnit.m_Focus.reset(new FOCUSMould(1, 0, 1, 1));
  134. m_DoseUnit.m_AECField.reset(new AECFIELDMould(0, 0, 111, 1));
  135. m_DoseUnit.m_AECFilm.reset(new AECFILMMould(0, 0, 2, 1));
  136. m_DoseUnit.m_AECDensity.reset(new AECDENSITYMould(0, -4, 4, 1));
  137. m_DoseUnit.m_HE.reset(new TUBEHEATMould(0, 0, 100, 1));
  138. m_DoseUnit.m_PostKV.reset(new POSTKVMould(0.0, 40.0, 120.0, 1.0));
  139. m_DoseUnit.m_PostMA.reset(new POSTMAMould(0.0, 10.0, 1000.0, 0.1));
  140. m_DoseUnit.m_PostMS.reset(new POSTMSMould(0.0, 1.0, 10000.0, 0.01));
  141. m_DoseUnit.m_PostMAS.reset(new POSTMASMould(0.0, 0.5, 1000.0, 0.01));
  142. m_DoseUnit.m_GenSynState.reset(new GENSYNSTATEMould(0, AttrKey::GENERATOR_SYNC_ERR, AttrKey::GENERATOR_SYNC_MAX, 1));
  143. m_DoseUnit.m_GenState.reset(new GENSTATEMould(4, AttrKey::GENERATOR_STATUS_SHUTDOWN, AttrKey::GENERATOR_STATUS_MAX, 1));
  144. m_DoseUnit.m_GenTotalExpNumber.reset(new TOTALEXPNUMMould(0, 0, 9999, 1));
  145. m_DoseUnit.m_GenTotalAcqTimes.reset(new TOTALACQTIMESMould(0, 0, 9999, 1));
  146. m_DoseUnit.m_GenTubeCoolWaitTimes.reset(new TUBECOOLTIMEMould(0, 0, 9999, 1));
  147. m_DoseUnit.m_GenTubeOverLoadNumber.reset(new TUBEOVERLOADNUMMould(0, 0, 9999, 1));
  148. m_DoseUnit.m_GenCurrentExpNumber.reset(new CUREXPNUMMould(0, 0, 9999, 1));
  149. m_DoseUnit.m_ExpMode.reset(new EXPMODEMould(AttrKey::EXPMODE_TYPE::Single));
  150. m_DoseUnit.m_FrameRate.reset(new FRAMERATEMould(0, 0, 16, 1));
  151. m_MSGUnit.reset(new nsDetail::MSGUnit(center, nsGEN::GeneratorUnitType));
  152. m_DAP.reset(new DevDAP::DOSEMould(0.0, 0.0, 1000.0, 0.01));
  153. m_DoseUnit.m_FLMode.reset(new FLUModeMould(AttrKey::GENERATOR_FLUMode::GENERATOR_FLMODE_NOTFLU));
  154. m_DoseUnit.m_FLIntTime.reset(new FLUIntTimeMould(0.0, 0.0, 100.0, 0.1));
  155. m_DoseUnit.m_FLAccTime.reset(new FLAccTimeMould(0.0, 0.0, 999.0, 0.1));
  156. m_DoseUnit.m_FLKV.reset(new FLUKVMould(0, 40, 125, 1));
  157. m_DoseUnit.m_FLMS.reset(new FLUMSMould(10.0, 10.0, 999999.0, 0.01));
  158. m_DoseUnit.m_FLMA.reset(new FLUMAMould(0.5, 0.5, 99.0, 0.1));
  159. m_DoseUnit.m_ABSStatus.reset(new FLUABSStatusMould(0, 0, 2, 1));
  160. m_DoseUnit.m_PPS.reset(new PPSMould(0.5, 0.5, 30, 0.1));
  161. m_DoseUnit.m_DoseLevel.reset(new FLUDoseLevelMould(0, 0, 2, 1));
  162. m_DoseUnit.m_Curve.reset(new FLUCurveMould(0, 0, 3, 1));
  163. FINFO("Dose unit moulds initialized successfully");
  164. m_hGenPostEvent = nullptr;
  165. m_bExtraFlag = true; // 启用硬件状态查询线程
  166. m_bIsConfigLoaded = false;
  167. m_strConfigPath = configfile;
  168. m_bMasR20 = 0;
  169. m_bUseEAcmd = 0;
  170. m_bResetActive = false;
  171. FINFO("Loading configuration from file: {$}", configfile.c_str());
  172. int loadResult = LoadConfig(configfile);
  173. if (loadResult != 0) {
  174. FERROR("Failed to load configuration file, result: {$}", loadResult);
  175. } else {
  176. FINFO("Configuration loaded successfully");
  177. }
  178. FINFO("Executing callback initialization...");
  179. OnCallBack();
  180. FINFO("Registering device interfaces...");
  181. Register();
  182. FINFO("Device interfaces registered");
  183. FINFO("Sending initial RE command...");
  184. HWSend("RE");
  185. FINFO("Sending initial RS command...");
  186. HWSend("RS");
  187. FINFO("Starting hardware status monitoring thread...");
  188. if (StartHardwareStatusThread()) {
  189. FINFO("Hardware status thread started successfully");
  190. } else {
  191. FERROR("Failed to start hardware status thread");
  192. }
  193. FINFO("========================================");
  194. FINFO("REMEDYSTDevice Constructor Completed");
  195. FINFO("========================================");
  196. }
  197. nsGEN::REMEDYSTDevice::~REMEDYSTDevice()
  198. {
  199. FINFO("========================================");
  200. FINFO("REMEDYSTDevice Destructor Starting...");
  201. FINFO("========================================");
  202. FINFO("Stopping hardware status thread...");
  203. m_bExtraFlag = false;
  204. if (m_pHardwareStatusThread.joinable()) {
  205. FINFO("Waiting for hardware status thread to join...");
  206. m_pHardwareStatusThread.join();
  207. FINFO("Hardware status thread joined successfully");
  208. } else {
  209. FINFO("Hardware status thread not joinable, skipping join");
  210. }
  211. FINFO("========================================");
  212. FINFO("REMEDYSTDevice Destructor Completed");
  213. FINFO("========================================");
  214. }
  215. std::string nsGEN::REMEDYSTDevice::GetGUID() const
  216. {
  217. FINFO("\n===============GetGUID : {$} ===================\n", GeneratorUnitType);
  218. return GeneratorUnitType;
  219. }
  220. void nsGEN::REMEDYSTDevice::Register()
  221. {
  222. auto Disp = m_Dispatch.Lock().As();
  223. superGen::Register(Disp);
  224. superGen::RegisterRAD(Disp);
  225. superGen::RegisterAEC(Disp);
  226. superGen::RegisterExpEnable(Disp);
  227. superGen::RegisterGeneratortoSyncStatus(Disp);
  228. superGen::RegisterFluoro(Disp);
  229. Disp->Get.Push(m_MSGUnit->GetKey().c_str(), [this](std::string& out) { out = m_MSGUnit->JSGet(); return RET_STATUS::RET_SUCCEED; });
  230. auto fun_Clear_DAP = [this](auto a, auto&)
  231. {
  232. return Clear_DAP();
  233. };
  234. Disp->Action.Push("Clear_DAP", fun_Clear_DAP);
  235. auto fun_GetValue_DAP = [this](auto a, auto& b)
  236. {
  237. float value = 0;
  238. RET_STATUS ret = GetValue_DAP(value);
  239. b = ToJSON(value);
  240. return ret;
  241. };
  242. Disp->Action.Push("GetValue_DAP", fun_GetValue_DAP);
  243. auto fun_StartMove = [this](auto a,auto& b)
  244. {
  245. return StartMove();
  246. };
  247. Disp->Action.Push("StartMove", fun_StartMove);
  248. auto fun_EndMove = [this](auto a, auto& b)
  249. {
  250. return EndMove();
  251. };
  252. Disp->Action.Push("EndMove", fun_EndMove);
  253. }
  254. RET_STATUS nsGEN::REMEDYSTDevice::IncKV()
  255. {
  256. FINFO("KV value before calling IncKV: {$}\n", m_DoseUnit.m_KV->JSGet().c_str());
  257. if (!m_DoseUnit.m_KV->CanInc()) return RET_STATUS::RET_SUCCEED;
  258. return HWSend("KV+");
  259. }
  260. RET_STATUS nsGEN::REMEDYSTDevice::DecKV()
  261. {
  262. FINFO("KV value before calling DecKV: {$}\n", m_DoseUnit.m_KV->JSGet().c_str());
  263. if (!m_DoseUnit.m_KV->CanDec()) return RET_STATUS::RET_SUCCEED;
  264. return HWSend("KV-");
  265. }
  266. RET_STATUS nsGEN::REMEDYSTDevice::SetKV(float value)
  267. {
  268. FINFO("KV value before calling SetKV: {$}\n", m_DoseUnit.m_KV->JSGet().c_str());
  269. if (!m_DoseUnit.m_KV->Verify(value)) return RET_STATUS::RET_SUCCEED;
  270. char temp[50] = { 0 };
  271. snprintf(temp, sizeof(temp), "KV%03d", (int)value);
  272. return HWSend(temp);
  273. }
  274. RET_STATUS nsGEN::REMEDYSTDevice::IncMA()
  275. {
  276. FINFO("MA value before calling IncMA: {$}\n", m_DoseUnit.m_MA->JSGet().c_str());
  277. if (!m_DoseUnit.m_MA->CanInc()) return RET_STATUS::RET_SUCCEED;
  278. if (m_DoseUnit.m_Techmode->Get() == AttrKey::TECHMODE_V2TYPE::ET_MAS)
  279. {
  280. FINFO("\n Techmode is MAS, can't inc MA");
  281. return RET_STATUS::RET_FAILED;
  282. }
  283. return HWSend("MA+");
  284. }
  285. RET_STATUS nsGEN::REMEDYSTDevice::DecMA()
  286. {
  287. FINFO("MA value before calling DecMA: {$}\n", m_DoseUnit.m_MA->JSGet().c_str());
  288. if (!m_DoseUnit.m_MA->CanDec()) return RET_STATUS::RET_SUCCEED;
  289. if (m_DoseUnit.m_Techmode->Get() == AttrKey::TECHMODE_V2TYPE::ET_MAS)
  290. {
  291. FINFO("\n Techmode is MAS, can't dec MA");
  292. return RET_STATUS::RET_FAILED;
  293. }
  294. return HWSend("MA-");
  295. }
  296. RET_STATUS nsGEN::REMEDYSTDevice::SetMA(float value)
  297. {
  298. FINFO("MA value before calling SetMA: {$}\n", m_DoseUnit.m_MA->JSGet().c_str());
  299. if (!m_DoseUnit.m_MA->Verify(value)) return RET_STATUS::RET_SUCCEED;
  300. if (m_DoseUnit.m_Techmode->Get() == AttrKey::TECHMODE_V2TYPE::ET_MAS)
  301. {
  302. FINFO("\n Techmode is MAS, can't set MA");
  303. return RET_STATUS::RET_FAILED;
  304. }
  305. char temp[50] = { 0 };
  306. snprintf(temp, sizeof(temp), "MA%05d", (int)(value * 10));
  307. return HWSend(temp);
  308. }
  309. RET_STATUS nsGEN::REMEDYSTDevice::IncMS()
  310. {
  311. FINFO("MS value before calling IncMS: {$}\n", m_DoseUnit.m_MS->JSGet().c_str());
  312. if (!m_DoseUnit.m_MS->CanInc())
  313. {
  314. int Level = 1;
  315. m_MSGUnit->AddWarnMessage("REMEDYST_WARN", Level, "Generator MS Limit");
  316. return RET_STATUS::RET_SUCCEED;
  317. }
  318. if (m_DoseUnit.m_Techmode->Get() == AttrKey::TECHMODE_V2TYPE::ET_MAS)
  319. {
  320. FINFO("\n Techmode is MAS, can't inc MS");
  321. return RET_STATUS::RET_FAILED;
  322. }
  323. return HWSend("MS+");
  324. }
  325. RET_STATUS nsGEN::REMEDYSTDevice::DecMS()
  326. {
  327. FINFO("MS value before calling DecMS: {$}\n", m_DoseUnit.m_MS->JSGet().c_str());
  328. if (!m_DoseUnit.m_MS->CanDec()) return RET_STATUS::RET_SUCCEED;
  329. if (m_DoseUnit.m_Techmode->Get() == AttrKey::TECHMODE_V2TYPE::ET_MAS)
  330. {
  331. FINFO("\n Techmode is MAS, can't dec MS");
  332. return RET_STATUS::RET_FAILED;
  333. }
  334. return HWSend("MS-");
  335. }
  336. RET_STATUS nsGEN::REMEDYSTDevice::SetMS(float value)
  337. {
  338. FINFO("MS value before calling SetMS: {$}\n", m_DoseUnit.m_MS->JSGet().c_str());
  339. if (!m_DoseUnit.m_MA->Verify(value)) return RET_STATUS::RET_SUCCEED;
  340. if (m_DoseUnit.m_Techmode->Get() == AttrKey::TECHMODE_V2TYPE::ET_MAS)
  341. {
  342. FINFO("\n Techmode is MAS, can't set MS");
  343. return RET_STATUS::RET_FAILED;
  344. }
  345. char temp[50] { 0 };
  346. snprintf(temp, sizeof(temp), "MS%05d", (int)(value * 10));
  347. return HWSend(temp);
  348. }
  349. RET_STATUS nsGEN::REMEDYSTDevice::IncMAS()
  350. {
  351. FINFO("MAS value before calling IncMAS: {$}\n", m_DoseUnit.m_MAS->JSGet().c_str());
  352. if (!m_DoseUnit.m_MAS->CanInc()) return RET_STATUS::RET_SUCCEED;
  353. if (!m_DoseUnit.m_MS->CanInc())
  354. {
  355. int Level = 1;
  356. m_MSGUnit->AddWarnMessage("REMEDYST_WARN", Level, "Generator MS Limit");
  357. return RET_STATUS::RET_SUCCEED;
  358. }
  359. if (m_DoseUnit.m_Techmode->Get() != AttrKey::TECHMODE_V2TYPE::ET_MAS)
  360. {
  361. FINFO("\n Techmode is not MAS, can't inc MAS");
  362. return RET_STATUS::RET_FAILED;
  363. }
  364. return HWSend("MX+");
  365. }
  366. RET_STATUS nsGEN::REMEDYSTDevice::DecMAS()
  367. {
  368. FINFO("MAS value before calling DecMAS: {$}\n", m_DoseUnit.m_MAS->JSGet().c_str());
  369. if (!m_DoseUnit.m_MAS->CanDec()) return RET_STATUS::RET_SUCCEED;
  370. if (m_DoseUnit.m_Techmode->Get() != AttrKey::TECHMODE_V2TYPE::ET_MAS)
  371. {
  372. FINFO("\n Techmode is not MAS, can't dec MAS");
  373. return RET_STATUS::RET_FAILED;
  374. }
  375. return HWSend("MX-");
  376. }
  377. RET_STATUS nsGEN::REMEDYSTDevice::SetMAS(float value)
  378. {
  379. FINFO("MAS value before calling SetMAS: {$}\n", m_DoseUnit.m_MAS->JSGet().c_str());
  380. if (!m_DoseUnit.m_MAS->Verify(value)) return RET_STATUS::RET_SUCCEED;
  381. if (m_DoseUnit.m_Techmode->Get() != AttrKey::TECHMODE_V2TYPE::ET_MAS)
  382. {
  383. FINFO("\n Techmode is not MAS, can't set MAS");
  384. return RET_STATUS::RET_FAILED;
  385. }
  386. char temp[50] = { 0 };
  387. if (m_bMasR20)
  388. {
  389. snprintf(temp, sizeof(temp), "MX%06d", (int)(value * 100));
  390. }
  391. else
  392. {
  393. snprintf(temp, sizeof(temp), "MX%05d", (int)(value * 10));
  394. }
  395. return HWSend(temp);
  396. }
  397. RET_STATUS nsGEN::REMEDYSTDevice::SetTechmode(int value)
  398. {
  399. FINFO("Techmode value before calling SetTechmode: {$}\n", m_DoseUnit.m_Techmode->JSGet().c_str());
  400. if (!m_DoseUnit.m_Techmode->Verify(value)) return RET_STATUS::RET_SUCCEED;
  401. char temp[50] = { 0 };
  402. snprintf(temp, sizeof(temp), "ET%01d", (int)value);
  403. return HWSend(temp);
  404. }
  405. RET_STATUS nsGEN::REMEDYSTDevice::SetFocus(int value)
  406. {
  407. FINFO("Focus value before calling SetFocus: {$}\n", m_DoseUnit.m_Focus->JSGet().c_str());
  408. if (!m_DoseUnit.m_Focus->Verify(value)) return RET_STATUS::RET_SUCCEED;
  409. char temp[50] = { 0 };
  410. snprintf(temp, sizeof(temp), "FO%01d", (int)value);
  411. return HWSend(temp);
  412. }
  413. RET_STATUS nsGEN::REMEDYSTDevice::SetAECDensity(int value)
  414. {
  415. if (!m_DoseUnit.m_AECDensity->Verify(value)) return RET_STATUS::RET_SUCCEED;
  416. if (m_DoseUnit.m_Techmode->Get() != AttrKey::TECHMODE_V2TYPE::ET_AEC)
  417. return RET_STATUS::RET_FAILED;
  418. char temp[50] = { 0 };
  419. if (value >= 0)
  420. {
  421. snprintf(temp, sizeof(temp), "FN+%01d", (int)value);
  422. }
  423. else
  424. {
  425. snprintf(temp, sizeof(temp), "FN-%01d", (int)value);
  426. }
  427. return HWSend(temp);
  428. }
  429. RET_STATUS nsGEN::REMEDYSTDevice::SetAECField(int value)
  430. {
  431. if (!m_DoseUnit.m_AECField->Verify(value)) return RET_STATUS::RET_SUCCEED;
  432. if (m_DoseUnit.m_Techmode->Get() != AttrKey::TECHMODE_V2TYPE::ET_AEC)
  433. return RET_STATUS::RET_FAILED;
  434. char temp[50] = { 0 };
  435. snprintf(temp, sizeof(temp), "FI%03d", (int)value);
  436. return HWSend(temp);
  437. }
  438. RET_STATUS nsGEN::REMEDYSTDevice::SetAECFilm(int value)
  439. {
  440. if (!m_DoseUnit.m_AECFilm->Verify(value)) return RET_STATUS::RET_SUCCEED;
  441. if (m_DoseUnit.m_Techmode->Get() != AttrKey::TECHMODE_V2TYPE::ET_AEC)
  442. return RET_STATUS::RET_FAILED;
  443. char temp[50] = { 0 };
  444. snprintf(temp, sizeof(temp), "FS%03d", (int)value);
  445. return HWSend(temp);
  446. }
  447. RET_STATUS nsGEN::REMEDYSTDevice::SetWS(const string value)
  448. {
  449. int tempws = 0;
  450. if (value == "Table") tempws = (int)m_GenConfig["WSTable"];
  451. else if (value == "Wall") tempws = (int)m_GenConfig["WSWall"];
  452. else if (value == "Direct") tempws = (int)m_GenConfig["WSConventional"];
  453. else if (value == "Free") tempws = (int)m_GenConfig["WSFree"];
  454. else if (value == "Tomo") tempws = (int)m_GenConfig["WSTomo"];
  455. char temp[50] = { 0 };
  456. snprintf(temp, sizeof(temp), "WS%01d", tempws);
  457. return HWSend(temp);
  458. }
  459. string nsGEN::REMEDYSTDevice::WSUI2Gen(int nUIWS)
  460. {
  461. string strWS = "";
  462. try
  463. {
  464. if (nUIWS == AttrKey::GENWS_TYPE::TABLE) //lying: cross mode
  465. {
  466. strWS = m_GenConfig["WSTable"].encode();
  467. }
  468. else if (nUIWS == AttrKey::GENWS_TYPE::WALL) //standing mode
  469. {
  470. strWS = m_GenConfig["WSWall"].encode();
  471. }
  472. else if (nUIWS == AttrKey::GENWS_TYPE::FREE_TABLE) //standing mode
  473. {
  474. strWS = m_GenConfig["WSFree"].encode();
  475. }
  476. else if (nUIWS == AttrKey::GENWS_TYPE::TOMO) //standing mode
  477. {
  478. strWS = m_GenConfig["WSTOMO"].encode();
  479. }
  480. else if (nUIWS == AttrKey::GENWS_TYPE::CONVENTIONAL) //standing mode
  481. {
  482. strWS = m_GenConfig["WSConventional"].encode();
  483. }
  484. }
  485. catch (ResDataObjectExption& exp)
  486. {
  487. FERROR("Get configuration failed, {$}\n", exp.what());
  488. }
  489. FINFO("Set WS: {$},Generator workstaion: {$}\n", nUIWS, strWS);
  490. if (strWS == "")
  491. {
  492. strWS = "Table";
  493. }
  494. return strWS;
  495. }
  496. RET_STATUS nsGEN::REMEDYSTDevice::SetAPR(const _tAPRArgs& t)
  497. {
  498. m_t = t;
  499. FINFO("*********************Enter SetAPR*********************");
  500. FINFO("t.ws={$},t.fKV={$},t.fMA={$},t.fMAS={$},t.nAECDensity={$},t.nAECField={$},t.nAECFilm={$},t.nFocus={$},t.nTechmode={$}", t.nWS,t.fKV, t.fMA, t.fMAS, t.nAECDensity, t.nAECField, t.nAECFilm, t.nFocus, t.nTechmode);
  501. //2
  502. SetKV(t.fKV);
  503. //3
  504. SetFocus(t.nFocus);
  505. //4
  506. if (t.nTechmode == AttrKey::TECHMODE_V2TYPE::ET_AEC)//aec
  507. {
  508. SetTechmode(t.nTechmode);
  509. SetAECField(t.nAECField);
  510. SetAECDensity(t.nAECDensity);
  511. SetMA(t.fMA);
  512. SetMS(t.fMS);
  513. }
  514. else if (t.nTechmode == AttrKey::TECHMODE_V2TYPE::ET_MAS)//2p
  515. {
  516. SetTechmode(t.nTechmode);
  517. const float EPSINON = 0.000001;
  518. SetMAS(t.fMAS);
  519. }
  520. else if (t.nTechmode == AttrKey::TECHMODE_V2TYPE::ET_TIME)//3p
  521. {
  522. SetTechmode(t.nTechmode);
  523. SetMA(t.fMA);
  524. SetMS(t.fMS);
  525. }
  526. HWSend("RR");
  527. FINFO("*********************Leave SetAPR*********************");
  528. return RET_STATUS::RET_SUCCEED;
  529. }
  530. RET_STATUS nsGEN::REMEDYSTDevice::QueryHE(int& value)
  531. {
  532. return HWSend("HE?");
  533. }
  534. RET_STATUS nsGEN::REMEDYSTDevice::QueryPostKV(float& value)
  535. {
  536. m_DoseUnit.m_PostKV->Update(m_DoseUnit.m_KV->Get());
  537. value = m_DoseUnit.m_PostKV->Get();
  538. return HWSend("AP?");
  539. return RET_STATUS::RET_SUCCEED;
  540. }
  541. RET_STATUS nsGEN::REMEDYSTDevice::QueryPostMA(float& value)
  542. {
  543. return HWSend("AP?");
  544. }
  545. RET_STATUS nsGEN::REMEDYSTDevice::QueryPostMS(float& value)
  546. {
  547. return HWSend("AT?");
  548. }
  549. RET_STATUS nsGEN::REMEDYSTDevice::QueryPostMAS(float& value)
  550. {
  551. value = m_DoseUnit.m_PostMAS->Get();
  552. return RET_STATUS::RET_SUCCEED;
  553. }
  554. RET_STATUS nsGEN::REMEDYSTDevice::Clear_DAP()
  555. {
  556. if (m_bDAPEnable)
  557. {
  558. return HWSend("DZ");
  559. }
  560. return RET_STATUS::RET_SUCCEED;
  561. }
  562. RET_STATUS nsGEN::REMEDYSTDevice::GetValue_DAP(float& value)
  563. {
  564. if (m_bDAPEnable)
  565. {
  566. HWSend("DA");
  567. Sleep(300); //wait 300ms to get real dap value.
  568. value = m_DAP->Get();
  569. }
  570. return RET_STATUS::RET_SUCCEED;
  571. }
  572. RET_STATUS nsGEN::REMEDYSTDevice::StartMove()
  573. {
  574. FINFO("Enter startMove");
  575. FINFO("end startmove");
  576. return RET_STATUS::RET_SUCCEED;
  577. }
  578. RET_STATUS nsGEN::REMEDYSTDevice::EndMove()
  579. {
  580. FINFO("Enter endmove");
  581. FINFO("end EndMove");
  582. return RET_STATUS::RET_SUCCEED;
  583. }
  584. RET_STATUS nsGEN::REMEDYSTDevice::SetGenSynState(int value)
  585. {
  586. FINFO("Enter SetGenSynState...{$} \n", value);
  587. //if (AttrKey::GENERATOR_RAD_XRAYON == value) //软同步,收到XR1时,子系统会变为XRAYON状态,并调用此处,然后我立刻回复XR1至发生器,然后才真正出线。
  588. //{
  589. // FINFO("SetGenSynState be call.this is soft syn mode.");
  590. // HWSend("XR1");
  591. // m_DoseUnit.m_GenSynState->Update(AttrKey::GENERATOR_RAD_XRAYON);
  592. // FireNotify(m_DoseUnit.m_GenSynState->GetKey(), m_DoseUnit.m_GenSynState->JSGet());
  593. //}
  594. return RET_STATUS::RET_SUCCEED;
  595. }
  596. RET_STATUS nsGEN::REMEDYSTDevice::SetGenState(int value)
  597. {
  598. return RET_STATUS::RET_SUCCEED;
  599. }
  600. RET_STATUS nsGEN::REMEDYSTDevice::SetExpMode(std::string value)
  601. {
  602. //note: when time the func be called?
  603. FINFO("Enter SetExpMode...{$}",value);
  604. m_DoseUnit.m_ExpMode->Update(value);
  605. FireNotify(AttrKey::GENSTATE, m_DoseUnit.m_GenState->JSGet());
  606. //
  607. ////退出CBCT,更改exp mode时候强制退出cbct,因为在内endmove中,偶尔会执行不成功,很诡异。
  608. //SetFLFMode("0");
  609. //HWSend("TIC0");
  610. //
  611. //if (m_DoseUnit.m_ExpMode->JSGet() == EXPMODE_TYPE::Single)
  612. //{
  613. // FINFO("Enter SetAPR Single kv={$} ma={$}",m_t.fKV,m_t.fMA);
  614. // SetWS(m_DoseUnit.m_WS->JSGet());
  615. //
  616. // if (abs(m_t.fKV) == 0) //如果上层传下来为0,那么查询
  617. // {
  618. // HWSend("RKV?");
  619. // }
  620. // else
  621. // {
  622. // SetKV(m_t.fKV);
  623. // }
  624. // SetFocus(m_t.nFocus);
  625. // SetTechmode(m_t.nTechmode);
  626. // if (m_t.nTechmode == AttrKey::TECHMODE_V2TYPE::ET_MAS)//mas
  627. // {
  628. // SetMAS(m_t.fMAS);
  629. // }
  630. // else if (m_t.nTechmode == AttrKey::TECHMODE_V2TYPE::ET_AEC)//aec
  631. // {
  632. // SetAECField(m_t.nAECField);
  633. // SetAECFilm(m_t.nAECFilm);
  634. // SetAECDensity(m_t.nAECDensity);
  635. // SetMA(m_t.fMA);
  636. // SetMS(m_t.fMS);
  637. // }
  638. // else//time
  639. // {
  640. // if (abs(m_t.fMA) == 0)
  641. // {
  642. // HWSend("RMA?");
  643. // }
  644. // else
  645. // {
  646. // SetMA(m_t.fMA);
  647. // }
  648. // SetMS(m_t.fMS);
  649. // }
  650. //}
  651. //else if (m_DoseUnit.m_ExpMode->JSGet() == EXPMODE_TYPE::TOMO)
  652. //{
  653. // char temp[50] = { 0 };
  654. // sprintf_s(temp, "FLK%03d", (int)(m_DoseUnit.m_KV->Get()));
  655. // HWSend(temp);
  656. // sprintf_s(temp, "FLM%03d", (int)(10*(m_DoseUnit.m_MA->Get())));
  657. // HWSend(temp);
  658. // sprintf_s(temp, "FLS%03d", (int)(10*(m_DoseUnit.m_FrameRate->Get())));
  659. // FINFO("Enter SetAPR TOMO kv={$} ma={$}", m_DoseUnit.m_KV->Get(), m_DoseUnit.m_MA->Get());
  660. // HWSend(temp);
  661. //}
  662. //
  663. ////这是老机器模式,其中是FLF2= PF. 新机器上,建议新式版本中删除.
  664. //char temp[50] = { 0 };
  665. //sprintf_s(temp, "FLF%01d", (int)(2));
  666. //HWSend(temp);
  667. ////这里有问题,如果是expmode单时,照射片的RPS必须设置为0.
  668. //if (EXPMODE_TYPE::Single == value)
  669. //{
  670. // FINFO("now is Single mode, send RPS0");
  671. // SetRPS(0);
  672. //}
  673. return RET_STATUS::RET_SUCCEED;
  674. }
  675. RET_STATUS nsGEN::REMEDYSTDevice::SetFLFMode(std::string value)
  676. {
  677. FINFO("Enter SetFLFMode...,FLFMode:{$} \n", value.c_str());
  678. if (value == "CF")
  679. {
  680. m_DoseUnit.m_FLMode->Update(1);
  681. HWSend("FLF1", 4);
  682. SetPPS(15);
  683. SetPluseWidth(15);
  684. }
  685. else if (value == "PF")
  686. {
  687. if (m_DoseUnit.m_FLKV->Get() > m_fPFLimitMaxKV)
  688. {
  689. HWSend("FLK040", 6);
  690. }
  691. if (m_DoseUnit.m_FLMA->Get() > m_fPFLimitMaxMA)
  692. {
  693. HWSend("FLM100", 6);
  694. }
  695. m_DoseUnit.m_FLMode->Update(2);
  696. HWSend("FLF2", 4);
  697. SetPPS(5);
  698. SetPluseWidth(5);
  699. }
  700. else if (value == "HLF")
  701. {
  702. if (m_DoseUnit.m_FLKV->Get() < m_fHLFLimitMinKV)
  703. {
  704. HWSend("FLK080", 6);
  705. }
  706. if (m_DoseUnit.m_FLMA->Get() < m_fHLFLimitMinMA)
  707. {
  708. HWSend("FLM4000", 7);
  709. }
  710. m_DoseUnit.m_FLMode->Update(2);
  711. HWSend("FLF2", 4);
  712. SetPPS(5);
  713. SetPluseWidth(5);
  714. }
  715. else
  716. {
  717. FINFO("other FluMode : {$}", value.c_str());
  718. }
  719. return RET_STATUS::RET_SUCCEED;
  720. }
  721. RET_STATUS nsGEN::REMEDYSTDevice::SetAPF(const _tAPFArgs& t)
  722. {
  723. FINFO("APF:FLKV={$},FLMA={$},PPS={$},WS={$},FLuType={$},ABSMode={$},DoseLever={$}", t.nFLKV, t.fFLMA, t.nPPS, t.nWS, t.nFluMode, t.nABSMode, t.nDoseLever);
  724. SetFluKV(t.nFLKV);
  725. SetFluMA(t.fFLMA);
  726. HWSend("RF");
  727. return RET_STATUS::RET_SUCCEED;
  728. }
  729. RET_STATUS nsGEN::REMEDYSTDevice::IncFluKV()
  730. {
  731. FINFO("FluKV value before calling IncFluKV: {$}\n", m_DoseUnit.m_FLKV->JSGet().c_str());
  732. if (!m_DoseUnit.m_FLKV->CanInc()) return RET_STATUS::RET_SUCCEED;
  733. return HWSend("FLK+", 4);
  734. }
  735. RET_STATUS nsGEN::REMEDYSTDevice::DecFluKV()
  736. {
  737. FINFO("FluKV value before calling DecFluKV: {$}\n", m_DoseUnit.m_FLKV->JSGet().c_str());
  738. if (!m_DoseUnit.m_FLKV->CanDec()) return RET_STATUS::RET_SUCCEED;
  739. return HWSend("FLK-", 4);
  740. }
  741. RET_STATUS nsGEN::REMEDYSTDevice::SetFluKV(float value)
  742. {
  743. FINFO("FluKV value before calling SetFluKV: {$}\n", m_DoseUnit.m_FLKV->JSGet().c_str());
  744. if (!m_DoseUnit.m_FLKV->Verify(value)) return RET_STATUS::RET_SUCCEED;
  745. char temp[50] = { 0 };
  746. snprintf(temp, sizeof(temp), "FLK%03d", (int)value);
  747. return HWSend(temp, strlen(temp));
  748. }
  749. RET_STATUS nsGEN::REMEDYSTDevice::IncFluMA()
  750. {
  751. FINFO("FluMA value before calling IncFluMA: {$}\n", m_DoseUnit.m_FLMA->JSGet().c_str());
  752. if (!m_DoseUnit.m_FLMA->CanInc()) return RET_STATUS::RET_SUCCEED;
  753. return HWSend("FLM+", 4);
  754. }
  755. RET_STATUS nsGEN::REMEDYSTDevice::DecFluMA()
  756. {
  757. FINFO("FluMA value before calling DecFluMA: {$}\n", m_DoseUnit.m_FLMA->JSGet().c_str());
  758. if (!m_DoseUnit.m_FLMA->CanDec()) return RET_STATUS::RET_SUCCEED;
  759. return HWSend("FLM-", 4);
  760. }
  761. RET_STATUS nsGEN::REMEDYSTDevice::SetFluMA(float value)
  762. {
  763. FINFO("FluMA value before calling SetFluMA: {$}\n", m_DoseUnit.m_FLMA->JSGet().c_str());
  764. if (!m_DoseUnit.m_FLMA->Verify(value)) return RET_STATUS::RET_SUCCEED;
  765. char temp[50] = { 0 };
  766. snprintf(temp, sizeof(temp), "FLM%03d", (int)(value * 10));
  767. return HWSend(temp, strlen(temp));
  768. }
  769. RET_STATUS nsGEN::REMEDYSTDevice::INCPPS()
  770. {
  771. if (!m_DoseUnit.m_PPS->CanInc()) return RET_STATUS::RET_SUCCEED;
  772. return HWSend("FLS+", 4);
  773. }
  774. RET_STATUS nsGEN::REMEDYSTDevice::DECPPS()
  775. {
  776. if (!m_DoseUnit.m_PPS->CanDec()) return RET_STATUS::RET_SUCCEED;
  777. return HWSend("FLS-", 4);
  778. }
  779. RET_STATUS nsGEN::REMEDYSTDevice::SetPPS(float value)
  780. {
  781. if (!m_DoseUnit.m_PPS->Verify(value)) return RET_STATUS::RET_SUCCEED;
  782. char temp[50] = { 0 };
  783. snprintf(temp, sizeof(temp), "FLS%03d", (int)(value * 10));
  784. return HWSend(temp, strlen(temp));
  785. }
  786. RET_STATUS nsGEN::REMEDYSTDevice::SetABSMode(int nMode)
  787. {
  788. if (!m_DoseUnit.m_ABSStatus->Verify(nMode)) return RET_STATUS::RET_SUCCEED;
  789. char temp[50] = { 0 };
  790. FINFO("SetABSMode[{$}] \n", nMode);
  791. snprintf(temp, sizeof(temp), "FLA%1d", (int)nMode);
  792. return HWSend(temp, strlen(temp));
  793. }
  794. RET_STATUS nsGEN::REMEDYSTDevice::SetABSCurve(int curveNum)
  795. {
  796. return RET_STATUS::RET_SUCCEED;
  797. }
  798. RET_STATUS nsGEN::REMEDYSTDevice::IncABSCurve()
  799. {
  800. return RET_STATUS::RET_SUCCEED;
  801. }
  802. RET_STATUS nsGEN::REMEDYSTDevice::DecABSCurve()
  803. {
  804. return RET_STATUS::RET_SUCCEED;
  805. }
  806. RET_STATUS nsGEN::REMEDYSTDevice::GetABSCurve()
  807. {
  808. return HWSend("FLA?", 4);
  809. }
  810. float nsGEN::REMEDYSTDevice::GetFluIntTimer()
  811. {
  812. return HWSend("FLI?", 4);
  813. }
  814. float nsGEN::REMEDYSTDevice::GetFluAccTimer()
  815. {
  816. return HWSend("FLT?", 4);
  817. }
  818. RET_STATUS nsGEN::REMEDYSTDevice::ResetFluTimer(int ntype)
  819. {
  820. char temp[50] = { 0 };
  821. snprintf(temp, sizeof(temp), "FLR%1d", (int)ntype);
  822. FINFO("ReSetFluAccTimer[{$}] \n", ntype);
  823. return HWSend(temp, strlen(temp));
  824. }
  825. RET_STATUS nsGEN::REMEDYSTDevice::SetFluPre(int value)
  826. {
  827. return RET_STATUS::RET_SUCCEED;
  828. }
  829. RET_STATUS nsGEN::REMEDYSTDevice::SetFluEXP(int value)
  830. {
  831. return RET_STATUS::RET_SUCCEED;
  832. }
  833. RET_STATUS nsGEN::REMEDYSTDevice::SetFluMode(std::string value)
  834. {
  835. FINFO("Enter SetFLFMode...{$} \n", value.c_str());
  836. if (value == "CF")
  837. {
  838. m_DoseUnit.m_FLMode->Update(1);
  839. return HWSend("FLF1", 4);
  840. }
  841. else if (value == "PF")
  842. {
  843. m_DoseUnit.m_FLMode->Update(2);
  844. return HWSend("FLF2", 4);
  845. }
  846. else
  847. {
  848. FINFO("other FluMode : {$}", value.c_str());
  849. return RET_STATUS::RET_SUCCEED;
  850. }
  851. }
  852. RET_STATUS nsGEN::REMEDYSTDevice::SetFluDoseLever(int value)
  853. {
  854. return RET_STATUS::RET_SUCCEED;
  855. }
  856. void CCOS::Dev::Detail::Generator::REMEDYSTDevice::UpdateLimits(const std::string& key, float& currentValue, float defaultValue)
  857. {
  858. if (m_GenConfig.GetKeyCount(key.c_str()) > 0)
  859. {
  860. currentValue = static_cast<float>(m_GenConfig[key.c_str()]);
  861. }
  862. else
  863. {
  864. currentValue = defaultValue;
  865. }
  866. }
  867. void CCOS::Dev::Detail::Generator::REMEDYSTDevice::UpdateLimitsInt(const std::string& key, int& currentValue, int defaultValue)
  868. {
  869. if (m_GenConfig.GetKeyCount(key.c_str()) > 0)
  870. {
  871. currentValue = static_cast<int>(m_GenConfig[key.c_str()]);
  872. }
  873. else
  874. {
  875. currentValue = defaultValue;
  876. }
  877. }
  878. int CCOS::Dev::Detail::Generator::REMEDYSTDevice::GetGenState()
  879. {
  880. if (m_DoseUnit.m_GenState != NULL)
  881. {
  882. return m_DoseUnit.m_GenState->Get();
  883. }
  884. else
  885. {
  886. return 0;
  887. }
  888. }
  889. int CCOS::Dev::Detail::Generator::REMEDYSTDevice::LoadConfig(string configfile)
  890. {
  891. FINFO("=====================LoadConfig=========================");
  892. // 检查文件是否存在
  893. std::ifstream file(configfile);
  894. if (!file) {
  895. // 文件不存在,直接返回空的Connection对象
  896. FINFO("Config file does not exist: {$}", configfile.c_str());
  897. return -1;
  898. }
  899. if (m_bIsConfigLoaded)
  900. {
  901. FINFO("Configuration already loaded.");
  902. return 0;
  903. }
  904. ResDataObject temp;
  905. temp.loadFile(m_strConfigPath.c_str());
  906. m_GenConfig = temp["CONFIGURATION"];
  907. TransJsonText(m_GenConfig);
  908. if (m_GenConfig.GetKeyCount("R20Enable") > 0)
  909. {
  910. m_bMasR20 = (bool)m_GenConfig["R20Enable"];
  911. }
  912. if (m_GenConfig.GetKeyCount("USEEACMD") > 0)
  913. {
  914. m_bUseEAcmd = (bool)m_GenConfig["USEEACMD"];
  915. }
  916. m_bIsConfigLoaded = true;
  917. return 0;
  918. }
  919. RET_STATUS nsGEN::REMEDYSTDevice::SetEXAMMode(std::string value)
  920. {
  921. //EXAMMODE_TYPE::MANUAL
  922. return RET_STATUS::RET_SUCCEED;
  923. }
  924. void nsGEN::REMEDYSTDevice::HandleError(const char* value, const char* prefix, const std::string& type)
  925. {
  926. FINFO("========================================");
  927. FINFO("HandleError Entry");
  928. FINFO("Input value: {$}", value ? value : "NULL");
  929. FINFO("Prefix: {$}", prefix ? prefix : "NULL");
  930. FINFO("Type: {$}", type.c_str());
  931. assert(value);
  932. int nValue = atoi(value);
  933. FINFO("Parsed error value: {$}", nValue);
  934. if (nValue != 0)
  935. {
  936. char ErrorCode[20];
  937. snprintf(ErrorCode, sizeof(ErrorCode), "%s%d", prefix, nValue);
  938. FERROR("Error detected - Code: {$}", ErrorCode);
  939. int level = 1;
  940. auto it = errorMessages.find(nValue);
  941. FINFO("Looking up error message for code {$}", nValue);
  942. if (it != errorMessages.end())
  943. {
  944. FINFO("Error message found: {$}", it->second.c_str());
  945. char temp[50] = { 0 };
  946. snprintf(temp, sizeof(temp), "%s%03d", type.c_str(), nValue);
  947. FINFO("Sending acknowledgement command: {$}", temp);
  948. HWSend(temp);
  949. if (std::find(m_localWarnlist.begin(), m_localWarnlist.end(), ErrorCode) == m_localWarnlist.end())
  950. {
  951. FINFO("Error code not in local warning list, adding...");
  952. if (specialErrorValues.find(nValue) != specialErrorValues.end())
  953. {
  954. FERROR("Special error detected - Adding as ERROR: {$}", ErrorCode);
  955. m_MSGUnit->AddErrorMessage(ErrorCode, level, it->second.c_str());
  956. }
  957. else
  958. {
  959. FWARN("Adding as WARNING: {$}", ErrorCode);
  960. m_MSGUnit->AddWarnMessage(ErrorCode, level, it->second.c_str());
  961. }
  962. m_localWarnlist.push_back(ErrorCode);
  963. FINFO("Error code added to local warning list (list size: {$})", m_localWarnlist.size());
  964. }
  965. else
  966. {
  967. FINFO("ErrorCode {$} is already in the local warning list, skipping", ErrorCode);
  968. }
  969. }
  970. else
  971. {
  972. // 处理未知错误码
  973. FWARN("Unknown error code: {$}", nValue);
  974. if (std::find(m_localWarnlist.begin(), m_localWarnlist.end(), ErrorCode) == m_localWarnlist.end())
  975. {
  976. FINFO("Adding unknown error code to warning list");
  977. m_localWarnlist.push_back(ErrorCode);
  978. m_MSGUnit->AddWarnMessage(ErrorCode, level, "Unknown error");
  979. }
  980. }
  981. FINFO("========================================");
  982. }
  983. else
  984. {
  985. FINFO("Error value is 0, clearing all errors and warnings");
  986. int level = 1;
  987. char EmptyCode[10] = { "" };
  988. m_MSGUnit->DelWarnMessage(EmptyCode, level, "");
  989. m_MSGUnit->DelErrorMessage(EmptyCode, level, "");
  990. FINFO("All errors and warnings cleared");
  991. FINFO("========================================");
  992. }
  993. }
  994. RET_STATUS nsGEN::REMEDYSTDevice::ActiveSyncMode(_tSyncModeArgs value)
  995. {
  996. FINFO("value.strSyncMode: {$}, value.strSyncValue: {$}, value.strWS: {$} \n", value.strSyncMode, value.strSyncValue, value.strWS);
  997. int nSyncModeValue = atoi(value.strSyncValue.c_str());
  998. char temp[50] = { 0 };
  999. snprintf(temp, sizeof(temp), "WS%01d", nSyncModeValue);
  1000. return HWSend(temp);
  1001. }
  1002. RET_STATUS nsGEN::REMEDYSTDevice::SetFrameRate(float frameRate)
  1003. {
  1004. m_DoseUnit.m_FrameRate->Update(frameRate); //this variable should be set when in oncallback.
  1005. char temp[50]{ 0 };
  1006. snprintf(temp, sizeof(temp), "FLS%03d", int(frameRate*10));
  1007. return HWSend(temp);
  1008. }
  1009. RET_STATUS nsGEN::REMEDYSTDevice::SetRPS(int rps)
  1010. {
  1011. return RET_STATUS::RET_SUCCEED;
  1012. //char temp[50]{ 0 };
  1013. //sprintf_s(temp, "RPS%03d", rps * 10);
  1014. //return HWSend(temp);
  1015. }
  1016. RET_STATUS nsGEN::REMEDYSTDevice::RefreshData()
  1017. {
  1018. HWSend("RR");
  1019. HWSend("RS");
  1020. return RET_STATUS::RET_SUCCEED;
  1021. }
  1022. RET_STATUS nsGEN::REMEDYSTDevice::SetExpEnable()
  1023. {
  1024. FINFO("========================================");
  1025. FINFO("SetExpEnable Entry");
  1026. FINFO("UseEAcmd flag: {$}", m_bUseEAcmd);
  1027. if (m_bUseEAcmd)
  1028. {
  1029. FINFO("Sending EA111 command (Exposure Enable)");
  1030. RET_STATUS ret = HWSend("EA111");
  1031. FINFO("EA111 command result: {$}", ret == RET_STATUS::RET_SUCCEED ? "SUCCESS" : "FAILED");
  1032. FINFO("========================================");
  1033. return ret;
  1034. }
  1035. FINFO("EA command disabled, skipping");
  1036. FINFO("========================================");
  1037. FireNotify(AttrKey::GENSTATE, m_DoseUnit.m_GenState->JSGet());
  1038. return RET_STATUS::RET_SUCCEED;
  1039. //return HWSend("EXB1");
  1040. }
  1041. RET_STATUS nsGEN::REMEDYSTDevice::SetExpDisable()
  1042. {
  1043. FINFO("========================================");
  1044. FINFO("SetExpDisable Entry");
  1045. FINFO("UseEAcmd flag: {$}", m_bUseEAcmd);
  1046. if (m_bUseEAcmd)
  1047. {
  1048. FINFO("Sending EA000 command (Exposure Disable)");
  1049. RET_STATUS ret = HWSend("EA000");
  1050. FINFO("EA000 command result: {$}", ret == RET_STATUS::RET_SUCCEED ? "SUCCESS" : "FAILED");
  1051. } else {
  1052. FINFO("EA command disabled, skipping");
  1053. }
  1054. FireNotify(AttrKey::GENSTATE, m_DoseUnit.m_GenState->JSGet());
  1055. FINFO("Generator state: {$}", m_DoseUnit.m_GenState->JSGet().c_str());
  1056. FINFO("========================================");
  1057. return RET_STATUS::RET_SUCCEED;
  1058. }
  1059. RET_STATUS nsGEN::REMEDYSTDevice::Reset()
  1060. {
  1061. FINFO("========================================");
  1062. FINFO("Reset Entry");
  1063. m_bResetActive = true;
  1064. FINFO("Reset active flag set to true");
  1065. int level = 0;
  1066. if (!m_localWarnlist.empty())
  1067. {
  1068. FINFO("Clearing local warning list (size: {$})", m_localWarnlist.size());
  1069. m_localWarnlist.clear();
  1070. FINFO("Local warning list cleared successfully");
  1071. m_MSGUnit->DelErrorMessage("0", level, "clear all errors");
  1072. m_MSGUnit->DelWarnMessage("0", level, "clear all Warning");
  1073. FINFO("Sending RE command (Reset)");
  1074. RET_STATUS ret = HWSend("RE");
  1075. FINFO("Reset command result: {$}", ret == RET_STATUS::RET_SUCCEED ? "SUCCESS" : "FAILED");
  1076. FINFO("========================================");
  1077. return ret;
  1078. }
  1079. else
  1080. {
  1081. FINFO("Local warning list is empty, nothing to clear");
  1082. FINFO("========================================");
  1083. return RET_STATUS::RET_SUCCEED;
  1084. }
  1085. }
  1086. RET_STATUS nsGEN::REMEDYSTDevice::HWSend(const char* strCommand, int length, bool reSend, int nTimeOut)
  1087. {
  1088. if (!m_SCF) {
  1089. FINFO("Failed - Serial communication interface not initialized");
  1090. if (m_DoseUnit.m_GenState->Update(nsGEN::AttrKey::GENERATOR_STATUS_SHUTDOWN))
  1091. {
  1092. FireNotify(AttrKey::GENSTATE, m_DoseUnit.m_GenState->JSGet());
  1093. FINFO("Generator status updated to {$}", static_cast<int>(nsGEN::AttrKey::GENERATOR_STATUS_SHUTDOWN));
  1094. }
  1095. return RET_STATUS::RET_FAILED;
  1096. }
  1097. if (!m_SCF->IsConnected())
  1098. {
  1099. FERROR("Failed - Device not connected");
  1100. if (m_DoseUnit.m_GenState->Update(nsGEN::AttrKey::GENERATOR_STATUS_SHUTDOWN))
  1101. {
  1102. FireNotify(AttrKey::GENSTATE, m_DoseUnit.m_GenState->JSGet());
  1103. FINFO("Generator status updated to {$}", static_cast<int>(nsGEN::AttrKey::GENERATOR_STATUS_SHUTDOWN));
  1104. }
  1105. return RET_STATUS::RET_FAILED;
  1106. }
  1107. // 使用传入的length参数,如果为0则用strlen计算
  1108. int cmdLen = (length > 0) ? length : strlen(strCommand);
  1109. // 检查缓冲区大小,数据包 = 命令 + ETX(1字节) + CheckSum(1字节)
  1110. const int maxCmdLen = 256; // 增大缓冲区以支持更长的命令
  1111. if (cmdLen > maxCmdLen - 2)
  1112. {
  1113. FERROR("Command too long: {$} bytes, max allowed: {$} bytes\n", cmdLen, maxCmdLen - 2);
  1114. return RET_STATUS::RET_FAILED;
  1115. }
  1116. char strSendCommand[maxCmdLen] = { 0 };
  1117. // 计算校验和
  1118. int tmpSum = 0;
  1119. for (int i = 0; i < cmdLen; i++)
  1120. {
  1121. tmpSum += (unsigned char)strCommand[i];
  1122. }
  1123. char checkSum = char(tmpSum + 3);
  1124. // 构建数据包:命令 + ETX + CheckSum
  1125. memcpy(strSendCommand, strCommand, cmdLen);
  1126. strSendCommand[cmdLen] = 0x03;
  1127. strSendCommand[cmdLen + 1] = checkSum;
  1128. int totalLen = cmdLen + 2; // 实际发送的总长度
  1129. // 打印完整数据包的十六进制和ASCII(含ETX和CheckSum)便于调试
  1130. std::string hexStr;
  1131. std::string asciiStr;
  1132. hexStr.reserve(totalLen * 3);
  1133. asciiStr.reserve(cmdLen + 10);
  1134. int printLen = std::min(totalLen, 32); // 最多打印前32字节
  1135. for (int i = 0; i < printLen; i++) {
  1136. char buf[4];
  1137. snprintf(buf, sizeof(buf), "%02X ", (unsigned char)strSendCommand[i]);
  1138. hexStr += buf;
  1139. }
  1140. if (totalLen > 32) hexStr += "...";
  1141. // 提取可打印的ASCII字符串(命令部分,不包括ETX和CheckSum)
  1142. for (int i = 0; i < cmdLen; i++) {
  1143. char ch = strCommand[i];
  1144. if (ch >= 32 && ch <= 126) { // 可打印字符
  1145. asciiStr += ch;
  1146. } else {
  1147. asciiStr += '.'; // 不可打印字符用'.'表示
  1148. }
  1149. }
  1150. asciiStr += " + ETX + CKS"; // 标注后面的控制字符
  1151. FINFO("==OUT== Packet[{$}]: HEX=[{$}] ASCII=[{$}]\n", totalLen, hexStr.c_str(), asciiStr.c_str());
  1152. // 发送数据包,支持重发机制
  1153. int maxRetry = reSend ? 2 : 1; // 如果reSend为true,最多重试2次
  1154. unsigned int retLength = 0;
  1155. for (int retry = 0; retry < maxRetry; retry++)
  1156. {
  1157. if (retry > 0)
  1158. {
  1159. FWARN("Retry sending packet, attempt {$}/{$}\n", retry + 1, maxRetry);
  1160. Sleep(100); // 重试前短暂延时
  1161. }
  1162. if (m_SCF->Lock(1000) == WAIT_OBJECT_0)
  1163. {
  1164. // 使用实际长度totalLen,而不是strlen
  1165. int result = m_SCF->SendPacket(strSendCommand, totalLen, nTimeOut, retLength);
  1166. m_SCF->Unlock();
  1167. if (result == SCF_SUCCEED)
  1168. {
  1169. if (retry > 0)
  1170. {
  1171. FINFO("Send succeeded after {$} retries\n", retry);
  1172. }
  1173. return RET_STATUS::RET_SUCCEED;
  1174. }
  1175. else
  1176. {
  1177. FERROR("SendPacket failed, result={$}, retry={$}/{$}\n", result, retry + 1, maxRetry);
  1178. }
  1179. }
  1180. else
  1181. {
  1182. FERROR("Lock failed, retry={$}/{$}\n", retry + 1, maxRetry);
  1183. }
  1184. }
  1185. FERROR("Send failed after {$} attempts\n", maxRetry);
  1186. return RET_STATUS::RET_FAILED;
  1187. }
  1188. //-----------------------------------------------------------------------------
  1189. // ProcessCmd
  1190. //-----------------------------------------------------------------------------
  1191. void nsGEN::REMEDYSTDevice::FireNotify(std::string key, std::string content)
  1192. {
  1193. EventCenter->OnNotify(1, key, content);
  1194. }
  1195. struct tFrameMapping
  1196. {
  1197. static const int MaxLen = 5;
  1198. using cbFun = std::function <void(const char*, int)>;
  1199. char strHead[MaxLen];
  1200. int NbOfCharOfHead;
  1201. cbFun fun;
  1202. tFrameMapping(const char* str, int len, cbFun f)
  1203. {
  1204. assert(len < MaxLen);
  1205. //strHead[0] = 0x02;
  1206. for (int i = 0; i < len; i++)
  1207. strHead[i] = str[i];
  1208. NbOfCharOfHead = len;
  1209. fun = f;
  1210. }
  1211. };
  1212. static std::list <tFrameMapping> arFrame;
  1213. static bool DecodeFrame(const char* strFrame, int length);
  1214. void nsGEN::REMEDYSTDevice::OnCallBack()
  1215. {
  1216. auto HWNotProcess = [](const char* value, int length) -> void
  1217. {
  1218. printf("\n This commands didn't need to process!\n");
  1219. FINFO("\n This commands didn't need to process!\n");
  1220. };
  1221. //==IN==:KV070 MA00320 MS00063 MX00036 sometimes : this long str appear. so must deal with it
  1222. auto HWKV = [this](const char* value, int length) -> void
  1223. {
  1224. assert(value);
  1225. FINFO("hwkv={$},len={$}",value, length);
  1226. if (length > 20) //if length more than 20, it must be a long string like :070 MA00320 MS00063 MX00036
  1227. {
  1228. //loop the long string to find kv ma ms mas
  1229. int tmpkv;
  1230. float tmpma, tmpms, tmpmx;
  1231. char tmpbuf[6]{ 0,0,0,0,0,0 };
  1232. //kv
  1233. tmpbuf[0] = value[0];
  1234. tmpbuf[1] = value[1];
  1235. tmpbuf[2] = value[2];
  1236. tmpkv = atoi(tmpbuf);
  1237. if (m_DoseUnit.m_KV->Update(tmpkv))
  1238. FireNotify(AttrKey::KV, m_DoseUnit.m_KV->JSGet());
  1239. //ma
  1240. tmpbuf[0] = value[6];
  1241. tmpbuf[1] = value[7];
  1242. tmpbuf[2] = value[8];
  1243. tmpbuf[3] = value[9];
  1244. tmpbuf[4] = value[10];
  1245. tmpma = atof(tmpbuf)/10.0;
  1246. /*if (m_DoseUnit.m_Techmode->Get() != AttrKey::TECHMODE_V2TYPE::ET_TIME)
  1247. {
  1248. FireNotify(AttrKey::MA, to_string(0));
  1249. }
  1250. else
  1251. {*/
  1252. m_DoseUnit.m_MA->Update(tmpma);
  1253. FireNotify(AttrKey::MA, m_DoseUnit.m_MA->JSGet());
  1254. /*}*/
  1255. //ms
  1256. tmpbuf[0] = value[14];
  1257. tmpbuf[1] = value[15];
  1258. tmpbuf[2] = value[16];
  1259. tmpbuf[3] = value[17];
  1260. tmpbuf[4] = value[18];
  1261. tmpms = atof(tmpbuf) / 10.0;
  1262. /*if (m_DoseUnit.m_Techmode->Get() != AttrKey::TECHMODE_V2TYPE::ET_TIME)
  1263. {
  1264. FireNotify(AttrKey::MS, to_string(0));
  1265. }
  1266. else
  1267. {*/
  1268. m_DoseUnit.m_MS->Update(tmpms);
  1269. FireNotify(AttrKey::MS, m_DoseUnit.m_MS->JSGet());
  1270. /*}*/
  1271. //mx
  1272. tmpbuf[0] = value[22];
  1273. tmpbuf[1] = value[23];
  1274. tmpbuf[2] = value[24];
  1275. tmpbuf[3] = value[25];
  1276. tmpbuf[4] = value[26];
  1277. tmpbuf[5] = value[27];
  1278. if (m_bMasR20)
  1279. {
  1280. tmpmx = atof(tmpbuf) / 100.0;
  1281. }
  1282. else
  1283. {
  1284. tmpmx = atof(tmpbuf) / 10.0;
  1285. }
  1286. /*
  1287. if (m_DoseUnit.m_Techmode->Get() == AttrKey::TECHMODE_V2TYPE::ET_TIME)
  1288. {
  1289. FireNotify(AttrKey::MAS, to_string(0));
  1290. }
  1291. else
  1292. {*/
  1293. m_DoseUnit.m_MAS->Update(tmpmx);
  1294. FireNotify(AttrKey::MAS, m_DoseUnit.m_MAS->JSGet());
  1295. /*}*/
  1296. FINFO("tmpkv={$} tmpma={$}, tmpms={$}, tmpmx={$};", tmpkv, tmpma, tmpms, tmpmx);
  1297. }
  1298. else
  1299. {
  1300. int tmpkv = atoi(value);
  1301. if (m_DoseUnit.m_KV->Update(tmpkv))
  1302. FireNotify(AttrKey::KV, m_DoseUnit.m_KV->JSGet());
  1303. }
  1304. };
  1305. //==IN==:TU0 WS1 FO0 ET0 FI010 FS001 FN 0 HE000
  1306. auto HWTU = [this](const char* value, int length) -> void
  1307. {
  1308. assert(value);
  1309. FINFO("recv TU={$},len={$}", value,length);
  1310. char tmpbuf[3] = { 0,0,0 };
  1311. int tmpWS, tmpFO, tmpET, tmpField, tmpFilm, tmpDensity, tmpHE;
  1312. //ws
  1313. tmpbuf[0] = value[4];
  1314. tmpWS = atoi(tmpbuf);
  1315. m_DoseUnit.m_WS->Update(tmpWS);
  1316. {
  1317. FireNotify(m_DoseUnit.m_WS->GetKey(), m_DoseUnit.m_WS->JSGet());
  1318. }
  1319. //FO
  1320. tmpbuf[0] = value[8];
  1321. tmpFO = atoi(tmpbuf);
  1322. m_DoseUnit.m_Focus->Update(tmpFO);
  1323. {
  1324. FireNotify(AttrKey::FOCUS, m_DoseUnit.m_Focus->JSGet());
  1325. FINFO("Current focus:{$}, FO={$}", atoi(m_DoseUnit.m_Focus->JSGet().c_str()) ? "large focus" : "small focus", m_DoseUnit.m_Focus->JSGet().c_str());
  1326. }
  1327. //ET
  1328. tmpbuf[0] = value[12];
  1329. tmpET = atoi(tmpbuf);
  1330. m_DoseUnit.m_Techmode->Update(tmpET);
  1331. FireNotify(AttrKey::TECHMODE, m_DoseUnit.m_Techmode->JSGet());
  1332. switch (tmpET)
  1333. {
  1334. case 0:
  1335. FINFO("ET={$}", "mA/ms", m_DoseUnit.m_Techmode->JSGet().c_str());
  1336. break;
  1337. case 1:
  1338. FINFO("ET={$}", "mAs", m_DoseUnit.m_Techmode->JSGet().c_str());
  1339. break;
  1340. case 2:
  1341. FINFO("ET={$}", "AEC / mA", m_DoseUnit.m_Techmode->JSGet().c_str());
  1342. break;
  1343. case 3:
  1344. FINFO("ET={$}", "mAs / ms", m_DoseUnit.m_Techmode->JSGet().c_str());
  1345. break;
  1346. case 4:
  1347. FINFO("ET={$}", "AEC", m_DoseUnit.m_Techmode->JSGet().c_str());
  1348. break;
  1349. }
  1350. //FIELD
  1351. tmpbuf[0] = value[16];
  1352. tmpbuf[1] = value[17];
  1353. tmpbuf[2] = value[18];
  1354. tmpField = atoi(tmpbuf);
  1355. if (m_DoseUnit.m_AECField->Update(tmpField))
  1356. FireNotify(AttrKey::AECFIELD, m_DoseUnit.m_AECField->JSGet());
  1357. //Film
  1358. tmpbuf[0] = value[22];
  1359. tmpbuf[1] = value[23];
  1360. tmpbuf[2] = value[24];
  1361. tmpFilm = atoi(tmpbuf);
  1362. if (m_DoseUnit.m_AECFilm->Update(tmpFilm))
  1363. FireNotify(AttrKey::AECFILM, m_DoseUnit.m_AECFilm->JSGet());
  1364. //Density
  1365. tmpbuf[0] = value[29];
  1366. tmpbuf[1] = 0;
  1367. tmpbuf[2] = 0;
  1368. tmpDensity = atoi(tmpbuf);
  1369. if (m_DoseUnit.m_AECDensity->Update(tmpDensity))
  1370. FireNotify(AttrKey::AECDENSITY, m_DoseUnit.m_AECDensity->JSGet());
  1371. //HE
  1372. tmpbuf[0] = value[33];
  1373. tmpbuf[1] = value[34];
  1374. tmpbuf[2] = value[35];
  1375. tmpHE = atoi(tmpbuf);
  1376. if (m_DoseUnit.m_HE->Update(tmpHE))
  1377. FireNotify(m_DoseUnit.m_HE->GetKey(), m_DoseUnit.m_HE->JSGet());
  1378. FINFO("parse tmpWS={$}, tmpFO={$}, tmpET={$}, tmpField={$}, tmpFilm={$}, tmpDensity={$}, tmpHE={$}", tmpWS, tmpFO, tmpET, tmpField, tmpFilm, tmpDensity, tmpHE);
  1379. };
  1380. auto HWEC = [this](const char* value, int length) -> void
  1381. {
  1382. assert(value);
  1383. FINFO("recv EC{$}",value);
  1384. };
  1385. auto HWST = [this](const char* value, int length) -> void
  1386. {
  1387. assert(value);
  1388. int genStatus = atoi(value);
  1389. if (m_bResetActive)
  1390. {
  1391. m_bResetActive = false;
  1392. //clear all error list
  1393. int level = 1;
  1394. for (auto errorStr : m_localErrorlist)
  1395. {
  1396. m_MSGUnit->DelErrorMessage(errorStr.c_str(), level, "");
  1397. FINFO("clear error = {$}\n", errorStr);
  1398. }
  1399. m_localErrorlist.clear();
  1400. }
  1401. switch (genStatus)
  1402. {
  1403. case 0:
  1404. FDEBUG("Get Gen Status_1:GENSTATE {$}", m_DoseUnit.m_GenState->JSGet());
  1405. FINFO("Initialization Phase\n");
  1406. if (1 == m_bUseEAcmd)
  1407. {
  1408. static int nST001Count = 0;
  1409. if (0 == nST001Count)//ִֻ
  1410. {
  1411. FINFO("recv st001,and feedback EA000,just once");
  1412. HWSend("EA000");
  1413. nST001Count = 1;
  1414. }
  1415. }
  1416. break;
  1417. case 1:
  1418. FDEBUG("Get Gen Status_2:GENSTATE {$} -> Standby Phase", m_DoseUnit.m_GenState->JSGet());
  1419. if (m_DoseUnit.m_GenState->Update(nsGEN::AttrKey::GENERATOR_STATUS_STANDBY))
  1420. FireNotify(AttrKey::GENSTATE, m_DoseUnit.m_GenState->JSGet());
  1421. break;
  1422. case 2:
  1423. FINFO("Rad Preparation Phase\n");
  1424. break;
  1425. case 3:
  1426. FINFO("Rad Ready Phase\n");
  1427. break;
  1428. case 4:
  1429. FDEBUG("Get Gen Status_10:GENSTATE {$} -> GENERATOR_STATUS_EXP", m_DoseUnit.m_GenSynState->JSGet());
  1430. if (m_DoseUnit.m_GenState->Update(nsGEN::AttrKey::GENERATOR_STATUS_EXP))
  1431. FireNotify(AttrKey::GENSTATE, m_DoseUnit.m_GenState->JSGet());
  1432. break;
  1433. case 7:
  1434. FDEBUG("Get Gen Status_7:GENSTATE {$} -> Error Phase", m_DoseUnit.m_GenState->JSGet());
  1435. if (m_DoseUnit.m_GenState->Update(nsGEN::AttrKey::GENERATOR_STATUS_ERROR))
  1436. FireNotify(AttrKey::GENSTATE, m_DoseUnit.m_GenState->JSGet());
  1437. break;
  1438. default:
  1439. FDEBUG("Get Gen Status:[{$}] unknown", genStatus);
  1440. break;
  1441. }
  1442. };
  1443. auto HWMAS = [this](const char* value, int length)
  1444. {
  1445. assert(value);
  1446. float fmas = 0.0f;
  1447. if (m_bMasR20)
  1448. {
  1449. fmas = atof(value) / 100.0;
  1450. }
  1451. else
  1452. {
  1453. fmas = atof(value) / 10.0;
  1454. }
  1455. /*if (m_DoseUnit.m_Techmode->Get() == AttrKey::TECHMODE_V2TYPE::ET_TIME)
  1456. {
  1457. FireNotify(AttrKey::MAS, to_string(0));
  1458. }
  1459. else
  1460. {*/
  1461. m_DoseUnit.m_MAS->Update(fmas);
  1462. FireNotify(AttrKey::MAS, m_DoseUnit.m_MAS->JSGet());
  1463. /*}*/
  1464. };
  1465. auto HWMA = [this](const char* value, int length)
  1466. {
  1467. assert(value);
  1468. float fma = atof(value) / 10.0;
  1469. /*if (m_DoseUnit.m_Techmode->Get() != AttrKey::TECHMODE_V2TYPE::ET_TIME)
  1470. {
  1471. FireNotify(AttrKey::MA, to_string(0));
  1472. }
  1473. else
  1474. {*/
  1475. m_DoseUnit.m_MA->Update(fma);
  1476. FireNotify(AttrKey::MA, m_DoseUnit.m_MA->JSGet());
  1477. /*}*/
  1478. };
  1479. auto HWMS = [this](const char* value, int length)
  1480. {
  1481. assert(value);
  1482. float fms = atof(value) / 10.0;
  1483. /*if (m_DoseUnit.m_Techmode->Get() != AttrKey::TECHMODE_V2TYPE::ET_TIME)
  1484. {
  1485. FireNotify(AttrKey::MS, to_string(0));
  1486. }
  1487. else
  1488. {*/
  1489. m_DoseUnit.m_MS->Update(fms);
  1490. FireNotify(AttrKey::MS, m_DoseUnit.m_MS->JSGet());
  1491. /*}*/
  1492. };
  1493. auto HWFocus = [this](const char* value, int length)
  1494. {
  1495. assert(value);
  1496. int nfous = atoi(value);
  1497. m_DoseUnit.m_Focus->Update(nfous);
  1498. {
  1499. FireNotify(AttrKey::FOCUS, m_DoseUnit.m_Focus->JSGet());
  1500. FINFO("Current focus:{$}, FO={$}", atoi(m_DoseUnit.m_Focus->JSGet().c_str()) ? "large focus" : "small focus", m_DoseUnit.m_Focus->JSGet().c_str());
  1501. }
  1502. };
  1503. auto HWTechmode = [this](const char* value, int length)
  1504. {
  1505. assert(value);
  1506. int ntechmode = atoi(value);
  1507. m_DoseUnit.m_Techmode->Update(ntechmode);
  1508. FireNotify(AttrKey::TECHMODE, m_DoseUnit.m_Techmode->JSGet());
  1509. switch (ntechmode)
  1510. {
  1511. case 0:
  1512. FINFO("ET={$}", "mA/ms", m_DoseUnit.m_Techmode->JSGet().c_str());
  1513. break;
  1514. case 1:
  1515. FINFO("ET={$}", "mAs", m_DoseUnit.m_Techmode->JSGet().c_str());
  1516. break;
  1517. case 2:
  1518. FINFO("ET={$}", "AEC / mA", m_DoseUnit.m_Techmode->JSGet().c_str());
  1519. break;
  1520. case 3:
  1521. FINFO("ET={$}", "mAs / ms", m_DoseUnit.m_Techmode->JSGet().c_str());
  1522. break;
  1523. case 4:
  1524. FINFO("ET={$}", "AEC", m_DoseUnit.m_Techmode->JSGet().c_str());
  1525. break;
  1526. }
  1527. };
  1528. auto HWAECField = [this](const char* value, int length)
  1529. {
  1530. assert(value);
  1531. int nvalue = atoi(value);
  1532. if (m_DoseUnit.m_AECField->Update(nvalue))
  1533. FireNotify(AttrKey::AECFIELD, m_DoseUnit.m_AECField->JSGet());
  1534. };
  1535. auto HWAECFilm = [this](const char* value, int length)
  1536. {
  1537. assert(value);
  1538. int nvalue = atoi(value);
  1539. if (m_DoseUnit.m_AECFilm->Update(nvalue))
  1540. FireNotify(AttrKey::AECFILM, m_DoseUnit.m_AECFilm->JSGet());
  1541. };
  1542. auto HWAECDensity = [this](const char* value, int length)
  1543. {
  1544. assert(value);
  1545. int nvalue = atoi(value);
  1546. if (m_DoseUnit.m_AECDensity->Update(nvalue))
  1547. FireNotify(AttrKey::AECDENSITY, m_DoseUnit.m_AECDensity->JSGet());
  1548. };
  1549. auto HWWS = [this](const char* value, int length)
  1550. {
  1551. assert(value);
  1552. int nValue = atoi(value);
  1553. if (m_DoseUnit.m_WS->Update(nValue))
  1554. {
  1555. FireNotify(m_DoseUnit.m_WS->GetKey(), m_DoseUnit.m_WS->JSGet());
  1556. }
  1557. };
  1558. auto HWPR = [this](const char* value, int length)
  1559. {
  1560. assert(value);
  1561. int nValue = atoi(value);
  1562. if (nValue == 2)
  1563. {
  1564. FINFO("The high voltage generator enters the exposure preparation stage");
  1565. HWSend("PR2");
  1566. }
  1567. else if (nValue == 1)
  1568. {
  1569. HWSend("PR1");
  1570. m_iLoopTime = REMEDYST_LoopExpTime;
  1571. if (m_DoseUnit.m_GenSynState->Update(AttrKey::GENERATOR_RAD_PREPARE))
  1572. {
  1573. FireNotify(m_DoseUnit.m_GenSynState->GetKey(), m_DoseUnit.m_GenSynState->JSGet());
  1574. FINFO("Generator exposure process status:{$};", "GENERATOR_RAD_PREPARE");
  1575. }
  1576. }
  1577. else if (nValue == 0)
  1578. {
  1579. HWSend("PR0");
  1580. if (m_DoseUnit.m_GenSynState->Update(AttrKey::GENERATOR_RAD_OFF));
  1581. {
  1582. FireNotify(m_DoseUnit.m_GenSynState->GetKey(), m_DoseUnit.m_GenSynState->JSGet());
  1583. FINFO("Generator exposure process status:{$};", "GENERATOR_RAD_OFF");
  1584. FINFO("HWPR m_DoseUnit.m_GenSynState->JSGet()={$}", m_DoseUnit.m_GenSynState->JSGet().c_str());
  1585. RefreshData();
  1586. }
  1587. }
  1588. };
  1589. auto HWXR = [this](const char* value, int length)
  1590. {
  1591. assert(value);
  1592. int nValue = atoi(value);
  1593. if (nValue == 1)
  1594. {
  1595. HWSend("XR1");
  1596. if (m_DoseUnit.m_GenSynState->Update(AttrKey::GENERATOR_RAD_READY))
  1597. {
  1598. FireNotify(m_DoseUnit.m_GenSynState->GetKey(), m_DoseUnit.m_GenSynState->JSGet());
  1599. FINFO("Generator exposure process status:{$};", "GENERATOR_RAD_READY");
  1600. }
  1601. }
  1602. else if (nValue == 2)
  1603. {
  1604. HWSend("XR2");
  1605. if (m_DoseUnit.m_GenState->Update(nsGEN::AttrKey::GENERATOR_STATUS_EXP))
  1606. FireNotify(AttrKey::GENSTATE, m_DoseUnit.m_GenState->JSGet());
  1607. if (m_DoseUnit.m_GenSynState->Update(AttrKey::GENERATOR_RAD_XRAYON))
  1608. {
  1609. FireNotify(m_DoseUnit.m_GenSynState->GetKey(), m_DoseUnit.m_GenSynState->JSGet());
  1610. FINFO("Generator exposure process status:{$};", "GENERATOR_RAD_XRAYON");
  1611. }
  1612. }
  1613. else if (nValue == 0)
  1614. {
  1615. HWSend("XR0");
  1616. if(m_DoseUnit.m_GenSynState->Update(AttrKey::GENERATOR_RAD_XRAYOFF));
  1617. {
  1618. FireNotify(m_DoseUnit.m_GenSynState->GetKey(), m_DoseUnit.m_GenSynState->JSGet());
  1619. FINFO("Generator exposure process status:{$};", "GENERATOR_RAD_XRAYOFF");
  1620. FINFO("HWXR m_DoseUnit.m_GenSynState->JSGet()={$}", m_DoseUnit.m_GenSynState->JSGet().c_str());
  1621. HWSend("AP?");
  1622. Sleep(30);
  1623. HWSend("AT?");
  1624. Sleep(30);
  1625. }
  1626. }
  1627. };
  1628. auto HWVPDOSE = [this](const char* value, int length)//mas
  1629. {
  1630. assert(value);
  1631. m_DoseUnit.m_PostKV->Update(atof(value));
  1632. FireNotify(AttrKey::POSTKV, m_DoseUnit.m_PostKV->JSGet());
  1633. FINFO("Actual exposure parameters KV:{$}", m_DoseUnit.m_PostKV->JSGet().c_str());
  1634. };
  1635. auto HWAPDOSE = [this](const char* value, int length)//mas
  1636. {
  1637. assert(value);
  1638. m_DoseUnit.m_PostMAS->Update(atof(value) / 10.0);
  1639. FireNotify(m_DoseUnit.m_PostMAS->GetKey(), m_DoseUnit.m_PostMAS->JSGet());
  1640. m_DoseUnit.m_PostKV->Update(m_DoseUnit.m_KV->Get());
  1641. FireNotify(AttrKey::POSTKV, m_DoseUnit.m_PostKV->JSGet());
  1642. FINFO("Actual exposure parametersMAS:{$}", m_DoseUnit.m_PostMAS->JSGet().c_str());
  1643. };
  1644. auto HWATDOSE = [this](const char* value, int length)
  1645. {
  1646. assert(value);
  1647. m_DoseUnit.m_PostMS->Update(atof(value) / 10.0);
  1648. FireNotify(m_DoseUnit.m_PostMS->GetKey(), m_DoseUnit.m_PostMS->JSGet());
  1649. m_DoseUnit.m_PostMA->Update(m_DoseUnit.m_PostMAS->Get() * 1000.0 / m_DoseUnit.m_PostMS->Get());
  1650. FireNotify(m_DoseUnit.m_PostMA->GetKey(), m_DoseUnit.m_PostMA->JSGet());
  1651. FINFO("Actual exposure parametersMS:{$}", m_DoseUnit.m_PostMS->JSGet().c_str());
  1652. };
  1653. auto HWDAPST = [this](const char* value, int length)
  1654. {
  1655. assert(value);
  1656. int dapStatus = atoi(value);
  1657. if (dapStatus == 1)
  1658. {
  1659. m_bDAPEnable = true;
  1660. m_bAKEnable = false;
  1661. }
  1662. else if (dapStatus == 2)
  1663. {
  1664. m_bDAPEnable = false;
  1665. m_bAKEnable = true;
  1666. }
  1667. else if (dapStatus == 3)
  1668. {
  1669. m_bDAPEnable = true;
  1670. m_bAKEnable = true;
  1671. }
  1672. else
  1673. {
  1674. m_bDAPEnable = false;
  1675. m_bAKEnable = false;
  1676. }
  1677. };
  1678. auto HWDT = [this](const char* value, int length)
  1679. {
  1680. assert(value);
  1681. int dapStatus = atoi(value);
  1682. if (dapStatus == 0)
  1683. {
  1684. m_bDAPEnable = false;
  1685. FINFO("DAP test failed");
  1686. }
  1687. else if (dapStatus == 1)
  1688. {
  1689. m_bDAPEnable = true;
  1690. FINFO("DAP test passed");
  1691. }
  1692. else if (dapStatus == 2)
  1693. {
  1694. m_bDAPEnable = true;
  1695. FINFO("DAP test in progress.");
  1696. }
  1697. };
  1698. auto HWDAP = [this](const char* value, int length)
  1699. {
  1700. assert(value);
  1701. //m_DoseUnit.->Update(atof(value));
  1702. //FireNotify(m_DoseUnit.m_PostMS->GetKey(), m_DoseUnit.m_PostMS->JSGet());
  1703. //SetEvent(m_hGenPostEvent);
  1704. m_DAP->Update(atof(value)); //should push to subsystem.......
  1705. };
  1706. auto HWEL = [this](const char* value, int length)
  1707. {
  1708. HandleError(value, "REMEDY_EL_", "EL");
  1709. };
  1710. auto HWER = [this](const char* value, int length)
  1711. {
  1712. HandleError(value, "REMEDY_ER_", "ER");
  1713. };
  1714. auto HWWARN = [this](const char* value, int length)
  1715. {
  1716. HandleError(value, "REMEDY_WARN_", "EW");
  1717. };
  1718. auto HWEHE = [this](const char* value, int length)
  1719. {
  1720. assert(value);
  1721. int nhe = atoi(value);
  1722. if (m_DoseUnit.m_HE->Update(nhe))
  1723. FireNotify(m_DoseUnit.m_HE->GetKey(), m_DoseUnit.m_HE->JSGet());
  1724. };
  1725. //075 FLM100 FLI000 FLT006 FLF2 FLA0 FLS060 FLZ0 FLD0
  1726. auto HWFLK = [this](const char* value, int length)
  1727. {
  1728. assert(value);
  1729. if (length > 20) // Check if length is more than 20
  1730. {
  1731. FINFO("HWFLK={$}", value);
  1732. int tmpflk, tmpflf, tmpfla, tmpfld, tmpflo;
  1733. float tmpflm, tmpfli, tmpflt, tmpfls, tmpflw;
  1734. char tmpbuf[3]{ 0, 0, 0 };
  1735. //flk
  1736. tmpbuf[0] = value[0];
  1737. tmpbuf[1] = value[1];
  1738. tmpbuf[2] = value[2];
  1739. tmpflk = atoi(tmpbuf);
  1740. if (m_DoseUnit.m_FLKV->Update(tmpflk))
  1741. FireNotify(AttrKey::FLUKV, m_DoseUnit.m_FLKV->JSGet());
  1742. // flm
  1743. tmpbuf[0] = value[7];
  1744. tmpbuf[1] = value[8];
  1745. tmpbuf[2] = value[9];
  1746. tmpflm = atof(tmpbuf) / 10.0;
  1747. if (m_DoseUnit.m_FLMA->Update(tmpflm))
  1748. FireNotify(AttrKey::FLUMA, m_DoseUnit.m_FLMA->JSGet());
  1749. // fli
  1750. tmpbuf[0] = value[14];
  1751. tmpbuf[1] = value[15];
  1752. tmpbuf[2] = value[16];
  1753. tmpfli = atof(tmpbuf) / 10.0;
  1754. if (m_DoseUnit.m_FLIntTime->Update(tmpfli))
  1755. FireNotify(AttrKey::FLUIntTime, m_DoseUnit.m_FLIntTime->JSGet());
  1756. // flt
  1757. tmpbuf[0] = value[21];
  1758. tmpbuf[1] = value[22];
  1759. tmpbuf[2] = value[23];
  1760. tmpflt = atof(tmpbuf) / 10.0;
  1761. if (m_DoseUnit.m_FLAccTime->Update(tmpflt))
  1762. FireNotify(AttrKey::FLUAccTime, m_DoseUnit.m_FLAccTime->JSGet());
  1763. // flf
  1764. tmpbuf[0] = value[28];
  1765. tmpbuf[1] = 0;
  1766. tmpbuf[2] = 0;
  1767. tmpflf = atoi(tmpbuf);
  1768. if (m_DoseUnit.m_FLMode->Update(tmpflf))
  1769. FireNotify(AttrKey::FLUMode, m_DoseUnit.m_FLMode->JSGet());
  1770. // fla
  1771. tmpbuf[0] = value[33];
  1772. tmpfla = atoi(tmpbuf);
  1773. if (m_DoseUnit.m_ABSStatus->Update(tmpfla))
  1774. FireNotify(AttrKey::FLUABSStatus, m_DoseUnit.m_ABSStatus->JSGet());
  1775. // fls
  1776. tmpbuf[0] = value[38];
  1777. tmpbuf[1] = value[39];
  1778. tmpbuf[2] = value[40];
  1779. tmpfls = atof(tmpbuf) / 10.0;
  1780. if (m_DoseUnit.m_PPS->Update(tmpfls))
  1781. FireNotify(AttrKey::FLUPPS, m_DoseUnit.m_PPS->JSGet());
  1782. // fld
  1783. tmpbuf[0] = value[50];
  1784. tmpbuf[1] = 0;
  1785. tmpbuf[2] = 0;
  1786. tmpfld = atoi(tmpbuf);
  1787. if (m_DoseUnit.m_DoseLevel->Update(tmpfld))
  1788. FireNotify(AttrKey::FLUDoseLevel, m_DoseUnit.m_DoseLevel->JSGet());
  1789. FINFO("tmpflk={$}, tmpflf={$}, tmpfla={$}, tmpfld={$}, tmpflm={$}, tmpfli={$}, tmpflt={$}, tmpfls={$};", tmpflk, tmpflf, tmpfla, tmpfld, tmpflm, tmpfli, tmpflt, tmpfls);
  1790. }
  1791. else
  1792. {
  1793. if (m_DoseUnit.m_FLKV->Update(atof(value)))
  1794. FireNotify(AttrKey::FLUKV, m_DoseUnit.m_FLKV->JSGet());
  1795. }
  1796. };
  1797. auto HWFLM = [this](const char* value, int length)
  1798. {
  1799. assert(value);
  1800. float tmpflm = atof(value) / 10.0;
  1801. if (m_DoseUnit.m_FLMA->Update(tmpflm))
  1802. FireNotify(AttrKey::FLUMA, m_DoseUnit.m_FLMA->JSGet());
  1803. };
  1804. auto HWFLS = [this](const char* value, int length)
  1805. {
  1806. assert(value);
  1807. FINFO("HWFLS={$}", value);
  1808. float tmppps = atof(value) / 10.0;
  1809. if (m_DoseUnit.m_PPS->Update(tmppps))
  1810. FireNotify(AttrKey::FLUPPS, m_DoseUnit.m_PPS->JSGet());
  1811. };
  1812. auto HWFLX = [this](const char* value, int length)
  1813. {
  1814. assert(value);
  1815. int nValue = atoi(value);
  1816. if (nValue == 0)
  1817. {
  1818. HWSend("FLX0");
  1819. if (m_DoseUnit.m_GenSynState->Update(AttrKey::GENERATOR_FLU_XRAYOFF))
  1820. {
  1821. FINFO("Generator exposure process status{$};", "GENERATOR_FLU_XRAYOFF");
  1822. FireNotify(m_DoseUnit.m_GenSynState->GetKey(), m_DoseUnit.m_GenSynState->JSGet());
  1823. }
  1824. }
  1825. else
  1826. {
  1827. HWSend("FLX1");
  1828. if (m_DoseUnit.m_GenState->Update(nsGEN::AttrKey::GENERATOR_STATUS_EXP))
  1829. FireNotify(AttrKey::GENSTATE, m_DoseUnit.m_GenState->JSGet());
  1830. if (m_DoseUnit.m_GenSynState->Update(AttrKey::GENERATOR_FLU_XRAYON))
  1831. {
  1832. FINFO("Generator exposure process status{$};", "GENERATOR_FLU_XRAYON");
  1833. FireNotify(m_DoseUnit.m_GenSynState->GetKey(), m_DoseUnit.m_GenSynState->JSGet());
  1834. }
  1835. }
  1836. };
  1837. auto HWFLP = [this](const char* value, int length)
  1838. {
  1839. assert(value);
  1840. int nValue = atoi(value);
  1841. if (nValue == 0)
  1842. {
  1843. if (m_iLoopTime == REMEDYST_LoopExpTime)
  1844. {
  1845. if ((int)m_GenConfig["loopTime"] >= 100)
  1846. {
  1847. m_iLoopTime = (int)m_GenConfig["loopTime"];
  1848. }
  1849. else
  1850. m_iLoopTime = REMEDYST_LoopDefTime;
  1851. FDEBUG("reduction loopTime[{$}]->[{$}]", REMEDYST_LoopExpTime, m_iLoopTime.load());
  1852. }
  1853. HWSend("FLP0");
  1854. if (m_DoseUnit.m_GenSynState->Update(AttrKey::GENERATOR_FLU_OFF))
  1855. {
  1856. FINFO("{$};", "GENERATOR_FLU_OFF");
  1857. FireNotify(m_DoseUnit.m_GenSynState->GetKey(), m_DoseUnit.m_GenSynState->JSGet());
  1858. }
  1859. RefreshData();
  1860. }
  1861. else
  1862. {
  1863. m_iLoopTime = REMEDYST_LoopExpTime;
  1864. HWSend("FLP1");
  1865. if (m_DoseUnit.m_GenSynState->Update(AttrKey::GENERATOR_FLU_READY))
  1866. {
  1867. FINFO("Generator exposure process status{$};", "GENERATOR_FLU_READY");
  1868. FireNotify(m_DoseUnit.m_GenSynState->GetKey(), m_DoseUnit.m_GenSynState->JSGet());
  1869. }
  1870. }
  1871. };
  1872. auto HWFLF = [this](const char* value, int length)
  1873. {
  1874. assert(value);
  1875. FINFO("HWFLF={$};", value);
  1876. int tmpflf = atoi(value);
  1877. if (m_DoseUnit.m_FLMode->Update(tmpflf))
  1878. FireNotify(AttrKey::FLUMode, m_DoseUnit.m_FLMode->JSGet());
  1879. };
  1880. auto HWFLA = [this](const char* value, int length)
  1881. {
  1882. assert(value);
  1883. int tmpfla = atoi(value);
  1884. if (m_DoseUnit.m_ABSStatus->Update(tmpfla))
  1885. FireNotify(AttrKey::FLUABSStatus, m_DoseUnit.m_ABSStatus->JSGet());
  1886. };
  1887. auto HWFLD = [this](const char* value, int length)
  1888. {
  1889. assert(value);
  1890. };
  1891. auto HWFLC = [this](const char* value, int length)
  1892. {
  1893. assert(value);
  1894. };
  1895. auto HWFLO = [this](const char* value, int length)
  1896. {
  1897. assert(value);
  1898. int nValue = atoi(value);
  1899. if (m_DoseUnit.m_Curve->Update(nValue))
  1900. FireNotify(AttrKey::FLUCurve, m_DoseUnit.m_Curve->JSGet());
  1901. };
  1902. auto HWFLW = [this](const char* value, int length)
  1903. {
  1904. assert(value);;
  1905. float tmpflms = atof(value) / 100.0;
  1906. if (m_DoseUnit.m_FLMS->Update(tmpflms))
  1907. FireNotify(AttrKey::FLUMS, m_DoseUnit.m_FLMS->JSGet());
  1908. };
  1909. auto HWFLI = [this](const char* value, int length)
  1910. {
  1911. assert(value);
  1912. float tmpfli = atof(value) / 10.0;
  1913. if (m_DoseUnit.m_FLIntTime->Update(tmpfli))
  1914. FireNotify(AttrKey::FLUIntTime, m_DoseUnit.m_FLIntTime->JSGet());
  1915. };
  1916. auto HWFLT = [this](const char* value, int length)
  1917. {
  1918. assert(value);
  1919. float tmpflt = atof(value) / 10.0;
  1920. if (m_DoseUnit.m_FLAccTime->Update(tmpflt))
  1921. FireNotify(AttrKey::FLUAccTime, m_DoseUnit.m_FLAccTime->JSGet());
  1922. };
  1923. arFrame.clear();
  1924. arFrame.push_back(tFrameMapping("KV", 2, HWKV));
  1925. arFrame.push_back(tFrameMapping("TU", 2, HWTU));
  1926. arFrame.push_back(tFrameMapping("MX", 2, HWMAS));
  1927. arFrame.push_back(tFrameMapping("MA", 2, HWMA));
  1928. arFrame.push_back(tFrameMapping("MS", 2, HWMS));
  1929. arFrame.push_back(tFrameMapping("ET", 2, HWTechmode));
  1930. arFrame.push_back(tFrameMapping("FO", 2, HWFocus));
  1931. arFrame.push_back(tFrameMapping("FI", 2, HWAECField));
  1932. arFrame.push_back(tFrameMapping("FS", 2, HWAECFilm));
  1933. arFrame.push_back(tFrameMapping("FN", 2, HWAECDensity));
  1934. arFrame.push_back(tFrameMapping("WS", 2, HWWS));
  1935. arFrame.push_back(tFrameMapping("PR", 2, HWPR));
  1936. arFrame.push_back(tFrameMapping("XR", 2, HWXR));
  1937. arFrame.push_back(tFrameMapping("VP", 2, HWVPDOSE));
  1938. arFrame.push_back(tFrameMapping("AP", 2, HWAPDOSE));
  1939. arFrame.push_back(tFrameMapping("AT", 2, HWATDOSE));
  1940. arFrame.push_back(tFrameMapping("EL", 2, HWEL));
  1941. arFrame.push_back(tFrameMapping("ER", 2, HWER));
  1942. arFrame.push_back(tFrameMapping("EW", 2, HWWARN));
  1943. arFrame.push_back(tFrameMapping("HE", 2, HWEHE));
  1944. arFrame.push_back(tFrameMapping("FLK", 3, HWFLK));
  1945. arFrame.push_back(tFrameMapping("FLM", 3, HWFLM));
  1946. arFrame.push_back(tFrameMapping("FLS", 3, HWFLS));
  1947. arFrame.push_back(tFrameMapping("FLF", 3, HWFLF));
  1948. arFrame.push_back(tFrameMapping("FLP", 3, HWFLP));
  1949. arFrame.push_back(tFrameMapping("FLX", 3, HWFLX));
  1950. arFrame.push_back(tFrameMapping("FLW", 3, HWFLW));
  1951. arFrame.push_back(tFrameMapping("FLI", 3, HWFLI));
  1952. arFrame.push_back(tFrameMapping("FLT", 3, HWFLT));
  1953. arFrame.push_back(tFrameMapping("FLA", 3, HWFLA));
  1954. arFrame.push_back(tFrameMapping("FLD", 3, HWFLD));
  1955. arFrame.push_back(tFrameMapping("FLC", 3, HWFLD));
  1956. arFrame.push_back(tFrameMapping("FLO", 3, HWFLO));
  1957. arFrame.push_back(tFrameMapping("ST", 2, HWST));
  1958. arFrame.push_back(tFrameMapping("EC", 2, HWEC));
  1959. arFrame.push_back(tFrameMapping("DS", 2, HWDAPST)); //dap status
  1960. arFrame.push_back(tFrameMapping("DA", 2, HWDAP)); //dap value
  1961. arFrame.push_back(tFrameMapping("DT", 2, HWDT)); //test dap
  1962. }
  1963. bool nsGEN::REMEDYSTDevice::StartHardwareStatusThread()
  1964. {
  1965. FINFO("========================================");
  1966. FINFO("Starting Hardware Status Thread...");
  1967. if (!m_pHardwareStatusThread.joinable())
  1968. {
  1969. FINFO("Creating new hardware status thread");
  1970. m_pHardwareStatusThread = std::thread(HardwareStatusThread, this);
  1971. FINFO("Hardware status thread created successfully");
  1972. FINFO("========================================");
  1973. return true;
  1974. }
  1975. FWARN("Hardware status thread already running");
  1976. FINFO("========================================");
  1977. return false;
  1978. }
  1979. void nsGEN::REMEDYSTDevice::HardwareStatusThread(REMEDYSTDevice* pParam)
  1980. {
  1981. FINFO("========================================");
  1982. FINFO("HardwareStatusThread Entry");
  1983. FINFO("========================================");
  1984. REMEDYSTDevice* pCurGen = pParam;
  1985. if (pCurGen == NULL)
  1986. {
  1987. FERROR("HardwareStatusThread: pParam is NULL, exiting thread");
  1988. return;
  1989. }
  1990. int currtTime = pCurGen->m_iLoopTime;
  1991. int messageIndex = 0;
  1992. int loopCount = 0;
  1993. FINFO("Hardware status monitoring started");
  1994. FINFO("Initial loop time: {$} ms", currtTime);
  1995. while (pCurGen->m_bExtraFlag)
  1996. {
  1997. // 检查循环时间是否变化
  1998. if (currtTime != pCurGen->m_iLoopTime)
  1999. {
  2000. FINFO("Loop time changed from {$} ms to {$} ms", currtTime, pCurGen->m_iLoopTime.load());
  2001. currtTime = pCurGen->m_iLoopTime;
  2002. }
  2003. Sleep(currtTime);
  2004. loopCount++;
  2005. // 每10次循环打印一次统计信息
  2006. if (loopCount % 10 == 0)
  2007. {
  2008. FINFO("Hardware status thread loop count: {$}", loopCount);
  2009. }
  2010. // 发送不同的信息,通过messageIndex循环
  2011. switch (messageIndex)
  2012. {
  2013. case 0:
  2014. FINFO("Sending HE? query (Heat Exchanger status)");
  2015. pCurGen->HWSend("HE?");
  2016. break;
  2017. case 1:
  2018. FINFO("Sending ST query (Status)");
  2019. pCurGen->HWSend("ST");
  2020. break;
  2021. default:
  2022. FERROR("Unexpected messageIndex: {$}", messageIndex);
  2023. break;
  2024. }
  2025. // 更新messageIndex以便下一次发送不同的信息
  2026. messageIndex = (messageIndex + 1) % 2;
  2027. }
  2028. FINFO("========================================");
  2029. FINFO("Hardware status thread stopping...");
  2030. FINFO("Total loop count: {$}", loopCount);
  2031. FINFO("HardwareStatusThread Exit");
  2032. FINFO("========================================");
  2033. }
  2034. //-----------------------------------------------------------------------------
  2035. // REMEDYSTDriver
  2036. //-----------------------------------------------------------------------------
  2037. nsGEN::REMEDYSTDriver::REMEDYSTDriver()
  2038. : m_scfWrapper(std::make_shared<SCFWrapper>())
  2039. {
  2040. }
  2041. nsGEN::REMEDYSTDriver::~REMEDYSTDriver()
  2042. {
  2043. Disconnect();
  2044. }
  2045. auto nsGEN::REMEDYSTDriver::CreateDevice(int index) -> std::unique_ptr <IODevice>
  2046. {
  2047. FINFO("CreateDevice in\n");
  2048. m_pDevice = new REMEDYSTDevice(EventCenter, m_scfWrapper, m_ConfigFileName);
  2049. auto dev = std::unique_ptr <IODevice>(new IODevice(m_pDevice));
  2050. FINFO("CreateDevice out\n");
  2051. return dev;
  2052. }
  2053. void nsGEN::REMEDYSTDriver::FireNotify(int code, std::string key, std::string content)
  2054. {
  2055. EventCenter->OnNotify(code, key, content);
  2056. }
  2057. void nsGEN::REMEDYSTDriver::Prepare()
  2058. {
  2059. FINFO("========================================");
  2060. FINFO("REMEDYSTDriver::Prepare() Starting...");
  2061. FINFO("========================================");
  2062. // 初始化日志系统
  2063. std::string strLogPath = GetProcessDirectory() + R"(/Conf/log_config.xml)";
  2064. std::string LogHost = "DevREMEDYST";
  2065. std::string moduleName = "DevREMEDYST";
  2066. FINFO("Initializing log module...");
  2067. FINFO("Log config path: {$}", strLogPath.c_str());
  2068. FINFO("Log host: {$}", LogHost.c_str());
  2069. FINFO("Module name: {$}", moduleName.c_str());
  2070. bool ret = initLogModule(
  2071. LogHost, // 主机名(用于日志路径中的{host}占位符)
  2072. moduleName, // 唯一模块名
  2073. strLogPath, // 配置文件路径
  2074. true // 是否输出到控制台(可选)
  2075. );
  2076. if (!ret) {
  2077. std::cerr << "Log init failed!" << std::endl;
  2078. FERROR("Failed to initialize log module");
  2079. return;
  2080. }
  2081. FINFO("Log module initialized successfully");
  2082. Remedy_SetLocalModuleName(moduleName);
  2083. FINFO("Getting connection DLL from config: {$}", m_ConfigFileName.c_str());
  2084. m_SCFDllName = GetConnectDLL(m_ConfigFileName);
  2085. FINFO("SCF DLL name: {$}", m_SCFDllName.c_str());
  2086. FINFO("Calling parent Prepare()...");
  2087. super::Prepare();
  2088. FINFO("========================================");
  2089. FINFO("REMEDYSTDriver::Prepare() Completed");
  2090. FINFO("========================================");
  2091. }
  2092. bool DATA_ACTION nsGEN::REMEDYSTDriver::Connect()
  2093. {
  2094. std::lock_guard<std::mutex> lock(m_connectionMutex);
  2095. const auto currentState = m_connectionState.load();
  2096. auto now = std::chrono::steady_clock::now();
  2097. // 1. 处理可重试的失败状态
  2098. if (currentState == ConnectionState::Failed) {
  2099. if ((now - m_lastConnectionAttempt) >= RETRY_INTERVAL && m_connectionRetryCount < MAX_RETRY_COUNT) {
  2100. m_connectionState = ConnectionState::Disconnected;
  2101. }
  2102. else {
  2103. return false; // 不满足重试条件,直接返回
  2104. }
  2105. }
  2106. // 2. 检查无效状态(正在连接/已连接但实际有效)
  2107. if (currentState == ConnectionState::Connecting) {
  2108. FINFO("Already connecting (type: {$})",
  2109. m_currentConnType == ConnectionType::Serial ? "Serial" : "Ethernet");
  2110. return true;
  2111. }
  2112. if (currentState == ConnectionState::Connected && m_scfWrapper && m_scfWrapper->IsConnected()) {
  2113. FINFO("Already connected (type: {$})",
  2114. m_currentConnType == ConnectionType::Serial ? "Serial" : "Ethernet");
  2115. return true;
  2116. }
  2117. // 3. 检查重试间隔
  2118. if (m_connectionRetryCount > 0 && (now - m_lastConnectionAttempt) < RETRY_INTERVAL) {
  2119. FINFO("Retry in {$}s (type: {$})",
  2120. std::chrono::duration_cast<std::chrono::seconds>(RETRY_INTERVAL - (now - m_lastConnectionAttempt)).count(),
  2121. m_currentConnType == ConnectionType::Serial ? "Serial" : "Ethernet");
  2122. return false;
  2123. }
  2124. ResDataObject connParam = GetConnectParam(m_ConfigFileName);
  2125. std::string connPortStr = "";
  2126. std::string connTypeStr = (std::string)connParam["type"]; // 从配置读取type字段
  2127. m_currentConnType = (connTypeStr == "COM") ? ConnectionType::Serial : ConnectionType::Ethernet;
  2128. if (m_currentConnType == ConnectionType::Serial)
  2129. {
  2130. connPortStr = (std::string)connParam["port"];// 从配置读取port字段
  2131. // 查找配置端口在现有端口列表中的位置
  2132. auto it = std::find(m_serialPorts.begin(), m_serialPorts.end(), connPortStr);
  2133. if (it == m_serialPorts.end()) {
  2134. // 配置的端口不在列表中,添加到首位
  2135. FINFO("Configured serial port {$} not found, adding to front of port list", connPortStr);
  2136. m_serialPorts.insert(m_serialPorts.begin(), connPortStr);
  2137. }
  2138. else if (it != m_serialPorts.begin()) {
  2139. // 配置的端口存在但不在首位,移动到首位
  2140. FINFO("Moving configured serial port {$} to front of port list", connPortStr);
  2141. m_serialPorts.erase(it);
  2142. m_serialPorts.insert(m_serialPorts.begin(), connPortStr);
  2143. }
  2144. }
  2145. // 4. 执行连接流程
  2146. m_connectionState = ConnectionState::Connecting;
  2147. m_lastConnectionAttempt = now;
  2148. std::string connInfo;
  2149. try {
  2150. if (m_currentConnType == ConnectionType::Serial) {
  2151. // 串口连接:使用当前索引的端口
  2152. std::string currentPort = m_serialPorts[m_currentSerialPortIndex];
  2153. connParam.update("port", currentPort.c_str()); // 将当前尝试的端口写入参数
  2154. connInfo = "Serial (port: " + currentPort + ")";
  2155. }
  2156. else {
  2157. // 网口连接:直接使用配置参数
  2158. connInfo = "Ethernet (ip: " + std::string(connParam["ip"]) + ")";
  2159. }
  2160. FINFO("Enter Connect ({$}), config: {$}", connInfo, connParam.encode());
  2161. if (!m_scfWrapper->Initialize(m_SCFDllName)) {
  2162. FINFO("Init failed: {$}", m_scfWrapper->GetLastError());
  2163. m_connectionState = ConnectionState::Failed;
  2164. return false;
  2165. }
  2166. m_scfWrapper->SetDataReceivedCallback([this](const char* data, uint32_t length) {
  2167. this->Dequeue(data, length);
  2168. });
  2169. auto erCode = m_scfWrapper->Connect(connParam, &PSGHRDriver::callbackPackageProcess, SCF_PACKET_TRANSFER, 3000);
  2170. if (erCode != SCF_SUCCEED || !m_scfWrapper->StartAutoReceive()) {
  2171. FINFO("Connect failed (code: {$}) for {$}", erCode, connInfo);
  2172. m_scfWrapper->Disconnect();
  2173. m_connectionState = ConnectionState::Failed;
  2174. // 串口连接:未遍历完所有端口时,优先切换端口重试(不计入总重试次数)
  2175. if (m_currentConnType == ConnectionType::Serial) {
  2176. int nextIndex = (m_currentSerialPortIndex + 1) % m_serialPorts.size();
  2177. // 判断是否已遍历所有端口(当前索引是最后一个时,nextIndex会回到0)
  2178. bool allPortsTried = (nextIndex == 0);
  2179. if (!allPortsTried) {
  2180. // 未遍历完所有端口:切换到下一端口,不增加重试计数
  2181. m_currentSerialPortIndex = nextIndex;
  2182. m_connectionRetryCount = 0;
  2183. FINFO("Trying next serial port: {$}", m_serialPorts[nextIndex]);
  2184. return false; // 触发外部线程立即尝试下一端口
  2185. }
  2186. else {
  2187. // 已遍历所有端口:重置到第一个端口,增加重试计数(进入间隔等待)
  2188. m_currentSerialPortIndex = 0;
  2189. m_connectionRetryCount++;
  2190. FINFO("All serial ports tried, retry count: {$}/{$}", m_connectionRetryCount, MAX_RETRY_COUNT);
  2191. return false;
  2192. }
  2193. }
  2194. // 所有端口失败(串口)或网口失败,才增加总重试计数
  2195. m_connectionRetryCount++;
  2196. return false;
  2197. }
  2198. // 连接成功:重置状态
  2199. m_connectionState = ConnectionState::Connected;
  2200. m_connectionRetryCount = 0;
  2201. m_currentSerialPortIndex = 0; // 重置串口端口索引
  2202. FINFO("Connected successfully ({$})", connInfo);
  2203. return true;
  2204. }
  2205. catch (const std::exception& e) {
  2206. FINFO("Exception for {$}: {$}", connInfo, e.what());
  2207. m_connectionState = ConnectionState::Failed;
  2208. m_connectionRetryCount++;
  2209. return false;
  2210. }
  2211. }
  2212. void nsGEN::REMEDYSTDriver::Disconnect()
  2213. {
  2214. FINFO("========================================");
  2215. FINFO("REMEDYSTDriver::Disconnect() Entry");
  2216. if (m_scfWrapper) {
  2217. FINFO("Stopping auto receive...");
  2218. m_scfWrapper->StopAutoReceive();
  2219. FINFO("Auto receive stopped");
  2220. FINFO("Disconnecting SCF wrapper...");
  2221. m_scfWrapper->Disconnect();
  2222. FINFO("SCF wrapper disconnected");
  2223. m_connectionState = ConnectionState::Disconnected;
  2224. FINFO("Connection state set to Disconnected");
  2225. } else {
  2226. FWARN("SCF wrapper is null, nothing to disconnect");
  2227. }
  2228. FINFO("REMEDYSTDriver::Disconnect() Completed");
  2229. FINFO("========================================");
  2230. }
  2231. bool nsGEN::REMEDYSTDriver::isConnected() const
  2232. {
  2233. const auto state = m_connectionState.load();
  2234. // 1. 连接中/实际已连接:返回true(无需重连)
  2235. if (state == ConnectionState::Connecting || (m_scfWrapper && m_scfWrapper->IsConnected())) {
  2236. //FINFO(state == ConnectionState::Connecting ? "Connecting in progress" : "Already connected");
  2237. return true;
  2238. }
  2239. // 2. 失败状态处理:判断是否允许重试
  2240. if (state == ConnectionState::Failed) {
  2241. auto now = std::chrono::steady_clock::now();
  2242. const auto timeSinceLast = now - m_lastConnectionAttempt;
  2243. // 2.1 达到最大重试次数,但超过重置间隔:重置计数,允许重新重试
  2244. if (m_connectionRetryCount >= MAX_RETRY_COUNT && timeSinceLast >= RESET_RETRY_AFTER) {
  2245. FINFO("Max retries reached, resetting count after {$}s",
  2246. std::chrono::duration_cast<std::chrono::seconds>(timeSinceLast).count());
  2247. m_connectionRetryCount = 0; // 重置计数(因mutable修饰,const函数可修改)
  2248. }
  2249. // 2.2 不适合重连(时间未到 或 次数仍超限):返回true阻止重连
  2250. if (timeSinceLast < RETRY_INTERVAL || m_connectionRetryCount >= MAX_RETRY_COUNT) {
  2251. FINFO(timeSinceLast < RETRY_INTERVAL ?
  2252. "Retry later ({$}s)" : "Max retries, waiting {$}s to reset",
  2253. std::chrono::duration_cast<std::chrono::seconds>(
  2254. timeSinceLast < RETRY_INTERVAL ? RETRY_INTERVAL - timeSinceLast : RESET_RETRY_AFTER - timeSinceLast
  2255. ).count()
  2256. );
  2257. return true;
  2258. }
  2259. }
  2260. // 3. 其他情况(适合重连):返回false触发Connect()
  2261. return false;
  2262. }
  2263. std::string nsGEN::REMEDYSTDriver::DriverProbe()
  2264. {
  2265. FINFO("DriverProbe in \n");
  2266. ResDataObject r_config, HardwareInfo;
  2267. if (r_config.loadFile(m_ConfigFileName.c_str()))
  2268. {
  2269. HardwareInfo.add("MajorID", r_config["CONFIGURATION"]["MajorID"]);
  2270. HardwareInfo.add("MinorID", r_config["CONFIGURATION"]["MinorID"]);
  2271. HardwareInfo.add("VendorID", r_config["CONFIGURATION"]["VendorID"]);
  2272. HardwareInfo.add("ProductID", r_config["CONFIGURATION"]["ProductID"]);
  2273. HardwareInfo.add("SerialID", r_config["CONFIGURATION"]["SerialID"]);
  2274. }
  2275. else
  2276. {
  2277. HardwareInfo.add("MajorID", "Generator");
  2278. HardwareInfo.add("MinorID", "Dr");
  2279. HardwareInfo.add("VendorID", "REMEDYST");
  2280. HardwareInfo.add("ProductID", "HF");
  2281. HardwareInfo.add("SerialID", "Drv");
  2282. }
  2283. string ret = HardwareInfo.encode();
  2284. FINFO("DriverProbe out \n");
  2285. return ret;
  2286. }
  2287. std::string nsGEN::REMEDYSTDriver::GetResource()
  2288. {
  2289. ResDataObject temp;
  2290. if (!temp.loadFile(m_ConfigFileName.c_str()))
  2291. return std::string();
  2292. auto r_config = temp["CONFIGURATION"];
  2293. for (auto& Item : m_ConfigInfo)
  2294. {
  2295. string key = Item.GetKey();
  2296. if (key == ConfKey::CcosGeneratorType)
  2297. {
  2298. Item.SetCurrentValue(((string)r_config["VendorID"]).c_str());
  2299. }
  2300. else if (key == ConfKey::CcosGeneratorModel)
  2301. {
  2302. Item.SetCurrentValue(((string)r_config["ProductID"]).c_str());
  2303. }
  2304. else if (key == ConfKey::CcosWSTable || key == ConfKey::CcosWSWall || key == ConfKey::CcosWSFree
  2305. || key == ConfKey::CcosWSTomo || key == ConfKey::CcosWSConventional)
  2306. {
  2307. Item.SetCurrentValue(((string)r_config[key.c_str()]).c_str());
  2308. }
  2309. else if (key == ConfKey::CcosSynTable || key == ConfKey::CcosSynWall || key == ConfKey::CcosSynFree
  2310. || key == ConfKey::CcosSynTomo || key == ConfKey::CcosSynConventional)
  2311. {
  2312. Item.SetCurrentValue(((string)r_config[key.c_str()]).c_str());
  2313. }
  2314. else if (key == ConfKey::CcosSCFType)
  2315. {
  2316. Item.SetCurrentValue(((string)r_config["connections"][0]["type"]).c_str());
  2317. }
  2318. else if (key == ConfKey::CcosSCFPort || key == ConfKey::CcosSCFBaudrate || key == ConfKey::CcosSCFBytesize
  2319. || key == ConfKey::CcosSCFParity || key == ConfKey::CcosSCFStopbits || key == ConfKey::CcosSCFIP)
  2320. {
  2321. if (r_config["connections"][0].GetFirstOf(key.c_str()) >= 0)
  2322. {
  2323. Item.SetCurrentValue(((string)r_config["connections"][0][key.c_str()]).c_str());
  2324. }
  2325. }
  2326. }
  2327. ResDataObject resAttr, resDescription;
  2328. for (auto Item : m_ConfigInfo)
  2329. {
  2330. resAttr.add(Item.GetKey(), Item.GetCurrentValue());
  2331. resDescription.add(Item.GetKey(), Item.GetDescription());
  2332. }
  2333. ResDataObject resDeviceResource;
  2334. resDeviceResource.add(ConfKey::CcosGeneratorAttribute, resAttr);
  2335. resDeviceResource.add(ConfKey::CcosGeneratorDescription, resDescription);
  2336. string res = resDeviceResource.encode();
  2337. //printf("resDeviceResource :%s \n", resDeviceResource.encode());
  2338. FINFO("resDeviceResource :{$} \n", resDeviceResource.encode());
  2339. ResDataObject DescriptionTempEx;
  2340. DescriptionTempEx.add(ConfKey::CcosGeneratorConfig, resDeviceResource);
  2341. m_DeviceConfig.clear();
  2342. m_DeviceConfig = DescriptionTempEx;
  2343. return res;
  2344. }
  2345. bool nsGEN::REMEDYSTDriver::GetDeviceConfig(std::string& Cfg)
  2346. {
  2347. //Cfg = m_DeviceConfigSend.encode();
  2348. Cfg = m_DeviceConfig.encode();
  2349. //printf("GetDeviceConfig over");
  2350. printf("GetDeviceConfig over , %s", Cfg.c_str());
  2351. return true;
  2352. }
  2353. bool nsGEN::REMEDYSTDriver::SetDeviceConfig(std::string Cfg)
  2354. {
  2355. FINFO("--Func-- SetDeviceConfig {$}\n", Cfg.c_str());
  2356. return true;
  2357. }
  2358. bool nsGEN::REMEDYSTDriver::SaveConfigFile(bool bSendNotify)
  2359. {
  2360. m_ConfigAll["CONFIGURATION"] = m_Configurations;
  2361. bool bRt = m_ConfigAll.SaveFile(m_ConfigFileName.c_str());
  2362. FINFO("SaveConfigFile over {$}", bRt);
  2363. return true;
  2364. }
  2365. std::string nsGEN::REMEDYSTDriver::DeviceProbe()
  2366. {
  2367. FINFO("std::string nsGEN::PSGRFDriver::DeviceProbe() in\n");
  2368. ResDataObject r_config, HardwareInfo;
  2369. if (r_config.loadFile(m_ConfigFileName.c_str()))
  2370. {
  2371. HardwareInfo.add("MajorID", r_config["CONFIGURATION"]["MajorID"]);
  2372. HardwareInfo.add("MinorID", r_config["CONFIGURATION"]["MinorID"]);
  2373. HardwareInfo.add("VendorID", r_config["CONFIGURATION"]["VendorID"]);
  2374. HardwareInfo.add("ProductID", r_config["CONFIGURATION"]["ProductID"]);
  2375. HardwareInfo.add("SerialID", r_config["CONFIGURATION"]["SerialID"]);
  2376. }
  2377. else
  2378. {
  2379. HardwareInfo.add("MajorID", "Generator");
  2380. HardwareInfo.add("MinorID", "Dr");
  2381. HardwareInfo.add("VendorID", "REMEDYST");
  2382. HardwareInfo.add("ProductID", "HF");
  2383. HardwareInfo.add("SerialID", "1234");
  2384. }
  2385. string ret = HardwareInfo.encode();
  2386. FINFO("std::string nsGEN::PSGRFDriver::DeviceProbe() out\n");
  2387. return ret;
  2388. }
  2389. void nsGEN::REMEDYSTDriver::Dequeue(const char* Packet, DWORD Length)
  2390. {
  2391. DecodeFrame(Packet, Length);
  2392. }
  2393. /*
  2394. ==IN==:KV070 MA00320 MS00063 MX00036
  2395. ==IN==:TU0 WS1 FO0 ET0 FI010 FS001 FN 0 HE000
  2396. how to split the str like up.
  2397. //command+03+sum
  2398. */
  2399. PACKET_RET nsGEN::REMEDYSTDriver::callbackPackageProcess(const char* RecData, uint32_t nLength, uint32_t& PacketLength)
  2400. {
  2401. if (nLength < 1)
  2402. {
  2403. printf("nLength < 1, nLength==%d \n", nLength);
  2404. return PACKET_USELESS;
  2405. }
  2406. for (DWORD i = 0; i < nLength - 1; i++)
  2407. {
  2408. if (RecData[i] == 0x03)
  2409. {
  2410. PacketLength = i + 2;
  2411. char strtemp[100] = { 0 };
  2412. memcpy(strtemp, RecData, i);
  2413. strtemp[i + 1] = 0;
  2414. FINFO("==IN==:{$}\n", strtemp);
  2415. return PACKET_ISPACKET;
  2416. }
  2417. }
  2418. return PACKET_NOPACKET;
  2419. }
  2420. //-----------------------------------------------------------------------------
  2421. // DecodeFrame
  2422. //-----------------------------------------------------------------------------
  2423. static bool DecodeFrame(const char* strFrame, int length)
  2424. {
  2425. auto pr = [strFrame, length](const tFrameMapping& Item)
  2426. {
  2427. for (int i = 0; i < Item.NbOfCharOfHead; i++)
  2428. {
  2429. if (strFrame[i] != Item.strHead[i])
  2430. {
  2431. return false;
  2432. }
  2433. }
  2434. return true;
  2435. };
  2436. auto found = std::find_if(arFrame.begin(), arFrame.end(), pr);
  2437. if (found == arFrame.end())
  2438. {
  2439. return false;
  2440. }
  2441. const auto& Item = *found;
  2442. auto pc = strFrame;
  2443. pc += Item.NbOfCharOfHead;
  2444. Item.fun(pc, length - Item.NbOfCharOfHead);
  2445. return true;
  2446. }
  2447. //-----------------------------------------------------------------------------
  2448. // GetIODriver & CreateIODriver
  2449. //-----------------------------------------------------------------------------
  2450. static nsGEN::REMEDYSTDriver gIODriver;
  2451. extern "C" CCOS::Dev::IODriver * GetIODriver()
  2452. {
  2453. return &gIODriver;
  2454. }
  2455. extern "C" CCOS::Dev::IODriver * CreateIODriver()
  2456. {
  2457. return new nsGEN::REMEDYSTDriver();
  2458. }