ModuleDevice.cpp 31 KB

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