12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250 |
- #include <string>
- #include <cstring>
- #include <clocale>
- #include <stdexcept>
- #include <filesystem>
- #include "ModuleDevice.h"
- #include "PacketAnalizer.h"
- #include "common_api.h"
- #include "LocalConfig.h"
- #include "Base64.h"
- #include "SystemLogger.hpp"
- #include "LogLocalHelper.h"
- #include "Log4CPP.h"
- ModuleDevice::ModuleDevice()
- {
- m_pSendConn = nullptr;
- m_bSendIndependently = false;
- string strLogPath = GetProcessDirectory() + R"(/Conf/log_config.xml)";
- string LogHost = (string)getRootpath();
- if (LogHost.length() <= 1)
- {
- char szName[256];
- sprintf(szName, "/LogicDevice_%08d", getpid());
- LogHost = szName;
- }
- std::string moduleName = "Platform";
- bool ret = initLogModule(
- LogHost, // 主机名(用于日志路径中的{host}占位符)
- moduleName, // 唯一模块名
- strLogPath, // 配置文件路径
- true // 是否输出到控制台(可选)
- );
- if (!ret) {
- std::cerr << "Log init failed!" << std::endl;
- }
- // 绑定当前动态库的模块名(调用自身实现的接口)
- DPC_SetLocalModuleName(moduleName);
- }
- 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
- {
- FINFO("no Guid??");
- return RET_FAILED;
- }
- //打印LOG
- switch (Level)
- {
- case Syslog_Debug:
- //RES_PRINTA_DEBUG(m_pLogger, SysLogNode, "SysLog");
- FDEBUG("SysLog {$} ", SysLogNode.encode());
- break;
- case Syslog_Information:
- ///RES_PRINTA_INFO(m_pLogger, SysLogNode, "SysLog");
- FINFO("SysLog {$} ", SysLogNode.encode());
- break;
- case Syslog_Warning:
- //RES_PRINTA_WARN(m_pLogger, SysLogNode, "SysLog");
- FWARN("SysLog {$} ", SysLogNode.encode());
- break;
- case Syslog_Error:
- //RES_PRINTA_ERROR(m_pLogger, SysLogNode, "SysLog");
- FERROR("SysLog {$} ", SysLogNode.encode());
- break;
- case Syslog_Fatal:
- //RES_PRINTA_FATAL(m_pLogger, SysLogNode, "SysLog");
- FINFO("SysLog {$} ", SysLogNode.encode());
- break;
- default:
- 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
- {
- FERROR("no Guid??");
- return RET_FAILED;
- }
- //打印LOG
- switch (Level)
- {
- case Syslog_Debug:
- //RES_PRINTA_DEBUG(m_pLogger, SysLogNode, "SysLog");
- FDEBUG("SysLog {$}", SysLogNode.encode());
- break;
- case Syslog_Information:
- //RES_PRINTA_INFO(m_pLogger, SysLogNode, "SysLog");
- FINFO("SysLog {$}", SysLogNode.encode());
- break;
- case Syslog_Warning:
- //RES_PRINTA_WARN(m_pLogger, SysLogNode, "SysLog");
- FWARN("SysLog {$}", SysLogNode.encode());
- break;
- case Syslog_Error:
- //RES_PRINTA_ERROR(m_pLogger, SysLogNode, "SysLog");
- FERROR("SysLog {$}", SysLogNode.encode());
- break;
- case Syslog_Fatal:
- //RES_PRINTA_FATAL(m_pLogger, SysLogNode, "SysLog");
- FINFO("SysLog {$}", SysLogNode.encode());
- break;
- default:
- 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();
- FINFO("Action[{$}].req:{$}", keystr.c_str(), req.c_str());
- ret = DevAction("", keystr.c_str(), req.c_str(), resReponse);
-
- pResponse->update("CONTEXT", resReponse);
- FINFO("Action res packet done");
- }
- else if (cmd == PACKET_CMD_GET)
- {
- string res;
- 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)
- {
- 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)
- {
- 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)
- {
- 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)
- {
- 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)
- {
- 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()
- {
- FINFO("Begin");
- 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(), "");
- 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) {
- 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;
- FINFO("Got module file [{$}] Read file path [{$}] ok.", m_strModuleFileName, modulePath);
- }
- catch (...)
- {
- 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();
- }
- 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());
- FINFO("No config file at path [{$}] Save content ok. [{$}]", m_strConfigFilePath, m_resProperties.encode());
- }
- }
- else
- {
- m_resProperties = m_resModuleConfig["Get"];
- }
- FINFO("Module Content: {$}", m_resModuleConfig.encode());
- //{
- // ResDataObject points = m_resProperties["ABSCurve"]["Value"]["Curve1"]["Points"];
- // for (int x = 0; x < points.size(); x++)
- // {
- // 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)
- {
- 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);
- FINFO("Notify Transaction: {$}", m_strCurTransaction);
- PacketAnalizer::UpdatePacketTransaction(*pCmd, m_strCurTransaction);
- ;
- if (m_strEBusRoot.length() <= 0)
- {
- FINFO("EBusRoot is null");
- }
- //服务使用 m_pMqttConntion 区分子系统设备
- PacketAnalizer::UpdateDeviceNotifyResponse(*pCmd, getLocalMachineId(), getLocalEbusId(), (UINT64)getpid(), (UINT64)m_pMqttConntion);
- 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]);
- }
- 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);
- 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)
- {
- 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()))
- {
- FINFO("Save Module Config file [{$}] content {$}", m_strConfigFilePath, resConfig.encode());
- }
- else
- {
- 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);
- 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);
- 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;
- }
|