123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248 |
- #include "ModuleDevice.h"
- #include "PacketAnalizer.h"
- #include "common_api.h"
- #include "LocalConfig.h"
- #include "Base64.h"
- #include "SystemLogger.hpp"
- #include <string>
- #include <cstring>
- #include <clocale>
- #include <stdexcept>
- #include <filesystem>
- ModuleDevice::ModuleDevice()
- {
- m_pSendConn = nullptr;
- m_bSendIndependently = false;
- //if (//mLog::gLogger == nullptr)
- //{
- // string strLogPath = GetProcessDirectory() + R"(\Conf\Log4CPP.Config.xml)";
- // string LogHost = ((string)getLogRootpath()).c_str();
- // //if (LogHost.length() <= 1)
- // //{
- // // char szName[256];
- // // sprintf(szName, "/LogicDevice_%08d", GetCurrentProcessId());
- // // LogHost = szName;
- // //}
- // Log4CPP::ThreadContext::Map::Set(ECOM::Utility::Hash("LogFileName"), "Platform");
- // //Log4CPP::GlobalContext::Map::Set("LogHost", LogHost.c_str());
- // Log4CPP::ThreadContext::Map::Set(ECOM::Utility::Hash("LogHost"), LogHost.c_str() + 1);
- // auto rc = Log4CPP::LogManager::LoadConfigFile(strLogPath.c_str());
- // //mLog::gLogger = Log4CPP::LogManager::GetLogger("Platform");
- //}
- }
- ModuleDevice::~ModuleDevice()
- {
- }
- std::wstring mb2wc_a(const char* mbstr)
- {
- // 保存当前 locale 设置
- std::string old_locale = std::setlocale(LC_CTYPE, nullptr);
- try {
- // 设置 UTF-8 环境(Linux 宽字符转换依赖 locale)
- if (!std::setlocale(LC_CTYPE, "en_US.UTF-8")) {
- throw std::runtime_error("Failed to set UTF-8 locale");
- }
- // 计算所需宽字符缓冲区大小
- std::size_t size = std::mbstowcs(nullptr, mbstr, 0);
- if (size == static_cast<std::size_t>(-1)) {
- throw std::runtime_error("Invalid multibyte sequence");
- }
- // 创建宽字符缓冲区 (+1 给空终止符)
- wchar_t* wcstr = new wchar_t[size + 1];
- // 执行实际转换
- if (std::mbstowcs(wcstr, mbstr, size + 1) == static_cast<std::size_t>(-1)) {
- delete[] wcstr;
- throw std::runtime_error("Conversion failed");
- }
- std::wstring result(wcstr);
- delete[] wcstr;
- // 恢复原始 locale
- std::setlocale(LC_CTYPE, old_locale.c_str());
- return result;
- }
- catch (...) {
- // 确保异常时恢复 locale
- std::setlocale(LC_CTYPE, old_locale.c_str());
- throw;
- }
- }
- RET_STATUS ModuleDevice::IoSystemLog(int Level, const char* pCode, const char* pContext, size_t ContextSize, const char* pAppId)
- {
- std::string strResult = "";
- //组Context包
- //if (m_pLogger)
- {
- wstring wContect = mb2wc_a(pContext);
- CBase64::Encode((const unsigned char*)wContect.c_str(), (unsigned long)wContect.size() * sizeof(wchar_t), strResult);
- }
- //Thread_Lock();
- //if (NULL != fmt)
- //{
- // va_list marker = NULL;
- // va_start(marker, fmt);
- // size_t nLength = _vscprintf(fmt, marker) + 1;
- // std::vector<char> vBuffer(nLength, '\0');
- // int nWritten = vsnprintf_s(&vBuffer[0], vBuffer.size(), nLength, fmt, marker);
- // if (nWritten > 0)
- // {
- // strResult = &vBuffer[0];
- // }
- // va_end(marker);
- //}
- //Thread_UnLock();
- ResDataObject SysLogNode;
- string guidstr;
- GUID DeviceGuid;
- //组Log包
- if (GetDeviceType(DeviceGuid))
- {
- guid_2_string(DeviceGuid, guidstr);
- SysLogNode.add("Module", guidstr.c_str());
- SysLogNode.add("AppId", pAppId);
- SysLogNode.add("ThreadId", GetCurrentThreadId());
- if (pCode)
- {
- SysLogNode.add("BusinessKey", pCode);
- }
- else
- {
- SysLogNode.add("BusinessKey", "");
- }
- SysLogNode.add("IP", (const char*)getLocalIpAddress());
- struct timeval tv;
- gettimeofday(&tv, nullptr);
- struct tm tm_time;
- localtime_r(&tv.tv_sec, &tm_time);
- string TimeTag = FormatstdString("%04d-%02d-%02d %02d:%02d:%02d.%03ld",
- tm_time.tm_year + 1900, // 年份
- tm_time.tm_mon + 1, // 月份
- tm_time.tm_mday, // 日
- tm_time.tm_hour, // 时
- tm_time.tm_min, // 分
- tm_time.tm_sec, // 秒
- tv.tv_usec / 1000);
- SysLogNode.add("CreationTime", TimeTag.c_str());
- string strLevel = SysLogLevel2str(Level);
- SysLogNode.add("Level", strLevel.c_str());
- SysLogNode.add("HostName", (const char*)getLocalMachineId());
- SysLogNode.add("ProcessName", (const char*)GetModuleTitle());
- SysLogNode.add("FreeText", strResult.c_str());
- SysLogNode.add("Context", pCode);
- ResDataObject NotifyData;
- PacketAnalizer::MakeNotify(NotifyData, PACKET_CMD_MSG, "Syslog", SysLogNode);
- SendNotify(&NotifyData);
- //PublishAction(&NotifyData, (m_strEBusRoot + "/Notify").c_str(), m_pMqttConntion);
- }
- else
- {
- //mLog::FINFO("no Guid??");
- return RET_FAILED;
- }
- //打印LOG
- switch (Level)
- {
- case Syslog_Debug:
- //RES_PRINTA_DEBUG(m_pLogger, SysLogNode, "SysLog");
- //mLog::FDEBUG("SysLog {$} ", SysLogNode.encode());
- break;
- case Syslog_Information:
- ///RES_PRINTA_INFO(m_pLogger, SysLogNode, "SysLog");
- //mLog::FINFO("SysLog {$} ", SysLogNode.encode());
- break;
- case Syslog_Warning:
- //RES_PRINTA_WARN(m_pLogger, SysLogNode, "SysLog");
- //mLog::Warn("SysLog {$} ", SysLogNode.encode());
- break;
- case Syslog_Error:
- //RES_PRINTA_ERROR(m_pLogger, SysLogNode, "SysLog");
- //mLog::FERROR("SysLog {$} ", SysLogNode.encode());
- break;
- case Syslog_Fatal:
- //RES_PRINTA_FATAL(m_pLogger, SysLogNode, "SysLog");
- //mLog::FINFO("SysLog {$} ", SysLogNode.encode());
- break;
- default:
- //mLog::FINFO("SysLog {$} ", SysLogNode.encode());
- break;
- }
- return RET_SUCCEED;
- }
- RET_STATUS ModuleDevice::SystemLog(SYSLOGLEVEL Level, const char* pCode, const char* fmt, ...)
- {
- std::string strResult = "";
- //组Context包
- //if (m_pLogger)
- //{
- // m_pLogger->Thread_Lock();
- // if (NULL != fmt)
- // {
- // va_list marker = NULL;
- // va_start(marker, fmt);
- // size_t nLength = _vscprintf(fmt, marker) + 1;
- // std::vector<char> vBuffer(nLength, '\0');
- // int nWritten = vsnprintf_s(&vBuffer[0], vBuffer.size(), nLength, fmt, marker);
- // if (nWritten > 0)
- // {
- // strResult = &vBuffer[0];
- // }
- // va_end(marker);
- // }
- // m_pLogger->Thread_UnLock();
- //}
- //else
- {
- Thread_Lock();
- if (fmt != nullptr) // 使用 nullptr 代替 NULL
- {
- va_list marker;
- va_start(marker, fmt);
- // 计算格式化字符串所需长度(不包括终止空字符)
- va_list args_copy;
- va_copy(args_copy, marker); // 复制参数列表
- int nLength = vsnprintf(nullptr, 0, fmt, args_copy); // Linux下获取长度的方法
- va_end(args_copy);
- if (nLength < 0) {
- // 处理错误:格式化失败
- va_end(marker);
- // 这里可以添加错误处理逻辑
- }
- else {
- // 分配足够空间(包括终止空字符)
- std::vector<char> vBuffer(nLength + 1, '\0');
- // 实际执行格式化
- int nWritten = vsnprintf(vBuffer.data(), vBuffer.size(), fmt, marker);
- if (nWritten >= 0 && static_cast<size_t>(nWritten) < vBuffer.size()) {
- strResult = vBuffer.data(); // 直接赋值给结果字符串
- }
- // 如果 nWritten 无效则保持 strResult 不变
- }
- va_end(marker);
- }
- Thread_UnLock();
- }
- ResDataObject SysLogNode;
- string guidstr;
- GUID DeviceGuid;
- //组Log包
- if (GetDeviceType(DeviceGuid))
- {
- guid_2_string(DeviceGuid, guidstr);
- SysLogNode.add("Module", guidstr.c_str());
- SysLogNode.add("AppId", "");
- SysLogNode.add("ThreadId", GetCurrentThreadId());
- if (pCode)
- {
- SysLogNode.add("BusinessKey", pCode);
- }
- else
- {
- SysLogNode.add("BusinessKey", "");
- }
- SysLogNode.add("IP", (const char*)getLocalIpAddress());
- struct timeval tv;
- gettimeofday(&tv, nullptr);
- struct tm tm_time;
- localtime_r(&tv.tv_sec, &tm_time);
- string TimeTag = FormatstdString("%04d-%02d-%02d %02d:%02d:%02d.%03ld",
- tm_time.tm_year + 1900, // 年份
- tm_time.tm_mon + 1, // 月份
- tm_time.tm_mday, // 日
- tm_time.tm_hour, // 时
- tm_time.tm_min, // 分
- tm_time.tm_sec, // 秒
- tv.tv_usec / 1000);
- SysLogNode.add("CreationTime", TimeTag.c_str());
- SysLogNode.add("Level", Level);
- SysLogNode.add("HostName", (const char*)getLocalMachineId());
- SysLogNode.add("ProcessName", (const char*)GetModuleTitle());
- SysLogNode.add("FreeText", strResult.c_str());
- ResDataObject NotifyData;
- PacketAnalizer::MakeNotify(NotifyData, PACKET_CMD_MSG, "Syslog", SysLogNode);
- SendNotify(&NotifyData);
- //PublishAction(&NotifyData, (m_strEBusRoot + "/Notify").c_str(), m_pMqttConntion);
- if (m_pParent != nullptr)
- NotifyParent(&NotifyData, "/Notify");
- }
- else
- {
- //mLog::FERROR("no Guid??");
- return RET_FAILED;
- }
- //打印LOG
- switch (Level)
- {
- case Syslog_Debug:
- //RES_PRINTA_DEBUG(m_pLogger, SysLogNode, "SysLog");
- //mLog::FDEBUG("SysLog {$}", SysLogNode.encode());
- break;
- case Syslog_Information:
- //RES_PRINTA_INFO(m_pLogger, SysLogNode, "SysLog");
- //mLog::FINFO("SysLog {$}", SysLogNode.encode());
- break;
- case Syslog_Warning:
- //RES_PRINTA_WARN(m_pLogger, SysLogNode, "SysLog");
- //mLog::Warn("SysLog {$}", SysLogNode.encode());
- break;
- case Syslog_Error:
- //RES_PRINTA_ERROR(m_pLogger, SysLogNode, "SysLog");
- //mLog::FERROR("SysLog {$}", SysLogNode.encode());
- break;
- case Syslog_Fatal:
- //RES_PRINTA_FATAL(m_pLogger, SysLogNode, "SysLog");
- //mLog::FINFO("SysLog {$}", SysLogNode.encode());
- break;
- default:
- //mLog::FINFO("SysLog {$}", SysLogNode.encode());
- break;
- }
- return RET_SUCCEED;
- }
- RET_STATUS ModuleDevice::Request(ResDataObject PARAM_IN* pRequest, ResDataObject PARAM_OUT* pResponse)
- {
- INT ret = RET_NOSUPPORT;
- PACKET_CMD cmd = PacketAnalizer::GetPacketCmd(pRequest);
- PACKET_TYPE type = PacketAnalizer::GetPacketType(pRequest);
- string keystr = PacketAnalizer::GetPacketKey(pRequest);
- ResDataObject Context;
- if (PacketAnalizer::GetPacketContext(pRequest, Context) == false)
- {
- return RET_FAILED;
- }
- ResDataObject resReponse;
- if (type == PACKET_TYPE_NOTIFY)
- {
- //通知类,不需要答复
- return RET_SUCCEED;
- }
- else if (type == PACKET_TYPE_RES)
- {
- //收到了应答包。。。
- return RET_SUCCEED;
- }
- if (cmd == PACKET_CMD_EXE)
- {
- string req, res;
- req = (const char*)Context.encode();
- //mLog::FINFO("Action[{$}].req:{$}", keystr.c_str(), req.c_str());
- ret = DevAction("", keystr.c_str(), req.c_str(), resReponse);
-
- pResponse->update("CONTEXT", resReponse);
- //mLog::FINFO("Action res packet done");
- }
- else if (cmd == PACKET_CMD_GET)
- {
- string res;
- //mLog::FINFO("get CMD_GET req:{$}", keystr.c_str());
- ret = DevGet(m_strCCOSDevicePath.c_str(), keystr.c_str(), resReponse);
- pResponse->update("CONTEXT", resReponse);
- }
- else if (cmd == PACKET_CMD_UPDATE)
- {
- //mLog::FINFO("get CMD_UPDATE req:{$}", keystr.c_str());
- ret = DevUpdate(m_strCCOSDevicePath.c_str(), keystr.c_str(), Context, resReponse);
- pResponse->update("CONTEXT", resReponse);
- }
- else if (cmd == PACKET_CMD_SET)
- {
- //mLog::FINFO("get CMD_UPDATE req:{$}", keystr.c_str());
- ret = DevSet(m_strCCOSDevicePath.c_str(), keystr.c_str(), Context, resReponse);
- pResponse->update("CONTEXT", resReponse);
- }
- else if (cmd == PACKET_CMD_MSG)
- {
- //mLog::FINFO("get CMD_UPDATE req:{$}", keystr.c_str());
- ret = DevMessage(m_strCCOSDevicePath.c_str(), keystr.c_str(), Context, resReponse);
- pResponse->update("CONTEXT", resReponse);
- }
- else if (cmd == PACKET_CMD_ADD)
- {
- //mLog::FINFO("get CMD_ADD req:{$}", keystr.c_str());
- ret = DevAdd(m_strCCOSDevicePath.c_str(), keystr.c_str(), Context, resReponse);
- pResponse->update("CONTEXT", resReponse);
- }
- else if (cmd == PACKET_CMD_DEL)
- {
- //mLog::FINFO("get CMD_DEL req:{$}", keystr.c_str());
- ret = DevDel(m_strCCOSDevicePath.c_str(), keystr.c_str(), Context, resReponse);
- pResponse->update("CONTEXT", resReponse);
- }
- else
- {
- //wtf?? 忽略掉
- return RET_SUCCEED;
- }
- PacketAnalizer::MakeRetCode((RET_STATUS)ret, pResponse);
- return (RET_STATUS)ret;
- }
- RET_STATUS ModuleDevice::CmdToLogicDev(ResDataObject PARAM_IN* pCmd)
- {
- return RET_SUCCEED;
- }
- bool ModuleDevice::GetDeviceType(GUID& DevType)
- {
- return true;
- }
- void ModuleDevice::SubscribeSelf()
- {
- LogicDevice::SubscribeSelf();
- }
- bool ModuleDevice::CheckSubDevice()
- {
- //mLog::FINFO("Begin");
- //mLog::FINFO("{$} have {$} SubDevices", m_strCCOSDevicePath, m_subCcosDevices.size());
- if (m_subCcosDevices.size() > 0)
- {
- //有子设备,则构建模型设备树
- ResDataObject resSub;
- ResDataObject subList;
- for (int y = 0; y < m_subCcosDevices.size(); y++)
- {
- subList.add(m_subCcosDevices[y]->GetCcosRootPath().c_str(), "");
- //mLog::FINFO("{$} devpath {$}", y, m_subCcosDevices[y]->GetCcosRootPath());
- }
- resSub.add("Value", subList);
- resSub.add("DescKey", "SubDevice");
- m_resProperties.update("SubDevice", resSub);
- return true;
- }
- return false;
- }
- void ModuleDevice::OnSetClientID()
- {
- //这里根据 CCOS设备 路径决定加载什么配置
- LogicDevice::OnSetClientID();
- string configName;
- if (m_strModuleFileName.length() <= 0)
- {
- //标准设备
- string devicePath = m_strCCOSDevicePath;
- //CCOS/DEVICE, 11个字符
- if (devicePath.substr(0, 11) == "CCOS/DEVICE")
- {
- //是设备
- //todo 要生成模型文件名
- string module = devicePath.substr(12);
- configName = module;
- int x, moduleLen,spCount = 0;
- for (x = 0; x < module.length(); x++)
- {
- if (module[x] == '/')
- {
- if(spCount <= 3)
- module[x] = '_';
- configName[x] = '_';
- spCount++;
- if (spCount == 3)
- {
- moduleLen = x;
- }
- }
- }
- module = module.substr(0, moduleLen);
- module += ".json";
- m_strModuleFileName = module;
- configName += ".json";
- }
- }
- else
- {
- configName = m_strModuleFileName;
- }
- if (m_strModuleFileName.length() <= 0)
- {
- //没有取到模型名
- return;
- }
- if (m_bSendIndependently)
- {
- m_strSendClientID = m_strClientID + "_Sender";
- std::cout << " ModuleDevice::OnSetClientID New Connection.." << endl;
- m_pSendConn = NewConnection(m_strServer.c_str(), m_strServerPort.c_str(), m_strMqttUser.c_str(), m_strMqttPassword.c_str(), m_strSendClientID.c_str(),
- [this](ResDataObject* req, const char* topic, void* conn) {
- //mLog::FINFO("Got msg from [$] body: {$}", topic, req->encode());
- //CmdToLogicDev(req);
- });
- }
- string tmplPath, modulePath = GetProcessDirectory();
- modulePath += "/DriverDefine/";
- tmplPath = modulePath;
- string configPath = modulePath ;
- modulePath += m_strModuleFileName;
- configPath += "Config/";
- mkdir(configPath.c_str(), 0755);
- configPath += configName;
- try {
- m_resModuleConfig.loadFile(modulePath.c_str());
- m_strModuleFilePath = modulePath;
- //mLog::FINFO("Got module file [{$}] Read file path [{$}] ok.", m_strModuleFileName, modulePath);
- }
- catch (...)
- {
- //mLog::FINFO("Got module file [{$}] but Read file path [{$}] failed.", m_strModuleFileName, modulePath);
- //没有配置模型文件,尝试寻找通用模型文件
- std::vector<string> devVec;
- SplitCcosDevicePath(m_strCCOSDevicePath, devVec);
- if (devVec.size() >= 3)
- {
- string type = devVec[2];
- tmplPath += type;
- tmplPath += ".json";
- try {
- ResDataObject resTest;
- resTest.loadFile(tmplPath.c_str());
- std::filesystem::copy_file(
- tmplPath, // 源文件路径
- modulePath, // 目标文件路径
- std::filesystem::copy_options::overwrite_existing // 覆盖已存在文件
- );
- // mLog::FINFO("Copied template module file from {$} to {$}", tmplPath, modulePath);
- m_resModuleConfig.loadFile(modulePath.c_str());
- m_strModuleFilePath = modulePath;
- }
- catch (const std::exception& e) { // 捕获标准异常
- // mLog::FERROR("File operation failed: {$}", e.what());
- // mLog::FINFO("There is still no template module file {$}", tmplPath);
- return;
- }
- catch (...) { // 保留捕获所有异常的兜底逻辑
- // mLog::FINFO("There is still no template module file {$}", tmplPath);
- return;
- }
- }
- else
- return;
- }
- if (configName.length() > 0)
- {
- try {
- ResDataObject resConfig;
- resConfig.loadFile(configPath.c_str());
- m_resProperties = resConfig[0];
- m_strConfigFilePath = configPath;
- if (CheckSubDevice())
- {
- SaveToConfigFile();
- }
- //mLog::FINFO("Got config file path [{$}] Read content ok. [{$}]", m_strConfigFilePath, m_resProperties.encode());
- }
- catch (...)
- {
- //没有取到配置,则保存默认配置
- m_strConfigFilePath = configPath;
- ResDataObject resConfig;
- m_resProperties = m_resModuleConfig["Get"];
- CheckSubDevice();
- resConfig.add("CONFIGURATION", m_resProperties);
- resConfig.SaveFile(m_strConfigFilePath.c_str());
- //mLog::FINFO("No config file at path [{$}] Save content ok. [{$}]", m_strConfigFilePath, m_resProperties.encode());
- }
- }
- else
- {
- m_resProperties = m_resModuleConfig["Get"];
- }
- //mLog::FINFO("Module Content: {$}", m_resModuleConfig.encode());
- //{
- // ResDataObject points = m_resProperties["ABSCurve"]["Value"]["Curve1"]["Points"];
- // for (int x = 0; x < points.size(); x++)
- // {
- // //mLog::FINFO("Array ? [{$}] value {$}", points.GetKey(x), points[x].encode());
- // }
- //}
- if(m_resModuleConfig.GetKeyCount("Get") > 0)
- m_resGets = m_resModuleConfig["Get"];
- if (m_resModuleConfig.GetKeyCount("Set") > 0)
- m_resSets = m_resModuleConfig["Set"];
- if (m_resModuleConfig.GetKeyCount("Add") > 0)
- m_resAdds = m_resModuleConfig["Add"];
- if (m_resModuleConfig.GetKeyCount("Del") > 0)
- m_resDels = m_resModuleConfig["Del"];
- if (m_resModuleConfig.GetKeyCount("Update") > 0)
- {
- //mLog::FINFO("WHAT ? {$}", m_resModuleConfig["Update"].encode());
- m_resUpdates = m_resModuleConfig["Update"];
- }
- if (m_resModuleConfig.GetKeyCount("Action") > 0)
- m_resActions = m_resModuleConfig["Action"];
- }
- RET_STATUS ModuleDevice::SendNotify(ResDataObject* pCmd)
- {
- RET_STATUS ret = RET_FAILED;
- if (m_bSendIndependently && m_pSendConn != nullptr)
- {
- PACKET_CMD cmd = PacketAnalizer::GetPacketCmd(pCmd);
- PACKET_TYPE type = PacketAnalizer::GetPacketType(pCmd);
- if (type == PACKET_TYPE_NOTIFY)
- {
- CcosDevFileHandle* pHandle = new CcosDevFileHandle;
- PacketAnalizer::UpdateNotifyHandle(*pCmd, *pHandle);
- //mLog::FINFO("Notify Transaction: {$}", m_strCurTransaction);
- PacketAnalizer::UpdatePacketTransaction(*pCmd, m_strCurTransaction);
- ;
- if (m_strEBusRoot.length() <= 0)
- {
- //mLog::FINFO("EBusRoot is null");
- }
- //服务使用 m_pMqttConntion 区分子系统设备
- PacketAnalizer::UpdateDeviceNotifyResponse(*pCmd, getLocalMachineId(), getLocalEbusId(), (UINT64)getpid(), (UINT64)m_pMqttConntion);
- //mLog::FINFO("[{$}] Notify: {$}", m_strSendClientID, pCmd->encode());
- //printf("--> %s \n", pCmd->encode());
- PacketAnalizer::UpdatePacketTopic(pCmd, (m_strEBusRoot + "/Notify").c_str(), m_strSendClientID.c_str());
- PublishAction(pCmd, (m_strEBusRoot + "/Notify").c_str(), m_pSendConn);
- string strNotifyPath = "/Notify/" + PacketAnalizer::GetPacketKey(pCmd);
- PacketAnalizer::UpdatePacketTopic(pCmd, (m_strCCOSDevicePath + strNotifyPath).c_str(), m_strSendClientID.c_str());
- PublishAction(pCmd, (m_strCCOSDevicePath + strNotifyPath).c_str(), m_pSendConn);
- if (m_strAbstractPath.length() > 0)
- {
- PublishAction(pCmd, (m_strAbstractPath + strNotifyPath).c_str(), m_pSendConn);
- string realPath, devPath;
- devPath = m_strAbstractPath.substr(((string)"CCOS/DEVICE").length());
- for (int x = 0; x < m_rsOnlineGroup.size(); x++)
- {
- if ((int)m_rsOnlineGroup[x] == 1)
- {
- realPath = "CCOS/" + (string)m_rsOnlineGroup.GetKey(x) + devPath + strNotifyPath;
- PublishAction(pCmd, realPath.c_str(), m_pSendConn);
- }
- }
- } //m_pPacketSendingQue->InQueue(*pCmd);
- delete pHandle;
- }
- return RET_SUCCEED;
- }
- else
- {
- CmdFromLogicDev(pCmd);
- }
- return ret;
- }
- RET_STATUS ModuleDevice::NotifyProperty(const char* property)
- {
- RET_STATUS ret = RET_SUCCEED;
- ResDataObject resValue;
- if (m_resProperties.GetKeyCount(property) > 0 && m_resProperties[property].GetKeyCount("Value") > 0)
- {
- resValue = m_resProperties[property]["Value"];
- ResDataObject notify;
- PacketAnalizer::MakeNotify(notify, PACKET_CMD_UPDATE, property, resValue.encode());
- PacketAnalizer::UpdatePacketContext(notify, resValue);
- SendNotify(¬ify);
- return ret;
- }
- return RET_NOSUPPORT;
- }
- RET_STATUS ModuleDevice::GetDeviceResource(ResDataObject PARAM_OUT* pDeviceResource)
- {
- //父类会生成Ations
- LogicDevice::GetDeviceResource(pDeviceResource);
- //ResDataObject getPerp = m_resModuleConfig["Get"];
- for (int x = 0; x < m_resProperties.size(); x++)
- {
- (*pDeviceResource)["Attribute"].update(m_resProperties.GetKey(x), m_resProperties[x]["Value"]);
- }
- /*/
- {
- ResDataObject resAll;
- DevGet("", "", resAll);
- for (int x = 0; x < resAll.size(); x++)
- (*pDeviceResource)["Attribute"].update(resAll.GetKey(x), resAll[x]["Value"]);
- }
- //*/
- pDeviceResource->update("ClientType", DPC_UnitClient);
- pDeviceResource->add("Get", m_resProperties);
-
- ResDataObject setPerp, updatePerp, addPerp, delPerp, actionPerp, msgPerp;
- if (m_resSets.size() <= 0)
- setPerp = m_resModuleConfig["Set"];
- else
- setPerp = m_resSets;
- pDeviceResource->add("Set", setPerp);
-
- if (m_resUpdates.size() <= 0)
- updatePerp = m_resModuleConfig["Update"];
- else
- updatePerp = m_resUpdates;
- pDeviceResource->add("Update", updatePerp);
- if (m_resAdds.size() <= 0)
- addPerp = m_resModuleConfig["Add"];
- else
- addPerp = m_resAdds;
- pDeviceResource->add("Add", addPerp);
- if (m_resDels.size() <= 0)
- delPerp = m_resModuleConfig["Del"];
- else
- delPerp = m_resDels;
- pDeviceResource->add("Del", delPerp);
- actionPerp = m_resModuleConfig["Action"];
- for (int x = 0; x < actionPerp.size(); x++)
- {
- (*pDeviceResource)["Action"].update(actionPerp.GetKey(x), actionPerp[x]);
- }
- //msgPerp = m_resModuleConfig["Message"];
- return RET_SUCCEED;
- }
- /// <summary>
- /// 枚举配置项,level == "Public" ,仅返回Pulic
- /// level == "E-COM" ,返回 Public 和 E-COM
- /// level == "Private" , 返回所有
- /// </summary>
- /// <param name="level">三个固定常量字符串 "Public"/"E-COM"/"Private"</param>
- /// <param name="resItems"></param>
- /// <returns></returns>
- RET_STATUS ModuleDevice::GetUpdatableItems(string level, ResDataObject& resItems)
- {
- ResDataObject resUpdate;
- resUpdate = m_resModuleConfig["Update"];
- bool bOutput = false;
- for (int x = 0; x < resUpdate.size(); x++)
- {
- bOutput = false;
- string itemLevel;
- if (resUpdate[x].GetKeyCount("Level") > 0)
- {
- itemLevel = (const char*)resUpdate[x]["Level"];
- if (itemLevel == level)
- bOutput = true;
- else
- {
- if (level == "Private") {
- bOutput = true;
- }
- else if (level == "E-COM") {
- if (itemLevel == "Public" || itemLevel == "E-COM") {
- bOutput = true;
- }
- }
- }
- }
- else
- {
- //没有配置Level是Private
- if (level == "Private")
- bOutput = true;
- }
- if (bOutput)
- {
- resItems.update(resUpdate.GetKey(x), resUpdate[x]);
- }
- }
- return RET_SUCCEED;
- }
- /// <summary>
- /// 标准模型 是整体更新,如果是局部更新,需要重载自己写逻辑
- /// </summary>
- /// <param name="pszProperty"></param>
- /// <param name="pszValueUpdate"></param>
- /// <param name="resRespons"></param>
- /// <returns></returns>
- RET_STATUS ModuleDevice::UpdateItem(const char* pszProperty, const char* pszValueUpdate, ResDataObject& resRespons)
- {
- //保存到配置文件
- //
- ResDataObject resNewValue = m_resProperties[pszProperty];
- ResDataObject resUpdate;
- try
- {
- resUpdate.decode(pszValueUpdate);
- }
- catch (...)
- {
- resUpdate = pszValueUpdate;
- }
- if (resUpdate.size() > 0)
- {
- //是个对象字典
- for (int x = 0; x < resUpdate.size(); x++)
- {
- ResDataObject resv = resUpdate[x];
- if (resv.size() > 0)
- {
- //key: value (有值)更新
- resNewValue["Value"].update(resUpdate.GetKey(x), resUpdate[x]);
- }
- else
- {
- string value = (const char*)resv;
- if (value.length() > 0)
- {
- resNewValue["Value"].update(resUpdate.GetKey(x), resUpdate[x]);
- }
- else
- {
- //if (value == "Remove")
- //{
- resNewValue["Value"].eraseAllOf(resUpdate.GetKey(x));
- //}
- }
- }
- //resNewValue["Value"].update(resUpdate.GetKey(x), resUpdate[x]);
- }
- //mLog::FINFO("Save Object [{$}] new value {$}", pszProperty, resNewValue.encode());
- m_resProperties.update(pszProperty, resNewValue);
- //通知模型对象,值更新了
- return OnUpdate(pszProperty, m_resProperties[pszProperty]["Value"].encode(), resRespons);
- }
- else
- {
- resNewValue.update("Value", pszValueUpdate);
- //mLog::FINFO("Save [{$}] new value {$}", pszProperty, pszValueUpdate);
- m_resProperties[pszProperty].update("Value", pszValueUpdate);
- //通知模型对象,值更新了
- return OnUpdate(pszProperty, pszValueUpdate, resRespons);
- }
- }
- RET_STATUS ModuleDevice::OnMessage(const char* pszTopic, const char* pszMessageValue, ResDataObject& resResponse)
- {
- //mLog::FINFO("Message to {$} with {$}", pszTopic, pszMessageValue);
- return RET_SUCCEED;
- }
- RET_STATUS ModuleDevice::DevGet(const char* pszDevUri, const char* pszProperty, ResDataObject& resRespons)
- {
- string property = pszProperty;
- if (property.length() <= 0)
- {
- string key;
- for (int x = 0; x < m_resProperties.size(); x++)
- {
- key = m_resProperties.GetKey(x);
- if (GetItem(key.c_str(), resRespons) == RET_SUCCEED)
- {
- if (m_resProperties[x].GetKeyCount("Type") > 0 && string((const char*)m_resProperties[x]["Type"]) == "Switch")
- {
- string v = (const char*)resRespons;
- if (v == "YES" || v == "NO")
- {
- m_resProperties[key.c_str()].update("Value", v=="YES"?"1":"0");
- }
- else
- {
- m_resProperties[key.c_str()].update("Value", resRespons);
- }
- }
- else
- {
- m_resProperties[key.c_str()].update("Value", resRespons);
- }
- }
- }
- resRespons = m_resProperties;
- ResDataObject resMa,resMa2;
- //"": "Public",
- // "DescKey" : "TUBEHEAT",
- // "Value" : "0"
- resMa.add("Level", "Public");
- resMa.update("DescKey", "Manufacturer");
- resMa.update("Value", m_resModuleConfig["Manufacturer"]);
- resRespons.update("Manufacturer", resMa);
- resMa2.clear();
- resMa2.add("Level", "Public");
- resMa2.update("DescKey", "Model");
- resMa2.update("Value", m_resModuleConfig["Model"]);
- resRespons.update("Model", resMa2);
- resMa2.clear();
- resMa2.add("Level", "Public");
- resMa2.update("DescKey", "Modality");
- resMa2.update("Value", m_resModuleConfig["Modality"]);
- resRespons.update("Modality", resMa2);
- return RET_SUCCEED;
- }
- bool canGet = m_resGets.GetKeyCount(pszProperty) > 0;
- canGet &= m_resProperties.GetKeyCount(pszProperty) > 0;
- if (!canGet)
- return RET_NOSUPPORT;
- if (GetItem(pszProperty, resRespons) == RET_SUCCEED)
- {
- m_resProperties[pszProperty].update("Value", resRespons);
- }
- resRespons = m_resProperties[pszProperty]["Value"];
- return RET_SUCCEED;
- }
- RET_STATUS ModuleDevice::DevSet(const char* pszDevUri, const char* pszProperty, const char* pszValueSet, ResDataObject& resRespons)
- {
- bool canGet = m_resSets.GetKeyCount(pszProperty) > 0;
- canGet &= m_resProperties.GetKeyCount(pszProperty) > 0;
- if (!canGet)
- return RET_NOSUPPORT;
- ResDataObject resNewValue;
- resNewValue.decode(pszValueSet);
- RET_STATUS ret = SetItem(pszProperty, resNewValue, resRespons);
- if (ret == RET_SUCCEED)
- {
- m_resProperties[pszProperty].update("Value", resNewValue);
- NotifyProperty(pszProperty);
- }
- //通知模型对象,值更新了
- return ret;
- }
- RET_STATUS ModuleDevice::SaveToConfigFile()
- {
- RET_STATUS ret = RET_FAILED;
- if (m_strConfigFilePath.length() > 0)
- {
- ResDataObject resConfig;
- //m_resProperties = m_resModuleConfig["Get"];
- resConfig.add("CONFIGURATION", m_resProperties);
- if (resConfig.SaveFile(m_strConfigFilePath.c_str()))
- {
- //mLog::FINFO("Save Module Config file [{$}] content {$}", m_strConfigFilePath, resConfig.encode());
- }
- else
- {
- //mLog::FINFO("Failed Save Module Config file [{$}] content {$}", m_strConfigFilePath, resConfig.encode());
- }
- ret = RET_SUCCEED;
- }
- return ret;
- }
- RET_STATUS ModuleDevice::DevUpdate(const char* pszDevUri, const char* pszProperty, const char* pszValueUpdate, ResDataObject& resRespons)
- {
- string strProperty = pszProperty;
- if (strProperty.length() == 0)
- {
- //查询可以更新的属性
- string level = pszValueUpdate;
- if (level.length() <= 0)
- level = "Public";
- if (level == "Public" || level == "E-COM" || level == "Private")
- {
- //
- return GetUpdatableItems(level, resRespons);
- }
- level = "Public";
- return GetUpdatableItems(level, resRespons);
- }
- bool canGet = m_resUpdates.GetKeyCount(pszProperty) > 0;
- canGet &= m_resProperties.GetKeyCount(pszProperty) > 0;
- if (!canGet)
- return RET_NOSUPPORT;
- if (strProperty == "RestoreConfig")
- {
- //恢复出厂设置
- }
- RET_STATUS ret = UpdateItem(pszProperty, pszValueUpdate, resRespons);
- //mLog::FINFO("UpdateItem to Device [{$}] ret [{$}]", pszProperty, (int)ret);
- m_resModuleConfig.update("Get", m_resProperties);
- SaveToConfigFile();
- return ret;
- }
- RET_STATUS ModuleDevice::DevAdd(const char* pszDevUri, const char* pszProperty, const char* pszValueAdd, ResDataObject& resRespons)
- {
- bool canGet = m_resAdds.GetKeyCount(pszProperty) > 0;
- canGet &= m_resProperties.GetKeyCount(pszProperty) > 0;
- if (!canGet)
- return RET_NOSUPPORT;
- ResDataObject resNewValue;
- resNewValue.decode(pszValueAdd);
- for (int x = 0; x < resNewValue.size(); x++)
- {
- m_resProperties[pszProperty].update(resNewValue.GetKey(x), resNewValue[x]);
- }
- //m_resProperties.update(pszProperty, resNewValue);
- return OnAdd(pszProperty, resNewValue, resRespons);
- }
- RET_STATUS ModuleDevice::DevDel(const char* pszDevUri, const char* pszProperty, const char* pszValueDel, ResDataObject& resRespons)
- {
- bool canGet = m_resDels.GetKeyCount(pszProperty) > 0;
- canGet &= m_resProperties.GetKeyCount(pszProperty) > 0;
- if (!canGet)
- return RET_NOSUPPORT;
- ResDataObject resDelValue;
- string strDel = pszValueDel;
- if (strDel.length() < 0)
- {
- //什么参数都没有,清除所有数据
- m_resProperties[pszProperty].clear();
- return OnDel(pszProperty, resDelValue, resRespons);
- }
- resDelValue.decode(pszValueDel);
- string key = pszProperty;
- if (key == "ErrorList")
- {
- //如果是ErrorList,提供单独删除某类错误的能力
- int nIndex = resDelValue.GetFirstOf("ErrorIndex");
- if (nIndex >= 0)
- {
- nIndex = (int)resDelValue["ErrorIndex"];
- if (nIndex >= 0 && nIndex < (m_resProperties[key.c_str()]).size())
- {
- //m_resProperties[key.c_str()].eraseOneOf()
- }
- }
- }
- if (RET_SUCCEED == OnDel(pszProperty, resDelValue, resRespons))
- {
- m_resProperties.update(pszProperty, resRespons);
- return RET_SUCCEED;
- }
- return RET_SUCCEED;
- }
- RET_STATUS ModuleDevice::DevAction(const char* pszDevUri, const char* pszActionName, const char* pszParams, ResDataObject& resRespons)
- {
- cout << "ModuleDevice::DevAction - Entering. pszDevUri: " << (pszDevUri ? pszDevUri : "nullptr")
- << ", pszActionName: " << (pszActionName ? pszActionName : "nullptr")
- << ", pszParams: " << (pszParams ? pszParams : "nullptr") << endl;
- bool canGet = m_resActions.GetKeyCount(pszActionName) > 0;
- if (!canGet)
- return RET_NOSUPPORT;
- RET_STATUS ret = OnAction(pszActionName, pszParams, resRespons);
- //mLog::FINFO("Got Action {$} with param {$} to {$} ret {$} Result {$}", pszActionName, pszDevUri, pszParams, (int)ret, resRespons.encode());
- return ret;
- }
- RET_STATUS ModuleDevice::DevMessage(const char* pszDevUri, const char* pszTopic, const char* pszMessageValue, ResDataObject& resRespons)
- {
- return OnMessage(pszTopic, pszMessageValue, resRespons);
- }
- RET_STATUS ModuleDevice::OnUpdate(const char* pszProperty, const char* pszValueUpdate, ResDataObject& resRespons)
- {
- RET_STATUS ret = RET_NOSUPPORT;
- return ret;
- }
- RET_STATUS ModuleDevice::OnDel(const char* pszPropery, ResDataObject& resDelValue, ResDataObject& resResponse)
- {
- RET_STATUS ret = RET_NOSUPPORT;
- return ret;
- }
- RET_STATUS ModuleDevice::OnAdd(const char* pszPropery, ResDataObject& reAddValue, ResDataObject& resResponse)
- {
- RET_STATUS ret = RET_NOSUPPORT;
- return ret;
- }
- RET_STATUS ModuleDevice::SetItem(const char* pszPropery, ResDataObject& resSetValue, ResDataObject& resResponse)
- {
- RET_STATUS ret = RET_NOSUPPORT;
- return ret;
- }
- RET_STATUS ModuleDevice::GetItem(const char* pszPropery, ResDataObject& resResponse)
- {
- RET_STATUS ret = RET_NOSUPPORT;
- return ret;
- }
- RET_STATUS ModuleDevice::OnAction(const char* pszActionName, const char* pszParams, ResDataObject& resResponse)
- {
- RET_STATUS ret = RET_NOSUPPORT;
- string strAction = pszActionName;
- if (strAction == "RestoreConfig")
- {
- //恢复出厂设置
- m_resProperties = m_resModuleConfig["Get"];
- SaveToConfigFile();
- ret = RET_SUCCEED;
- }
- return ret;
- }
|