ModuleDevice.cpp 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248
  1. #include "ModuleDevice.h"
  2. #include "PacketAnalizer.h"
  3. #include "common_api.h"
  4. #include "LocalConfig.h"
  5. #include "Base64.h"
  6. #include "SystemLogger.hpp"
  7. #include <string>
  8. #include <cstring>
  9. #include <clocale>
  10. #include <stdexcept>
  11. #include <filesystem>
  12. ModuleDevice::ModuleDevice()
  13. {
  14. m_pSendConn = nullptr;
  15. m_bSendIndependently = false;
  16. //if (//mLog::gLogger == nullptr)
  17. //{
  18. // string strLogPath = GetProcessDirectory() + R"(\Conf\Log4CPP.Config.xml)";
  19. // string LogHost = ((string)getLogRootpath()).c_str();
  20. // //if (LogHost.length() <= 1)
  21. // //{
  22. // // char szName[256];
  23. // // sprintf(szName, "/LogicDevice_%08d", GetCurrentProcessId());
  24. // // LogHost = szName;
  25. // //}
  26. // Log4CPP::ThreadContext::Map::Set(ECOM::Utility::Hash("LogFileName"), "Platform");
  27. // //Log4CPP::GlobalContext::Map::Set("LogHost", LogHost.c_str());
  28. // Log4CPP::ThreadContext::Map::Set(ECOM::Utility::Hash("LogHost"), LogHost.c_str() + 1);
  29. // auto rc = Log4CPP::LogManager::LoadConfigFile(strLogPath.c_str());
  30. // //mLog::gLogger = Log4CPP::LogManager::GetLogger("Platform");
  31. //}
  32. }
  33. ModuleDevice::~ModuleDevice()
  34. {
  35. }
  36. std::wstring mb2wc_a(const char* mbstr)
  37. {
  38. // 保存当前 locale 设置
  39. std::string old_locale = std::setlocale(LC_CTYPE, nullptr);
  40. try {
  41. // 设置 UTF-8 环境(Linux 宽字符转换依赖 locale)
  42. if (!std::setlocale(LC_CTYPE, "en_US.UTF-8")) {
  43. throw std::runtime_error("Failed to set UTF-8 locale");
  44. }
  45. // 计算所需宽字符缓冲区大小
  46. std::size_t size = std::mbstowcs(nullptr, mbstr, 0);
  47. if (size == static_cast<std::size_t>(-1)) {
  48. throw std::runtime_error("Invalid multibyte sequence");
  49. }
  50. // 创建宽字符缓冲区 (+1 给空终止符)
  51. wchar_t* wcstr = new wchar_t[size + 1];
  52. // 执行实际转换
  53. if (std::mbstowcs(wcstr, mbstr, size + 1) == static_cast<std::size_t>(-1)) {
  54. delete[] wcstr;
  55. throw std::runtime_error("Conversion failed");
  56. }
  57. std::wstring result(wcstr);
  58. delete[] wcstr;
  59. // 恢复原始 locale
  60. std::setlocale(LC_CTYPE, old_locale.c_str());
  61. return result;
  62. }
  63. catch (...) {
  64. // 确保异常时恢复 locale
  65. std::setlocale(LC_CTYPE, old_locale.c_str());
  66. throw;
  67. }
  68. }
  69. RET_STATUS ModuleDevice::IoSystemLog(int Level, const char* pCode, const char* pContext, size_t ContextSize, const char* pAppId)
  70. {
  71. std::string strResult = "";
  72. //组Context包
  73. //if (m_pLogger)
  74. {
  75. wstring wContect = mb2wc_a(pContext);
  76. CBase64::Encode((const unsigned char*)wContect.c_str(), (unsigned long)wContect.size() * sizeof(wchar_t), strResult);
  77. }
  78. //Thread_Lock();
  79. //if (NULL != fmt)
  80. //{
  81. // va_list marker = NULL;
  82. // va_start(marker, fmt);
  83. // size_t nLength = _vscprintf(fmt, marker) + 1;
  84. // std::vector<char> vBuffer(nLength, '\0');
  85. // int nWritten = vsnprintf_s(&vBuffer[0], vBuffer.size(), nLength, fmt, marker);
  86. // if (nWritten > 0)
  87. // {
  88. // strResult = &vBuffer[0];
  89. // }
  90. // va_end(marker);
  91. //}
  92. //Thread_UnLock();
  93. ResDataObject SysLogNode;
  94. string guidstr;
  95. GUID DeviceGuid;
  96. //组Log包
  97. if (GetDeviceType(DeviceGuid))
  98. {
  99. guid_2_string(DeviceGuid, guidstr);
  100. SysLogNode.add("Module", guidstr.c_str());
  101. SysLogNode.add("AppId", pAppId);
  102. SysLogNode.add("ThreadId", GetCurrentThreadId());
  103. if (pCode)
  104. {
  105. SysLogNode.add("BusinessKey", pCode);
  106. }
  107. else
  108. {
  109. SysLogNode.add("BusinessKey", "");
  110. }
  111. SysLogNode.add("IP", (const char*)getLocalIpAddress());
  112. struct timeval tv;
  113. gettimeofday(&tv, nullptr);
  114. struct tm tm_time;
  115. localtime_r(&tv.tv_sec, &tm_time);
  116. string TimeTag = FormatstdString("%04d-%02d-%02d %02d:%02d:%02d.%03ld",
  117. tm_time.tm_year + 1900, // 年份
  118. tm_time.tm_mon + 1, // 月份
  119. tm_time.tm_mday, // 日
  120. tm_time.tm_hour, // 时
  121. tm_time.tm_min, // 分
  122. tm_time.tm_sec, // 秒
  123. tv.tv_usec / 1000);
  124. SysLogNode.add("CreationTime", TimeTag.c_str());
  125. string strLevel = SysLogLevel2str(Level);
  126. SysLogNode.add("Level", strLevel.c_str());
  127. SysLogNode.add("HostName", (const char*)getLocalMachineId());
  128. SysLogNode.add("ProcessName", (const char*)GetModuleTitle());
  129. SysLogNode.add("FreeText", strResult.c_str());
  130. SysLogNode.add("Context", pCode);
  131. ResDataObject NotifyData;
  132. PacketAnalizer::MakeNotify(NotifyData, PACKET_CMD_MSG, "Syslog", SysLogNode);
  133. SendNotify(&NotifyData);
  134. //PublishAction(&NotifyData, (m_strEBusRoot + "/Notify").c_str(), m_pMqttConntion);
  135. }
  136. else
  137. {
  138. //mLog::FINFO("no Guid??");
  139. return RET_FAILED;
  140. }
  141. //打印LOG
  142. switch (Level)
  143. {
  144. case Syslog_Debug:
  145. //RES_PRINTA_DEBUG(m_pLogger, SysLogNode, "SysLog");
  146. //mLog::FDEBUG("SysLog {$} ", SysLogNode.encode());
  147. break;
  148. case Syslog_Information:
  149. ///RES_PRINTA_INFO(m_pLogger, SysLogNode, "SysLog");
  150. //mLog::FINFO("SysLog {$} ", SysLogNode.encode());
  151. break;
  152. case Syslog_Warning:
  153. //RES_PRINTA_WARN(m_pLogger, SysLogNode, "SysLog");
  154. //mLog::Warn("SysLog {$} ", SysLogNode.encode());
  155. break;
  156. case Syslog_Error:
  157. //RES_PRINTA_ERROR(m_pLogger, SysLogNode, "SysLog");
  158. //mLog::FERROR("SysLog {$} ", SysLogNode.encode());
  159. break;
  160. case Syslog_Fatal:
  161. //RES_PRINTA_FATAL(m_pLogger, SysLogNode, "SysLog");
  162. //mLog::FINFO("SysLog {$} ", SysLogNode.encode());
  163. break;
  164. default:
  165. //mLog::FINFO("SysLog {$} ", SysLogNode.encode());
  166. break;
  167. }
  168. return RET_SUCCEED;
  169. }
  170. RET_STATUS ModuleDevice::SystemLog(SYSLOGLEVEL Level, const char* pCode, const char* fmt, ...)
  171. {
  172. std::string strResult = "";
  173. //组Context包
  174. //if (m_pLogger)
  175. //{
  176. // m_pLogger->Thread_Lock();
  177. // if (NULL != fmt)
  178. // {
  179. // va_list marker = NULL;
  180. // va_start(marker, fmt);
  181. // size_t nLength = _vscprintf(fmt, marker) + 1;
  182. // std::vector<char> vBuffer(nLength, '\0');
  183. // int nWritten = vsnprintf_s(&vBuffer[0], vBuffer.size(), nLength, fmt, marker);
  184. // if (nWritten > 0)
  185. // {
  186. // strResult = &vBuffer[0];
  187. // }
  188. // va_end(marker);
  189. // }
  190. // m_pLogger->Thread_UnLock();
  191. //}
  192. //else
  193. {
  194. Thread_Lock();
  195. if (fmt != nullptr) // 使用 nullptr 代替 NULL
  196. {
  197. va_list marker;
  198. va_start(marker, fmt);
  199. // 计算格式化字符串所需长度(不包括终止空字符)
  200. va_list args_copy;
  201. va_copy(args_copy, marker); // 复制参数列表
  202. int nLength = vsnprintf(nullptr, 0, fmt, args_copy); // Linux下获取长度的方法
  203. va_end(args_copy);
  204. if (nLength < 0) {
  205. // 处理错误:格式化失败
  206. va_end(marker);
  207. // 这里可以添加错误处理逻辑
  208. }
  209. else {
  210. // 分配足够空间(包括终止空字符)
  211. std::vector<char> vBuffer(nLength + 1, '\0');
  212. // 实际执行格式化
  213. int nWritten = vsnprintf(vBuffer.data(), vBuffer.size(), fmt, marker);
  214. if (nWritten >= 0 && static_cast<size_t>(nWritten) < vBuffer.size()) {
  215. strResult = vBuffer.data(); // 直接赋值给结果字符串
  216. }
  217. // 如果 nWritten 无效则保持 strResult 不变
  218. }
  219. va_end(marker);
  220. }
  221. Thread_UnLock();
  222. }
  223. ResDataObject SysLogNode;
  224. string guidstr;
  225. GUID DeviceGuid;
  226. //组Log包
  227. if (GetDeviceType(DeviceGuid))
  228. {
  229. guid_2_string(DeviceGuid, guidstr);
  230. SysLogNode.add("Module", guidstr.c_str());
  231. SysLogNode.add("AppId", "");
  232. SysLogNode.add("ThreadId", GetCurrentThreadId());
  233. if (pCode)
  234. {
  235. SysLogNode.add("BusinessKey", pCode);
  236. }
  237. else
  238. {
  239. SysLogNode.add("BusinessKey", "");
  240. }
  241. SysLogNode.add("IP", (const char*)getLocalIpAddress());
  242. struct timeval tv;
  243. gettimeofday(&tv, nullptr);
  244. struct tm tm_time;
  245. localtime_r(&tv.tv_sec, &tm_time);
  246. string TimeTag = FormatstdString("%04d-%02d-%02d %02d:%02d:%02d.%03ld",
  247. tm_time.tm_year + 1900, // 年份
  248. tm_time.tm_mon + 1, // 月份
  249. tm_time.tm_mday, // 日
  250. tm_time.tm_hour, // 时
  251. tm_time.tm_min, // 分
  252. tm_time.tm_sec, // 秒
  253. tv.tv_usec / 1000);
  254. SysLogNode.add("CreationTime", TimeTag.c_str());
  255. SysLogNode.add("Level", Level);
  256. SysLogNode.add("HostName", (const char*)getLocalMachineId());
  257. SysLogNode.add("ProcessName", (const char*)GetModuleTitle());
  258. SysLogNode.add("FreeText", strResult.c_str());
  259. ResDataObject NotifyData;
  260. PacketAnalizer::MakeNotify(NotifyData, PACKET_CMD_MSG, "Syslog", SysLogNode);
  261. SendNotify(&NotifyData);
  262. //PublishAction(&NotifyData, (m_strEBusRoot + "/Notify").c_str(), m_pMqttConntion);
  263. if (m_pParent != nullptr)
  264. NotifyParent(&NotifyData, "/Notify");
  265. }
  266. else
  267. {
  268. //mLog::FERROR("no Guid??");
  269. return RET_FAILED;
  270. }
  271. //打印LOG
  272. switch (Level)
  273. {
  274. case Syslog_Debug:
  275. //RES_PRINTA_DEBUG(m_pLogger, SysLogNode, "SysLog");
  276. //mLog::FDEBUG("SysLog {$}", SysLogNode.encode());
  277. break;
  278. case Syslog_Information:
  279. //RES_PRINTA_INFO(m_pLogger, SysLogNode, "SysLog");
  280. //mLog::FINFO("SysLog {$}", SysLogNode.encode());
  281. break;
  282. case Syslog_Warning:
  283. //RES_PRINTA_WARN(m_pLogger, SysLogNode, "SysLog");
  284. //mLog::Warn("SysLog {$}", SysLogNode.encode());
  285. break;
  286. case Syslog_Error:
  287. //RES_PRINTA_ERROR(m_pLogger, SysLogNode, "SysLog");
  288. //mLog::FERROR("SysLog {$}", SysLogNode.encode());
  289. break;
  290. case Syslog_Fatal:
  291. //RES_PRINTA_FATAL(m_pLogger, SysLogNode, "SysLog");
  292. //mLog::FINFO("SysLog {$}", SysLogNode.encode());
  293. break;
  294. default:
  295. //mLog::FINFO("SysLog {$}", SysLogNode.encode());
  296. break;
  297. }
  298. return RET_SUCCEED;
  299. }
  300. RET_STATUS ModuleDevice::Request(ResDataObject PARAM_IN* pRequest, ResDataObject PARAM_OUT* pResponse)
  301. {
  302. INT ret = RET_NOSUPPORT;
  303. PACKET_CMD cmd = PacketAnalizer::GetPacketCmd(pRequest);
  304. PACKET_TYPE type = PacketAnalizer::GetPacketType(pRequest);
  305. string keystr = PacketAnalizer::GetPacketKey(pRequest);
  306. ResDataObject Context;
  307. if (PacketAnalizer::GetPacketContext(pRequest, Context) == false)
  308. {
  309. return RET_FAILED;
  310. }
  311. ResDataObject resReponse;
  312. if (type == PACKET_TYPE_NOTIFY)
  313. {
  314. //通知类,不需要答复
  315. return RET_SUCCEED;
  316. }
  317. else if (type == PACKET_TYPE_RES)
  318. {
  319. //收到了应答包。。。
  320. return RET_SUCCEED;
  321. }
  322. if (cmd == PACKET_CMD_EXE)
  323. {
  324. string req, res;
  325. req = (const char*)Context.encode();
  326. //mLog::FINFO("Action[{$}].req:{$}", keystr.c_str(), req.c_str());
  327. ret = DevAction("", keystr.c_str(), req.c_str(), resReponse);
  328. pResponse->update("CONTEXT", resReponse);
  329. //mLog::FINFO("Action res packet done");
  330. }
  331. else if (cmd == PACKET_CMD_GET)
  332. {
  333. string res;
  334. //mLog::FINFO("get CMD_GET req:{$}", keystr.c_str());
  335. ret = DevGet(m_strCCOSDevicePath.c_str(), keystr.c_str(), resReponse);
  336. pResponse->update("CONTEXT", resReponse);
  337. }
  338. else if (cmd == PACKET_CMD_UPDATE)
  339. {
  340. //mLog::FINFO("get CMD_UPDATE req:{$}", keystr.c_str());
  341. ret = DevUpdate(m_strCCOSDevicePath.c_str(), keystr.c_str(), Context, resReponse);
  342. pResponse->update("CONTEXT", resReponse);
  343. }
  344. else if (cmd == PACKET_CMD_SET)
  345. {
  346. //mLog::FINFO("get CMD_UPDATE req:{$}", keystr.c_str());
  347. ret = DevSet(m_strCCOSDevicePath.c_str(), keystr.c_str(), Context, resReponse);
  348. pResponse->update("CONTEXT", resReponse);
  349. }
  350. else if (cmd == PACKET_CMD_MSG)
  351. {
  352. //mLog::FINFO("get CMD_UPDATE req:{$}", keystr.c_str());
  353. ret = DevMessage(m_strCCOSDevicePath.c_str(), keystr.c_str(), Context, resReponse);
  354. pResponse->update("CONTEXT", resReponse);
  355. }
  356. else if (cmd == PACKET_CMD_ADD)
  357. {
  358. //mLog::FINFO("get CMD_ADD req:{$}", keystr.c_str());
  359. ret = DevAdd(m_strCCOSDevicePath.c_str(), keystr.c_str(), Context, resReponse);
  360. pResponse->update("CONTEXT", resReponse);
  361. }
  362. else if (cmd == PACKET_CMD_DEL)
  363. {
  364. //mLog::FINFO("get CMD_DEL req:{$}", keystr.c_str());
  365. ret = DevDel(m_strCCOSDevicePath.c_str(), keystr.c_str(), Context, resReponse);
  366. pResponse->update("CONTEXT", resReponse);
  367. }
  368. else
  369. {
  370. //wtf?? 忽略掉
  371. return RET_SUCCEED;
  372. }
  373. PacketAnalizer::MakeRetCode((RET_STATUS)ret, pResponse);
  374. return (RET_STATUS)ret;
  375. }
  376. RET_STATUS ModuleDevice::CmdToLogicDev(ResDataObject PARAM_IN* pCmd)
  377. {
  378. return RET_SUCCEED;
  379. }
  380. bool ModuleDevice::GetDeviceType(GUID& DevType)
  381. {
  382. return true;
  383. }
  384. void ModuleDevice::SubscribeSelf()
  385. {
  386. LogicDevice::SubscribeSelf();
  387. }
  388. bool ModuleDevice::CheckSubDevice()
  389. {
  390. //mLog::FINFO("Begin");
  391. //mLog::FINFO("{$} have {$} SubDevices", m_strCCOSDevicePath, m_subCcosDevices.size());
  392. if (m_subCcosDevices.size() > 0)
  393. {
  394. //有子设备,则构建模型设备树
  395. ResDataObject resSub;
  396. ResDataObject subList;
  397. for (int y = 0; y < m_subCcosDevices.size(); y++)
  398. {
  399. subList.add(m_subCcosDevices[y]->GetCcosRootPath().c_str(), "");
  400. //mLog::FINFO("{$} devpath {$}", y, m_subCcosDevices[y]->GetCcosRootPath());
  401. }
  402. resSub.add("Value", subList);
  403. resSub.add("DescKey", "SubDevice");
  404. m_resProperties.update("SubDevice", resSub);
  405. return true;
  406. }
  407. return false;
  408. }
  409. void ModuleDevice::OnSetClientID()
  410. {
  411. //这里根据 CCOS设备 路径决定加载什么配置
  412. LogicDevice::OnSetClientID();
  413. string configName;
  414. if (m_strModuleFileName.length() <= 0)
  415. {
  416. //标准设备
  417. string devicePath = m_strCCOSDevicePath;
  418. //CCOS/DEVICE, 11个字符
  419. if (devicePath.substr(0, 11) == "CCOS/DEVICE")
  420. {
  421. //是设备
  422. //todo 要生成模型文件名
  423. string module = devicePath.substr(12);
  424. configName = module;
  425. int x, moduleLen,spCount = 0;
  426. for (x = 0; x < module.length(); x++)
  427. {
  428. if (module[x] == '/')
  429. {
  430. if(spCount <= 3)
  431. module[x] = '_';
  432. configName[x] = '_';
  433. spCount++;
  434. if (spCount == 3)
  435. {
  436. moduleLen = x;
  437. }
  438. }
  439. }
  440. module = module.substr(0, moduleLen);
  441. module += ".json";
  442. m_strModuleFileName = module;
  443. configName += ".json";
  444. }
  445. }
  446. else
  447. {
  448. configName = m_strModuleFileName;
  449. }
  450. if (m_strModuleFileName.length() <= 0)
  451. {
  452. //没有取到模型名
  453. return;
  454. }
  455. if (m_bSendIndependently)
  456. {
  457. m_strSendClientID = m_strClientID + "_Sender";
  458. std::cout << " ModuleDevice::OnSetClientID New Connection.." << endl;
  459. m_pSendConn = NewConnection(m_strServer.c_str(), m_strServerPort.c_str(), m_strMqttUser.c_str(), m_strMqttPassword.c_str(), m_strSendClientID.c_str(),
  460. [this](ResDataObject* req, const char* topic, void* conn) {
  461. //mLog::FINFO("Got msg from [$] body: {$}", topic, req->encode());
  462. //CmdToLogicDev(req);
  463. });
  464. }
  465. string tmplPath, modulePath = GetProcessDirectory();
  466. modulePath += "/DriverDefine/";
  467. tmplPath = modulePath;
  468. string configPath = modulePath ;
  469. modulePath += m_strModuleFileName;
  470. configPath += "Config/";
  471. mkdir(configPath.c_str(), 0755);
  472. configPath += configName;
  473. try {
  474. m_resModuleConfig.loadFile(modulePath.c_str());
  475. m_strModuleFilePath = modulePath;
  476. //mLog::FINFO("Got module file [{$}] Read file path [{$}] ok.", m_strModuleFileName, modulePath);
  477. }
  478. catch (...)
  479. {
  480. //mLog::FINFO("Got module file [{$}] but Read file path [{$}] failed.", m_strModuleFileName, modulePath);
  481. //没有配置模型文件,尝试寻找通用模型文件
  482. std::vector<string> devVec;
  483. SplitCcosDevicePath(m_strCCOSDevicePath, devVec);
  484. if (devVec.size() >= 3)
  485. {
  486. string type = devVec[2];
  487. tmplPath += type;
  488. tmplPath += ".json";
  489. try {
  490. ResDataObject resTest;
  491. resTest.loadFile(tmplPath.c_str());
  492. std::filesystem::copy_file(
  493. tmplPath, // 源文件路径
  494. modulePath, // 目标文件路径
  495. std::filesystem::copy_options::overwrite_existing // 覆盖已存在文件
  496. );
  497. // mLog::FINFO("Copied template module file from {$} to {$}", tmplPath, modulePath);
  498. m_resModuleConfig.loadFile(modulePath.c_str());
  499. m_strModuleFilePath = modulePath;
  500. }
  501. catch (const std::exception& e) { // 捕获标准异常
  502. // mLog::FERROR("File operation failed: {$}", e.what());
  503. // mLog::FINFO("There is still no template module file {$}", tmplPath);
  504. return;
  505. }
  506. catch (...) { // 保留捕获所有异常的兜底逻辑
  507. // mLog::FINFO("There is still no template module file {$}", tmplPath);
  508. return;
  509. }
  510. }
  511. else
  512. return;
  513. }
  514. if (configName.length() > 0)
  515. {
  516. try {
  517. ResDataObject resConfig;
  518. resConfig.loadFile(configPath.c_str());
  519. m_resProperties = resConfig[0];
  520. m_strConfigFilePath = configPath;
  521. if (CheckSubDevice())
  522. {
  523. SaveToConfigFile();
  524. }
  525. //mLog::FINFO("Got config file path [{$}] Read content ok. [{$}]", m_strConfigFilePath, m_resProperties.encode());
  526. }
  527. catch (...)
  528. {
  529. //没有取到配置,则保存默认配置
  530. m_strConfigFilePath = configPath;
  531. ResDataObject resConfig;
  532. m_resProperties = m_resModuleConfig["Get"];
  533. CheckSubDevice();
  534. resConfig.add("CONFIGURATION", m_resProperties);
  535. resConfig.SaveFile(m_strConfigFilePath.c_str());
  536. //mLog::FINFO("No config file at path [{$}] Save content ok. [{$}]", m_strConfigFilePath, m_resProperties.encode());
  537. }
  538. }
  539. else
  540. {
  541. m_resProperties = m_resModuleConfig["Get"];
  542. }
  543. //mLog::FINFO("Module Content: {$}", m_resModuleConfig.encode());
  544. //{
  545. // ResDataObject points = m_resProperties["ABSCurve"]["Value"]["Curve1"]["Points"];
  546. // for (int x = 0; x < points.size(); x++)
  547. // {
  548. // //mLog::FINFO("Array ? [{$}] value {$}", points.GetKey(x), points[x].encode());
  549. // }
  550. //}
  551. if(m_resModuleConfig.GetKeyCount("Get") > 0)
  552. m_resGets = m_resModuleConfig["Get"];
  553. if (m_resModuleConfig.GetKeyCount("Set") > 0)
  554. m_resSets = m_resModuleConfig["Set"];
  555. if (m_resModuleConfig.GetKeyCount("Add") > 0)
  556. m_resAdds = m_resModuleConfig["Add"];
  557. if (m_resModuleConfig.GetKeyCount("Del") > 0)
  558. m_resDels = m_resModuleConfig["Del"];
  559. if (m_resModuleConfig.GetKeyCount("Update") > 0)
  560. {
  561. //mLog::FINFO("WHAT ? {$}", m_resModuleConfig["Update"].encode());
  562. m_resUpdates = m_resModuleConfig["Update"];
  563. }
  564. if (m_resModuleConfig.GetKeyCount("Action") > 0)
  565. m_resActions = m_resModuleConfig["Action"];
  566. }
  567. RET_STATUS ModuleDevice::SendNotify(ResDataObject* pCmd)
  568. {
  569. RET_STATUS ret = RET_FAILED;
  570. if (m_bSendIndependently && m_pSendConn != nullptr)
  571. {
  572. PACKET_CMD cmd = PacketAnalizer::GetPacketCmd(pCmd);
  573. PACKET_TYPE type = PacketAnalizer::GetPacketType(pCmd);
  574. if (type == PACKET_TYPE_NOTIFY)
  575. {
  576. CcosDevFileHandle* pHandle = new CcosDevFileHandle;
  577. PacketAnalizer::UpdateNotifyHandle(*pCmd, *pHandle);
  578. //mLog::FINFO("Notify Transaction: {$}", m_strCurTransaction);
  579. PacketAnalizer::UpdatePacketTransaction(*pCmd, m_strCurTransaction);
  580. ;
  581. if (m_strEBusRoot.length() <= 0)
  582. {
  583. //mLog::FINFO("EBusRoot is null");
  584. }
  585. //服务使用 m_pMqttConntion 区分子系统设备
  586. PacketAnalizer::UpdateDeviceNotifyResponse(*pCmd, getLocalMachineId(), getLocalEbusId(), (UINT64)getpid(), (UINT64)m_pMqttConntion);
  587. //mLog::FINFO("[{$}] Notify: {$}", m_strSendClientID, pCmd->encode());
  588. //printf("--> %s \n", pCmd->encode());
  589. PacketAnalizer::UpdatePacketTopic(pCmd, (m_strEBusRoot + "/Notify").c_str(), m_strSendClientID.c_str());
  590. PublishAction(pCmd, (m_strEBusRoot + "/Notify").c_str(), m_pSendConn);
  591. string strNotifyPath = "/Notify/" + PacketAnalizer::GetPacketKey(pCmd);
  592. PacketAnalizer::UpdatePacketTopic(pCmd, (m_strCCOSDevicePath + strNotifyPath).c_str(), m_strSendClientID.c_str());
  593. PublishAction(pCmd, (m_strCCOSDevicePath + strNotifyPath).c_str(), m_pSendConn);
  594. if (m_strAbstractPath.length() > 0)
  595. {
  596. PublishAction(pCmd, (m_strAbstractPath + strNotifyPath).c_str(), m_pSendConn);
  597. string realPath, devPath;
  598. devPath = m_strAbstractPath.substr(((string)"CCOS/DEVICE").length());
  599. for (int x = 0; x < m_rsOnlineGroup.size(); x++)
  600. {
  601. if ((int)m_rsOnlineGroup[x] == 1)
  602. {
  603. realPath = "CCOS/" + (string)m_rsOnlineGroup.GetKey(x) + devPath + strNotifyPath;
  604. PublishAction(pCmd, realPath.c_str(), m_pSendConn);
  605. }
  606. }
  607. } //m_pPacketSendingQue->InQueue(*pCmd);
  608. delete pHandle;
  609. }
  610. return RET_SUCCEED;
  611. }
  612. else
  613. {
  614. CmdFromLogicDev(pCmd);
  615. }
  616. return ret;
  617. }
  618. RET_STATUS ModuleDevice::NotifyProperty(const char* property)
  619. {
  620. RET_STATUS ret = RET_SUCCEED;
  621. ResDataObject resValue;
  622. if (m_resProperties.GetKeyCount(property) > 0 && m_resProperties[property].GetKeyCount("Value") > 0)
  623. {
  624. resValue = m_resProperties[property]["Value"];
  625. ResDataObject notify;
  626. PacketAnalizer::MakeNotify(notify, PACKET_CMD_UPDATE, property, resValue.encode());
  627. PacketAnalizer::UpdatePacketContext(notify, resValue);
  628. SendNotify(&notify);
  629. return ret;
  630. }
  631. return RET_NOSUPPORT;
  632. }
  633. RET_STATUS ModuleDevice::GetDeviceResource(ResDataObject PARAM_OUT* pDeviceResource)
  634. {
  635. //父类会生成Ations
  636. LogicDevice::GetDeviceResource(pDeviceResource);
  637. //ResDataObject getPerp = m_resModuleConfig["Get"];
  638. for (int x = 0; x < m_resProperties.size(); x++)
  639. {
  640. (*pDeviceResource)["Attribute"].update(m_resProperties.GetKey(x), m_resProperties[x]["Value"]);
  641. }
  642. /*/
  643. {
  644. ResDataObject resAll;
  645. DevGet("", "", resAll);
  646. for (int x = 0; x < resAll.size(); x++)
  647. (*pDeviceResource)["Attribute"].update(resAll.GetKey(x), resAll[x]["Value"]);
  648. }
  649. //*/
  650. pDeviceResource->update("ClientType", DPC_UnitClient);
  651. pDeviceResource->add("Get", m_resProperties);
  652. ResDataObject setPerp, updatePerp, addPerp, delPerp, actionPerp, msgPerp;
  653. if (m_resSets.size() <= 0)
  654. setPerp = m_resModuleConfig["Set"];
  655. else
  656. setPerp = m_resSets;
  657. pDeviceResource->add("Set", setPerp);
  658. if (m_resUpdates.size() <= 0)
  659. updatePerp = m_resModuleConfig["Update"];
  660. else
  661. updatePerp = m_resUpdates;
  662. pDeviceResource->add("Update", updatePerp);
  663. if (m_resAdds.size() <= 0)
  664. addPerp = m_resModuleConfig["Add"];
  665. else
  666. addPerp = m_resAdds;
  667. pDeviceResource->add("Add", addPerp);
  668. if (m_resDels.size() <= 0)
  669. delPerp = m_resModuleConfig["Del"];
  670. else
  671. delPerp = m_resDels;
  672. pDeviceResource->add("Del", delPerp);
  673. actionPerp = m_resModuleConfig["Action"];
  674. for (int x = 0; x < actionPerp.size(); x++)
  675. {
  676. (*pDeviceResource)["Action"].update(actionPerp.GetKey(x), actionPerp[x]);
  677. }
  678. //msgPerp = m_resModuleConfig["Message"];
  679. return RET_SUCCEED;
  680. }
  681. /// <summary>
  682. /// 枚举配置项,level == "Public" ,仅返回Pulic
  683. /// level == "E-COM" ,返回 Public 和 E-COM
  684. /// level == "Private" , 返回所有
  685. /// </summary>
  686. /// <param name="level">三个固定常量字符串 "Public"/"E-COM"/"Private"</param>
  687. /// <param name="resItems"></param>
  688. /// <returns></returns>
  689. RET_STATUS ModuleDevice::GetUpdatableItems(string level, ResDataObject& resItems)
  690. {
  691. ResDataObject resUpdate;
  692. resUpdate = m_resModuleConfig["Update"];
  693. bool bOutput = false;
  694. for (int x = 0; x < resUpdate.size(); x++)
  695. {
  696. bOutput = false;
  697. string itemLevel;
  698. if (resUpdate[x].GetKeyCount("Level") > 0)
  699. {
  700. itemLevel = (const char*)resUpdate[x]["Level"];
  701. if (itemLevel == level)
  702. bOutput = true;
  703. else
  704. {
  705. if (level == "Private") {
  706. bOutput = true;
  707. }
  708. else if (level == "E-COM") {
  709. if (itemLevel == "Public" || itemLevel == "E-COM") {
  710. bOutput = true;
  711. }
  712. }
  713. }
  714. }
  715. else
  716. {
  717. //没有配置Level是Private
  718. if (level == "Private")
  719. bOutput = true;
  720. }
  721. if (bOutput)
  722. {
  723. resItems.update(resUpdate.GetKey(x), resUpdate[x]);
  724. }
  725. }
  726. return RET_SUCCEED;
  727. }
  728. /// <summary>
  729. /// 标准模型 是整体更新,如果是局部更新,需要重载自己写逻辑
  730. /// </summary>
  731. /// <param name="pszProperty"></param>
  732. /// <param name="pszValueUpdate"></param>
  733. /// <param name="resRespons"></param>
  734. /// <returns></returns>
  735. RET_STATUS ModuleDevice::UpdateItem(const char* pszProperty, const char* pszValueUpdate, ResDataObject& resRespons)
  736. {
  737. //保存到配置文件
  738. //
  739. ResDataObject resNewValue = m_resProperties[pszProperty];
  740. ResDataObject resUpdate;
  741. try
  742. {
  743. resUpdate.decode(pszValueUpdate);
  744. }
  745. catch (...)
  746. {
  747. resUpdate = pszValueUpdate;
  748. }
  749. if (resUpdate.size() > 0)
  750. {
  751. //是个对象字典
  752. for (int x = 0; x < resUpdate.size(); x++)
  753. {
  754. ResDataObject resv = resUpdate[x];
  755. if (resv.size() > 0)
  756. {
  757. //key: value (有值)更新
  758. resNewValue["Value"].update(resUpdate.GetKey(x), resUpdate[x]);
  759. }
  760. else
  761. {
  762. string value = (const char*)resv;
  763. if (value.length() > 0)
  764. {
  765. resNewValue["Value"].update(resUpdate.GetKey(x), resUpdate[x]);
  766. }
  767. else
  768. {
  769. //if (value == "Remove")
  770. //{
  771. resNewValue["Value"].eraseAllOf(resUpdate.GetKey(x));
  772. //}
  773. }
  774. }
  775. //resNewValue["Value"].update(resUpdate.GetKey(x), resUpdate[x]);
  776. }
  777. //mLog::FINFO("Save Object [{$}] new value {$}", pszProperty, resNewValue.encode());
  778. m_resProperties.update(pszProperty, resNewValue);
  779. //通知模型对象,值更新了
  780. return OnUpdate(pszProperty, m_resProperties[pszProperty]["Value"].encode(), resRespons);
  781. }
  782. else
  783. {
  784. resNewValue.update("Value", pszValueUpdate);
  785. //mLog::FINFO("Save [{$}] new value {$}", pszProperty, pszValueUpdate);
  786. m_resProperties[pszProperty].update("Value", pszValueUpdate);
  787. //通知模型对象,值更新了
  788. return OnUpdate(pszProperty, pszValueUpdate, resRespons);
  789. }
  790. }
  791. RET_STATUS ModuleDevice::OnMessage(const char* pszTopic, const char* pszMessageValue, ResDataObject& resResponse)
  792. {
  793. //mLog::FINFO("Message to {$} with {$}", pszTopic, pszMessageValue);
  794. return RET_SUCCEED;
  795. }
  796. RET_STATUS ModuleDevice::DevGet(const char* pszDevUri, const char* pszProperty, ResDataObject& resRespons)
  797. {
  798. string property = pszProperty;
  799. if (property.length() <= 0)
  800. {
  801. string key;
  802. for (int x = 0; x < m_resProperties.size(); x++)
  803. {
  804. key = m_resProperties.GetKey(x);
  805. if (GetItem(key.c_str(), resRespons) == RET_SUCCEED)
  806. {
  807. if (m_resProperties[x].GetKeyCount("Type") > 0 && string((const char*)m_resProperties[x]["Type"]) == "Switch")
  808. {
  809. string v = (const char*)resRespons;
  810. if (v == "YES" || v == "NO")
  811. {
  812. m_resProperties[key.c_str()].update("Value", v=="YES"?"1":"0");
  813. }
  814. else
  815. {
  816. m_resProperties[key.c_str()].update("Value", resRespons);
  817. }
  818. }
  819. else
  820. {
  821. m_resProperties[key.c_str()].update("Value", resRespons);
  822. }
  823. }
  824. }
  825. resRespons = m_resProperties;
  826. ResDataObject resMa,resMa2;
  827. //"": "Public",
  828. // "DescKey" : "TUBEHEAT",
  829. // "Value" : "0"
  830. resMa.add("Level", "Public");
  831. resMa.update("DescKey", "Manufacturer");
  832. resMa.update("Value", m_resModuleConfig["Manufacturer"]);
  833. resRespons.update("Manufacturer", resMa);
  834. resMa2.clear();
  835. resMa2.add("Level", "Public");
  836. resMa2.update("DescKey", "Model");
  837. resMa2.update("Value", m_resModuleConfig["Model"]);
  838. resRespons.update("Model", resMa2);
  839. resMa2.clear();
  840. resMa2.add("Level", "Public");
  841. resMa2.update("DescKey", "Modality");
  842. resMa2.update("Value", m_resModuleConfig["Modality"]);
  843. resRespons.update("Modality", resMa2);
  844. return RET_SUCCEED;
  845. }
  846. bool canGet = m_resGets.GetKeyCount(pszProperty) > 0;
  847. canGet &= m_resProperties.GetKeyCount(pszProperty) > 0;
  848. if (!canGet)
  849. return RET_NOSUPPORT;
  850. if (GetItem(pszProperty, resRespons) == RET_SUCCEED)
  851. {
  852. m_resProperties[pszProperty].update("Value", resRespons);
  853. }
  854. resRespons = m_resProperties[pszProperty]["Value"];
  855. return RET_SUCCEED;
  856. }
  857. RET_STATUS ModuleDevice::DevSet(const char* pszDevUri, const char* pszProperty, const char* pszValueSet, ResDataObject& resRespons)
  858. {
  859. bool canGet = m_resSets.GetKeyCount(pszProperty) > 0;
  860. canGet &= m_resProperties.GetKeyCount(pszProperty) > 0;
  861. if (!canGet)
  862. return RET_NOSUPPORT;
  863. ResDataObject resNewValue;
  864. resNewValue.decode(pszValueSet);
  865. RET_STATUS ret = SetItem(pszProperty, resNewValue, resRespons);
  866. if (ret == RET_SUCCEED)
  867. {
  868. m_resProperties[pszProperty].update("Value", resNewValue);
  869. NotifyProperty(pszProperty);
  870. }
  871. //通知模型对象,值更新了
  872. return ret;
  873. }
  874. RET_STATUS ModuleDevice::SaveToConfigFile()
  875. {
  876. RET_STATUS ret = RET_FAILED;
  877. if (m_strConfigFilePath.length() > 0)
  878. {
  879. ResDataObject resConfig;
  880. //m_resProperties = m_resModuleConfig["Get"];
  881. resConfig.add("CONFIGURATION", m_resProperties);
  882. if (resConfig.SaveFile(m_strConfigFilePath.c_str()))
  883. {
  884. //mLog::FINFO("Save Module Config file [{$}] content {$}", m_strConfigFilePath, resConfig.encode());
  885. }
  886. else
  887. {
  888. //mLog::FINFO("Failed Save Module Config file [{$}] content {$}", m_strConfigFilePath, resConfig.encode());
  889. }
  890. ret = RET_SUCCEED;
  891. }
  892. return ret;
  893. }
  894. RET_STATUS ModuleDevice::DevUpdate(const char* pszDevUri, const char* pszProperty, const char* pszValueUpdate, ResDataObject& resRespons)
  895. {
  896. string strProperty = pszProperty;
  897. if (strProperty.length() == 0)
  898. {
  899. //查询可以更新的属性
  900. string level = pszValueUpdate;
  901. if (level.length() <= 0)
  902. level = "Public";
  903. if (level == "Public" || level == "E-COM" || level == "Private")
  904. {
  905. //
  906. return GetUpdatableItems(level, resRespons);
  907. }
  908. level = "Public";
  909. return GetUpdatableItems(level, resRespons);
  910. }
  911. bool canGet = m_resUpdates.GetKeyCount(pszProperty) > 0;
  912. canGet &= m_resProperties.GetKeyCount(pszProperty) > 0;
  913. if (!canGet)
  914. return RET_NOSUPPORT;
  915. if (strProperty == "RestoreConfig")
  916. {
  917. //恢复出厂设置
  918. }
  919. RET_STATUS ret = UpdateItem(pszProperty, pszValueUpdate, resRespons);
  920. //mLog::FINFO("UpdateItem to Device [{$}] ret [{$}]", pszProperty, (int)ret);
  921. m_resModuleConfig.update("Get", m_resProperties);
  922. SaveToConfigFile();
  923. return ret;
  924. }
  925. RET_STATUS ModuleDevice::DevAdd(const char* pszDevUri, const char* pszProperty, const char* pszValueAdd, ResDataObject& resRespons)
  926. {
  927. bool canGet = m_resAdds.GetKeyCount(pszProperty) > 0;
  928. canGet &= m_resProperties.GetKeyCount(pszProperty) > 0;
  929. if (!canGet)
  930. return RET_NOSUPPORT;
  931. ResDataObject resNewValue;
  932. resNewValue.decode(pszValueAdd);
  933. for (int x = 0; x < resNewValue.size(); x++)
  934. {
  935. m_resProperties[pszProperty].update(resNewValue.GetKey(x), resNewValue[x]);
  936. }
  937. //m_resProperties.update(pszProperty, resNewValue);
  938. return OnAdd(pszProperty, resNewValue, resRespons);
  939. }
  940. RET_STATUS ModuleDevice::DevDel(const char* pszDevUri, const char* pszProperty, const char* pszValueDel, ResDataObject& resRespons)
  941. {
  942. bool canGet = m_resDels.GetKeyCount(pszProperty) > 0;
  943. canGet &= m_resProperties.GetKeyCount(pszProperty) > 0;
  944. if (!canGet)
  945. return RET_NOSUPPORT;
  946. ResDataObject resDelValue;
  947. string strDel = pszValueDel;
  948. if (strDel.length() < 0)
  949. {
  950. //什么参数都没有,清除所有数据
  951. m_resProperties[pszProperty].clear();
  952. return OnDel(pszProperty, resDelValue, resRespons);
  953. }
  954. resDelValue.decode(pszValueDel);
  955. string key = pszProperty;
  956. if (key == "ErrorList")
  957. {
  958. //如果是ErrorList,提供单独删除某类错误的能力
  959. int nIndex = resDelValue.GetFirstOf("ErrorIndex");
  960. if (nIndex >= 0)
  961. {
  962. nIndex = (int)resDelValue["ErrorIndex"];
  963. if (nIndex >= 0 && nIndex < (m_resProperties[key.c_str()]).size())
  964. {
  965. //m_resProperties[key.c_str()].eraseOneOf()
  966. }
  967. }
  968. }
  969. if (RET_SUCCEED == OnDel(pszProperty, resDelValue, resRespons))
  970. {
  971. m_resProperties.update(pszProperty, resRespons);
  972. return RET_SUCCEED;
  973. }
  974. return RET_SUCCEED;
  975. }
  976. RET_STATUS ModuleDevice::DevAction(const char* pszDevUri, const char* pszActionName, const char* pszParams, ResDataObject& resRespons)
  977. {
  978. cout << "ModuleDevice::DevAction - Entering. pszDevUri: " << (pszDevUri ? pszDevUri : "nullptr")
  979. << ", pszActionName: " << (pszActionName ? pszActionName : "nullptr")
  980. << ", pszParams: " << (pszParams ? pszParams : "nullptr") << endl;
  981. bool canGet = m_resActions.GetKeyCount(pszActionName) > 0;
  982. if (!canGet)
  983. return RET_NOSUPPORT;
  984. RET_STATUS ret = OnAction(pszActionName, pszParams, resRespons);
  985. //mLog::FINFO("Got Action {$} with param {$} to {$} ret {$} Result {$}", pszActionName, pszDevUri, pszParams, (int)ret, resRespons.encode());
  986. return ret;
  987. }
  988. RET_STATUS ModuleDevice::DevMessage(const char* pszDevUri, const char* pszTopic, const char* pszMessageValue, ResDataObject& resRespons)
  989. {
  990. return OnMessage(pszTopic, pszMessageValue, resRespons);
  991. }
  992. RET_STATUS ModuleDevice::OnUpdate(const char* pszProperty, const char* pszValueUpdate, ResDataObject& resRespons)
  993. {
  994. RET_STATUS ret = RET_NOSUPPORT;
  995. return ret;
  996. }
  997. RET_STATUS ModuleDevice::OnDel(const char* pszPropery, ResDataObject& resDelValue, ResDataObject& resResponse)
  998. {
  999. RET_STATUS ret = RET_NOSUPPORT;
  1000. return ret;
  1001. }
  1002. RET_STATUS ModuleDevice::OnAdd(const char* pszPropery, ResDataObject& reAddValue, ResDataObject& resResponse)
  1003. {
  1004. RET_STATUS ret = RET_NOSUPPORT;
  1005. return ret;
  1006. }
  1007. RET_STATUS ModuleDevice::SetItem(const char* pszPropery, ResDataObject& resSetValue, ResDataObject& resResponse)
  1008. {
  1009. RET_STATUS ret = RET_NOSUPPORT;
  1010. return ret;
  1011. }
  1012. RET_STATUS ModuleDevice::GetItem(const char* pszPropery, ResDataObject& resResponse)
  1013. {
  1014. RET_STATUS ret = RET_NOSUPPORT;
  1015. return ret;
  1016. }
  1017. RET_STATUS ModuleDevice::OnAction(const char* pszActionName, const char* pszParams, ResDataObject& resResponse)
  1018. {
  1019. RET_STATUS ret = RET_NOSUPPORT;
  1020. string strAction = pszActionName;
  1021. if (strAction == "RestoreConfig")
  1022. {
  1023. //恢复出厂设置
  1024. m_resProperties = m_resModuleConfig["Get"];
  1025. SaveToConfigFile();
  1026. ret = RET_SUCCEED;
  1027. }
  1028. return ret;
  1029. }